Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-05-16 19:41:11 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-05-17 16:57:33 +0300
commitedf6676a77b30290918e60547544bc1a6f7a8838 (patch)
tree26012f315c75686553e6be87b73ad270b98eb01a /release/scripts
parent20cc14e2b7551bb043472174b8be79d8aaa4df3d (diff)
Tool System: per space/mode tool support
This patch adds support for: - Per space-type tools (3D view and edit). - Per mode tools (object, edit, weight-paint .. etc). The top-bar shows the last activated tools options, this is a design issue with using a global topbar to show per-space settings. See D3395
Diffstat (limited to 'release/scripts')
-rw-r--r--release/scripts/startup/bl_operators/wm.py13
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py78
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py109
3 files changed, 163 insertions, 37 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index a9d766b29e2..970eff34026 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -2335,10 +2335,21 @@ 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',
+ )
def execute(self, context):
from bl_ui.space_toolsystem_common import activate_by_name
- if activate_by_name(context, context.space_data.type, self.name):
+ space_type = self.space_type
+ if space_type == 'EMPTY':
+ space_type = context.space_data.type
+ if activate_by_name(context, space_type, self.name):
return {'FINISHED'}
else:
self.report({'WARNING'}, f"Tool {self.name!r} not found.")
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index b58bff7cf32..ad5c970a6d5 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -140,7 +140,7 @@ class ToolSelectPanelHelper:
The text prefix for each key-map for this spaces tools.
- tools_all():
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.
Each tool is a 'ToolDef' or None for a separator in the toolbar, use ``None``.
@@ -230,23 +230,23 @@ class ToolSelectPanelHelper:
yield item, -1
@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.
"""
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:
- 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)):
+ for item in ToolSelectPanelHelper._tools_flatten(cls.tools_from_context(context, mode)):
if item is not None:
- tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode)
- if (tool_def == tool_def_active):
+ if item.text == tool_active_text:
if with_icon:
- icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name)
+ icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(item.icon)
else:
icon_value = 0
return (item, icon_value)
@@ -259,7 +259,6 @@ class ToolSelectPanelHelper:
"""
cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
if cls is not None:
- context_mode = context.mode
for item, index in ToolSelectPanelHelper._tools_flatten_with_tool_index(cls.tools_from_context(context)):
if item is not None:
if item.text == text:
@@ -267,7 +266,7 @@ class ToolSelectPanelHelper:
return None, -1
@staticmethod
- def _tool_vars_from_def(item, context_mode):
+ def _tool_vars_from_def(item):
# For now be strict about whats in this dict
# prevent accidental adding unknown keys.
text = item.text
@@ -282,16 +281,22 @@ class ToolSelectPanelHelper:
return (km_idname, mp_idname, datablock_idname), icon_name
@staticmethod
- def _tool_vars_from_active_with_index(context):
- workspace = context.workspace
- return (
- (
- workspace.tool_keymap or None,
- workspace.tool_manipulator_group or None,
- workspace.tool_data_block or None,
- ),
- workspace.tool_index,
- )
+ def _tool_active_from_context(context, space_type, mode=None, create=False):
+ if space_type == 'VIEW_3D':
+ if mode is None:
+ obj = context.active_object
+ mode = obj.mode if obj is not None else 'OBJECT'
+ tool = context.workspace.tools.from_space_view3d_mode(mode, create)
+ if tool is not None:
+ return tool
+ 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
def _tool_text_from_button(context):
@@ -445,8 +450,11 @@ class ToolSelectPanelHelper:
# - tool-tips that include multiple key shortcuts.
# - ability to click and hold to expose sub-tools.
- context_mode = context.mode
- tool_def_active, index_active = ToolSelectPanelHelper._tool_vars_from_active_with_index(context)
+ space_type = context.space_data.type
+ 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)
@@ -464,8 +472,7 @@ class ToolSelectPanelHelper:
for i, sub_item in enumerate(item):
if sub_item is None:
continue
- tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(sub_item, context_mode)
- is_active = (tool_def == tool_def_active)
+ is_active = (sub_item.text == tool_active_text)
if is_active:
index = i
break
@@ -483,8 +490,8 @@ class ToolSelectPanelHelper:
index = -1
use_menu = False
- tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode)
- is_active = (tool_def == tool_def_active)
+ tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item)
+ is_active = (item.text == tool_active_text)
icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name)
@@ -510,7 +517,11 @@ class ToolSelectPanelHelper:
@staticmethod
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:
return
# Note: we could show 'item.text' here but it makes the layout jitter when switcuing tools.
@@ -527,7 +538,6 @@ class WM_MT_toolsystem_submenu(Menu):
@staticmethod
def _tool_group_from_button(context):
- context_mode = context.mode
# Lookup the tool definitions based on the space-type.
cls = ToolSelectPanelHelper._tool_class_from_space_type(context.space_data.type)
if cls is not None:
@@ -540,7 +550,6 @@ class WM_MT_toolsystem_submenu(Menu):
return None, None
def draw(self, context):
- context_mode = context.mode
layout = self.layout
layout.scale_y = 2.0
@@ -554,7 +563,7 @@ class WM_MT_toolsystem_submenu(Menu):
if item is None:
layout.separator()
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)
layout.operator(
"wm.tool_set_by_name",
@@ -566,9 +575,10 @@ class WM_MT_toolsystem_submenu(Menu):
def activate_by_name(context, space_type, text):
item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
if item is not None:
- context_mode = context.mode
- tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item, context_mode)
- bpy.ops.wm.tool_set(
+ tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True)
+ tool_def, icon_name = ToolSelectPanelHelper._tool_vars_from_def(item)
+ tool.setup(
+ name=text,
keymap=tool_def[0] or "",
manipulator_group=tool_def[1] or "",
data_block=tool_def[2] or "",
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index a0360c0900b..4a368bd712d 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -777,6 +777,108 @@ class _defs_weight_paint:
)
+class _defs_uv_select:
+
+ @ToolDef.from_fn
+ def border():
+ return dict(
+ text="Select Border",
+ icon="ops.generic.select_border",
+ widget=None,
+ keymap=(
+ ("uv.select_border",
+ dict(deselect=False),
+ dict(type='EVT_TWEAK_A', value='ANY')),
+ # ("uv.select_border",
+ # dict(deselect=True),
+ # dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
+ ),
+ )
+
+ @ToolDef.from_fn
+ def circle():
+ return dict(
+ text="Select Circle",
+ icon="ops.generic.select_circle",
+ widget=None,
+ keymap=(
+ ("uv.select_circle",
+ dict(), # dict(deselect=False),
+ dict(type='ACTIONMOUSE', value='PRESS')),
+ # ("uv.select_circle",
+ # dict(deselect=True),
+ # dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
+ ),
+ )
+
+ @ToolDef.from_fn
+ def lasso():
+ return dict(
+ text="Select Lasso",
+ icon="ops.generic.select_lasso",
+ widget=None,
+ keymap=(
+ ("uv.select_lasso",
+ dict(deselect=False),
+ dict(type='EVT_TWEAK_A', value='ANY')),
+ # ("uv.select_lasso",
+ # dict(deselect=True),
+ # dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
+ ),
+ )
+
+
+class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
+ bl_label = "Tools" # not visible
+ bl_options = {'HIDE_HEADER'}
+
+ # Satisfy the 'ToolSelectPanelHelper' API.
+ keymap_prefix = "Image Editor Tool: "
+
+ @classmethod
+ def tools_from_context(cls, context, mode=None):
+ if mode is None:
+ mode = context.space_data.mode
+ for tools in (cls._tools[None], cls._tools.get(mode, ())):
+ for item in tools:
+ if not (type(item) is ToolDef) and callable(item):
+ yield from item(context)
+ else:
+ yield item
+
+ @classmethod
+ def tools_all(cls):
+ yield from cls._tools.items()
+
+ # for reuse
+ _tools_select = (
+ (
+ _defs_uv_select.border,
+ _defs_uv_select.circle,
+ _defs_uv_select.lasso,
+ ),
+ )
+
+ _tools = {
+ None: [
+ # for all modes
+ ],
+ 'VIEW': [
+ *_tools_select,
+
+ ],
+ 'MASK': [
+ None,
+ ],
+ 'PAINT': [
+ _defs_texture_paint.generate_from_brushes,
+ ],
+ }
+
+
class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
@@ -788,8 +890,10 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
keymap_prefix = "3D View Tool: "
@classmethod
- def tools_from_context(cls, context):
- for tools in (cls._tools[None], cls._tools.get(context.mode, ())):
+ def tools_from_context(cls, context, mode=None):
+ if mode is None:
+ mode = context.mode
+ for tools in (cls._tools[None], cls._tools.get(mode, ())):
for item in tools:
if not (type(item) is ToolDef) and callable(item):
yield from item(context)
@@ -934,6 +1038,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
classes = (
+ IMAGE_PT_tools_active,
VIEW3D_PT_tools_active,
)