From 00d08896f491f21a956834155c03f42cb2baa5d5 Mon Sep 17 00:00:00 2001 From: vurtun Date: Mon, 20 Apr 2015 12:46:04 +0200 Subject: [PATCH] removed most of the group/tab/shelf state --- Readme.md | 2 +- demo/xlib.c | 55 ++++++++++++++++----------------- gui.c | 87 +++++++++++++++++++++++++++++++++++++++++------------ gui.h | 26 +++++++++------- 4 files changed, 112 insertions(+), 58 deletions(-) diff --git a/Readme.md b/Readme.md index 7f7142d..813a7cf 100644 --- a/Readme.md +++ b/Readme.md @@ -10,7 +10,7 @@ WORK IN PROGRESS: I do not garantee that everything works right now - Suited for embedding into graphical applications - No global hidden state - No direct dependencies (not even libc!) -- No memory allocation +- No memory allocation needed - Renderer and platform independent - Configurable - UTF-8 supported diff --git a/demo/xlib.c b/demo/xlib.c index 053c705..d5623c0 100644 --- a/demo/xlib.c +++ b/demo/xlib.c @@ -39,10 +39,10 @@ struct demo { gui_int spinner; gui_bool spin_act; gui_size item_cur; - gui_tab tab; - gui_group group; - gui_shelf shelf; gui_size current; + gui_bool tab_minimized; + gui_float group_offset; + gui_float shelf_offset; }; struct XFont { @@ -383,41 +383,42 @@ demo_panel(struct gui_panel *panel, struct demo *demo) const char *shelfs[] = {"Histogram", "Lines"}; const gui_float values[] = {8.0f, 15.0f, 20.0f, 12.0f, 30.0f}; const char *items[] = {"Fist", "Pistol", "Shotgun", "Railgun", "BFG"}; + struct gui_panel tab; /* Tabs */ gui_panel_layout(panel, 100, 1); - gui_panel_tab_begin(panel, &demo->tab, "Difficulty"); - gui_panel_layout(&demo->tab, 30, 3); - if (gui_panel_option(&demo->tab, "easy", demo->option == 0)) demo->option = 0; - if (gui_panel_option(&demo->tab, "normal", demo->option == 1)) demo->option = 1; - if (gui_panel_option(&demo->tab, "hard", demo->option == 2)) demo->option = 2; - if (gui_panel_option(&demo->tab, "hell", demo->option == 3)) demo->option = 3; - if (gui_panel_option(&demo->tab, "doom", demo->option == 4)) demo->option = 4; - if (gui_panel_option(&demo->tab, "godlike", demo->option == 5)) demo->option = 5; - gui_panel_tab_end(panel, &demo->tab); + demo->tab_minimized = gui_panel_tab_begin(panel, &tab, "Difficulty", demo->tab_minimized); + gui_panel_layout(&tab, 30, 3); + if (gui_panel_option(&tab, "easy", demo->option == 0)) demo->option = 0; + if (gui_panel_option(&tab, "normal", demo->option == 1)) demo->option = 1; + if (gui_panel_option(&tab, "hard", demo->option == 2)) demo->option = 2; + if (gui_panel_option(&tab, "hell", demo->option == 3)) demo->option = 3; + if (gui_panel_option(&tab, "doom", demo->option == 4)) demo->option = 4; + if (gui_panel_option(&tab, "godlike", demo->option == 5)) demo->option = 5; + gui_panel_tab_end(panel, &tab); /* Shelf */ gui_panel_layout(panel, 200, 2); - demo->current = gui_panel_shelf_begin(panel, &demo->shelf, shelfs, LEN(shelfs), demo->current); - gui_panel_layout(&demo->shelf, 100, 1); + demo->current = gui_panel_shelf_begin(panel, &tab, shelfs, LEN(shelfs), demo->current, demo->shelf_offset); + gui_panel_layout(&tab, 100, 1); if (demo->current == HISTO) { - gui_panel_histo(&demo->shelf, values, LEN(values)); + gui_panel_histo(&tab, values, LEN(values)); } else { - gui_panel_plot(&demo->shelf, values, LEN(values)); + gui_panel_plot(&tab, values, LEN(values)); } - gui_panel_shelf_end(panel, &demo->shelf); + demo->shelf_offset = gui_panel_shelf_end(panel, &tab); /* Group */ - gui_panel_group_begin(panel, &demo->group, "Options"); - gui_panel_layout(&demo->group, 30, 1); - if (gui_panel_button_text(&demo->group, "button", GUI_BUTTON_DEFAULT)) + gui_panel_group_begin(panel, &tab, "Options", demo->group_offset); + gui_panel_layout(&tab, 30, 1); + if (gui_panel_button_text(&tab, "button", GUI_BUTTON_DEFAULT)) fprintf(stdout, "button pressed!\n"); - demo->check = gui_panel_check(&demo->group, "advanced", demo->check); - demo->slider = gui_panel_slider(&demo->group, 0, demo->slider, 10, 1.0f); - demo->prog = gui_panel_progress(&demo->group, demo->prog, 100, gui_true); - demo->item_cur = gui_panel_selector(&demo->group, items, LEN(items), demo->item_cur); - demo->spin_act = gui_panel_spinner(&demo->group, 0, &demo->spinner, 250, 10, demo->spin_act); - gui_panel_group_end(panel, &demo->group); + demo->check = gui_panel_check(&tab, "advanced", demo->check); + demo->slider = gui_panel_slider(&tab, 0, demo->slider, 10, 1.0f); + demo->prog = gui_panel_progress(&tab, demo->prog, 100, gui_true); + demo->item_cur = gui_panel_selector(&tab, items, LEN(items), demo->item_cur); + demo->spin_act = gui_panel_spinner(&tab, 0, &demo->spinner, 250, 10, demo->spin_act); + demo->group_offset = gui_panel_group_end(panel, &tab); } int @@ -479,7 +480,7 @@ main(int argc, char *argv[]) panel.w = 420; panel.h = 300; memset(&demo, 0, sizeof(demo)); - demo.tab.minimized = gui_true; + demo.tab_minimized = gui_true; demo.spinner = 100; demo.slider = 2.0f; demo.prog = 60; diff --git a/gui.c b/gui.c index b151e3a..a4f01a5 100644 --- a/gui.c +++ b/gui.c @@ -436,6 +436,28 @@ gui_button_triangle(const struct gui_canvas *canvas, gui_float x, gui_float y, g return pressed; } +gui_bool +gui_button_icon(const struct gui_canvas *canvas, gui_float x, gui_float y, + gui_float w, gui_float h, const struct gui_button *button, void *img, + const struct gui_rect *src, enum gui_button_behavior behavior, + const struct gui_input *in) +{ + struct gui_rect dst; + gui_bool pressed; + assert(button); + assert(canvas); + if (!canvas || !button) + return gui_false; + + dst.x = x + button->padding.x; + dst.y = x + button->padding.y; + dst.w = w - 2 * button->padding.x; + dst.h = h - 2 * button->padding.y; + pressed = gui_button(canvas, x, y, w, h, button, in, behavior); + canvas->draw_bitmap(canvas->userdata, dst.x, dst.y, dst.w, dst.h, src, img); + return pressed; +} + gui_bool gui_toggle(const struct gui_canvas *canvas, gui_float x, gui_float y, gui_float w, gui_float h, gui_bool active, const char *string, const struct gui_toggle *toggle, @@ -1361,6 +1383,35 @@ gui_panel_button_toggle(struct gui_panel *panel, const char *str, gui_bool value return value; } +gui_bool +gui_panel_button_icon(struct gui_panel *panel, void *img, const struct gui_rect *src, + enum gui_button_behavior behavior) +{ + struct gui_rect bounds; + struct gui_button button; + const struct gui_config *config; + + assert(panel); + assert(panel->config); + assert(panel->canvas); + + if (!panel || !panel->config || !panel->canvas) return 0; + if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) return 0; + gui_panel_alloc_space(&bounds, panel); + config = panel->config; + + button.border = 1; + button.padding.x = config->item_padding.x; + button.padding.y = config->item_padding.y; + button.background = config->colors[GUI_COLOR_BUTTON]; + button.foreground = config->colors[GUI_COLOR_BUTTON_BORDER]; + button.content = config->colors[GUI_COLOR_TEXT]; + button.highlight = config->colors[GUI_COLOR_BUTTON_HOVER]; + button.highlight_content = config->colors[GUI_COLOR_BUTTON_HOVER_FONT]; + return gui_button_icon(panel->canvas, bounds.x, bounds.y, bounds.w, bounds.h, + &button, img, src, behavior, panel->in); +} + gui_bool gui_panel_check(struct gui_panel *panel, const char *text, gui_bool is_active) { @@ -1689,7 +1740,8 @@ gui_panel_histo(struct gui_panel *panel, const gui_float *values, gui_size count } gui_bool -gui_panel_tab_begin(struct gui_panel *panel, gui_tab *tab, const char *title) +gui_panel_tab_begin(struct gui_panel *panel, struct gui_panel *tab, + const char *title, gui_bool minimized) { struct gui_rect bounds; const struct gui_canvas *canvas; @@ -1697,15 +1749,13 @@ gui_panel_tab_begin(struct gui_panel *panel, gui_tab *tab, const char *title) gui_float old_height; gui_size old_cols; gui_flags flags; - gui_bool min; assert(panel); assert(tab); if (!panel || !tab) return gui_true; canvas = panel->canvas; - min = tab->minimized; zero(tab, sizeof(*tab)); - tab->minimized = min; + tab->minimized = minimized; if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) { tab->flags = GUI_PANEL_HIDDEN; tab->config = panel->config; @@ -1748,10 +1798,10 @@ gui_panel_tab_end(struct gui_panel *panel, struct gui_panel *tab) } void -gui_panel_group_begin(struct gui_panel *panel, gui_group *group, const char *title) +gui_panel_group_begin(struct gui_panel *panel, struct gui_panel *group, + const char *title, gui_float offset) { gui_flags flags; - gui_float offset; struct gui_rect bounds; const struct gui_canvas *canvas; struct gui_rect clip; @@ -1766,7 +1816,6 @@ gui_panel_group_begin(struct gui_panel *panel, gui_group *group, const char *tit return; } - offset = group->offset; gui_panel_alloc_space(&bounds, panel); zero(group, sizeof(*group)); canvas = panel->canvas; @@ -1780,26 +1829,27 @@ gui_panel_group_begin(struct gui_panel *panel, gui_group *group, const char *tit canvas->scissor(canvas->userdata, clip.x, clip.y, clip.w, clip.h); } -void -gui_panel_group_end(struct gui_panel *panel, gui_group* group) +gui_float +gui_panel_group_end(struct gui_panel *panel, struct gui_panel *group) { const struct gui_canvas *canvas; struct gui_rect clip; assert(panel); assert(group); - if (!panel || !group) return; - if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) return; + if (!panel || !group) return 0; + if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) return 0; canvas = panel->canvas; unify(&clip, &panel->clip, group->clip.x, group->clip.y, group->x + group->w, group->y + group->h); canvas->scissor(canvas->userdata, clip.x, clip.y, clip.w, clip.h); gui_panel_end(group); canvas->scissor(canvas->userdata, panel->clip.x, panel->clip.y, panel->clip.w, panel->clip.h); + return group->offset; } gui_size -gui_panel_shelf_begin(struct gui_panel *panel, gui_shelf *shelf, - const char *tabs[], gui_size size, gui_size active) +gui_panel_shelf_begin(struct gui_panel *panel, struct gui_panel *shelf, + const char *tabs[], gui_size size, gui_size active, gui_float offset) { const struct gui_config *config; const struct gui_canvas *canvas; @@ -1808,7 +1858,6 @@ gui_panel_shelf_begin(struct gui_panel *panel, gui_shelf *shelf, struct gui_rect bounds; struct gui_rect clip; gui_float item_width; - gui_float offset; gui_flags flags; gui_size i; @@ -1828,7 +1877,6 @@ gui_panel_shelf_begin(struct gui_panel *panel, gui_shelf *shelf, config = panel->config; canvas = panel->canvas; - offset = shelf->offset; gui_panel_alloc_space(&bounds, panel); zero(shelf, sizeof(*shelf)); @@ -1876,22 +1924,23 @@ gui_panel_shelf_begin(struct gui_panel *panel, gui_shelf *shelf, return active; } -void -gui_panel_shelf_end(struct gui_panel *panel, gui_shelf *shelf) +gui_float +gui_panel_shelf_end(struct gui_panel *panel, struct gui_panel *shelf) { const struct gui_canvas *canvas; struct gui_rect clip; assert(panel); assert(shelf); - if (!panel || !shelf) return; - if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) return; + if (!panel || !shelf) return 0; + if (panel->minimized || (panel->flags & GUI_PANEL_HIDDEN)) return 0; canvas = panel->canvas; unify(&clip, &panel->clip, shelf->clip.x, shelf->clip.y, shelf->x + shelf->w, shelf->y + shelf->h); canvas->scissor(canvas->userdata, clip.x, clip.y, clip.w, clip.h); gui_panel_end(shelf); canvas->scissor(canvas->userdata, panel->clip.x, panel->clip.y, panel->clip.w, panel->clip.h); + return shelf->offset; } void diff --git a/gui.h b/gui.h index c3d7489..646f0bc 100644 --- a/gui.h +++ b/gui.h @@ -51,17 +51,15 @@ struct gui_rect {gui_float x,y,w,h;}; struct gui_key {gui_bool down, clicked;}; struct gui_font; -typedef struct gui_panel gui_tab; -typedef struct gui_panel gui_group; -typedef struct gui_panel gui_shelf; typedef gui_char gui_glyph[GUI_UTF_SIZE]; -typedef union {void* handle; gui_uint id;} gui_texture; typedef gui_size(*gui_text_width_f)(void*,const gui_char*, gui_size); typedef void(*gui_scissor)(void*, gui_float, gui_float, gui_float, gui_float); typedef void(*gui_draw_line)(void*, gui_float, gui_float, gui_float, gui_float, struct gui_color); typedef void(*gui_draw_rect)(void*, gui_float, gui_float, gui_float, gui_float, struct gui_color); typedef void(*gui_draw_circle)(void*, gui_float, gui_float, gui_float, gui_float, struct gui_color); typedef void(*gui_draw_triangle)(void*, const struct gui_vec2*, struct gui_color); +typedef void(*gui_draw_bitmap)(void*, gui_float, gui_float, gui_float, gui_float, + const struct gui_rect*, void*); typedef void(*gui_draw_text)(void*, gui_float, gui_float, gui_float, gui_float, const gui_char*, gui_size, const struct gui_font*, struct gui_color, struct gui_color); @@ -104,6 +102,7 @@ struct gui_canvas { gui_draw_rect draw_rect; gui_draw_circle draw_circle; gui_draw_triangle draw_triangle; + gui_draw_bitmap draw_bitmap; gui_draw_text draw_text; }; @@ -293,6 +292,9 @@ gui_bool gui_button_text(const struct gui_canvas*, gui_float x, gui_float y, gui_bool gui_button_triangle(const struct gui_canvas*, gui_float x, gui_float y, gui_float w, gui_float h, const struct gui_button*, enum gui_heading, enum gui_button_behavior, const struct gui_input*); +gui_bool gui_button_icon(const struct gui_canvas*, gui_float x, gui_float y, + gui_float w, gui_float h, const struct gui_button*, void *bitmap, + const struct gui_rect *src, enum gui_button_behavior, const struct gui_input*); gui_bool gui_toggle(const struct gui_canvas*, gui_float x, gui_float y, gui_float w, gui_float h, gui_bool, const char*, const struct gui_toggle*, enum gui_toggle_type, const struct gui_input*); @@ -330,6 +332,8 @@ gui_bool gui_panel_button_text(struct gui_panel*, const char*, enum gui_button_b gui_bool gui_panel_button_color(struct gui_panel*, const struct gui_color, enum gui_button_behavior); gui_bool gui_panel_button_triangle(struct gui_panel*, enum gui_heading, enum gui_button_behavior); gui_bool gui_panel_button_toggle(struct gui_panel*, const char*, gui_bool value); +gui_bool gui_panel_button_icon(struct gui_panel*, void *bitmap, const struct gui_rect*, + enum gui_button_behavior); gui_float gui_panel_slider(struct gui_panel*, gui_float min, gui_float val, gui_float max, gui_float step); gui_size gui_panel_progress(struct gui_panel*, gui_size cur, gui_size max, @@ -342,13 +346,13 @@ gui_size gui_panel_selector(struct gui_panel*, const char *items[], gui_size item_count, gui_size item_current); gui_int gui_panel_plot(struct gui_panel*, const gui_float *values, gui_size value_count); gui_int gui_panel_histo(struct gui_panel*, const gui_float *values, gui_size value_count); -gui_bool gui_panel_tab_begin(gui_tab*, gui_tab*, const char *title); -void gui_panel_tab_end(gui_tab*, gui_tab *tab); -void gui_panel_group_begin(gui_group*, gui_group*, const char *title); -void gui_panel_group_end(gui_group*, gui_group* tab); -gui_size gui_panel_shelf_begin(gui_shelf*, gui_shelf *shelf, const char *tabs[], - gui_size size, gui_size active); -void gui_panel_shelf_end(struct gui_panel*, gui_shelf *shelf); +gui_bool gui_panel_tab_begin(struct gui_panel*, struct gui_panel*, const char *title, gui_bool minimized); +void gui_panel_tab_end(struct gui_panel*, struct gui_panel *tab); +void gui_panel_group_begin(struct gui_panel *panel, struct gui_panel*, const char *title, gui_float offset); +gui_float gui_panel_group_end(struct gui_panel*, struct gui_panel* tab); +gui_size gui_panel_shelf_begin(struct gui_panel*, struct gui_panel *shelf, + const char *tabs[], gui_size size, gui_size active, gui_float offset); +gui_float gui_panel_shelf_end(struct gui_panel*, struct gui_panel *shelf); void gui_panel_end(struct gui_panel*); #ifdef __cplusplus