[Bf-blender-cvs] [f4697b392d4] blender2.8: Tool System: change internal definitions (again)

Campbell Barton noreply at git.blender.org
Mon Apr 30 12:15:42 CEST 2018


Commit: f4697b392d48302fc5df70208c22f4678150c702
Author: Campbell Barton
Date:   Mon Apr 30 12:14:46 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBf4697b392d48302fc5df70208c22f4678150c702

Tool System: change internal definitions (again)

Was using classes to define tools, however this makes it awkward to
dynamically generate them (we can do it, but its not very "Pythonic").

Move to a named tuple.

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

M	release/scripts/startup/bl_ui/space_toolsystem_common.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py

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

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index af248df8698..1ae9a15b6a3 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -59,47 +59,73 @@ def _keymap_fn_from_seq(keymap_data):
 
 
 def _item_is_fn(item):
-    return (not (type(item) is type and issubclass(item, ToolDef)) and callable(item))
+    return (not (type(item) is ToolDef) and callable(item))
 
 
-class ToolDef:
-    """
-    Tool definition,
-    This class is never instanced, it's used as definition for tool types.
+from collections import namedtuple
+ToolDef = namedtuple(
+    "ToolDef",
+    (
+        # The name to display in the interface.
+        "text",
+        # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon.
+        "icon",
+        # An optional manipulator group to activate when the tool is set or None for no widget.
+        "widget",
+        # Optional keymap for tool, either:
+        # - A function that populates a keymaps passed in as an argument.
+        # - A tuple filled with triple's of:
+        #   ``(operator_id, operator_properties, keymap_item_args)``.
+        #
+        # Warning: currently 'from_dict' this is a list of one item,
+        # so internally we can swap the keymap function for the keymap it's self.
+        # This isn't very nice and may change, tool definitions shouldn't care about this.
+        "keymap",
+        # Optional data-block assosiated with this tool.
+        # (Typically brush name, usage depends on mode, we could use for non-brush ID's in other modes).
+        "data_block",
+        # Optional draw settings (operator options, toolsettings).
+        "draw_settings",
+    )
+)
+del namedtuple
 
-    Since we want to define functions here, it's more convenient to declare class-methods
-    then functions in a dict or tuple.
+def from_dict(kw_args):
+    """
+    Use so each tool can avoid defining all members of the named tuple.
+    Also convert the keymap from a tuple into a function
+    (since keymap is a callback).
+    """
+    kw = {
+        "icon": None,
+        "widget": None,
+        "keymap": None,
+        "data_block": None,
+        "draw_settings": None,
+    }
+    kw.update(kw_args)
+
+    keymap = kw["keymap"]
+    if kw["keymap"] is None:
+        pass
+    elif type(keymap) is tuple:
+        keymap = [_keymap_fn_from_seq(keymap)]
+    else:
+        keymap = [keymap]
+    kw["keymap"] = keymap
+    return ToolDef(**kw)
+
+def from_fn(fn):
     """
-    __slots__ = ()
-
-    def __new__(cls, *args, **kwargs):
-        raise RuntimeError("%s should not be instantiated" % cls)
-
-    def __init_subclass__(cls):
-        # All classes must have a name
-        assert(cls.text is not None)
-        # We must have a key-map or widget (otherwise the tool does nothing!)
-        assert(not (cls.keymap is None and cls.widget is None and cls.data_block is None))
-
-        if type(cls.keymap) is tuple:
-            cls.keymap = _keymap_fn_from_seq(cls.keymap)
-
-    # The name to display in the interface.
-    text = None
-    # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon.
-    icon = None
-    # An optional manipulator group to activate when the tool is set or None for no widget.
-    widget = None
-    # Optional keymap for tool, either:
-    # - A function that populates a keymaps passed in as an argument.
-    # - A tuple filled with triple's of:
-    #   ``(operator_id, operator_properties, keymap_item_args)``.
-    keymap = None
-    # Optional data-block assosiated with this tool.
-    # (Typically brush name, usage depends on mode, we could use for non-brush ID's in other modes).
-    data_block = None
-    # Optional draw settings (operator options, toolsettings).
-    draw_settings = None
+    Use as decorator so we can define functions.
+    """
+    return ToolDef.from_dict(fn())
+
+
+ToolDef.from_dict = from_dict
+ToolDef.from_fn = from_fn
+del from_dict
+del from_fn
 
 
 class ToolSelectPanelHelper:
@@ -169,14 +195,11 @@ class ToolSelectPanelHelper:
         icon_name = item.icon
         mp_idname = item.widget
         datablock_idname = item.data_block
-        keymap_fn = item.keymap
-        if keymap_fn is None:
-            km, km_idname = (None, None)
+        keymap = item.keymap
+        if keymap is None:
+            km_idname = None
         else:
-            km_test = cls._tool_keymap.get((context_mode, text))
-            if km_test is None and context_mode is not None:
-                km_test = cls._tool_keymap[None, text]
-            km, km_idname = km_test
+            km_idname = keymap[0].name
         return (km_idname, mp_idname, datablock_idname), icon_name
 
     @staticmethod
@@ -198,23 +221,21 @@ class ToolSelectPanelHelper:
             (
                 props.keymap or None or None,
                 props.manipulator_group or None,
-                props.data_block,
+                props.data_block or None,
             ),
             props.index,
         )
 
     @classmethod
     def _km_action_simple(cls, kc, context_mode, text, keymap_fn):
-
         if context_mode is None:
             context_mode = "All"
         km_idname = f"{cls.keymap_prefix} {context_mode}, {text}"
         km = kc.keymaps.get(km_idname)
-        if km is not None:
-            return km, km_idname
-        km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW')
-        keymap_fn(km)
-        return km, km_idname
+        if km is None:
+            km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW')
+            keymap_fn[0](km)
+        keymap_fn[0] = km
 
     @classmethod
     def register(cls):
@@ -226,9 +247,6 @@ class ToolSelectPanelHelper:
         # This needs some careful consideration.
         kc = wm.keyconfigs.user
 
-        # {context_mode: {tool_name: (keymap, keymap_idname, manipulator_group_idname), ...}, ...}
-        cls._tool_keymap = {}
-
         # Track which tool-group was last used for non-active groups.
         # Blender stores the active tool-group index.
         #
@@ -248,11 +266,10 @@ class ToolSelectPanelHelper:
                     if item is None or _item_is_fn(item):
                         continue
                     keymap_data = item.keymap
-                    if keymap_data is not None:
+                    if keymap_data is not None and callable(keymap_data[0]):
                         text = item.text
                         icon_name = item.icon
-                        km, km_idname = cls._km_action_simple(kc, context_mode, text, keymap_data)
-                        cls._tool_keymap[context_mode, text] = km, km_idname
+                        cls._km_action_simple(kc, context_mode, text, keymap_data)
 
 
     # -------------------------------------------------------------------------
@@ -487,7 +504,6 @@ class WM_MT_toolsystem_submenu(Menu):
                         item = item_group[index_button]
                         tool_def, icon_name = cls._tool_vars_from_def(item, context_mode)
                         is_active = (tool_def == tool_def_button)
-                        print(tool_def, tool_def_button)
                         if is_active:
                             return cls, item_group, index_button
         return None, None, -1
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index c3d58d49142..036d248667e 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -31,377 +31,475 @@ from .space_toolsystem_common import (
     ToolDef,
 )
 
-
 class _defs_view3d_generic:
-
-    class cursor(ToolDef):
-        text = "Cursor"
-        icon = "ops.generic.cursor"
-        widget = None
-
-        keymap = (
+    @ToolDef.from_fn
+    def cursor():
+        return dict(
+        text="Cursor",
+        icon="ops.generic.cursor",
+        keymap=(
             ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
-        )
+        ),
+    )
 
-    class ruler(ToolDef):
-        text = "Ruler/Protractor"
-        icon = "ops.view3d.ruler"
-        widget = "VIEW3D_WGT_ruler"
-        keymap = (
+    @ToolDef.from_fn
+    def ruler():
+        return dict(
+        text="Ruler/Protractor",
+        icon="ops.view3d.ruler",
+        widget="VIEW3D_WGT_ruler",
+        keymap=(
             ("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
-        )
-
+        ),
+    )
 
 class _defs_transform:
 
-    class translate(ToolDef):
-        text = "Move"
-        icon = "ops.transform.translate"
-        widget = "TRANSFORM_WGT_manipulator"
-        keymap = (
+    @ToolDef.from_fn
+    def translate():
+        return dict(
+        text="Move",
+        icon="ops.transform.translate",
+        widget="TRANSFORM_WGT_manipulator",
+        keymap=(
             ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
-        )
+        ),
+    )
 
-    class rotate(ToolDef):
-        text = "Rotate"
-        icon = "ops.transform.rotate"
-        widget = "TRANSFORM_WGT_manipulator"
-        keymap = (
-            ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
+    @ToolDef.from_fn
+    def rotate():
+        return dict(
+            text="Rotate",
+            icon="ops.transform.rotate",
+            widget="TRANSFORM_WGT_manipulator",
+            keymap=(
+                ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
+            ),
         )
 
-    class scale(ToolDef):
-        text = "Scale"
-        icon = "ops.transform.resize"
-        widget = "TRANSFORM_WGT_manipulator"
-        keymap = (
-            ("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
+    @ToolDef.from_fn
+    def scale():
+        return dict(
+            text="Scale",
+            icon

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list