diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-08-26 09:02:31 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-08-26 09:02:31 +0300 |
commit | 082ddc9379b2bdc963635c1109fbd6c6bce91eed (patch) | |
tree | ccb9a5e7d5a48064c27b8f0d0aebf3de6a5d10bb /release/scripts | |
parent | f464cac55a683387ae3511c76d08c8cca0a216c1 (diff) |
ToolSystem: support per-tool gizmo group properties
Also add gizmo group example to the tool-template.
Diffstat (limited to 'release/scripts')
-rw-r--r-- | release/scripts/modules/bl_keymap_utils/io.py | 36 | ||||
-rw-r--r-- | release/scripts/modules/bpy/utils/__init__.py | 1 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_toolsystem_common.py | 40 | ||||
-rw-r--r-- | release/scripts/templates_py/ui_tool_simple.py | 24 |
4 files changed, 84 insertions, 17 deletions
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__": |