[Bf-blender-cvs] [41176cd3d82] blender2.8: UI: support adding menu's to favourites

Campbell Barton noreply at git.blender.org
Sat Jun 30 12:09:08 CEST 2018


Commit: 41176cd3d820649488ec5a5475d5dc7e97a01a59
Author: Campbell Barton
Date:   Sat Jun 30 12:08:08 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB41176cd3d820649488ec5a5475d5dc7e97a01a59

UI: support adding menu's to favourites

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

M	source/blender/blenkernel/intern/blender_user_menu.c
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/interface/interface_context_menu.c
M	source/blender/editors/screen/screen_user_menu.c
M	source/blender/makesdna/DNA_userdef_types.h

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

diff --git a/source/blender/blenkernel/intern/blender_user_menu.c b/source/blender/blenkernel/intern/blender_user_menu.c
index 3bb150b8fac..387776aa144 100644
--- a/source/blender/blenkernel/intern/blender_user_menu.c
+++ b/source/blender/blenkernel/intern/blender_user_menu.c
@@ -79,6 +79,9 @@ bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, int type)
 	if (type == USER_MENU_TYPE_OPERATOR) {
 		size = sizeof(bUserMenuItem_Op);
 	}
+	else if (type == USER_MENU_TYPE_MENU) {
+		size = sizeof(bUserMenuItem_Menu);
+	}
 	else if (type == USER_MENU_TYPE_SEP) {
 		size = sizeof(bUserMenuItem);
 	}
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index a2a619209db..0785b63ca37 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -62,6 +62,7 @@ struct wmMsgSubscribeKey;
 struct wmMsgSubscribeValue;
 struct wmOperatorType;
 struct IDProperty;
+struct MenuType;
 
 /* regions */
 void    ED_region_do_listen(
@@ -325,10 +326,18 @@ struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C);
 
 struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
         struct ListBase *lb,
-        struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+        const struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(
+        struct ListBase *lb,
+        const struct MenuType *mt);
+
 void ED_screen_user_menu_item_add_operator(
         struct ListBase *lb, const char *ui_name,
-        struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+        const struct wmOperatorType *ot, const struct IDProperty *prop, short opcontext);
+void ED_screen_user_menu_item_add_menu(
+        struct ListBase *lb, const char *ui_name,
+        const struct MenuType *mt);
+
 void ED_screen_user_menu_item_remove(
         struct ListBase *lb, struct bUserMenuItem *umi);
 void ED_screen_user_menu_register(void);
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index f28d80bebe1..d425ba1f985 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -216,10 +216,31 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
 	UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
 }
 
-static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
+static bool ui_but_is_user_menu_compatible(uiBut *but)
 {
-	uiBut *but = arg1;
-	bUserMenu *um = ED_screen_user_menu_ensure(C);
+	return (but->optype || UI_but_menutype_get(but));
+}
+
+static bUserMenuItem *ui_but_user_menu_find(uiBut *but, bUserMenu *um)
+{
+	MenuType *mt = NULL;
+	if (but->optype) {
+		IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+		return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
+		        &um->items, but->optype, prop, but->opcontext);
+	}
+	else if ((mt = UI_but_menutype_get(but))) {
+		return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(
+		        &um->items, mt);
+	}
+	else {
+		return NULL;
+	}
+}
+
+static void ui_but_user_menu_add(uiBut *but, bUserMenu *um)
+{
+	BLI_assert(ui_but_is_user_menu_compatible(but));
 
 	char drawstr[sizeof(but->drawstr)];
 	STRNCPY(drawstr, but->drawstr);
@@ -229,9 +250,25 @@ static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *U
 			*sep = '\0';
 		}
 	}
-	ED_screen_user_menu_item_add_operator(
-	        &um->items, drawstr,
-	        but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
+
+	MenuType *mt = NULL;
+	if (but->optype) {
+		ED_screen_user_menu_item_add_operator(
+		        &um->items, drawstr,
+		        but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
+	}
+	else if ((mt = UI_but_menutype_get(but))) {
+		ED_screen_user_menu_item_add_menu(
+		        &um->items, drawstr,
+		        mt);
+	}
+}
+
+static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
+{
+	uiBut *but = arg1;
+	bUserMenu *um = ED_screen_user_menu_ensure(C);
+	ui_but_user_menu_add(but, um);
 }
 
 static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2)
@@ -614,33 +651,36 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
 			UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
 		}
 
+		/* Set the operator pointer for python access */
+		uiLayoutSetContextFromBut(layout, but);
+
 		uiItemS(layout);
+	}
 
-		{
-			but2 = uiDefIconTextBut(
-			        block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
-			        CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Favorites Menu"),
-			        0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
-			        "Add to a user defined context menu (stored in the user preferences)");
-			UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL);
-
-			bUserMenu *um = ED_screen_user_menu_find(C);
-			if (um) {
-				bUserMenuItem_Op *umi_op = ED_screen_user_menu_item_find_operator(
-				        &um->items, but->optype, prop, but->opcontext);
-				if (umi_op != NULL) {
-					but2 = uiDefIconTextBut(
-					        block, UI_BTYPE_BUT, 0, ICON_CANCEL,
-					        CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Favorites Menu"),
-					        0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
-					UI_but_func_set(but2, popup_user_menu_remove_func, um, umi_op);
-				}
+	/* Favorites Menu */
+	if (ui_but_is_user_menu_compatible(but)) {
+		uiBlock *block = uiLayoutGetBlock(layout);
+		const int w = uiLayoutGetWidth(layout);
+		uiBut *but2;
+
+		but2 = uiDefIconTextBut(
+		        block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
+		        CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Favorites Menu"),
+		        0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
+		        "Add to a user defined context menu (stored in the user preferences)");
+		UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL);
+
+		bUserMenu *um = ED_screen_user_menu_find(C);
+		if (um) {
+			bUserMenuItem *umi = ui_but_user_menu_find(but, um);
+			if (umi != NULL) {
+				but2 = uiDefIconTextBut(
+				        block, UI_BTYPE_BUT, 0, ICON_CANCEL,
+				        CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Favorites Menu"),
+				        0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+				UI_but_func_set(but2, popup_user_menu_remove_func, um, umi);
 			}
 		}
-
-		/* Set the operator pointer for python access */
-		uiLayoutSetContextFromBut(layout, but);
-
 		uiItemS(layout);
 	}
 
diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c
index d942602c896..f36bceaa129 100644
--- a/source/blender/editors/screen/screen_user_menu.c
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -82,7 +82,7 @@ bUserMenu *ED_screen_user_menu_ensure(bContext *C)
 
 bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
         ListBase *lb,
-        wmOperatorType *ot, IDProperty *prop, short opcontext)
+        const wmOperatorType *ot, IDProperty *prop, short opcontext)
 {
 	for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
 		if (umi->type == USER_MENU_TYPE_OPERATOR) {
@@ -98,19 +98,45 @@ bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
 	return NULL;
 }
 
+struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(
+        struct ListBase *lb,
+        const struct MenuType *mt)
+{
+	for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
+		if (umi->type == USER_MENU_TYPE_MENU) {
+			bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
+			if (STREQ(mt->idname, umi_mt->mt_idname)) {
+				return umi_mt;
+			}
+		}
+	}
+	return NULL;
+}
+
 void ED_screen_user_menu_item_add_operator(
         ListBase *lb, const char *ui_name,
-        wmOperatorType *ot, IDProperty *prop, short opcontext)
+        const wmOperatorType *ot, const IDProperty *prop, short opcontext)
 {
 	bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_OPERATOR);
 	umi_op->opcontext = opcontext;
 	if (!STREQ(ui_name, ot->name)) {
-		BLI_strncpy(umi_op->item.ui_name, ui_name, OP_MAX_TYPENAME);
+		STRNCPY(umi_op->item.ui_name, ui_name);
 	}
-	BLI_strncpy(umi_op->opname, ot->idname, OP_MAX_TYPENAME);
+	STRNCPY(umi_op->opname, ot->idname);
 	umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
 }
 
+void ED_screen_user_menu_item_add_menu(
+        ListBase *lb, const char *ui_name,
+        const MenuType *mt)
+{
+	bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_MENU);
+	if (!STREQ(ui_name, mt->idname)) {
+		STRNCPY(umi_mt->item.ui_name, ui_name);
+	}
+	STRNCPY(umi_mt->mt_idname, mt->idname);
+}
+
 void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
 {
 	BLI_remlink(lb, umi);
@@ -144,6 +170,12 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
 				        menu->layout, umi_op->opname, umi->ui_name[0] ? umi->ui_name : NULL,
 				        ICON_NONE, prop, umi_op->opcontext, 0, NULL);
 			}
+			else if (umi->type == USER_MENU_TYPE_MENU) {
+				bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
+				uiItemM(
+				        menu->layout, NULL, umi_mt->mt_idname, umi->ui_name[0] ? umi->ui_name : NULL,
+				        ICON_NONE);
+			}
 			else if (umi->type == USER_MENU_TYPE_SEP) {
 				uiItemS(menu->layout);
 			}
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 18ec9f37f86..71082572e24 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -460,9 +460,15 @@ typedef struct bUserMenuItem_Op {
 	char _pad0[7];
 } bUserMenuItem_Op;
 
+typedef struct bUserMenuItem_Menu {
+	bUserMenuItem item;
+	char mt_idname[64];
+} bUserMenuItem_Menu;
+
 enum {
 	USER_MENU_TYPE_SEP = 1,
 	USER_MENU_TYPE_OPERATOR = 2,
+	USER_MENU_TYPE_MENU = 3,
 };
 
 typedef struct SolidLight {



More information about the Bf-blender-cvs mailing list