diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_toolsystem_common.py | 15 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/workspace.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_workspace_types.h | 13 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_workspace_api.c | 24 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 33 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_toolsystem.c | 46 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 1 |
11 files changed, 140 insertions, 31 deletions
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 717beac1289..8a494369cf5 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -237,14 +237,11 @@ class ToolSelectPanelHelper: """ Return the active Python tool definition and icon name. """ - workspace = context.workspace cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) if cls is not None: - tool_active_text = getattr( - ToolSelectPanelHelper._tool_active_from_context(context, space_type, mode), - "name", None) - + tool_active = ToolSelectPanelHelper._tool_active_from_context(context, space_type, mode) + tool_active_text = getattr(tool_active, "name", None) for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context, mode)): if item is not None: if item.text == tool_active_text: @@ -252,8 +249,8 @@ class ToolSelectPanelHelper: icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon) else: icon_value = 0 - return (item, icon_value) - return None, 0 + return (item, tool_active, icon_value) + return None, None, 0 @staticmethod def _tool_get_by_name(context, space_type, text): @@ -517,14 +514,14 @@ class ToolSelectPanelHelper: workspace = context.workspace space_type = workspace.tools_space_type mode = workspace.tools_mode - item, icon_value = ToolSelectPanelHelper._tool_get_active(context, space_type, mode, with_icon=True) + item, tool, icon_value = ToolSelectPanelHelper._tool_get_active(context, space_type, mode, with_icon=True) if item is None: return # Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools. layout.label(" ", icon_value=icon_value) draw_settings = item.draw_settings if draw_settings is not None: - draw_settings(context, layout) + draw_settings(context, layout, tool) # The purpose of this menu is to be a generic popup to select between tools diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 137ca779065..8bcd56ce561 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -293,9 +293,9 @@ class _defs_edit_mesh: @ToolDef.from_fn def rip_region(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): wm = context.window_manager - props = wm.operator_properties_last("mesh.rip_move") + props = tool.operator_properties("mesh.rip_move") props_macro = props.MESH_OT_rip layout.prop(props_macro, "use_fill") @@ -393,9 +393,9 @@ class _defs_edit_mesh: @ToolDef.from_fn def inset(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): wm = context.window_manager - props = wm.operator_properties_last("mesh.inset") + props = tool.operator_properties("mesh.inset") layout.prop(props, "use_outset") layout.prop(props, "use_individual") layout.prop(props, "use_even_offset") @@ -507,9 +507,9 @@ class _defs_edit_mesh: @ToolDef.from_fn def shrink_fatten(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): wm = context.window_manager - props = wm.operator_properties_last("transform.shrink_fatten") + props = tool.operator_properties("transform.shrink_fatten") layout.prop(props, "use_even_offset") return dict( @@ -537,9 +537,9 @@ class _defs_edit_mesh: @ToolDef.from_fn def knife(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): wm = context.window_manager - props = wm.operator_properties_last("mesh.knife_tool") + props = tool.operator_properties("mesh.knife_tool") layout.prop(props, "use_occlude_geometry") layout.prop(props, "only_selected") @@ -573,7 +573,7 @@ class _defs_edit_curve: @ToolDef.from_fn def draw(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): # Tool settings initialize operator options. tool_settings = context.tool_settings cps = tool_settings.curve_paint_settings @@ -765,9 +765,9 @@ class _defs_weight_paint: @ToolDef.from_fn def gradient(): - def draw_settings(context, layout): + def draw_settings(context, layout, tool): wm = context.window_manager - props = wm.operator_properties_last("paint.weight_gradient") + props = tool.operator_properties("paint.weight_gradient") layout.prop(props, "type") return dict( diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index fd316cb9d82..7fc0d814089 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -34,6 +34,7 @@ #include "BLI_listbase.h" #include "BKE_global.h" +#include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_scene.h" @@ -176,6 +177,10 @@ void BKE_workspace_free(WorkSpace *workspace) tref_next = tref->next; if (tref->runtime) { MEM_freeN(tref->runtime); + if (tref->properties) { + IDP_FreeProperty(tref->properties); + MEM_freeN(tref->properties); + } } } BLI_freelistN(&workspace->tools); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a8181f1e043..c92b27bdb1c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2941,6 +2941,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { tref->runtime = NULL; + tref->properties = newdataadr(fd, tref->properties); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 8ea1205be38..a3cac39f609 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3602,6 +3602,11 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace) writelist(wd, DATA, WorkSpaceDataRelation, &workspace->scene_viewlayer_relations); writelist(wd, DATA, wmOwnerID, &workspace->owner_ids); writelist(wd, DATA, bToolRef, &workspace->tools); + for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { + if (tref->properties) { + IDP_WriteProperty(tref->properties, wd); + } + } } /* Keep it last of write_foodata functions. */ diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index 24fa0e06d90..ca9186e16bf 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -56,11 +56,13 @@ # # typedef struct bToolRef_Runtime { - /* One of these must be defined. */ int cursor; + + /* One of these 3 must be defined. */ char keymap[64]; char manipulator_group[64]; char data_block[64]; + /* index when a tool is a member of a group */ int index; } bToolRef_Runtime; @@ -82,6 +84,15 @@ typedef struct bToolRef { */ int mode; + /** + * Use for tool options, each group's name must match a tool name: + * + * {"Tool Name": {"SOME_OT_operator": {...}, ..}, ..} + * + * This is done since different tools may call the same operators with their own options. + */ + IDProperty *properties; + /** Variables needed to operate the tool. */ bToolRef_Runtime *runtime; } bToolRef; diff --git a/source/blender/makesrna/intern/rna_workspace_api.c b/source/blender/makesrna/intern/rna_workspace_api.c index 4c6949cc33d..e56d9a0bc33 100644 --- a/source/blender/makesrna/intern/rna_workspace_api.c +++ b/source/blender/makesrna/intern/rna_workspace_api.c @@ -64,6 +64,20 @@ static void rna_WorkspaceTool_setup( WM_toolsystem_ref_set_from_runtime(C, (WorkSpace *)id, tref, &tref_rt, name); } +static PointerRNA rna_WorkspaceTool_operator_properties( + bToolRef *tref, + const char *idname) +{ + wmOperatorType *ot = WM_operatortype_find(idname, true); + + if (ot != NULL) { + PointerRNA ptr; + WM_toolsystem_ref_properties_ensure(tref, ot, &ptr); + return ptr; + } + return PointerRNA_NULL; +} + #else void RNA_api_workspace(StructRNA *UNUSED(srna)) @@ -91,6 +105,16 @@ void RNA_api_workspace_tool(StructRNA *srna) RNA_def_string(func, "manipulator_group", NULL, MAX_NAME, "Manipulator Group", ""); RNA_def_string(func, "data_block", NULL, MAX_NAME, "Data Block", ""); RNA_def_int(func, "index", 0, INT_MIN, INT_MAX, "Index", "", INT_MIN, INT_MAX); + + /* Access tool operator options (optionally create). */ + func = RNA_def_function(srna, "operator_properties", "rna_WorkspaceTool_operator_properties"); + parm = RNA_def_string(func, "operator", NULL, 0, "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* return */ + parm = RNA_def_pointer(func, "result", "OperatorProperties", "", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR); + RNA_def_function_return(func, parm); + } #endif diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 050edb980e9..33222b2f1f1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -646,6 +646,12 @@ bool WM_toolsystem_active_tool_is_brush(const struct bContext *C); void WM_toolsystem_do_msg_notify_tag_refresh( struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val); +struct IDProperty *WM_toolsystem_ref_properties_ensure_idprops(struct bToolRef *tref); +void WM_toolsystem_ref_properties_ensure(struct bToolRef *tref, struct wmOperatorType *ot, struct PointerRNA *ptr); + +void WM_toolsystem_ref_properties_init_for_keymap( + struct bToolRef *tref, struct PointerRNA *dst_ptr, struct PointerRNA *src_ptr, struct wmOperatorType *ot); + /* wm_tooltip.c */ typedef struct ARegion *(*wmTooltipInitFn)(struct bContext *, struct ARegion *, bool *); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index df19f30e31e..f49f961f505 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1235,7 +1235,8 @@ bool WM_operator_last_properties_store(wmOperator *UNUSED(op)) */ static int wm_operator_invoke( bContext *C, wmOperatorType *ot, wmEvent *event, - PointerRNA *properties, ReportList *reports, const bool poll_only) + PointerRNA *properties, ReportList *reports, + const bool poll_only, bool use_last_properties) { int retval = OPERATOR_PASS_THROUGH; @@ -1253,7 +1254,7 @@ static int wm_operator_invoke( } /* initialize setting from previous run */ - if (!is_nested_call) { /* not called by py script */ + if (!is_nested_call && use_last_properties) { /* not called by py script */ WM_operator_last_properties_init(op); } @@ -1301,7 +1302,7 @@ static int wm_operator_invoke( /* do nothing, wm_operator_exec() has been called somewhere */ } else if (retval & OPERATOR_FINISHED) { - const bool store = !is_nested_call; + const bool store = !is_nested_call && use_last_properties; wm_operator_finished(C, op, false, store); } else if (retval & OPERATOR_RUNNING_MODAL) { @@ -1464,7 +1465,7 @@ static int wm_operator_call_internal( CTX_wm_region_set(C, ar1); } - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); /* set region back */ CTX_wm_region_set(C, ar); @@ -1478,7 +1479,7 @@ static int wm_operator_call_internal( ARegion *ar = CTX_wm_region(C); CTX_wm_region_set(C, NULL); - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); CTX_wm_region_set(C, ar); return retval; @@ -1492,7 +1493,7 @@ static int wm_operator_call_internal( CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); CTX_wm_area_set(C, area); CTX_wm_region_set(C, ar); @@ -1500,7 +1501,7 @@ static int wm_operator_call_internal( } case WM_OP_EXEC_DEFAULT: case WM_OP_INVOKE_DEFAULT: - return wm_operator_invoke(C, ot, event, properties, reports, poll_only); + return wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); } } @@ -1975,9 +1976,19 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand else { wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0); - if (ot) { - if (wm_operator_check_locked_interface(C, ot)) { - retval = wm_operator_invoke(C, ot, event, properties, NULL, false); + if (ot && wm_operator_check_locked_interface(C, ot)) { + bool use_last_properties = true; + PointerRNA tool_properties = {0}; + if (handler->keymap_tool) { + WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot); + properties = &tool_properties; + use_last_properties = false; + } + + retval = wm_operator_invoke(C, ot, event, properties, NULL, false, use_last_properties); + + if (handler->keymap_tool) { + WM_operator_properties_free(&tool_properties); } } } @@ -2887,6 +2898,8 @@ void wm_event_do_handlers(bContext *C) C, tref_rt->keymap, sa->spacetype, RGN_TYPE_WINDOW); if (km != NULL) { sneaky_handler.keymap = km; + sneaky_handler.keymap_tool = sa->runtime.tool; + /* Handle widgets first. */ wmEventHandler *handler_last = ar->handlers.last; while (handler_last && handler_last->manipulator_map == NULL) { diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index c616d143b69..3d9c6d88d2c 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -45,6 +45,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_paint.h" +#include "BKE_idprop.h" #include "BKE_workspace.h" #include "RNA_access.h" @@ -527,3 +528,48 @@ void WM_toolsystem_do_msg_notify_tag_refresh( }; WM_toolsystem_refresh(C, workspace, &tkey); } + +IDProperty *WM_toolsystem_ref_properties_ensure_idprops(bToolRef *tref) +{ + if (tref->properties == NULL) { + IDPropertyTemplate val = {0}; + tref->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); + } + return tref->properties; +} + +void WM_toolsystem_ref_properties_ensure(bToolRef *tref, wmOperatorType *ot, PointerRNA *ptr) +{ + IDProperty *group = WM_toolsystem_ref_properties_ensure_idprops(tref); + IDProperty *prop = IDP_GetPropertyFromGroup(group, ot->idname); + if (prop == NULL) { + IDPropertyTemplate val = {0}; + prop = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); + STRNCPY(prop->name, ot->idname); + IDP_ReplaceInGroup_ex(group, prop, NULL); + } + else { + BLI_assert(prop->type == IDP_GROUP); + } + + RNA_pointer_create(NULL, ot->srna, prop, ptr); +} + +void WM_toolsystem_ref_properties_init_for_keymap( + bToolRef *tref, PointerRNA *dst_ptr, PointerRNA *src_ptr, wmOperatorType *ot) +{ + *dst_ptr = *src_ptr; + if (dst_ptr->data) { + dst_ptr->data = IDP_CopyProperty(dst_ptr->data); + } + else { + IDPropertyTemplate val = {0}; + dst_ptr->data = IDP_New(IDP_GROUP, &val, "wmOpItemProp"); + } + if (tref->properties != NULL) { + IDProperty *prop = IDP_GetPropertyFromGroup(tref->properties, ot->idname); + if (prop) { + IDP_MergeGroup(dst_ptr->data, prop, true); + } + } +} diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 452fe377665..7b18ed54c85 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -54,6 +54,7 @@ typedef struct wmEventHandler { /* Run after the keymap item runs. */ void (*keymap_callback)(wmKeyMap *keymap, wmKeyMapItem *kmi, void *user_data); void *keymap_callback_user_data; + struct bToolRef *keymap_tool; /* modal operator handler */ wmOperator *op; /* for derived/modal handlers */ |