diff --git a/Readme.md b/Readme.md index ea2d2cf..47c8b98 100644 --- a/Readme.md +++ b/Readme.md @@ -3,12 +3,13 @@ Work in progress ## Features - Immediate mode graphical user interface -- Suited for embedding into graphical applications - Written in C89 (ANSI C) - Small (~3kLOC) -- Focus on portability and ease of use +- Focus on portability and minimized internal state +- Suited for embedding into graphical applications +- Flexible abstraction layer (Widgets, Panel, Window) - No global hidden state -- No direct dependencies (not even libc) +- No direct dependencies (not even libc!) - Renderer and platform independent - Complete memory management control - Configurable diff --git a/gui.c b/gui.c index d0be8c0..ec8c400 100644 --- a/gui.c +++ b/gui.c @@ -277,7 +277,8 @@ void gui_input_motion(struct gui_input *in, gui_int x, gui_int y) { assert(in); - vec2_load(in->mouse_pos, (gui_float)x, (gui_float)y); + in->mouse_pos.x = (gui_float)x; + in->mouse_pos.y = (gui_float)y; } void @@ -296,7 +297,8 @@ gui_input_button(struct gui_input *in, gui_int x, gui_int y, gui_bool down) assert(in); if (!in) return; if (in->mouse_down == down) return; - vec2_load(in->mouse_clicked_pos, (gui_float)x, (gui_float)y); + in->mouse_clicked_pos.x = (gui_float)x; + in->mouse_clicked_pos.y = (gui_float)y; in->mouse_down = down; in->mouse_clicked++; } @@ -394,6 +396,7 @@ gui_output_begin(struct gui_draw_buffer *buffer, const struct gui_memory *memory assert(buffer); assert(memory); + assert((memory->vertex_percentage+memory->command_percentage+memory->clip_percentage) <= 1.0f); if (!buffer || !memory) return; if ((memory->vertex_percentage + memory->command_percentage + memory->clip_percentage) > 1.0f) return; @@ -455,7 +458,6 @@ gui_output_end(struct gui_draw_buffer *buffer, struct gui_draw_call_list *list, } if (list) { - list->memory = buffer->vertexes; list->vertexes = buffer->vertexes; list->vertex_size = buffer->vertex_size; list->commands = buffer->commands; @@ -505,12 +507,13 @@ gui_push_command(struct gui_draw_buffer *buffer, gui_size count, gui_texture tex { struct gui_draw_command *cmd; const struct gui_rect *clip; - buffer->vertex_needed += count * sizeof(struct gui_vertex); - buffer->command_needed += sizeof(struct gui_draw_command); - assert(buffer); assert(count); - if (!buffer || !count) return gui_false; + if (!buffer || !count) + return gui_false; + + buffer->vertex_needed += count * sizeof(struct gui_vertex); + buffer->command_needed += sizeof(struct gui_draw_command); if (!buffer->commands || buffer->command_size >= buffer->command_capacity || !buffer->command_capacity) return gui_false; @@ -1554,7 +1557,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out, gui_float mouse_x, mouse_y; gui_float clicked_x, clicked_y; - gui_float header_w = w; + gui_float header_x, header_w; gui_bool ret = gui_true; assert(panel); @@ -1580,22 +1583,14 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out, mouse_y = (panel->in) ? panel->in->mouse_pos.y: -1; clicked_x = (panel->in) ? panel->in->mouse_clicked_pos.x: - 1; clicked_y = (panel->in) ? panel->in->mouse_clicked_pos.y: - 1; + header_x = x + config->panel_padding.x; + header_w = w - 2 * config->panel_padding.x; if (panel->flags & GUI_PANEL_HEADER) { panel->header_height = panel->font->height + 3 * config->item_padding.y; panel->header_height += config->panel_padding.y; gui_draw_rectf(out, x, y, w, panel->header_height, *header); - if (text) { - const gui_size text_len = strsiz(text); - const gui_float label_x = x + config->panel_padding.x + config->item_padding.x; - const gui_float label_y = y + config->panel_padding.y; - const gui_float label_w = w - (2*config->panel_padding.x + 2 * config->item_padding.x); - const gui_float label_h = panel->font->height + 2 * config->item_padding.y; - gui_draw_string(panel->out, panel->font, label_x, label_y, label_w, label_h, - config->colors[GUI_COLOR_TEXT], (const gui_char*)text, text_len); - } - clip.x = x; clip.w = w; clip.y = y + panel->header_height; clip.h = h - panel->header_height; @@ -1612,16 +1607,17 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out, } if (panel->flags & GUI_PANEL_CLOSEABLE && panel->flags & GUI_PANEL_HEADER) { - const gui_char *X = (const gui_char*)"X"; + const gui_char *X = (const gui_char*)"x"; const gui_size text_width = gui_font_text_width(panel->font, X, 1); - const gui_float close_x = (x + w) - ((gui_float)text_width + config->panel_padding.x); + const gui_float close_x = header_x + config->item_padding.x; const gui_float close_y = y + config->panel_padding.y; - const gui_float close_w = (gui_float)text_width + config->panel_padding.x; + const gui_float close_w = (gui_float)text_width + config->item_padding.x; const gui_float close_h = panel->font->height + 2 * config->item_padding.y; - header_w -= ((gui_float)text_width + config->panel_padding.x); gui_draw_string(panel->out, panel->font, close_x, close_y, close_w, close_h, config->colors[GUI_COLOR_TEXT], X, 1); + header_w -= close_w; + header_x += close_h - config->item_padding.x; if (INBOX(mouse_x, mouse_y, close_x, close_y, close_w, close_h)) { if (INBOX(clicked_x, clicked_y, close_x, close_y, close_w, close_h)) { ret = !(panel->in->mouse_down && panel->in->mouse_clicked); @@ -1638,13 +1634,15 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out, (const gui_char*)"-"; text_width = gui_font_text_width(panel->font, score, 1); - min_x = (x + header_w) - ((gui_float)text_width + config->item_padding.y); + min_x = header_x + config->item_padding.x; min_y = y + config->panel_padding.y; - min_w = (gui_float)text_width; + min_w = (gui_float)text_width + 2 * config->item_padding.x; min_h = panel->font->height + 2 * config->item_padding.y; gui_draw_string(panel->out, panel->font, min_x, min_y, min_w, min_h, config->colors[GUI_COLOR_TEXT], score, 1); + header_w -= min_w; + header_x += min_w - config->item_padding.x; if (INBOX(mouse_x, mouse_y, min_x, min_y, min_w, min_h)) { if (INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h)) if (panel->in->mouse_down && panel->in->mouse_clicked) @@ -1652,6 +1650,17 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out, } } + if (panel->flags & GUI_PANEL_HEADER && text) { + const gui_size text_len = strsiz(text); + const gui_float label_x = header_x + config->item_padding.x; + const gui_float label_y = y + config->panel_padding.y; + const gui_float label_w = header_w - (2 * config->item_padding.x); + const gui_float label_h = panel->font->height + 2 * config->item_padding.y; + gui_draw_string(panel->out, panel->font, label_x, label_y, label_w, label_h, + config->colors[GUI_COLOR_TEXT], (const gui_char*)text, text_len); + } + + panel->row_height = panel->header_height; if (panel->flags & GUI_PANEL_SCROLLBAR) { const struct gui_color *color = &config->colors[GUI_COLOR_PANEL]; diff --git a/gui.h b/gui.h index 2ff4ad1..6e46816 100644 --- a/gui.h +++ b/gui.h @@ -55,6 +55,26 @@ struct gui_font { const struct gui_font_glyph *fallback; }; +struct gui_memory { + void *memory; + gui_size size; + gui_size max_panels; + gui_float vertex_percentage; + gui_float command_percentage; + gui_float clip_percentage; +}; + +struct gui_memory_status { + gui_size vertexes_allocated; + gui_size vertexes_needed; + gui_size commands_allocated; + gui_size commands_needed; + gui_size clips_allocated; + gui_size clips_needed; + gui_size allocated; + gui_size needed; +}; + enum gui_keys { GUI_KEY_SHIFT, GUI_KEY_CTRL, @@ -90,26 +110,6 @@ struct gui_draw_command { gui_texture texture; }; -struct gui_memory { - void *memory; - gui_size size; - gui_size max_panels; - gui_float vertex_percentage; - gui_float command_percentage; - gui_float clip_percentage; -}; - -struct gui_memory_status { - gui_size vertexes_allocated; - gui_size vertexes_needed; - gui_size commands_allocated; - gui_size commands_needed; - gui_size clips_allocated; - gui_size clips_needed; - gui_size allocated; - gui_size needed; -}; - struct gui_draw_buffer { struct gui_vertex *vertexes; gui_size vertex_capacity; @@ -126,7 +126,6 @@ struct gui_draw_buffer { }; struct gui_draw_call_list { - void *memory; struct gui_vertex *vertexes; gui_size vertex_size; struct gui_draw_command *commands;