[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