[Bf-blender-cvs] [a56d6e467b9] blender2.8: UI: show popover arrow directly under the button

Campbell Barton noreply at git.blender.org
Sun Apr 29 09:16:36 CEST 2018


Commit: a56d6e467b9a8ad422de100a969dc2d0b9276135
Author: Campbell Barton
Date:   Sat Apr 28 22:54:11 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBa56d6e467b9a8ad422de100a969dc2d0b9276135

UI: show popover arrow directly under the button

A visual hint but looks broken when its not pointing to the button.

===================================================================

M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_region_popover.c
M	source/blender/editors/interface/interface_widgets.c

===================================================================

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, &center[0], &center[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);
 	}
 }



More information about the Bf-blender-cvs mailing list