diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-05-13 09:59:50 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-05-13 10:03:37 +0300 |
commit | cee39da318f23904e334cc98cdd1e6fb100297d6 (patch) | |
tree | e48ca00149bc612cf5af266ee4dbe16a81cea0b7 /release | |
parent | 03281c080c07fcd6a985265c777bde9c5ea500ab (diff) |
WM: Operator to set the tool by name
Needed to bind keys to tools (T55036).
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 20 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_toolsystem_common.py | 129 |
2 files changed, 114 insertions, 35 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 84857170f27..f48cf69d1c9 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2326,6 +2326,25 @@ class WM_OT_app_template_install(Operator): return {'RUNNING_MODAL'} +class WM_OT_tool_set_by_name(Operator): + """Set the tool by name (for keymaps)""" + bl_idname = "wm.tool_set_by_name" + bl_label = "Set Tool By Name" + + name = StringProperty( + name="Text", + description="Display name of the tool", + ) + + def execute(self, context): + from bl_ui.space_toolsystem_common import activate_by_name + if activate_by_name(context, self.name): + return {'FINISHED'} + else: + self.report({'WARNING'}, f"Tool {self.name!r} not found.") + return {'CANCELLED'} + + classes = ( BRUSH_OT_active_index_set, WM_OT_addon_disable, @@ -2380,4 +2399,5 @@ classes = ( WM_OT_owner_disable, WM_OT_owner_enable, WM_OT_url_open, + WM_OT_tool_set_by_name, ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 9a9e86f6871..ee2f11c46d0 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -39,6 +39,7 @@ if "_icon_cache" in locals(): # (filename -> icon_value) map _icon_cache = {} + def _keymap_fn_from_seq(keymap_data): # standalone @@ -91,6 +92,7 @@ ToolDef = namedtuple( ) del namedtuple + def from_dict(kw_args): """ Use so each tool can avoid defining all members of the named tuple. @@ -116,6 +118,7 @@ def from_dict(kw_args): kw["keymap"] = keymap return ToolDef(**kw) + def from_fn(fn): """ Use as decorator so we can define functions. @@ -186,19 +189,83 @@ class ToolSelectPanelHelper: Flattens, skips None and calls generators. """ for item in tools: - if item is not None: - if type(item) is tuple: - for sub_item in item: - if sub_item is not None: - if _item_is_fn(sub_item): - yield from sub_item(context) - else: - yield sub_item + if item is None: + yield None + elif type(item) is tuple: + for sub_item in item: + if sub_item is None: + yield None + elif _item_is_fn(sub_item): + yield from sub_item(context) + else: + yield sub_item + else: + if _item_is_fn(item): + yield from item(context) else: - if _item_is_fn(item): - yield from item(context) + yield item + + @staticmethod + def _tools_flatten_with_tool_index(tools): + for item in tools: + if item is None: + yield None, -1 + elif type(item) is tuple: + i = 0 + for sub_item in item: + if sub_item is None: + yield None + elif _item_is_fn(sub_item): + for item_dyn in sub_item(context): + yield item_dyn, i + i += 1 else: - yield item + yield sub_item, i + i += 1 + else: + if _item_is_fn(item): + for item_dyn in item(context): + yield item_dyn, -1 + else: + yield item, -1 + + @staticmethod + def _tool_get_active(context, with_icon=False): + """ + Return the active Python tool definition and icon name. + """ + + workspace = context.workspace + cls = ToolSelectPanelHelper._tool_class_from_space_type(workspace.tool_space_type) + if cls is not None: + tool_def_active, index_active = ToolSelectPanelHelper._tool_vars_from_active_with_index(context) + + context_mode = context.mode + for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context)): + if item is not None: + tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) + if (tool_def == tool_def_active): + if with_icon: + icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) + else: + icon_value = 0 + return (item, icon_value) + return None, 0 + + @staticmethod + def _tool_get_by_name(context, text): + """ + Return the active Python tool definition and index (if in sub-group, else -1). + """ + workspace = context.workspace + cls = ToolSelectPanelHelper._tool_class_from_space_type(workspace.tool_space_type) + if cls is not None: + context_mode = context.mode + for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)): + if item is not None: + if item.text == text: + return (item, index) + return None, -1 @staticmethod def _tool_vars_from_def(item, context_mode): @@ -284,7 +351,6 @@ class ToolSelectPanelHelper: icon_name = item.icon cls._km_action_simple(kc, context_mode, text, keymap_data) - # ------------------------------------------------------------------------- # Layout Generators # @@ -456,30 +522,8 @@ class ToolSelectPanelHelper: ui_gen.send(None) @staticmethod - def _active_tool(context, with_icon=False): - """ - Return the active Python tool definition and icon name. - """ - - workspace = context.workspace - cls = ToolSelectPanelHelper._tool_class_from_space_type(workspace.tool_space_type) - if cls is not None: - tool_def_active, index_active = ToolSelectPanelHelper._tool_vars_from_active_with_index(context) - - context_mode = context.mode - for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context)): - tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) - if (tool_def == tool_def_active): - if with_icon: - icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) - else: - icon_value = 0 - return (item, icon_value) - return None, 0 - - @staticmethod def draw_active_tool_header(context, layout): - item, icon_value = ToolSelectPanelHelper._active_tool(context, with_icon=True) + item, icon_value = ToolSelectPanelHelper._tool_get_active(context, with_icon=True) if item is None: return # Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools. @@ -541,6 +585,21 @@ class WM_MT_toolsystem_submenu(Menu): index += 1 +def activate_by_name(context, text): + item, index = ToolSelectPanelHelper._tool_get_by_name(context, text) + if item is not None: + context_mode = context.mode + tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) + bpy.ops.wm.tool_set( + keymap=tool_def[0] or "", + manipulator_group=tool_def[1] or "", + data_block=tool_def[2] or "", + index=index, + ) + return True + return False + + classes = ( WM_MT_toolsystem_submenu, ) |