From 56cd92413f8fb9d9b628d18c9c986f413f77d8b9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Sep 2020 17:42:41 +1000 Subject: Fix tool-system index error with mode-specific tools added to groups It was possible to have invalid indices when a script registered a tool into an existing group of tools. Address issue raised by D7436 --- .../startup/bl_ui/space_toolsystem_common.py | 29 ++++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 50316f50474..748b5733433 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -288,7 +288,6 @@ class ToolSelectPanelHelper: else: yield item - @classmethod def _tool_get_active(cls, context, space_type, mode, with_icon=False): """ @@ -326,7 +325,7 @@ class ToolSelectPanelHelper: if item is not None: if type(item) is tuple: if item[0].idname == idname: - index = cls._tool_group_active.get(item[0].idname, 0) + index = cls._tool_group_active_get_from_item(item) return (item[index], index) else: if item.idname == idname: @@ -342,7 +341,7 @@ class ToolSelectPanelHelper: if item is not None: if type(item) is tuple: if item[0].idname == idname: - index = cls._tool_group_active.get(item[0].idname, 0) + index = cls._tool_group_active_get_from_item(item) return (item[index], index, item) else: if item.idname == idname: @@ -395,7 +394,7 @@ class ToolSelectPanelHelper: if item is not None: if i == tool_index: if type(item) is tuple: - index = cls._tool_group_active.get(item[0].idname, 0) + index = cls._tool_group_active_get_from_item(item) item = item[index] else: index = -1 @@ -403,6 +402,19 @@ class ToolSelectPanelHelper: i += 1 return None, -1 + @classmethod + def _tool_group_active_get_from_item(cls, item): + index = cls._tool_group_active.get(item[0].idname, 0) + # Can happen in the case a group is dynamic. + # + # NOTE(Campbell): that in this case it's possible the order could change too, + # So if we want to support this properly we will need to switch away from using + # an index and instead use an ID. + # Currently this is such a rare case occurrence that a range check is OK for now. + if index >= len(item): + index = 0 + return index + @classmethod def _tool_group_active_set_by_id(cls, context, idname_group, idname): item_group = cls._tool_get_group_by_id(context, idname_group, coerce=True) @@ -664,7 +676,7 @@ class ToolSelectPanelHelper: # not ideal, write this every time :S cls._tool_group_active[item[0].idname] = index else: - index = cls._tool_group_active.get(item[0].idname, 0) + index = cls._tool_group_active_get_from_item(item) item = item[index] use_menu = True @@ -821,7 +833,8 @@ class ToolSelectPanelHelper: if is_active_tool: index_current = -1 else: - index_current = cls._tool_group_active.get(item_group[0].idname, 0) + index_current = cls._tool_group_active_get_from_item(item_group) + for i, sub_item in enumerate(item_group): is_active = (i == index_current) @@ -871,7 +884,7 @@ class ToolSelectPanelHelper: if is_active_tool: index_current = -1 else: - index_current = cls._tool_group_active.get(item_group[0].idname, 0) + index_current = cls._tool_group_active_get_from_item(item_group) for i, sub_item in enumerate(item_group): is_active = (i == index_current) props = pie.operator( @@ -1023,7 +1036,7 @@ def activate_by_id_or_cycle(context, space_type, idname, *, offset=1, as_fallbac id_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].idname, 0) + index_current = cls._tool_group_active_get_from_item(item_group) for sub_item in item_group: if sub_item.idname == idname: id_current = item_group[index_current].idname -- cgit v1.2.3