From 81a04d9eb885d107aebc9dc00ff17b35a811fd28 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 13 Mar 2018 16:39:55 +0100 Subject: gl: Rework how popup menus are handled. Handle the logic immediately, but put the drawing commands into a display list that is invoked after the rest of the UI is drawn. --- platform/gl/gl-app.h | 8 ++--- platform/gl/gl-ui.c | 91 ++++++++++++++++++++++++---------------------------- 2 files changed, 45 insertions(+), 54 deletions(-) (limited to 'platform') diff --git a/platform/gl/gl-app.h b/platform/gl/gl-app.h index a966641a..675ece0e 100644 --- a/platform/gl/gl-app.h +++ b/platform/gl/gl-app.h @@ -93,9 +93,8 @@ struct ui struct layout layout_stack[32]; fz_irect cavity_stack[32]; - struct { fz_irect area; const char *title; } popup[32]; - fz_irect popup_area; - int popup_count; + int overlay; + GLuint overlay_list; void (*dialog)(void); }; @@ -183,10 +182,9 @@ int ui_list_item(struct list *list, const void *id, const char *label, int selec int ui_list_item_x(struct list *list, const void *id, int indent, const char *label, int selected); void ui_list_end(struct list *list); -int ui_popup(const void *id, const char *title, int is_button, int count); +int ui_popup(const void *id, const char *label, int is_button, int count); int ui_popup_item(const char *title); void ui_popup_end(void); -void ui_draw_popup(void); void ui_init_open_file(const char *dir, int (*filter)(const char *fn)); int ui_open_file(char filename[]); diff --git a/platform/gl/gl-ui.c b/platform/gl/gl-ui.c index a91723b8..3ae7f6b5 100644 --- a/platform/gl/gl-ui.c +++ b/platform/gl/gl-ui.c @@ -419,10 +419,13 @@ void ui_init(int w, int h, const char *title) ui.gridsize = DEFAULT_UI_GRIDSIZE * ui_scale; ui_init_fonts(ui.fontsize); + + ui.overlay_list = glGenLists(1); } void ui_finish(void) { + glDeleteLists(ui.overlay_list, 1); ui_finish_fonts(); glutExit(); } @@ -449,10 +452,10 @@ void ui_begin(void) ui.layout->padx = 0; ui.layout->pady = 0; - ui.popup_count = 0; - ui.cursor = GLUT_CURSOR_INHERIT; + ui.overlay = 0; + glViewport(0, 0, ui.window_w, ui.window_h); glClearColor(0.3f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -469,8 +472,8 @@ void ui_end(void) { int code; - if (ui.popup_count > 0) - ui_draw_popup(); + if (ui.overlay) + glCallList(ui.overlay_list); if (ui.cursor != ui.last_cursor) { @@ -1010,20 +1013,21 @@ void ui_list_end(struct list *list) glDisable(GL_SCISSOR_TEST); } -int ui_popup(const void *popup, const char *label, int is_button, int count) +int ui_popup(const void *id, const char *label, int is_button, int count) { int width = ui_measure_string(label); fz_irect area = ui_pack(width + 22 + 6, ui.gridsize); + fz_irect menu_area; int pressed; if (ui_mouse_inside(&area)) { - ui.hot = popup; + ui.hot = id; if (!ui.active && ui.down) - ui.active = popup; + ui.active = id; } - pressed = (ui.active == popup); + pressed = (ui.active == id); if (is_button) { @@ -1054,25 +1058,34 @@ int ui_popup(const void *popup, const char *label, int is_button, int count) if (pressed) { + ui.overlay = 1; + + glNewList(ui.overlay_list, GL_COMPILE); + /* Area inside the border line */ - ui.popup_area.x0 = area.x0+1; - ui.popup_area.x1 = area.x1-1; // TODO: width of submenu + menu_area.x0 = area.x0+1; + menu_area.x1 = area.x1-1; // TODO: width of submenu if (area.y1+2 + count * ui.lineheight < ui.window_h) { - ui.popup_area.y0 = area.y1+2; - ui.popup_area.y1 = ui.popup_area.y0 + count * ui.lineheight; + menu_area.y0 = area.y1+2; + menu_area.y1 = menu_area.y0 + count * ui.lineheight; } else { - ui.popup_area.y1 = area.y0-2; - ui.popup_area.y0 = ui.popup_area.y1 - count * ui.lineheight; + menu_area.y1 = area.y0-2; + menu_area.y0 = menu_area.y1 - count * ui.lineheight; } - ui_pack_push(ui.popup_area); + + glColorHex(UI_COLOR_TEXT_FG); + glRectf(menu_area.x0-1, menu_area.y0-1, menu_area.x1+1, menu_area.y1+1); + glColorHex(UI_COLOR_TEXT_BG); + glRectf(menu_area.x0, menu_area.y0, menu_area.x1, menu_area.y1); + + ui_pack_push(menu_area); ui_layout(T, X, NW, 0, 0); - return 1; } - return 0; + return pressed; } int ui_popup_item(const char *title) @@ -1080,48 +1093,28 @@ int ui_popup_item(const char *title) fz_irect area = ui_pack(0, ui.lineheight); if (ui_mouse_inside(&area)) + { ui.hot = title; - - ui.popup[ui.popup_count].area = area; - ui.popup[ui.popup_count].title = title; - ++ui.popup_count; + glColorHex(UI_COLOR_TEXT_SEL_BG); + glRectf(area.x0, area.y0, area.x1, area.y1); + glColorHex(UI_COLOR_TEXT_SEL_FG); + ui_draw_string(area.x0 + 4, area.y0 + ui.baseline, title); + } + else + { + glColorHex(UI_COLOR_TEXT_FG); + ui_draw_string(area.x0 + 4, area.y0 + ui.baseline, title); + } return ui.hot == title && !ui.down; } void ui_popup_end(void) { + glEndList(); ui_pack_pop(); } -void ui_draw_popup(void) -{ - int i; - - glColorHex(UI_COLOR_TEXT_FG); - glRectf(ui.popup_area.x0-1, ui.popup_area.y0-1, ui.popup_area.x1+1, ui.popup_area.y1+1); - glColorHex(UI_COLOR_TEXT_BG); - glRectf(ui.popup_area.x0, ui.popup_area.y0, ui.popup_area.x1, ui.popup_area.y1); - - for (i = 0; i < ui.popup_count; ++i) - { - const char *title = ui.popup[i].title; - fz_irect area = ui.popup[i].area; - if (ui_mouse_inside(&area)) - { - glColorHex(UI_COLOR_TEXT_SEL_BG); - glRectf(area.x0, area.y0, area.x1, area.y1); - glColorHex(UI_COLOR_TEXT_SEL_FG); - ui_draw_string(area.x0 + 4, area.y0 + ui.baseline, title); - } - else - { - glColorHex(UI_COLOR_TEXT_FG); - ui_draw_string(area.x0 + 4, area.y0 + ui.baseline, title); - } - } -} - int ui_select(const void *id, const char *current, const char *options[], int n) { int i, choice = -1; -- cgit v1.2.3