Commit: d95e9c7cf80ae2eb40728e7369216e48146a3a36 Author: Philipp Oeser Date: Thu Feb 6 14:07:53 2020 +0100 Branches: master https://developer.blender.org/rBd95e9c7cf80ae2eb40728e7369216e48146a3a36
Fix T63892: Tools cannot be registered into some contexts (e.g. PAINT_TEXTURE) This fails because some tool contexts define their tools with functions [see the following list for context that fail]: - PARTICLE (_defs_particle.generate_from_brushes) - SCULPT (_defs_sculpt.generate_from_brushes) - PAINT_TEXTURE (_defs_texture_paint.generate_from_brushes) - PAINT_VERTEX (_defs_vertex_paint.generate_from_brushes) - PAINT_WEIGHT (_defs_weight_paint.generate_from_brushes) - PAINT_GPENCIL (_defs_gpencil_paint.generate_from_brushes) - SCULPT_GPENCIL (_defs_gpencil_sculpt.generate_from_brushes) - WEIGHT_GPENCIL (_defs_gpencil_weight.generate_from_brushes) ToolSelectPanelHelper._tools_flatten() is usually called with cls.tools_from_context(context) [that already yields from the function]. But when registering a tool, _tools_flatten() will still give back this function, not a ToolDef - and we cannot get a bl_idname from that. Now check for this and yield None in that case. Also share logic across all tool_flatten functions: - _tools_flatten - _tools_flatten_with_tool_index - _tools_flatten_with_keymap Maniphest Tasks: T63892 Differential Revision: https://developer.blender.org/D6763 =================================================================== M release/scripts/startup/bl_ui/space_toolsystem_common.py =================================================================== diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 4dc724299f0..d2deb70d4a2 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -216,29 +216,52 @@ class ToolSelectPanelHelper: else: return 0 + # tool flattening + # + # usually 'tools' is already expanded into ToolDef + # but when registering a tool, this can still be a function + # (_tools_flatten is usually called with cls.tools_from_context(context) + # [that already yields from the function]) + # so if item is still a function (e.g._defs_XXX.generate_from_brushes) + # seems like we cannot expand here (have no context yet) + # if we yield None here, this will risk running into duplicate tool bl_idname [in register_tool()] + # but still better than erroring out @staticmethod def _tools_flatten(tools): - for item in tools: - if type(item) is tuple: - yield from item - else: - # May be None. - yield item + for item_parent in tools: + if item_parent is None: + yield None + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + if item is None or _item_is_fn(item): + yield None + else: + yield item @staticmethod def _tools_flatten_with_tool_index(tools): - for item in tools: - if type(item) is tuple: - i = 0 - for sub_item in item: - if sub_item is None: - yield None, -1 - else: - yield sub_item, i - i += 1 - else: - # May be None. - yield item, -1 + for item_parent in tools: + if item_parent is None: + yield None, -1 + i = 0 + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + if item is None or _item_is_fn(item): + yield None, -1 + else: + yield item, i + i += 1 + + # Special internal function, gives use items that contain keymaps. + @staticmethod + def _tools_flatten_with_keymap(tools): + for item_parent in tools: + if item_parent is None: + continue + for item in item_parent if (type(item_parent) is tuple) else (item_parent,): + # skip None or generator function + if item is None or _item_is_fn(item): + continue + if item.keymap is not None: + yield item @classmethod def _tool_get_active(cls, context, space_type, mode, with_icon=False): @@ -413,19 +436,6 @@ class ToolSelectPanelHelper: keymap_fn[0](km) keymap_fn[0] = km.name - # Special internal function, gives use items that contain keymaps. - @staticmethod - def _tools_flatten_with_keymap(tools): - for item_parent in tools: - if item_parent is None: - continue - for item in item_parent if (type(item_parent) is tuple) else (item_parent,): - # skip None or generator function - if item is None or _item_is_fn(item): - continue - if item.keymap is not None: - yield item - @classmethod def register(cls): wm = bpy.context.window_manager _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs