Tool System: optionally cycle tools in a group
Add the ability for key bindings to set a tool-group, which cycles to the next tool when the tool is already active.
This commit is contained in:
parent
264a4a8f97
commit
16d3f4db4c
|
@ -55,6 +55,15 @@ rna_relative_prop = BoolProperty(
|
|||
default=False,
|
||||
)
|
||||
|
||||
rna_space_type_prop = EnumProperty(
|
||||
name="Type",
|
||||
items=tuple(
|
||||
(e.identifier, e.name, "", e. value)
|
||||
for e in bpy.types.Space.bl_rna.properties["type"].enum_items
|
||||
),
|
||||
default='EMPTY',
|
||||
)
|
||||
|
||||
|
||||
def context_path_validate(context, data_path):
|
||||
try:
|
||||
|
@ -2335,21 +2344,27 @@ class WM_OT_tool_set_by_name(Operator):
|
|||
name="Text",
|
||||
description="Display name of the tool",
|
||||
)
|
||||
space_type = EnumProperty(
|
||||
name="Type",
|
||||
items=tuple(
|
||||
(e.identifier, e.name, "", e. value)
|
||||
for e in bpy.types.Space.bl_rna.properties["type"].enum_items
|
||||
),
|
||||
default='EMPTY',
|
||||
|
||||
cycle = BoolProperty(
|
||||
name="Cycle",
|
||||
description="Cycle through tools in this group",
|
||||
default=False,
|
||||
options={'SKIP_SAVE'},
|
||||
)
|
||||
|
||||
space_type = rna_space_type_prop
|
||||
|
||||
def execute(self, context):
|
||||
from bl_ui.space_toolsystem_common import activate_by_name
|
||||
from bl_ui.space_toolsystem_common import (
|
||||
activate_by_name,
|
||||
activate_by_name_or_cycle,
|
||||
)
|
||||
space_type = self.space_type
|
||||
if space_type == 'EMPTY':
|
||||
space_type = context.space_data.type
|
||||
if activate_by_name(context, space_type, self.name):
|
||||
|
||||
fn = activate_by_name_or_cycle if self.cycle else activate_by_name
|
||||
if fn(context, space_type, self.name):
|
||||
return {'FINISHED'}
|
||||
else:
|
||||
self.report({'WARNING'}, f"Tool {self.name!r} not found.")
|
||||
|
|
|
@ -262,8 +262,8 @@ class ToolSelectPanelHelper:
|
|||
for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)):
|
||||
if item is not None:
|
||||
if item.text == text:
|
||||
return (item, index)
|
||||
return None, -1
|
||||
return (cls, item, index)
|
||||
return None, None, -1
|
||||
|
||||
@staticmethod
|
||||
def _tool_active_from_context(context, space_type, mode=None, create=False):
|
||||
|
@ -564,20 +564,60 @@ class WM_MT_toolsystem_submenu(Menu):
|
|||
).name = item.text
|
||||
|
||||
|
||||
def _activate_by_item(context, space_type, item, index):
|
||||
tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
|
||||
tool.setup(
|
||||
name=item.text,
|
||||
keymap=item.keymap[0].name if item.keymap is not None else "",
|
||||
cursor=item.cursor or 'DEFAULT',
|
||||
manipulator_group=item.widget or "",
|
||||
data_block=item.data_block or "",
|
||||
index=index,
|
||||
)
|
||||
|
||||
|
||||
def activate_by_name(context, space_type, text):
|
||||
item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
|
||||
if item is not None:
|
||||
tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
|
||||
tool.setup(
|
||||
name=text,
|
||||
keymap=item.keymap[0].name if item.keymap is not None else "",
|
||||
cursor=item.cursor or 'DEFAULT',
|
||||
manipulator_group=item.widget or "",
|
||||
data_block=item.data_block or "",
|
||||
index=index,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
|
||||
if item is None:
|
||||
return False
|
||||
_activate_by_item(context, space_type, item, index)
|
||||
return True
|
||||
|
||||
|
||||
def activate_by_name_or_cycle(context, space_type, text, offset=1):
|
||||
|
||||
# Only cycle when the active tool is activated again.
|
||||
cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
|
||||
if item is None:
|
||||
return False
|
||||
|
||||
tool_active = ToolSelectPanelHelper._tool_active_from_context(context, space_type)
|
||||
text_active = getattr(tool_active, "name", None)
|
||||
|
||||
text_current = ""
|
||||
for item_group in cls.tools_from_context(context):
|
||||
if type(item_group) is tuple:
|
||||
index_current = cls._tool_group_active.get(item_group[0].text, 0)
|
||||
ok = False
|
||||
for i, sub_item in enumerate(item_group):
|
||||
if sub_item.text == text:
|
||||
text_current = item_group[index_current].text
|
||||
break
|
||||
if text_current:
|
||||
break
|
||||
|
||||
if text_current == "":
|
||||
return activate_by_name(context, space_type, text)
|
||||
if text_active != text_current:
|
||||
return activate_by_name(context, space_type, text_current)
|
||||
|
||||
index_found = (tool_active.index + offset) % len(item_group)
|
||||
|
||||
cls._tool_group_active[item_group[0].text] = index_found
|
||||
|
||||
item_found = item_group[index_found]
|
||||
_activate_by_item(context, space_type, item_found, index_found)
|
||||
return True
|
||||
|
||||
|
||||
def keymap_from_context(context, space_type):
|
||||
|
|
Loading…
Reference in New Issue