Refactor: UI changes for collection export presets #120034
|
@ -1099,7 +1099,7 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
|||
def path_menu(self, searchpaths, operator, *,
|
||||
props_default=None, prop_filepath="filepath",
|
||||
filter_ext=None, filter_path=None, display_name=None,
|
||||
add_operator=None):
|
||||
add_operator=None, add_operator_props=None):
|
||||
"""
|
||||
Populate a menu from a list of paths.
|
||||
|
||||
|
@ -1176,6 +1176,9 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
|||
props = row.operator(add_operator, text="", icon='REMOVE')
|
||||
props.name = name
|
||||
props.remove_name = True
|
||||
if add_operator_props is not None:
|
||||
for attr, value in add_operator_props.items():
|
||||
setattr(props, attr, value)
|
||||
|
||||
if add_operator:
|
||||
wm = bpy.data.window_managers[0]
|
||||
|
@ -1189,6 +1192,9 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
|||
|
||||
props = row.operator(add_operator, text="", icon='ADD')
|
||||
props.name = wm.preset_name
|
||||
if add_operator_props is not None:
|
||||
for attr, value in add_operator_props.items():
|
||||
setattr(props, attr, value)
|
||||
|
||||
def draw_preset(self, _context):
|
||||
"""
|
||||
|
@ -1205,12 +1211,14 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
|
|||
ext_valid = getattr(self, "preset_extensions", {".py", ".xml"})
|
||||
props_default = getattr(self, "preset_operator_defaults", None)
|
||||
add_operator = getattr(self, "preset_add_operator", None)
|
||||
add_operator_props = getattr(self, "preset_add_operator_properties", None)
|
||||
self.path_menu(
|
||||
bpy.utils.preset_paths(self.preset_subdir),
|
||||
self.preset_operator,
|
||||
props_default=props_default,
|
||||
filter_ext=lambda ext: ext.lower() in ext_valid,
|
||||
add_operator=add_operator,
|
||||
add_operator_props=add_operator_props,
|
||||
display_name=lambda name: bpy.path.display_name(name, title_case=False)
|
||||
)
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ from bpy.types import (
|
|||
Menu,
|
||||
Operator,
|
||||
OperatorFileListElement,
|
||||
Panel,
|
||||
WindowManager,
|
||||
)
|
||||
from bpy.props import (
|
||||
|
@ -18,6 +19,7 @@ from bpy.app.translations import (
|
|||
pgettext_rpt as rpt_,
|
||||
pgettext_data as data_,
|
||||
)
|
||||
from bl_ui.utils import PresetPanel
|
||||
|
||||
|
||||
# For preset popover menu
|
||||
|
@ -750,6 +752,24 @@ class WM_MT_operator_presets(Menu):
|
|||
preset_operator = "script.execute_preset"
|
||||
|
||||
|
||||
class WM_PT_operator_presets(PresetPanel, Panel):
|
||||
bl_label = "Operator Presets"
|
||||
preset_add_operator = "wm.operator_preset_add"
|
||||
preset_operator = "script.execute_preset"
|
||||
|
||||
@property
|
||||
def preset_subdir(self):
|
||||
return AddPresetOperator.operator_path(self.operator)
|
||||
|
||||
@property
|
||||
def preset_add_operator_properties(self):
|
||||
return {"operator": self.operator}
|
||||
|
||||
def draw(self, context):
|
||||
self.operator = context.active_operator.bl_idname
|
||||
PresetPanel.draw(self, context)
|
||||
|
||||
|
||||
class WM_OT_operator_presets_cleanup(Operator):
|
||||
"""Remove outdated operator properties from presets that may cause problems"""
|
||||
|
||||
|
@ -921,5 +941,6 @@ classes = (
|
|||
AddPresetEEVEERaytracing,
|
||||
ExecutePreset,
|
||||
WM_MT_operator_presets,
|
||||
WM_PT_operator_presets,
|
||||
WM_OT_operator_presets_cleanup,
|
||||
)
|
||||
|
|
|
@ -841,6 +841,11 @@ bool UI_block_is_search_only(const uiBlock *block);
|
|||
*/
|
||||
void UI_block_set_search_only(uiBlock *block, bool search_only);
|
||||
|
||||
/**
|
||||
* Used for operator presets.
|
||||
*/
|
||||
void UI_block_set_active_operator(uiBlock *block, wmOperator *op, const bool free);
|
||||
|
||||
/**
|
||||
* Can be called with C==NULL.
|
||||
*/
|
||||
|
|
|
@ -3438,6 +3438,29 @@ static void ui_but_free(const bContext *C, uiBut *but)
|
|||
MEM_delete(but);
|
||||
}
|
||||
|
||||
static void ui_block_free_active_operator(uiBlock *block)
|
||||
{
|
||||
if (block->ui_operator_free) {
|
||||
/* This assumes the operator instance owns the pointer. This is not
|
||||
* true for all operators by default, but it can be copied when needed. */
|
||||
MEM_freeN(block->ui_operator->ptr);
|
||||
MEM_freeN(block->ui_operator);
|
||||
}
|
||||
|
||||
block->ui_operator_free = false;
|
||||
block->ui_operator = nullptr;
|
||||
}
|
||||
|
||||
void UI_block_set_active_operator(uiBlock *block, wmOperator *op, const bool free)
|
||||
{
|
||||
if (op != block->ui_operator) {
|
||||
ui_block_free_active_operator(block);
|
||||
|
||||
block->ui_operator = op;
|
||||
block->ui_operator_free = free;
|
||||
}
|
||||
}
|
||||
|
||||
void UI_block_free(const bContext *C, uiBlock *block)
|
||||
{
|
||||
UI_butstore_clear(block);
|
||||
|
@ -3454,6 +3477,8 @@ void UI_block_free(const bContext *C, uiBlock *block)
|
|||
MEM_freeN(block->func_argN);
|
||||
}
|
||||
|
||||
ui_block_free_active_operator(block);
|
||||
|
||||
BLI_freelistN(&block->saferct);
|
||||
BLI_freelistN(&block->color_pickers.list);
|
||||
BLI_freelistN(&block->dynamic_listeners);
|
||||
|
|
|
@ -613,6 +613,7 @@ struct uiBlock {
|
|||
/** use so presets can find the operator,
|
||||
* across menus and from nested popups which fail for operator context. */
|
||||
wmOperator *ui_operator;
|
||||
bool ui_operator_free;
|
||||
|
||||
/** XXX hack for dynamic operator enums */
|
||||
void *evil_C;
|
||||
|
|
|
@ -2727,7 +2727,7 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single(
|
|||
PointerRNA op_ptr;
|
||||
uiLayout *row;
|
||||
|
||||
block->ui_operator = op;
|
||||
UI_block_set_active_operator(block, op, false);
|
||||
|
||||
row = uiLayoutRow(layout, true);
|
||||
uiItemM(row, "WM_MT_operator_presets", nullptr, ICON_NONE);
|
||||
|
|
Loading…
Reference in New Issue