diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-04-28 23:54:11 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-04-29 10:16:32 +0300 |
commit | a56d6e467b9a8ad422de100a969dc2d0b9276135 (patch) | |
tree | ef99b1c0f1fd15565ddf9aafa76a1fa1d7c2ad2d /source | |
parent | ca7964c24b814182c0261d1c3f4ffeb6cfd799a7 (diff) |
UI: show popover arrow directly under the button
A visual hint but looks broken when its not pointing to the button.
Diffstat (limited to 'source')
4 files changed, 73 insertions, 62 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 7c7ba553015..eb69ccef2e4 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1309,7 +1309,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) if (block->flag & UI_BLOCK_RADIAL) ui_draw_pie_center(block); else if (block->flag & UI_BLOCK_POPOVER) - ui_draw_popover_back(&style, block, &rect); + ui_draw_popover_back(ar, &style, block, &rect); else if (block->flag & UI_BLOCK_LOOP) ui_draw_menu_back(&style, block, &rect); else if (block->panel) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index a0515d7d4f0..c9ed3c36b22 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -92,7 +92,6 @@ typedef enum { UI_WTYPE_MENU_ITEM, UI_WTYPE_MENU_ITEM_RADIAL, UI_WTYPE_MENU_BACK, - UI_WTYPE_POPOVER_BACK, /* specials */ UI_WTYPE_ICON, @@ -742,7 +741,7 @@ struct Gwn_Batch *ui_batch_roundbox_shadow_get(void); void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha, const float color[4]); void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect); -void ui_draw_popover_back(struct uiStyle *style, uiBlock *block, rcti *rect); +void ui_draw_popover_back(ARegion *ar, struct uiStyle *style, uiBlock *block, rcti *rect); void ui_draw_pie_center(uiBlock *block); uiWidgetColors *ui_tooltip_get_theme(void); void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *block, rcti *rect); diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index ea8c4d9ddce..845511b3279 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -140,6 +140,15 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v bool slideout = false; //ui_block_is_menu(pup->but->block); if (slideout) UI_block_direction_set(block, UI_DIR_RIGHT); + + /* Store the button location for positioning the popover arrow hint. */ + { + float center[2] = {BLI_rctf_cent_x(&pup->but->rect), BLI_rctf_cent_y(&pup->but->rect)}; + ui_block_to_window_fl(handle->ctx_region, pup->but->block, ¢er[0], ¢er[1]); + /* These variables aren't used for popovers, we could add new variables if there is a conflict. */ + block->mx = (int)center[0]; + block->my = (int)center[1]; + } } else { /* Not attached to a button. */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index d745c9b4207..004c33ecc90 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1159,7 +1159,7 @@ static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb) } } -static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) +static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol) { unsigned char inner_col1[4] = {0}; unsigned char inner_col2[4] = {0}; @@ -2767,56 +2767,6 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir glDisable(GL_BLEND); } -static void widget_popover_back(uiWidgetColors *wcol, rcti *rect, int UNUSED(flag), int direction) -{ - /* tsk, this isn't nice. */ - const float unit_half = (BLI_rcti_size_x(rect) / UI_POPOVER_WIDTH_UNITS) / 2; - const float cent_x = BLI_rcti_cent_x(rect); - rect->ymax -= unit_half; - rect->ymin += unit_half; - - - glEnable(GL_BLEND); - - /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */ - { - uiWidgetBase wtb; - widget_init(&wtb); - - const int roundboxalign = UI_CNR_ALL; - widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit); - - round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit); - wtb.draw_emboss = false; - widgetbase_draw(&wtb, wcol); - } - - /* Draw popover arrow (top/bottom) */ - if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4ubv((unsigned char *)wcol->inner); - glEnable(GL_BLEND); - immBegin(GWN_PRIM_TRIS, 3); - if (direction == UI_DIR_DOWN) { - const float y = rect->ymax; - immVertex2f(pos, cent_x - unit_half, y); - immVertex2f(pos, cent_x + unit_half, y); - immVertex2f(pos, cent_x, y + unit_half); - } - else { - const float y = rect->ymin; - immVertex2f(pos, cent_x - unit_half, y); - immVertex2f(pos, cent_x + unit_half, rect->ymin); - immVertex2f(pos, cent_x, y - unit_half); - } - immEnd(); - immUnbindProgram(); - } - - glDisable(GL_BLEND); -} - static void ui_hsv_cursor(float x, float y) { unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -4261,10 +4211,6 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) wt.wcol_theme = &btheme->tui.wcol_menu_back; wt.draw = widget_menu_back; break; - case UI_WTYPE_POPOVER_BACK: - wt.wcol_theme = &btheme->tui.wcol_menu_back; - wt.draw = widget_popover_back; - break; /* specials */ case UI_WTYPE_ICON: @@ -4707,15 +4653,72 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) } } -void ui_draw_popover_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) +/** + * Similar to 'widget_menu_back', however we can't use the widget preset system + * because we need to pass in the original location so we know where to show the arrow. + */ +static void ui_draw_popover_back_impl( + const uiWidgetColors *wcol, rcti *rect, int direction, + const float mval_origin[2]) { - uiWidgetType *wt = widget_type(UI_WTYPE_POPOVER_BACK); + /* tsk, this isn't nice. */ + const float unit_half = (BLI_rcti_size_x(rect) / UI_POPOVER_WIDTH_UNITS) / 2; + const float cent_x = mval_origin ? mval_origin[0] : BLI_rcti_cent_x(rect); + rect->ymax -= unit_half; + rect->ymin += unit_half; - wt->state(wt, 0); + glEnable(GL_BLEND); + + /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */ + { + uiWidgetBase wtb; + widget_init(&wtb); + + const int roundboxalign = UI_CNR_ALL; + widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit); + + round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit); + wtb.draw_emboss = false; + widgetbase_draw(&wtb, wcol); + } + + /* Draw popover arrow (top/bottom) */ + if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) { + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ubv((unsigned char *)wcol->inner); + glEnable(GL_BLEND); + immBegin(GWN_PRIM_TRIS, 3); + if (direction == UI_DIR_DOWN) { + const float y = rect->ymax; + immVertex2f(pos, cent_x - unit_half, y); + immVertex2f(pos, cent_x + unit_half, y); + immVertex2f(pos, cent_x, y + unit_half); + } + else { + const float y = rect->ymin; + immVertex2f(pos, cent_x - unit_half, y); + immVertex2f(pos, cent_x + unit_half, rect->ymin); + immVertex2f(pos, cent_x, y - unit_half); + } + immEnd(); + immUnbindProgram(); + } + + glDisable(GL_BLEND); +} + +void ui_draw_popover_back(ARegion *ar, uiStyle *UNUSED(style), uiBlock *block, rcti *rect) +{ if (block) { - wt->draw(&wt->wcol, rect, block->flag, block->direction); + float mval_origin[2] = {block->mx, block->my}; + ui_window_to_block_fl(ar, block, &mval_origin[0], &mval_origin[1]); + ui_draw_popover_back_impl(&wcol_menu_back, rect, block->direction, mval_origin); } else { + uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK); + + wt->state(wt, 0); wt->draw(&wt->wcol, rect, 0, 0); } } |