diff options
author | Julian Eisel <julian@blender.org> | 2021-06-29 18:20:33 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2021-06-29 19:20:56 +0300 |
commit | 2ff714269e53f9a744242cd6c039ec65a47ec7ec (patch) | |
tree | 9c045b9cf56f50a86b7af87bc56a5495813f2e70 | |
parent | 63aa6dd845ebdb0f62c95a720e82e554c0208d95 (diff) |
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
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 14 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 54 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ui_api.c | 26 |
3 files changed, 66 insertions, 28 deletions
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 |