[Bf-blender-cvs] [cee39da318f] blender2.8: WM: Operator to set the tool by name

Campbell Barton noreply at git.blender.org
Sun May 13 09:03:51 CEST 2018


Commit: cee39da318f23904e334cc98cdd1e6fb100297d6
Author: Campbell Barton
Date:   Sun May 13 08:59:50 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBcee39da318f23904e334cc98cdd1e6fb100297d6

WM: Operator to set the tool by name

Needed to bind keys to tools (T55036).

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

M	release/scripts/startup/bl_operators/wm.py
M	release/scripts/startup/bl_ui/space_toolsystem_common.py

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

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
     #
@@ -455,31 +521,9 @@ class ToolSelectPanelHelper:
         # Signal to finish any remaining layout edits.
         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,
 )



More information about the Bf-blender-cvs mailing list