URI: 
       tUpdate various stuff - ltkx - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltkx.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit bfc883141ea28d04d8da91fa69dcd0dfeb01b6a0
   DIR parent eda322494fb1c420add7e80bf9ec112c8574f3b4
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Mon,  2 Jan 2017 12:07:15 +0100
       
       Update various stuff
       
       Change 'sticky' to a bitmask.
       Add 'ltk_create_widget' function to simplify widget creation.
       Start adding documentation.
       
       Diffstat:
         M button.c                            |      56 ++++++++++++++++---------------
         M button.h                            |       2 +-
         M common.c                            |       8 ++++----
         M common.h                            |      12 ++++++------
         M grid.c                              |      34 +++++++++++--------------------
         M grid.h                              |       2 +-
         M test1.c                             |      21 ++++++++++++++++-----
         M widget.c                            |      55 +++++++++++++++++++++++++------
         M widget.h                            |      20 ++++++++++++++------
       
       9 files changed, 128 insertions(+), 82 deletions(-)
       ---
   DIR diff --git a/button.c b/button.c
       t@@ -23,6 +23,12 @@
        
        #include "ltk.h"
        
       +/*
       + * Purpose: Extract style information for buttons.
       + * Parameters:
       + * button_json: A cJSON struct containing the JSON for the button style.
       + * Returns: An LtkButtonTheme struct containing the style for a button.
       + */
        LtkButtonTheme *ltk_parse_button_theme(cJSON *button_json)
        {
            LtkButtonTheme *button_theme = malloc(sizeof(LtkButtonTheme));
       t@@ -112,9 +118,13 @@ LtkButtonTheme *ltk_parse_button_theme(cJSON *button_json)
            return button_theme;
        }
        
       -void ltk_draw_button(void *widget)
       +/*
       + * Purpose: Draw a button in its current state.
       + * Parameters:
       + * button: Pointer to the button to draw.
       + */
       +void ltk_draw_button(LtkButton *button)
        {
       -    LtkButton *button = widget;
            LtkButtonTheme *theme = ltk_global->theme->button;
            LtkWindow *window = button->widget.window;
            LtkRect rect = button->widget.rect;
       t@@ -123,28 +133,28 @@ void ltk_draw_button(void *widget)
            int border_width;
            switch (button->widget.state)
            {
       -    case NORMAL:
       +    case LTK_NORMAL:
                border_color = theme->border_color;
                fill_color = theme->fill_color;
                border_width = theme->border_width;
                break;
       -    case HOVERACTIVE:
       -    case HOVER:
       +    case LTK_HOVERACTIVE:
       +    case LTK_HOVER:
                border_color = theme->border_color_hover;
                fill_color = theme->fill_color_hover;
                border_width = theme->border_width_hover;
                break;
       -    case PRESSED:
       +    case LTK_PRESSED:
                border_color = theme->border_color_pressed;
                fill_color = theme->fill_color_pressed;
                border_width = theme->border_width_pressed;
                break;
       -    case ACTIVE:
       +    case LTK_ACTIVE:
                border_color = theme->border_color_active;
                fill_color = theme->fill_color_active;
                border_width = theme->border_width_active;
                break;
       -    case DISABLED:
       +    case LTK_DISABLED:
                border_color = theme->border_color_disabled;
                fill_color = theme->fill_color_disabled;
                border_width = theme->border_width_disabled;
       t@@ -160,6 +170,15 @@ void ltk_draw_button(void *widget)
            XDrawRectangle(ltk_global->display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
        }
        
       +/*
       + * Purpose:    Create a button widget.
       + * Parameters:
       + * window:     The window the button will be shown on.
       + * text:       The text to be shown on the button.
       + * callback:   A function with no parameters or return
       + *             type to be called when the button is clicked.
       + * Returns:    A pointer to the newly created button.
       + */
        LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback)(void))
        {
            LtkButton *button = malloc(sizeof(LtkButton));
       t@@ -170,25 +189,8 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac
                    exit(1);
            }
        
       -    button->widget.window = window;
       -    button->widget.parent = NULL;
       -    button->widget.active_widget = NULL;
       -    button->widget.hover_widget = NULL;
       -    button->widget.key_press = NULL;
       -    button->widget.key_release = NULL;
       -    button->widget.mouse_press = NULL;
       +    button->widget = ltk_create_widget(window, &ltk_draw_button, &ltk_destroy_button, 1);
            button->widget.mouse_release = &ltk_button_mouse_release;
       -    button->widget.motion_notify = NULL;
       -    button->widget.resize = NULL;
       -    button->widget.draw = &ltk_draw_button;
       -    button->widget.destroy = &ltk_destroy_button;
       -    button->widget.redraw_state = 1;
       -    button->widget.rect.x = 0;
       -    button->widget.rect.y = 0;
       -    /* For testing, will default to size of text once text is implemented */
       -    button->widget.rect.w = 100;
       -    button->widget.rect.h = 100;
       -    button->widget.state = NORMAL;
        
            button->callback = callback;
            button->text = strdup(text);
       t@@ -210,7 +212,7 @@ void ltk_destroy_button(void *widget)
        void ltk_button_mouse_release(void *widget, XEvent event)
        {
            LtkButton *button = widget;
       -    if (button->widget.state == HOVERACTIVE && button->callback)
       +    if (button->widget.state == LTK_HOVERACTIVE && button->callback)
            {
                button->callback();
            }
   DIR diff --git a/button.h b/button.h
       t@@ -67,7 +67,7 @@ typedef struct LtkButtonTheme
        } LtkButtonTheme;
        
        LtkButtonTheme *ltk_parse_button_theme(cJSON *button_json);
       -void ltk_draw_button(void *widget);
       +void ltk_draw_button(LtkButton *button);
        LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback)(void));
        void ltk_button_key_event(void *widget, XEvent event);
        void ltk_button_mouse_event(void *widget, XEvent event);
   DIR diff --git a/common.c b/common.c
       t@@ -45,7 +45,7 @@ int ltk_collide_rect(LtkRect rect, int x, int y)
            return (rect.x <= x && (rect.x + rect.w) >= x && rect.y <= y && (rect.y + rect.h) >= y);
        }
        
       -/* Recursively set all active_widget states to NORMAL, redraw them,
       +/* Recursively set all active_widget states to LTK_NORMAL, redraw them,
         * and remove the references to them in their parent functions */
        void ltk_remove_active_widget(void *widget)
        {
       t@@ -55,7 +55,7 @@ void ltk_remove_active_widget(void *widget)
            while (parent->active_widget)
            {
                child = parent->active_widget;
       -        child->state = NORMAL;
       +        child->state = LTK_NORMAL;
                child->draw(child);
                parent->active_widget = NULL;
                parent = child;
       t@@ -74,7 +74,7 @@ void ltk_change_active_widget_state(void *widget, LtkWidgetState state)
            }
        }
        
       -/* Recursively set all hover_widget states to NORMAL, redraw them,
       +/* Recursively set all hover_widget states to LTK_NORMAL, redraw them,
         * and remove the references to them in their parent functions */
        void ltk_remove_hover_widget(void *widget)
        {
       t@@ -84,7 +84,7 @@ void ltk_remove_hover_widget(void *widget)
            while (parent->hover_widget)
            {
                child = parent->hover_widget;
       -        child->state = child->state == HOVERACTIVE ? ACTIVE : NORMAL;
       +        child->state = child->state == LTK_HOVERACTIVE ? LTK_ACTIVE : LTK_NORMAL;
                child->draw(child);
                parent->hover_widget = NULL;
                parent = child;
   DIR diff --git a/common.h b/common.h
       t@@ -29,12 +29,12 @@ typedef struct LtkWidget LtkWidget;
        
        typedef enum
        {
       -    NORMAL,
       -    HOVER,
       -    PRESSED,
       -    ACTIVE,
       -    HOVERACTIVE,
       -    DISABLED
       +    LTK_NORMAL,
       +    LTK_HOVER,
       +    LTK_PRESSED,
       +    LTK_ACTIVE,
       +    LTK_HOVERACTIVE,
       +    LTK_DISABLED
        } LtkWidgetState;
        
        typedef struct
   DIR diff --git a/grid.c b/grid.c
       t@@ -52,23 +52,11 @@ LtkGrid *ltk_create_grid(LtkWindow *window, int rows, int columns)
        {
            LtkGrid *grid = malloc(sizeof(LtkGrid));
        
       -    grid->widget.window = window;
       -    grid->widget.parent = NULL;
       +    grid->widget = ltk_create_widget(window, &ltk_draw_grid, &ltk_destroy_grid, 0);
            grid->widget.mouse_press = &ltk_grid_mouse_press;
            grid->widget.mouse_release = &ltk_grid_mouse_release;
            grid->widget.motion_notify = &ltk_grid_motion_notify;
       -    grid->widget.key_press = NULL;
       -    grid->widget.key_release = NULL;
            grid->widget.resize = &ltk_recalculate_grid;
       -    grid->widget.draw = &ltk_draw_grid;
       -    grid->widget.destroy = &ltk_destroy_grid;
       -    grid->widget.redraw_state = 0;
       -    grid->widget.rect.x = 0;
       -    grid->widget.rect.y = 0;
       -    grid->widget.rect.w = 0;
       -    grid->widget.rect.h = 0;
       -    grid->widget.active_widget = NULL;
       -    grid->widget.state = NORMAL;
        
            grid->rows = rows;
            grid->columns = columns;
       t@@ -194,11 +182,13 @@ void ltk_recalculate_grid(void *widget)
                    orig_height = ptr->rect.h;
                    end_row = i + ptr->row_span;
                    end_column = j + ptr->column_span;
       -            if (ptr->sticky[1] == 1 && ptr->sticky[3] == 1)
       +            if ((ptr->sticky & (LTK_STICKY_LEFT | LTK_STICKY_RIGHT)) ==
       +                (LTK_STICKY_LEFT | LTK_STICKY_RIGHT))
                    {
                        ptr->rect.w = grid->column_pos[end_column] - grid->column_pos[j];
                    }
       -            if (ptr->sticky[0] == 1 && ptr->sticky[2] == 1)
       +            if ((ptr->sticky & (LTK_STICKY_TOP | LTK_STICKY_BOTTOM)) ==
       +                (LTK_STICKY_TOP | LTK_STICKY_BOTTOM))
                    {
                        ptr->rect.h = grid->row_pos[end_row] - grid->row_pos[i];
                    }
       t@@ -210,11 +200,11 @@ void ltk_recalculate_grid(void *widget)
                        }
                    }
        
       -            if (ptr->sticky[1] == 1)
       +            if ((ptr->sticky & LTK_STICKY_RIGHT) == LTK_STICKY_RIGHT)
                    {
                        ptr->rect.x = grid->column_pos[end_column] - ptr->rect.w;
                    }
       -            else if (ptr->sticky[3] == 1)
       +            else if ((ptr->sticky & LTK_STICKY_LEFT) == LTK_STICKY_LEFT)
                    {
                        ptr->rect.x = grid->column_pos[j];
                    }
       t@@ -223,11 +213,11 @@ void ltk_recalculate_grid(void *widget)
                        ptr->rect.x = grid->column_pos[j] + ((grid->column_pos[end_column] - grid->column_pos[j]) / 2 - ptr->rect.w / 2);
                    }
        
       -            if (ptr->sticky[2] == 1)
       +            if ((ptr->sticky & LTK_STICKY_BOTTOM) == LTK_STICKY_BOTTOM)
                    {
                        ptr->rect.y = grid->row_pos[end_row] - ptr->rect.h;
                    }
       -            else if (ptr->sticky[0] == 1)
       +            else if ((ptr->sticky & LTK_STICKY_TOP) == LTK_STICKY_TOP)
                    {
                        ptr->rect.y = grid->row_pos[i];
                    }
       t@@ -239,10 +229,10 @@ void ltk_recalculate_grid(void *widget)
            }
        }
        
       -void ltk_grid_widget(void *ptr, LtkGrid *grid, int row, int column, int row_span, int column_span, int sticky[4])
       +void ltk_grid_widget(void *ptr, LtkGrid *grid, int row, int column, int row_span, int column_span, unsigned short sticky)
        {
            LtkWidget *widget = ptr;
       -    memcpy(widget->sticky, sticky, 4 * sizeof(int));
       +    widget->sticky = sticky;
            widget->row = row;
            widget->column = column;
            widget->row_span = row_span;
       t@@ -315,7 +305,7 @@ ltk_grid_mouse_release(void *widget, XEvent event)
                else
                {
                    ltk_remove_hover_widget(grid);
       -            ltk_change_active_widget_state(grid, ACTIVE);
       +            ltk_change_active_widget_state(grid, LTK_ACTIVE);
                }
            }
        }
   DIR diff --git a/grid.h b/grid.h
       t@@ -46,7 +46,7 @@ void ltk_draw_grid(LtkGrid *grid);
        LtkGrid *ltk_create_grid(LtkWindow *window, int rows, int columns);
        void ltk_destroy_grid(void *widget);
        void ltk_recalculate_grid(void *widget);
       -void ltk_grid_widget(void *ptr, LtkGrid *grid, int row, int column, int rowspan, int columnspan, int sticky[4]);
       +void ltk_grid_widget(void *ptr, LtkGrid *grid, int row, int column, int rowspan, int columnspan, unsigned short sticky);
        void ltk_grid_mouse_press(void *widget, XEvent event);
        void ltk_grid_mouse_release(void *widget, XEvent event);
        void ltk_grid_motion_notify(void *widget, XEvent event);
   DIR diff --git a/test1.c b/test1.c
       t@@ -5,6 +5,15 @@ void bob1(void)
            printf("bob\n");
        }
        
       +void bob2(void *widget, XEvent event)
       +{
       +    LtkButton *button = widget;
       +    if (button->widget.state == LTK_HOVERACTIVE)
       +    {
       +        ltk_quit();
       +    }
       +}
       +
        int main(int argc, char *argv[])
        {
            ltk_init("themes/default.json");
       t@@ -15,14 +24,16 @@ int main(int argc, char *argv[])
            ltk_set_row_weight(grid1, 1, 1);
            ltk_set_column_weight(grid1, 0, 1);
            ltk_set_column_weight(grid1, 1, 1);
       +    /* Test callback functions */
            LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1);
       -    int sticky1[4] = {0, 1, 0, 1};
       -    ltk_grid_widget(button1, grid1, 0, 0, 1, 1, sticky1);
       +    ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT);
       +    /* Test manual callback functions */
            LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL);
       -    ltk_grid_widget(button2, grid1, 0, 1, 1, 1, sticky1);
       +    button2->widget.mouse_release = &bob2;
       +    ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM);
            LtkButton *button3 = ltk_create_button(window1, "I'm a button!", NULL);
       -    ltk_grid_widget(button3, grid1, 1, 0, 1, 1, sticky1);
       +    ltk_grid_widget(button3, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
            LtkButton *button4 = ltk_create_button(window1, "I'm a button!", NULL);
       -    ltk_grid_widget(button4, grid1, 1, 1, 1, 1, sticky1);
       +    ltk_grid_widget(button4, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM);
            ltk_mainloop();
        }
   DIR diff --git a/widget.c b/widget.c
       t@@ -23,10 +23,45 @@
        
        #include "ltk.h"
        
       +LtkWidget ltk_create_widget(LtkWindow *window, void (*draw)(void *), void (*destroy)(void *), int needs_redraw)
       +{
       +    LtkWidget widget;
       +    widget.window = window;
       +    widget.active_widget = NULL;
       +    widget.hover_widget = NULL;
       +    widget.parent = NULL;
       +
       +    widget.key_press = NULL;
       +    widget.key_release = NULL;
       +    widget.mouse_press = NULL;
       +    widget.mouse_release = NULL;
       +    widget.motion_notify = NULL;
       +
       +    widget.resize = NULL;
       +    widget.draw = draw;
       +    widget.destroy = destroy;
       +
       +    widget.needs_redraw = needs_redraw;
       +    widget.state = LTK_NORMAL;
       +    widget.row = 0;
       +    widget.rect.x = 0;
       +    widget.rect.y = 0;
       +    widget.rect.w = 100;
       +    widget.rect.h = 100;
       +
       +    widget.row = NULL;
       +    widget.column = NULL;
       +    widget.row_span = NULL;
       +    widget.column_span = NULL;
       +    widget.sticky = NULL;
       +
       +    return widget;
       +}
       +
        void ltk_mouse_press_event(void *widget, XEvent event)
        {
            LtkWidget *ptr = widget;
       -    if (!ptr || ptr->state == DISABLED) return;
       +    if (!ptr || ptr->state == LTK_DISABLED) return;
            if (event.xbutton.button == 1)
            {
                LtkWidget *parent = ptr->parent;
       t@@ -35,8 +70,8 @@ void ltk_mouse_press_event(void *widget, XEvent event)
                    ltk_remove_active_widget(parent);
                    parent->active_widget = ptr;
                }
       -        ptr->state = PRESSED;
       -        if (ptr->redraw_state) ptr->draw(ptr);
       +        ptr->state = LTK_PRESSED;
       +        if (ptr->needs_redraw) ptr->draw(ptr);
            }
            if (ptr->mouse_press)
            {
       t@@ -47,11 +82,11 @@ void ltk_mouse_press_event(void *widget, XEvent event)
        void ltk_mouse_release_event(void *widget, XEvent event)
        {
            LtkWidget *ptr = widget;
       -    if (!ptr || ptr->state == DISABLED) return;
       -    if (ptr->state == PRESSED)
       +    if (!ptr || ptr->state == LTK_DISABLED) return;
       +    if (ptr->state == LTK_PRESSED)
            {
       -        ptr->state = HOVERACTIVE;
       -        if (ptr->redraw_state) ptr->draw(ptr);
       +        ptr->state = LTK_HOVERACTIVE;
       +        if (ptr->needs_redraw) ptr->draw(ptr);
            }
            if (ptr->mouse_release)
            {
       t@@ -62,17 +97,17 @@ void ltk_mouse_release_event(void *widget, XEvent event)
        void ltk_motion_notify_event(void *widget, XEvent event)
        {
            LtkWidget *ptr = widget;
       -    if (ptr && (ptr->state == NORMAL || ptr->state == ACTIVE) &&
       +    if (ptr && (ptr->state == LTK_NORMAL || ptr->state == LTK_ACTIVE) &&
                (event.xmotion.state & Button1Mask) != Button1Mask)
            {
       -        ptr->state = ptr->state == ACTIVE ? HOVERACTIVE : HOVER;
       +        ptr->state = ptr->state == LTK_ACTIVE ? LTK_HOVERACTIVE : LTK_HOVER;
                LtkWidget *parent = ptr->parent;
                if (parent)
                {
                    ltk_remove_hover_widget(parent);
                    parent->hover_widget = ptr;
                }
       -        if (ptr->redraw_state) ptr->draw(ptr);
       +        if (ptr->needs_redraw) ptr->draw(ptr);
            }
            if (ptr->motion_notify)
            {
   DIR diff --git a/widget.h b/widget.h
       t@@ -26,6 +26,13 @@
        
        #include "event.h"
        
       +typedef enum {
       +    LTK_STICKY_LEFT = 1 << 0,
       +    LTK_STICKY_RIGHT = 1 << 1,
       +    LTK_STICKY_TOP = 1 << 2,
       +    LTK_STICKY_BOTTOM = 1 << 3
       +} LtkStickyMask;
       +
        typedef struct LtkWindow LtkWindow;
        
        typedef struct LtkWidget
       t@@ -33,11 +40,11 @@ typedef struct LtkWidget
            /* The window the widget will be displayed on */
            LtkWindow *window;
            /* For container widgets; the widget that is currently active */
       -    void *active_widget;
       +    struct LtkWidget *active_widget;
            /* For container widgets; the widget that is currently highlighted */
       -    void *hover_widget;
       +    struct LtkWidget *hover_widget;
            /* Parent widget */
       -    void *parent;
       +    struct LtkWidget *parent;
        
            /* Called on KeyPress events */
            void (*key_press)(void *, XEvent event);
       t@@ -58,7 +65,7 @@ typedef struct LtkWidget
            void (*destroy)(void *);
        
            /* Specifies if the widget needs to be redrawn after a state change */
       -    int redraw_state;
       +    int needs_redraw;
            /* State of the widget */
            LtkWidgetState state;
            /* Position and size of the widget */
       t@@ -72,8 +79,9 @@ typedef struct LtkWidget
            /* Column span of widget if gridded */
            unsigned int column_span;
            /* Similar to sticky in tk */
       -    /* -y, +x, +y, -x */
       -    int sticky[4];
       +    unsigned short sticky;
        } LtkWidget;
        
       +LtkWidget ltk_create_widget(LtkWindow *window, void (*draw)(void *), void (*destroy)(void *), int needs_redraw);
       +
        #endif