Changeset View
Changeset View
Standalone View
Standalone View
release/scripts/startup/bl_ui/space_toolsystem_common.py
| Show First 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | |||||
| class ToolSelectPanelHelper: | class ToolSelectPanelHelper: | ||||
| """ | """ | ||||
| Generic Class, can be used for any toolbar. | Generic Class, can be used for any toolbar. | ||||
| - keymap_prefix: | - keymap_prefix: | ||||
| The text prefix for each key-map for this spaces tools. | The text prefix for each key-map for this spaces tools. | ||||
| - tools_all(): | - tools_all(): | ||||
| Returns (context_mode, tools) tuple pair for all tools defined. | Returns (context_mode, tools) tuple pair for all tools defined. | ||||
| - tools_from_context(context): | - tools_from_context(context, mode=None): | ||||
| Returns tools available in this context. | Returns tools available in this context. | ||||
| Each tool is a 'ToolDef' or None for a separator in the toolbar, use ``None``. | Each tool is a 'ToolDef' or None for a separator in the toolbar, use ``None``. | ||||
| """ | """ | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_class_from_space_type(space_type): | def _tool_class_from_space_type(space_type): | ||||
| return next( | return next( | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | def _tools_flatten_with_tool_index(tools): | ||||
| else: | else: | ||||
| if _item_is_fn(item): | if _item_is_fn(item): | ||||
| for item_dyn in item(context): | for item_dyn in item(context): | ||||
| yield item_dyn, -1 | yield item_dyn, -1 | ||||
| else: | else: | ||||
| yield item, -1 | yield item, -1 | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_get_active(context, with_icon=False): | def _tool_get_active(context, space_type, mode, with_icon=False): | ||||
| """ | """ | ||||
| Return the active Python tool definition and icon name. | Return the active Python tool definition and icon name. | ||||
| """ | """ | ||||
| workspace = context.workspace | workspace = context.workspace | ||||
| cls = ToolSelectPanelHelper._tool_class_from_space_type(workspace.tool_space_type) | cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) | ||||
| if cls is not None: | if cls is not None: | ||||
| tool_def_active, index_active = ToolSelectPanelHelper._tool_vars_from_active_with_index(context) | tool_active_text = getattr( | ||||
| ToolSelectPanelHelper._tool_active_from_context(context, space_type, mode), | |||||
| "name", None) | |||||
| context_mode = context.mode | for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context, mode)): | ||||
| for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context)): | |||||
| if item is not None: | if item is not None: | ||||
| tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) | if item.text == tool_active_text: | ||||
| if (tool_def == tool_def_active): | |||||
| if with_icon: | if with_icon: | ||||
| icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) | icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon) | ||||
| else: | else: | ||||
| icon_value = 0 | icon_value = 0 | ||||
| return (item, icon_value) | return (item, icon_value) | ||||
| return None, 0 | return None, 0 | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_get_by_name(context, space_type, text): | def _tool_get_by_name(context, space_type, text): | ||||
| """ | """ | ||||
| Return the active Python tool definition and index (if in sub-group, else -1). | Return the active Python tool definition and index (if in sub-group, else -1). | ||||
| """ | """ | ||||
| cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) | cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) | ||||
| if cls is not None: | if cls is not None: | ||||
| context_mode = context.mode | |||||
| 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)): | ||||
| if item is not None: | if item is not None: | ||||
| if item.text == text: | if item.text == text: | ||||
| return (item, index) | return (item, index) | ||||
| return None, -1 | return None, -1 | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_vars_from_def(item, context_mode): | def _tool_vars_from_def(item): | ||||
| # For now be strict about whats in this dict | # For now be strict about whats in this dict | ||||
| # prevent accidental adding unknown keys. | # prevent accidental adding unknown keys. | ||||
| text = item.text | text = item.text | ||||
| icon_name = item.icon | icon_name = item.icon | ||||
| mp_idname = item.widget | mp_idname = item.widget | ||||
| datablock_idname = item.data_block | datablock_idname = item.data_block | ||||
| keymap = item.keymap | keymap = item.keymap | ||||
| if keymap is None: | if keymap is None: | ||||
| km_idname = None | km_idname = None | ||||
| else: | else: | ||||
| km_idname = keymap[0].name | km_idname = keymap[0].name | ||||
| return (km_idname, mp_idname, datablock_idname), icon_name | return (km_idname, mp_idname, datablock_idname), icon_name | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_vars_from_active_with_index(context): | def _tool_active_from_context(context, space_type, mode=None, create=False): | ||||
| workspace = context.workspace | if space_type == 'VIEW_3D': | ||||
| return ( | if mode is None: | ||||
| ( | obj = context.active_object | ||||
| workspace.tool_keymap or None, | mode = obj.mode if obj is not None else 'OBJECT' | ||||
| workspace.tool_manipulator_group or None, | tool = context.workspace.tools.from_space_view3d_mode(mode, create) | ||||
| workspace.tool_data_block or None, | if tool is not None: | ||||
| ), | return tool | ||||
| workspace.tool_index, | elif space_type == 'IMAGE_EDITOR': | ||||
| ) | space_data = context.space_data | ||||
| if mode is None: | |||||
| mode = space_data.mode | |||||
| tool = context.workspace.tools.from_space_image_mode(mode, create) | |||||
| if tool is not None: | |||||
| return tool | |||||
| return None | |||||
| @staticmethod | @staticmethod | ||||
| def _tool_text_from_button(context): | def _tool_text_from_button(context): | ||||
| return context.button_operator.name | return context.button_operator.name | ||||
| @classmethod | @classmethod | ||||
| def _km_action_simple(cls, kc, context_mode, text, keymap_fn): | def _km_action_simple(cls, kc, context_mode, text, keymap_fn): | ||||
| if context_mode is None: | if context_mode is None: | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | class ToolSelectPanelHelper: | ||||
| def draw(self, context): | def draw(self, context): | ||||
| # XXX, this UI isn't very nice. | # XXX, this UI isn't very nice. | ||||
| # We might need to create new button types for this. | # We might need to create new button types for this. | ||||
| # Since we probably want: | # Since we probably want: | ||||
| # - tool-tips that include multiple key shortcuts. | # - tool-tips that include multiple key shortcuts. | ||||
| # - ability to click and hold to expose sub-tools. | # - ability to click and hold to expose sub-tools. | ||||
| context_mode = context.mode | space_type = context.space_data.type | ||||
| tool_def_active, index_active = ToolSelectPanelHelper._tool_vars_from_active_with_index(context) | tool_active_text = getattr( | ||||
| ToolSelectPanelHelper._tool_active_from_context(context, space_type), | |||||
| "name", None, | |||||
| ) | |||||
| ui_gen, show_text = self._layout_generator_detect_from_region(self.layout, context.region) | ui_gen, show_text = self._layout_generator_detect_from_region(self.layout, context.region) | ||||
| # Start iteration | # Start iteration | ||||
| ui_gen.send(None) | ui_gen.send(None) | ||||
| for item in self.tools_from_context(context): | for item in self.tools_from_context(context): | ||||
| if item is None: | if item is None: | ||||
| ui_gen.send(True) | ui_gen.send(True) | ||||
| continue | continue | ||||
| if type(item) is tuple: | if type(item) is tuple: | ||||
| is_active = False | is_active = False | ||||
| i = 0 | i = 0 | ||||
| for i, sub_item in enumerate(item): | for i, sub_item in enumerate(item): | ||||
| if sub_item is None: | if sub_item is None: | ||||
| continue | continue | ||||
| tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(sub_item, context_mode) | is_active = (sub_item.text == tool_active_text) | ||||
| is_active = (tool_def == tool_def_active) | |||||
| if is_active: | if is_active: | ||||
| index = i | index = i | ||||
| break | break | ||||
| del i, sub_item | del i, sub_item | ||||
| if is_active: | if is_active: | ||||
| # not ideal, write this every time :S | # not ideal, write this every time :S | ||||
| self._tool_group_active[item[0].text] = index | self._tool_group_active[item[0].text] = index | ||||
| else: | else: | ||||
| index = self._tool_group_active.get(item[0].text, 0) | index = self._tool_group_active.get(item[0].text, 0) | ||||
| item = item[index] | item = item[index] | ||||
| use_menu = True | use_menu = True | ||||
| else: | else: | ||||
| index = -1 | index = -1 | ||||
| use_menu = False | use_menu = False | ||||
| tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) | tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item) | ||||
| is_active = (tool_def == tool_def_active) | is_active = (item.text == tool_active_text) | ||||
| icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) | icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) | ||||
| sub = ui_gen.send(False) | sub = ui_gen.send(False) | ||||
| if use_menu: | if use_menu: | ||||
| sub.operator_menu_hold( | sub.operator_menu_hold( | ||||
| "wm.tool_set_by_name", | "wm.tool_set_by_name", | ||||
| Show All 9 Lines | def draw(self, context): | ||||
| depress=is_active, | depress=is_active, | ||||
| icon_value=icon_value, | icon_value=icon_value, | ||||
| ).name = item.text | ).name = item.text | ||||
| # Signal to finish any remaining layout edits. | # Signal to finish any remaining layout edits. | ||||
| ui_gen.send(None) | ui_gen.send(None) | ||||
| @staticmethod | @staticmethod | ||||
| def draw_active_tool_header(context, layout): | def draw_active_tool_header(context, layout): | ||||
| item, icon_value = ToolSelectPanelHelper._tool_get_active(context, with_icon=True) | # BAD DESIGN WARNING: last used tool | ||||
| workspace = context.workspace | |||||
| space_type = workspace.tools_space_type | |||||
| mode = workspace.tools_mode | |||||
| item, icon_value = ToolSelectPanelHelper._tool_get_active(context, space_type, mode, with_icon=True) | |||||
| if item is None: | if item is None: | ||||
| return | return | ||||
| # Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools. | # Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools. | ||||
| layout.label(" ", icon_value=icon_value) | layout.label(" ", icon_value=icon_value) | ||||
| draw_settings = item.draw_settings | draw_settings = item.draw_settings | ||||
| if draw_settings is not None: | if draw_settings is not None: | ||||
| draw_settings(context, layout) | draw_settings(context, layout) | ||||
| # The purpose of this menu is to be a generic popup to select between tools | # The purpose of this menu is to be a generic popup to select between tools | ||||
| # in cases when a single tool allows to select alternative tools. | # in cases when a single tool allows to select alternative tools. | ||||
| class WM_MT_toolsystem_submenu(Menu): | class WM_MT_toolsystem_submenu(Menu): | ||||
| bl_label = "" | bl_label = "" | ||||
| @staticmethod | @staticmethod | ||||
| def _tool_group_from_button(context): | def _tool_group_from_button(context): | ||||
| context_mode = context.mode | |||||
| # Lookup the tool definitions based on the space-type. | # Lookup the tool definitions based on the space-type. | ||||
| cls = ToolSelectPanelHelper._tool_class_from_space_type(context.space_data.type) | cls = ToolSelectPanelHelper._tool_class_from_space_type(context.space_data.type) | ||||
| if cls is not None: | if cls is not None: | ||||
| button_text = ToolSelectPanelHelper._tool_text_from_button(context) | button_text = ToolSelectPanelHelper._tool_text_from_button(context) | ||||
| for item_group in cls.tools_from_context(context): | for item_group in cls.tools_from_context(context): | ||||
| if type(item_group) is tuple: | if type(item_group) is tuple: | ||||
| for sub_item in item_group: | for sub_item in item_group: | ||||
| if sub_item.text == button_text: | if sub_item.text == button_text: | ||||
| return cls, item_group | return cls, item_group | ||||
| return None, None | return None, None | ||||
| def draw(self, context): | def draw(self, context): | ||||
| context_mode = context.mode | |||||
| layout = self.layout | layout = self.layout | ||||
| layout.scale_y = 2.0 | layout.scale_y = 2.0 | ||||
| cls, item_group = self._tool_group_from_button(context) | cls, item_group = self._tool_group_from_button(context) | ||||
| if item_group is None: | if item_group is None: | ||||
| # Should never happen, just in case | # Should never happen, just in case | ||||
| layout.label("Unable to find toolbar group") | layout.label("Unable to find toolbar group") | ||||
| return | return | ||||
| for item in item_group: | for item in item_group: | ||||
| if item is None: | if item is None: | ||||
| layout.separator() | layout.separator() | ||||
| continue | continue | ||||
| tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) | tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item) | ||||
| icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) | icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name) | ||||
| layout.operator( | layout.operator( | ||||
| "wm.tool_set_by_name", | "wm.tool_set_by_name", | ||||
| text=item.text, | text=item.text, | ||||
| icon_value=icon_value, | icon_value=icon_value, | ||||
| ).name = item.text | ).name = item.text | ||||
| def activate_by_name(context, space_type, text): | def activate_by_name(context, space_type, text): | ||||
| item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text) | item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text) | ||||
| if item is not None: | if item is not None: | ||||
| context_mode = context.mode | tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True) | ||||
| tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode) | tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item) | ||||
| bpy.ops.wm.tool_set( | tool.setup( | ||||
| name=text, | |||||
| keymap=tool_def[0] or "", | keymap=tool_def[0] or "", | ||||
| manipulator_group=tool_def[1] or "", | manipulator_group=tool_def[1] or "", | ||||
| data_block=tool_def[2] or "", | data_block=tool_def[2] or "", | ||||
| index=index, | index=index, | ||||
| ) | ) | ||||
| return True | return True | ||||
| return False | return False | ||||
| Show All 9 Lines | |||||