Python tool set/unset Handlers #118026

Open
Jaume Bellet wants to merge 5 commits from JaumeBellet/blender:pr-0021-tool-handlers into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 29 additions and 5 deletions

View File

@ -885,6 +885,12 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False):
"draw_settings": getattr(tool_cls, "draw_settings", None),
"draw_cursor": getattr(tool_cls, "draw_cursor", None),
})
if hasattr( tool_cls, 'set_cb' ) and callable(tool_cls.set_cb ):
tool_def.handlers.set.append(tool_cls.set_cb)
if hasattr( tool_cls, 'unset_cb' ) and callable(tool_cls.unset_cb ):
tool_def.handlers.set.append(tool_cls.unset_cb)
tool_cls._bl_tool = tool_def
keymap_data = tool_def.keymap
@ -904,7 +910,7 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False):
cls._km_action_simple(kc_default, kc, context_descr, tool_def.label, keymap_data)
return tool_def
tool_converted = tool_from_class(tool_cls)
tool_created = tool_converted = tool_from_class(tool_cls)
if group:
# Create a new group
@ -956,6 +962,7 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False):
if not changed:
tools.extend(tool_def_insert)
return tool_created
def unregister_tool(tool_cls):
space_type = tool_cls.bl_space_type

View File

@ -106,10 +106,16 @@ ToolDef = namedtuple(
"draw_cursor",
# Various options, see: `bpy.types.WorkSpaceTool.setup` options argument.
"options",
# Handlers
"handlers"
)
)
del namedtuple
class ToolDefHandlers:
def __init__ (self):
self.set = []
self.unset = []
def from_dict(kw_args):
"""
@ -129,6 +135,7 @@ def from_dict(kw_args):
"operator": None,
"draw_settings": None,
"draw_cursor": None,
"handlers" : ToolDefHandlers()
}
kw.update(kw_args)
@ -326,11 +333,11 @@ class ToolSelectPanelHelper:
return None, None, 0
@classmethod
def _tool_get_by_id(cls, context, idname):
def _tool_get_by_id(cls, context, idname, mode = None):
"""
Return the active Python tool definition and index (if in sub-group, else -1).
"""
for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)):
for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context, mode)):
if item is not None:
if item.idname == idname:
return (item, index)
@ -985,6 +992,9 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False):
tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
tool_fallback_id = cls.tool_fallback_id
curr_tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type)
curr_item, curr_index = cls._tool_get_by_id(context, getattr(curr_tool, "idname", None))
if as_fallback:
# To avoid complicating logic too much, isolate all fallback logic to this block.
# This will set the tool again, using the item for the fallback instead of the primary tool.
@ -1031,6 +1041,13 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False):
if keymap_fallback:
keymap_fallback = keymap_fallback + " (fallback)"
if curr_item is not None:
for cb in curr_item.handlers.unset:
cb()
for cb in item.handlers.set:
cb()
tool.setup(
idname=item.idname,
keymap=item.keymap[0] if item.keymap is not None else "",
@ -1155,12 +1172,12 @@ def description_from_id(context, space_type, idname, *, use_operator=True):
return ""
def item_from_id(context, space_type, idname):
def item_from_id(context, space_type, idname, mode = None):
# Used directly for tooltips.
cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
if cls is None:
return None
item, _index = cls._tool_get_by_id(context, idname)
item, _index = cls._tool_get_by_id(context, idname, mode)
return item