[Bf-blender-cvs] [2ff714269e5] master: UI: Support setting operator properties for `UILayout.operator_menu_enum()`

Julian Eisel noreply at git.blender.org
Tue Jun 29 18:21:04 CEST 2021


Commit: 2ff714269e53f9a744242cd6c039ec65a47ec7ec
Author: Julian Eisel
Date:   Tue Jun 29 17:20:33 2021 +0200
Branches: master
https://developer.blender.org/rB2ff714269e53f9a744242cd6c039ec65a47ec7ec

UI: Support setting operator properties for `UILayout.operator_menu_enum()`

`UILayout.operator_menu_enum()` now returns the operator properties, just like
`UILayout.operator()`. This makes it possible to set options for the operator
displayed in the menu. In C it can be done through the new
`uiItemMenuEnumFullO()` or `uiItemMenuEnumFullO_ptr()`.

It's reasonable to have this, probably just a small thing never bothered to
add. D10912 could use it, the following comment can be addressed now too:
https://developer.blender.org/diffusion/B/browse/master/source/blender/editors/space_nla/nla_buttons.c$583-586

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/makesrna/intern/rna_ui_api.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index b8443b952a8..b23f3e29551 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2425,12 +2425,20 @@ void uiItemPopoverPanelFromGroup(uiLayout *layout,
 
 void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg);
 void uiItemMenuFN(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *argN);
-void uiItemMenuEnumO_ptr(uiLayout *layout,
+void uiItemMenuEnumFullO_ptr(uiLayout *layout,
+                             struct bContext *C,
+                             struct wmOperatorType *ot,
+                             const char *propname,
+                             const char *name,
+                             int icon,
+                             struct PointerRNA *r_opptr);
+void uiItemMenuEnumFullO(uiLayout *layout,
                          struct bContext *C,
-                         struct wmOperatorType *ot,
+                         const char *opname,
                          const char *propname,
                          const char *name,
-                         int icon);
+                         int icon,
+                         struct PointerRNA *r_opptr);
 void uiItemMenuEnumO(uiLayout *layout,
                      struct bContext *C,
                      const char *opname,
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index cf3abc9be4a..a17a527c868 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -3381,10 +3381,13 @@ typedef struct MenuItemLevel {
 
 static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
 {
-  MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
+  uiBut *but = arg;
+  MenuItemLevel *lvl = but->func_argN;
+  /* Use the operator properties from the button owning the menu. */
+  IDProperty *op_props = but->opptr ? but->opptr->data : NULL;
 
   uiLayoutSetOperatorContext(layout, lvl->opcontext);
-  uiItemsEnumO(layout, lvl->opname, lvl->propname);
+  uiItemsFullEnumO(layout, lvl->opname, lvl->propname, op_props, lvl->opcontext, 0);
 
   layout->root->block->flag |= UI_BLOCK_IS_FLIP;
 
@@ -3392,12 +3395,13 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo
   UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
 }
 
-void uiItemMenuEnumO_ptr(uiLayout *layout,
-                         bContext *C,
-                         wmOperatorType *ot,
-                         const char *propname,
-                         const char *name,
-                         int icon)
+void uiItemMenuEnumFullO_ptr(uiLayout *layout,
+                             bContext *C,
+                             wmOperatorType *ot,
+                             const char *propname,
+                             const char *name,
+                             int icon,
+                             PointerRNA *r_opptr)
 {
   /* Caller must check */
   BLI_assert(ot->srna != NULL);
@@ -3416,6 +3420,15 @@ void uiItemMenuEnumO_ptr(uiLayout *layout,
   lvl->opcontext = layout->root->opcontext;
 
   uiBut *but = ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl, NULL, true);
+  /* Use the menu button as owner for the operator properties, which will then be passed to the
+   * individual menu items. */
+  if (r_opptr) {
+    but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
+    WM_operator_properties_create_ptr(but->opptr, ot);
+    BLI_assert(but->opptr->data == NULL);
+    WM_operator_properties_alloc(&but->opptr, (IDProperty **)&but->opptr->data, ot->idname);
+    *r_opptr = *but->opptr;
+  }
 
   /* add hotkey here, lower UI code can't detect it */
   if ((layout->root->block->flag & UI_BLOCK_LOOP) && (ot->prop && ot->invoke)) {
@@ -3427,12 +3440,13 @@ void uiItemMenuEnumO_ptr(uiLayout *layout,
   }
 }
 
-void uiItemMenuEnumO(uiLayout *layout,
-                     bContext *C,
-                     const char *opname,
-                     const char *propname,
-                     const char *name,
-                     int icon)
+void uiItemMenuEnumFullO(uiLayout *layout,
+                         bContext *C,
+                         const char *opname,
+                         const char *propname,
+                         const char *name,
+                         int icon,
+                         PointerRNA *r_opptr)
 {
   wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
 
@@ -3444,7 +3458,17 @@ void uiItemMenuEnumO(uiLayout *layout,
     return;
   }
 
-  uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
+  uiItemMenuEnumFullO_ptr(layout, C, ot, propname, name, icon, r_opptr);
+}
+
+void uiItemMenuEnumO(uiLayout *layout,
+                     bContext *C,
+                     const char *opname,
+                     const char *propname,
+                     const char *name,
+                     int icon)
+{
+  uiItemMenuEnumFullO(layout, C, opname, propname, name, icon, NULL);
 }
 
 static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 41d32bb0c92..aa235b599b7 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -384,26 +384,28 @@ static void rna_uiItemsEnumO(uiLayout *layout,
   uiItemsFullEnumO(layout, opname, propname, NULL, uiLayoutGetOperatorContext(layout), flag);
 }
 
-static void rna_uiItemMenuEnumO(uiLayout *layout,
-                                bContext *C,
-                                const char *opname,
-                                const char *propname,
-                                const char *name,
-                                const char *text_ctxt,
-                                bool translate,
-                                int icon)
+static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout,
+                                      bContext *C,
+                                      const char *opname,
+                                      const char *propname,
+                                      const char *name,
+                                      const char *text_ctxt,
+                                      bool translate,
+                                      int icon)
 {
   wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
 
   if (!ot || !ot->srna) {
     RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
-    return;
+    return PointerRNA_NULL;
   }
 
   /* Get translated name (label). */
   name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
 
-  uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
+  PointerRNA opptr;
+  uiItemMenuEnumFullO_ptr(layout, C, ot, propname, name, icon, &opptr);
+  return opptr;
 }
 
 static void rna_uiItemL(uiLayout *layout,
@@ -1028,6 +1030,10 @@ void RNA_api_ui_layout(StructRNA *srna)
   parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in operator");
   RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
   api_ui_item_common(func);
+  parm = RNA_def_pointer(
+      func, "properties", "OperatorProperties", "", "Operator properties to fill in");
+  RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
+  RNA_def_function_return(func, parm);
 
   /* useful in C but not in python */
 #  if 0



More information about the Bf-blender-cvs mailing list