[Bf-blender-cvs] [e1e7b6db2e0] blender2.8: WM: Initial Tool System

Campbell Barton noreply at git.blender.org
Sat Oct 21 07:36:28 CEST 2017


Commit: e1e7b6db2e01d8ea2219d410200a8856d4597222
Author: Campbell Barton
Date:   Sat Oct 21 16:19:48 2017 +1100
Branches: blender2.8
https://developer.blender.org/rBe1e7b6db2e01d8ea2219d410200a8856d4597222

WM: Initial Tool System

The tool-system it's self is primitive and may be changed.

Adding to 2.8 to develop operators and manipulators as tools.

Currently this is exposed in the toolbar, collapsed by default.
Work-flow remains unchanged if you don't change the active tool.

Placing the 3D cursor is now a Click instead of a Press event,
this allows tweak events to be mapped to tools such as border select,
keeping click for 3D cursor placement when selection tools are set.

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

M	release/scripts/startup/bl_ui/__init__.py
A	release/scripts/startup/bl_ui/space_toolsystem_common.py
A	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/space_view3d/view3d_ops.c
M	source/blender/makesdna/DNA_workspace_types.h
M	source/blender/makesrna/intern/rna_workspace.c
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index d7135ca202c..a12fd6352ea 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -64,6 +64,12 @@ _modules = [
     "properties_scene",
     "properties_texture",
     "properties_world",
+
+    # Generic Space Modules
+    #
+    # Depends on DNA_WORKSPACE_TOOL (C define).
+    "space_toolsystem_toolbar",
+
     "space_clip",
     "space_console",
     "space_dopesheet",
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
new file mode 100644
index 00000000000..38971f73984
--- /dev/null
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -0,0 +1,127 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+
+__all__ = (
+    "ToolSelectPanelHelper",
+)
+
+
+class ToolSelectPanelHelper:
+    """
+    Generic Class, can be used for any toolbar.
+
+    - keymap_prefix:
+      The text prefix for each key-map for this spaces tools.
+    - tools_all():
+      Returns all tools defined.
+    - tools_from_context(context):
+      Returns tools available in this context.
+
+    Each tool is a triplet:
+      ``(tool_name, manipulator_group_idname, keymap_actions)``
+    For a separator in the toolbar, use ``None``.
+
+      Where:
+      ``tool_name``
+        is the name to display in the interface.
+      ``manipulator_group_idname``
+        is an optional manipulator group to activate when the tool is set.
+      ``keymap_actions``
+        an optional triple of: ``(operator_id, operator_properties, keymap_item_args)``
+    """
+
+    @classmethod
+    def _km_actionmouse_simple(cls, kc, text, actions):
+
+        # standalone
+        def props_assign_recursive(rna_props, py_props):
+            for prop_id, value in py_props.items():
+                if isinstance(value, dict):
+                    props_assign_recursive(getattr(rna_props, prop_id), value)
+                else:
+                    setattr(rna_props, prop_id, value)
+
+        km_idname = cls.keymap_prefix + text
+        km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW')
+        for op_idname, op_props_dict, kmi_kwargs in actions:
+            kmi = km.keymap_items.new(op_idname, **kmi_kwargs)
+            kmi_props = kmi.properties
+            if op_props_dict:
+                props_assign_recursive(kmi.properties, op_props_dict)
+        return km, km_idname
+
+    @classmethod
+    def register(cls):
+        wm = bpy.context.window_manager
+
+        # XXX, should we be manipulating the user-keyconfig on load?
+        # Perhaps this should only add when keymap items don't already exist.
+        #
+        # This needs some careful consideration.
+        kc = wm.keyconfigs.user
+
+        # {tool_name: (keymap, keymap_idname, manipulator_group_idname), ...}
+        cls._tool_keymap = {}
+
+        for t in cls.tools_all():
+            text, mp_idname, actions = t
+            if actions is not None:
+                km, km_idname = cls._km_actionmouse_simple(kc, text, actions)
+                cls._tool_keymap[text] = km, km_idname
+
+    def draw(self, context):
+        # XXX, this UI isn't very nice.
+        # We might need to create new button types for this.
+        # Since we probably want:
+        # - tool-tips that include multiple key shortcuts.
+        # - ability to click and hold to expose sub-tools.
+
+        workspace = context.workspace
+        km_idname_active = workspace.tool_keymap or None
+        mp_idname_active = workspace.tool_manipulator_group or None
+        layout = self.layout
+
+        for tool_items in self.tools_from_context(context):
+            if tool_items:
+                col = layout.box().column()
+                for item in tool_items:
+                    if item is None:
+                        col = layout.box().column()
+                        continue
+                    text, mp_idname, actions = item
+
+                    if actions is not None:
+                        km, km_idname = self._tool_keymap[text]
+                    else:
+                        km = None
+                        km_idname = None
+
+                    props = col.operator(
+                        "wm.tool_set",
+                        text=text,
+                        emboss=(
+                            km_idname_active == km_idname and
+                            mp_idname_active == mp_idname
+                        ),
+                    )
+
+                    props.keymap = km_idname or ""
+                    props.manipulator_group = mp_idname or ""
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
new file mode 100644
index 00000000000..d8843d4fbce
--- /dev/null
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -0,0 +1,134 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# For now group all tools together
+# we may want to move these into per space-type files.
+#
+# For now keep this in a single file since it's an area that may change,
+# so avoid making changes all over the place.
+
+from bpy.types import Panel
+
+from .space_toolsystem_common import (
+    ToolSelectPanelHelper,
+)
+
+
+class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'TOOLS'
+    bl_category = "Tools"
+    bl_label = "Active Tool (Test)"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    # Satisfy the 'ToolSelectPanelHelper' API.
+    keymap_prefix = "3D View Tool: "
+
+    @classmethod
+    def tools_from_context(cls, context):
+        return (cls._tools[None], cls._tools.get(context.mode, ()))
+
+    @classmethod
+    def tools_all(cls):
+        return [t for t_list in cls._tools.values() for t in t_list if t is not None]
+
+    # Internal Data
+
+    # for reuse
+    _tools_transform = (
+        ("Translate", None,
+         (("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
+        ("Rotate", None,
+         (("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
+        ("Scale", None,
+         (("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),)),
+    )
+
+    _tools = {
+        None: [
+            ("Cursor", None,
+             (("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),)),
+            ("Select Border", None, (
+                ("view3d.select_border", dict(deselect=False), dict(type='EVT_TWEAK_A', value='ANY')),
+                ("view3d.select_border", dict(deselect=True), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
+            )),
+            ("Select Circle", None, (
+                ("view3d.select_circle", dict(deselect=False), dict(type='ACTIONMOUSE', value='PRESS')),
+                ("view3d.select_circle", dict(deselect=True), dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
+            )),
+            ("Select Lasso", None, (
+                ("view3d.select_lasso",
+                 dict(deselect=False), dict(type='EVT_TWEAK_A', value='ANY')),
+                ("view3d.select_lasso",
+                 dict(deselect=True), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
+            )),
+        ],
+        'OBJECT': [
+            *_tools_transform,
+        ],
+        'POSE': [
+            *_tools_transform,
+        ],
+        'EDIT_ARMATURE': [
+            *_tools_transform,
+            ("Roll", None, (
+                ("transform.transform",
+                 dict(release_confirm=True, mode='BONE_ROLL'),
+                 dict(type='EVT_TWEAK_A', value='ANY')),
+            )),
+            None,
+            ("Extrude Cursor", None,
+             (("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
+        ],
+        'EDIT_MESH': [
+            *_tools_transform,
+            None,
+            ("Rip Region", None, (
+                ("mesh.rip_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
+                 dict(type='ACTIONMOUSE', value='PRESS')),
+            )),
+            ("Rip Edge", None, (
+                ("mesh.rip_edge_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
+                 dict(type='ACTIONMOUSE', value='PRESS')),
+            )),
+            ("Knife", None, (("mesh.knife_tool", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),)),
+            ("Bisect", Non

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list