[Bf-blender-cvs] [f8a3636374b] master: UI: alternate fix for empty context menu

Campbell Barton noreply at git.blender.org
Sat Jun 23 10:37:26 CEST 2018


Commit: f8a3636374b76f6db31be21beaa0e40857644bc4
Author: Campbell Barton
Date:   Sat Jun 23 10:31:10 2018 +0200
Branches: master
https://developer.blender.org/rBf8a3636374b76f6db31be21beaa0e40857644bc4

UI: alternate fix for empty context menu

block and layout could be NULL and checking this everywhere
wasn't practical.

Instead of lazy initializing, add UI_popup_menu_end_or_cancel
which cancels empty popup menus.

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_region_menu_popup.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 94a0013d96b..6227ea15b71 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -395,6 +395,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(
         struct bContext *C, const char *title, const char *block_name,
         int icon) ATTR_NONNULL();
 void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
+bool UI_popup_menu_end_or_cancel(struct bContext *C, struct uiPopupMenu *head);
 struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
 
 void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
@@ -497,6 +498,8 @@ void    UI_block_order_flip(uiBlock *block);
 void    UI_block_flag_enable(uiBlock *block, int flag);
 void    UI_block_flag_disable(uiBlock *block, int flag);
 
+bool    UI_block_is_empty(const uiBlock *block);
+
 int     UI_but_return_value_get(uiBut *but);
 
 void    UI_but_drag_set_id(uiBut *but, struct ID *id);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 895190ab885..90fb477480a 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -4007,6 +4007,16 @@ int UI_blocklist_min_y_get(ListBase *lb)
 	return min;
 }
 
+bool UI_block_is_empty(const uiBlock *block)
+{
+	for (const uiBut *but = block->buttons.first; but; but = but->next) {
+		if (!ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
+			return false;
+		}
+	}
+	return true;
+}
+
 void UI_block_direction_set(uiBlock *block, char direction)
 {
 	block->direction = direction;
@@ -4753,4 +4763,3 @@ void UI_exit(void)
 	ui_resources_free();
 	ui_but_clipboard_free();
 }
-
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fa76113fa6f..0654e4d5f1b 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -6837,45 +6837,34 @@ static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, Pr
 	RNA_string_set(&props_ptr, "filepath", dir);
 }
 
-static void ui_but_menu_lazy_init(
-        bContext *C, uiBut *but,
-        uiPopupMenu **pup_p, uiLayout **layout_p)
-{
-	if (*pup_p != NULL) {
-		return;
-	}
-
-	uiStringInfo label = {BUT_GET_LABEL, NULL};
-
-	/* highly unlikely getting the label ever fails */
-	UI_but_string_info_get(C, but, &label, NULL);
-
-	*pup_p = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
-	*layout_p = UI_popup_menu_layout(*pup_p);
-	if (label.strinfo) {
-		MEM_freeN(label.strinfo);
-	}
-	uiLayoutSetOperatorContext(*layout_p, WM_OP_INVOKE_DEFAULT);
-}
-
 static bool ui_but_menu(bContext *C, uiBut *but)
 {
-	uiPopupMenu *pup = NULL;
-	uiLayout *layout = NULL;
 	MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
 	bool is_array, is_array_component;
 
-/*	if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/
-/*		return 0;*/
-
 	/* having this menu for some buttons makes no sense */
 	if (but->type == UI_BTYPE_IMAGE) {
 		return false;
 	}
 
-	if (but->rnapoin.data && but->rnaprop) {
-		ui_but_menu_lazy_init(C, but, &pup, &layout);
+	uiPopupMenu *pup;
+	uiLayout *layout;
+
+	{
+		uiStringInfo label = {BUT_GET_LABEL, NULL};
+
+		/* highly unlikely getting the label ever fails */
+		UI_but_string_info_get(C, but, &label, NULL);
+
+		pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
+		layout = UI_popup_menu_layout(pup);
+		if (label.strinfo) {
+			MEM_freeN(label.strinfo);
+		}
+		uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
+	}
 
+	if (but->rnapoin.data && but->rnaprop) {
 		PointerRNA *ptr = &but->rnapoin;
 		PropertyRNA *prop = but->rnaprop;
 		const PropertyType type = RNA_property_type(prop);
@@ -7074,8 +7063,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 
 		/* We do have a shortcut, but only keyboard ones are editbale that way... */
 		if (kmi) {
-			ui_but_menu_lazy_init(C, but, &pup, &layout);
-
 			if (ISKEYBOARD(kmi->type)) {
 #if 0			/* would rather use a block but, but gets weirdly positioned... */
 				uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut",
@@ -7102,8 +7089,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 		}
 		/* only show 'add' if there's a suitable key map for it to go in */
 		else if (WM_keymap_guess_opname(C, but->optype->idname)) {
-			ui_but_menu_lazy_init(C, but, &pup, &layout);
-
 			but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND,
 			                        CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
 			                        0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
@@ -7120,7 +7105,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 	if (ui_block_is_menu(but->block) == false) {
 		ARegion *ar = CTX_wm_region(C);
 		if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
-			ui_but_menu_lazy_init(C, but, &pup, &layout);
 			uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
 			uiItemS(layout);
 		}
@@ -7130,8 +7114,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 		char buf[512];
 
 		if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
-			ui_but_menu_lazy_init(C, but, &pup, &layout);
-
 			PointerRNA ptr_props;
 			uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
 			        ICON_URL, "WM_OT_doc_view_manual_ui_context");
@@ -7154,7 +7136,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 	}
 
 	if (but->optype) {
-		ui_but_menu_lazy_init(C, but, &pup, &layout);
 		uiItemO(layout, NULL,
 		        ICON_NONE, "UI_OT_copy_python_command_button");
 	}
@@ -7162,27 +7143,20 @@ static bool ui_but_menu(bContext *C, uiBut *but)
 	/* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
 	if (U.flag & USER_DEVELOPER_UI) {
 		if (ui_block_is_menu(but->block) == false) {
-			ui_but_menu_lazy_init(C, but, &pup, &layout);
 			uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
 		}
 	}
 
 	if (BKE_addon_find(&U.addons, "ui_translate")) {
-		ui_but_menu_lazy_init(C, but, &pup, &layout);
 		uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
 	}
 
 	mt = WM_menutype_find("WM_MT_button_context", true);
 	if (mt) {
-		ui_but_menu_lazy_init(C, but, &pup, &layout);
 		UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
 	}
 
-	if (pup != NULL) {
-		UI_popup_menu_end(C, pup);
-	}
-
-	return (pup != NULL);
+	return UI_popup_menu_end_or_cancel(C, pup);
 }
 
 static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 9aec955413f..fa7113f195e 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -454,6 +454,21 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
 	MEM_freeN(pup);
 }
 
+bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
+{
+	if (!UI_block_is_empty(pup->block)) {
+		UI_popup_menu_end(C, pup);
+		return true;
+	}
+	else {
+		UI_block_layout_resolve(pup->block, NULL, NULL);
+		MEM_freeN(pup->block->handle);
+		UI_block_free(C, pup->block);
+		MEM_freeN(pup);
+		return false;
+	}
+}
+
 uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
 {
 	return pup->layout;



More information about the Bf-blender-cvs mailing list