[Bf-blender-cvs] [082ddc9379b] master: ToolSystem: support per-tool gizmo group properties

Campbell Barton noreply at git.blender.org
Thu Aug 26 08:07:23 CEST 2021


Commit: 082ddc9379b2bdc963635c1109fbd6c6bce91eed
Author: Campbell Barton
Date:   Thu Aug 26 16:02:31 2021 +1000
Branches: master
https://developer.blender.org/rB082ddc9379b2bdc963635c1109fbd6c6bce91eed

ToolSystem: support per-tool gizmo group properties

Also add gizmo group example to the tool-template.

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

M	release/scripts/modules/bl_keymap_utils/io.py
M	release/scripts/modules/bpy/utils/__init__.py
M	release/scripts/startup/bl_ui/space_toolsystem_common.py
M	release/scripts/templates_py/ui_tool_simple.py
M	source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c

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

diff --git a/release/scripts/modules/bl_keymap_utils/io.py b/release/scripts/modules/bl_keymap_utils/io.py
index 7adcd799c0f..96832cbd9c7 100644
--- a/release/scripts/modules/bl_keymap_utils/io.py
+++ b/release/scripts/modules/bl_keymap_utils/io.py
@@ -22,6 +22,7 @@
 # Export Functions
 
 __all__ = (
+    "_init_properties_from_data",  # Shared with gizmo default property initialization.
     "keyconfig_export_as_data",
     "keyconfig_import_from_data",
     "keyconfig_init_from_data",
@@ -244,20 +245,24 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False):
 
 # -----------------------------------------------------------------------------
 # Import Functions
-
-def _kmi_props_setattr(kmi_props, attr, value):
-    if type(value) is list:
-        kmi_subprop = getattr(kmi_props, attr)
-        for subattr, subvalue in value:
-            _kmi_props_setattr(kmi_subprop, subattr, subvalue)
-        return
-
-    try:
-        setattr(kmi_props, attr, value)
-    except AttributeError:
-        print(f"Warning: property '{attr}' not found in keymap item '{kmi_props.__class__.__name__}'")
-    except Exception as ex:
-        print(f"Warning: {ex!r}")
+#
+# NOTE: unlike export, this runs on startup.
+# Take care making changes that could impact performance.
+
+def _init_properties_from_data(base_props, base_value):
+    assert(type(base_value) is list)
+    for attr, value in base_value:
+        if type(value) is list:
+            base_props.property_unset(attr)
+            props = getattr(base_props, attr)
+            _init_properties_from_data(props, value)
+        else:
+            try:
+                setattr(base_props, attr, value)
+            except AttributeError:
+                print(f"Warning: property '{attr}' not found in item '{base_props.__class__.__name__}'")
+            except Exception as ex:
+                print(f"Warning: {ex!r}")
 
 
 def keymap_init_from_data(km, km_items, is_modal=False):
@@ -271,8 +276,7 @@ def keymap_init_from_data(km, km_items, is_modal=False):
             if kmi_props_data is not None:
                 kmi_props = kmi.properties
                 assert type(kmi_props_data) is list
-                for attr, value in kmi_props_data:
-                    _kmi_props_setattr(kmi_props, attr, value)
+                _init_properties_from_data(kmi_props, kmi_props_data)
 
 
 def keyconfig_init_from_data(kc, keyconfig_data):
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 1fe73f50639..afa04a18ef6 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -859,6 +859,7 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False):
             "icon": getattr(tool_cls, "bl_icon", None),
             "cursor": getattr(tool_cls, "bl_cursor", None),
             "widget": getattr(tool_cls, "bl_widget", None),
+            "widget_properties": getattr(tool_cls, "bl_widget_properties", None),
             "keymap": getattr(tool_cls, "bl_keymap", None),
             "data_block": getattr(tool_cls, "bl_data_block", None),
             "operator": getattr(tool_cls, "bl_operator", None),
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index cde430c1e6f..74e0f242299 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -75,6 +75,8 @@ ToolDef = namedtuple(
         "icon",
         # An optional cursor to use when this tool is active.
         "cursor",
+        # The properties to use for the widget.
+        "widget_properties",
         # An optional gizmo group to activate when the tool is set or None for no gizmo.
         "widget",
         # Optional key-map for tool, possible values are:
@@ -132,6 +134,7 @@ def from_dict(kw_args):
         "icon": None,
         "cursor": None,
         "widget": None,
+        "widget_properties": None,
         "keymap": None,
         "data_block": None,
         "operator": None,
@@ -939,6 +942,21 @@ class WM_MT_toolsystem_submenu(Menu):
             ).name = item.idname
 
 
+def _kmi_props_setattr(kmi_props, attr, value):
+    if type(value) is list:
+        kmi_subprop = getattr(kmi_props, attr)
+        for subattr, subvalue in value:
+            _kmi_props_setattr(kmi_subprop, subattr, subvalue)
+        return
+
+    try:
+        setattr(kmi_props, attr, value)
+    except AttributeError:
+        print(f"Warning: property '{attr}' not found in keymap item '{kmi_props.__class__.__name__}'")
+    except Exception as ex:
+        print(f"Warning: {ex!r}")
+
+
 def _activate_by_item(context, space_type, item, index, *, as_fallback=False):
     cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
     tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
@@ -983,11 +1001,13 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False):
         item_fallback, _index = cls._tool_get_active_by_index(context, select_index)
     # End calculating fallback.
 
+    gizmo_group = item.widget or ""
+
     tool.setup(
         idname=item.idname,
         keymap=item.keymap[0] if item.keymap is not None else "",
         cursor=item.cursor or 'DEFAULT',
-        gizmo_group=item.widget or "",
+        gizmo_group=gizmo_group,
         data_block=item.data_block or "",
         operator=item.operator or "",
         index=index,
@@ -995,6 +1015,24 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False):
         keymap_fallback=(item_fallback and item_fallback.keymap and item_fallback.keymap[0]) or "",
     )
 
+    if (
+            (gizmo_group != "") and
+            (props := tool.gizmo_group_properties(gizmo_group))
+    ):
+        if props is None:
+            print("Error:", gizmo_group, "could not access properties!")
+        else:
+            for key in props.bl_rna.properties.keys():
+                props.property_unset(key)
+
+            gizmo_properties = item.widget_properties
+            if gizmo_properties is not None:
+                if not isinstance(gizmo_properties, list):
+                    raise Exception("expected a list, not a %r" % type(gizmo_properties))
+
+                from bl_keymap_utils.io import _init_properties_from_data
+                _init_properties_from_data(props, gizmo_properties)
+
     WindowManager = bpy.types.WindowManager
 
     handle_map = _activate_by_item._cursor_draw_handle
diff --git a/release/scripts/templates_py/ui_tool_simple.py b/release/scripts/templates_py/ui_tool_simple.py
index fc239093b9c..fa81b3b58a9 100644
--- a/release/scripts/templates_py/ui_tool_simple.py
+++ b/release/scripts/templates_py/ui_tool_simple.py
@@ -53,14 +53,38 @@ class MyOtherTool(WorkSpaceTool):
         layout.prop(props, "mode")
 
 
+class MyWidgetTool(WorkSpaceTool):
+    bl_space_type = 'VIEW_3D'
+    bl_context_mode = 'OBJECT'
+
+    bl_idname = "my_template.my_gizmo_translate"
+    bl_label = "My Gizmo Tool"
+    bl_description = "Short description"
+    bl_icon = "ops.transform.translate"
+    bl_widget="VIEW3D_GGT_tool_generic_handle_free"
+    bl_widget_properties=[
+        ("radius", 75.0),
+        ("backdrop_fill_alpha", 0.0),
+    ]
+    bl_keymap = (
+        ("transform.translate", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
+    )
+
+    def draw_settings(context, layout, tool):
+        props = tool.operator_properties("transform.translate")
+        layout.prop(props, "mode")
+
+
 def register():
     bpy.utils.register_tool(MyTool, after={"builtin.scale_cage"}, separator=True, group=True)
     bpy.utils.register_tool(MyOtherTool, after={MyTool.bl_idname})
+    bpy.utils.register_tool(MyWidgetTool, after={MyTool.bl_idname})
 
 
 def unregister():
     bpy.utils.unregister_tool(MyTool)
     bpy.utils.unregister_tool(MyOtherTool)
+    bpy.utils.unregister_tool(MyWidgetTool)
 
 
 if __name__ == "__main__":
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
index ad91af73a71..0e0d59764e5 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
@@ -36,6 +36,7 @@
 #include "WM_toolsystem.h"
 
 #include "RNA_access.h"
+#include "RNA_define.h"
 
 #include "WM_api.h"
 #include "WM_message.h"
@@ -47,6 +48,9 @@
 static const char *handle_normal_id;
 static const char *handle_free_id;
 
+static const float handle_normal_radius_default = 100.0f;
+static const float handle_free_radius_default = 36.0f;
+
 /* -------------------------------------------------------------------- */
 /** \name Generic Tool
  * \{ */
@@ -72,6 +76,7 @@ static bool WIDGETGROUP_tool_generic_poll(const bContext *C, wmGizmoGroupType *g
 
 static wmGizmo *tool_generic_create_gizmo(const bContext *C, wmGizmoGroup *gzgroup)
 {
+
   wmGizmo *gz = WM_gizmo_new("GIZMO_GT_button_2d", gzgroup, NULL);
   gz->flag |= WM_GIZMO_OPERATOR_TOOL_INIT;
 
@@ -82,8 +87,17 @@ static wmGizmo *tool_generic_create_gizmo(const bContext *C, wmGizmoGroup *gzgro
 
   RNA_enum_set(gz->ptr, "icon", ICON_NONE);
 
+  bToolRef *tref = WM_toolsystem_ref_from_context((bContext *)C);
+  PointerRNA gzgt_ptr;
+  const bool gzgt_ptr_is_valid = WM_toolsystem_ref_properties_get_from_gizmo_group(
+      tref, gzgroup->type, &gzgt_ptr);
+
   if (gzgroup->type->idname == handle_normal_id) {
-    gz->scale_basis = 0.12f;
+    const float radius = (gzgt_ptr_is_valid ? RNA_float_get(&gzgt_ptr, "radius") :
+                                              handle_normal_radius_default) /
+                         12.0f;
+
+    gz->scale_basis = radius / U.gizmo_size;
     gz->matrix_offset[3][2] -= 12.0;
     RNA_enum_set(gz->ptr,
                  "draw_options",
@@ -91,16 +105,20 @@ static wmGizmo *tool_generic_create_gizmo(const bContext *C, wmGizmoGroup *gzgro
                   ED_GIZMO_BUTTON_SHOW_OUTLINE));
   }
   else {
-    gz->scale_basis = 0.16f * 3;
+    const float radius = gzgt_ptr_is_valid ? RNA_float_ge

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list