UI: move tool definitions to classes

Originally it was nice to have a small list of definitions
with tools inline.

However we need to be able to define drawing functions for tools
which Python can't easily inline.

Use function for keymap definition,
support creating a function from a tuple as well
(handy for simple key-maps).
This commit is contained in:
Campbell Barton 2018-04-27 13:23:29 +02:00
parent e01cadd657
commit 9504652687
2 changed files with 435 additions and 362 deletions

@ -24,6 +24,7 @@ from bpy.types import (
__all__ = (
"ToolSelectPanelHelper",
"ToolDef",
)
# Support reloading icons.
@ -37,6 +38,59 @@ if "_icon_cache" in locals():
# (filename -> icon_value) map
_icon_cache = {}
def _keymap_fn_from_seq(keymap_data):
# standalone
def _props_assign_recursive(rna_props, py_props):
for prop_id, value in py_props.items():
if isinstance(value, dict):
_props_assign_recursive(getattr(rna_props, prop_id), value)
else:
setattr(rna_props, prop_id, value)
def keymap_fn(km):
for op_idname, op_props_dict, kmi_kwargs in keymap_fn.keymap_data:
kmi = km.keymap_items.new(op_idname, **kmi_kwargs)
kmi_props = kmi.properties
if op_props_dict:
_props_assign_recursive(kmi.properties, op_props_dict)
keymap_fn.keymap_data = keymap_data
return keymap_fn
class ToolDef:
"""
Tool definition,
This class is never instanced, it's used as definition for tool types.
Since we want to define functions here, it's more convenient to declare class-methods
then functions in a dict or tuple.
"""
__slots__ = ()
def __new__(cls, *args, **kwargs):
raise RuntimeError("%s should not be instantiated" % cls)
def __init_subclass__(cls):
# All classes must have a name
assert(cls.text is not None)
# We must have a key-map or widget (otherwise the tool does nothing!)
assert(cls.keymap is not None or cls.widget is not None)
if type(cls.keymap) is tuple:
cls.keymap = _keymap_fn_from_seq(cls.keymap)
# The name to display in the interface.
text = None
# The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon.
icon = None
# An optional manipulator group to activate when the tool is set or None for no widget.
widget = None
# An optional triple of: ``(operator_id, operator_properties, keymap_item_args)``.
keymap = None
class ToolSelectPanelHelper:
"""
Generic Class, can be used for any toolbar.
@ -48,19 +102,7 @@ class ToolSelectPanelHelper:
- tools_from_context(context):
Returns tools available in this context.
Each tool is a dict:
``(text=tool_name, icon=icon_name, widget=manipulator_group_idname, keymap=keymap_actions)``
For a separator in the toolbar, use ``None``.
Where:
``tool_name``
is the name to display in the interface.
``icon_name``
is the name of the icon to use (found in ``release/datafiles/icons``).
``manipulator_group_idname``
is an optional manipulator group to activate when the tool is set.
``keymap_actions``
an optional triple of: ``(operator_id, operator_properties, keymap_item_args)``
Each tool is a 'ToolDef' or None for a separator in the toolbar, use ``None``.
"""
@staticmethod
@ -88,15 +130,11 @@ class ToolSelectPanelHelper:
else:
return 0
@staticmethod
def _tool_is_group(tool):
return type(tool) is not dict
@staticmethod
def _tools_flatten(tools):
for item in tools:
if item is not None:
if ToolSelectPanelHelper._tool_is_group(item):
if type(item) is tuple:
for sub_item in item:
if sub_item is not None:
yield sub_item
@ -107,12 +145,11 @@ class ToolSelectPanelHelper:
def _tool_vars_from_def(cls, item, context_mode):
# For now be strict about whats in this dict
# prevent accidental adding unknown keys.
assert(len(item) == 4)
text = item["text"]
icon_name = item["icon"]
mp_idname = item["widget"]
actions = item["keymap"]
if actions is None:
text = item.text
icon_name = item.icon
mp_idname = item.widget
keymap_fn = item.keymap
if keymap_fn is None:
km, km_idname = (None, None)
else:
km_test = cls._tool_keymap.get((context_mode, text))
@ -138,15 +175,7 @@ class ToolSelectPanelHelper:
)
@classmethod
def _km_action_simple(cls, kc, context_mode, text, actions):
# standalone
def props_assign_recursive(rna_props, py_props):
for prop_id, value in py_props.items():
if isinstance(value, dict):
props_assign_recursive(getattr(rna_props, prop_id), value)
else:
setattr(rna_props, prop_id, value)
def _km_action_simple(cls, kc, context_mode, text, keymap_fn):
if context_mode is None:
context_mode = "All"
@ -155,11 +184,7 @@ class ToolSelectPanelHelper:
if km is not None:
return km, km_idname
km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW')
for op_idname, op_props_dict, kmi_kwargs in actions:
kmi = km.keymap_items.new(op_idname, **kmi_kwargs)
kmi_props = kmi.properties
if op_props_dict:
props_assign_recursive(kmi.properties, op_props_dict)
keymap_fn(km)
return km, km_idname
@classmethod
@ -189,14 +214,14 @@ class ToolSelectPanelHelper:
for item_parent in tools:
if item_parent is None:
continue
for item in item_parent if (cls._tool_is_group(item_parent)) else (item_parent,):
for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
if item is None:
continue
actions = item["keymap"]
if actions is not None:
text = item["text"]
icon_name = item["icon"]
km, km_idname = cls._km_action_simple(kc, context_mode, text, actions)
keymap_data = item.keymap
if keymap_data is not None:
text = item.text
icon_name = item.icon
km, km_idname = cls._km_action_simple(kc, context_mode, text, keymap_data)
cls._tool_keymap[context_mode, text] = km, km_idname
def draw(self, context):
@ -231,7 +256,7 @@ class ToolSelectPanelHelper:
col.scale_y = scale_y
continue
if self._tool_is_group(item):
if type(item) is tuple:
is_active = False
i = 0
for i, sub_item in enumerate(item):
@ -246,9 +271,9 @@ class ToolSelectPanelHelper:
if is_active:
# not ideal, write this every time :S
self._tool_group_active[item[0]["text"]] = index
self._tool_group_active[item[0].text] = index
else:
index = self._tool_group_active.get(item[0]["text"], 0)
index = self._tool_group_active.get(item[0].text, 0)
item = item[index]
use_menu = True
@ -262,7 +287,7 @@ class ToolSelectPanelHelper:
if use_menu:
props = col.operator_menu_hold(
"wm.tool_set",
text=item["text"] if show_text else "",
text=item.text if show_text else "",
depress=is_active,
menu="WM_MT_toolsystem_submenu",
icon_value=icon_value,
@ -270,7 +295,7 @@ class ToolSelectPanelHelper:
else:
props = col.operator(
"wm.tool_set",
text=item["text"] if show_text else "",
text=item.text if show_text else "",
depress=is_active,
icon_value=icon_value,
)
@ -282,7 +307,6 @@ class ToolSelectPanelHelper:
def tools_from_context(cls, context):
return (cls._tools[None], cls._tools.get(context.mode, ()))
@staticmethod
def _active_tool(context, with_icon=False):
"""
@ -318,7 +342,7 @@ class ToolSelectPanelHelper:
layout.label("No Tool Found")
return
# Indent until we have better icon scaling.
layout.label(" " + item["text"], icon_value=icon_value)
layout.label(" " + item.text, icon_value=icon_value)
# The purpose of this menu is to be a generic popup to select between tools
@ -341,7 +365,7 @@ class WM_MT_toolsystem_submenu(Menu):
for item_items in cls.tools_from_context(context):
for item_group in item_items:
if (item_group is not None) and ToolSelectPanelHelper._tool_is_group(item_group):
if type(item_group) is tuple:
if index_button < len(item_group):
item = item_group[index_button]
tool_def, icon_name = cls._tool_vars_from_def(item, context_mode)
@ -370,7 +394,7 @@ class WM_MT_toolsystem_submenu(Menu):
icon_value = ToolSelectPanelHelper._icon_value_from_icon_handle(icon_name)
props = layout.operator(
"wm.tool_set",
text=item["text"],
text=item.text,
icon_value=icon_value,
)
props.keymap = tool_def[0] or ""

@ -28,6 +28,331 @@ from bpy.types import Panel
from .space_toolsystem_common import (
ToolSelectPanelHelper,
ToolDef,
)
class _defs_view3d_generic:
class cursor(ToolDef):
text = "Cursor"
icon = "ops.generic.cursor"
widget = None
keymap = (
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
)
class ruler(ToolDef):
text = "Ruler/Protractor"
icon = "ops.view3d.ruler"
widget = "VIEW3D_WGT_ruler"
keymap = (
("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
)
class _defs_transform:
class translate(ToolDef):
text = "Translate"
icon = "ops.transform.translate"
widget = "TRANSFORM_WGT_manipulator"
keymap = (
("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
)
class rotate(ToolDef):
text = "Rotate"
icon = "ops.transform.rotate"
widget = "TRANSFORM_WGT_manipulator"
keymap = (
("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
)
class scale(ToolDef):
text = "Scale"
icon = "ops.transform.resize"
widget = "TRANSFORM_WGT_manipulator"
keymap = (
("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
)
class scale_cage(ToolDef):
text = "Scale Cage"
icon = "ops.transform.resize.cage"
widget = "VIEW3D_WGT_xform_cage"
keymap = None
class _defs_view3d_select:
class border(ToolDef):
text = "Select Border"
icon = "ops.generic.select_border"
widget = None
keymap = (
("view3d.select_border",
dict(deselect=False),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_border",
dict(deselect=True),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
)
class circle(ToolDef):
text = "Select Circle"
icon = "ops.generic.select_circle"
widget = None
keymap = (
("view3d.select_circle",
dict(deselect=False),
dict(type='ACTIONMOUSE', value='PRESS')),
("view3d.select_circle",
dict(deselect=True),
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
)
class lasso(ToolDef):
text = "Select Lasso"
icon = "ops.generic.select_lasso"
widget = None
keymap = (
("view3d.select_lasso",
dict(deselect=False),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_lasso",
dict(deselect=True),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
)
# -----------------------------------------------------------------------------
# Object Modes (named based on context.mode)
class _defs_weight_paint:
class gradient_linear(ToolDef):
text = "Linear Gradient"
icon = None
widget = None
keymap = (
("paint.weight_gradient", dict(type='LINEAR'),
dict(type='EVT_TWEAK_A', value='ANY')),
)
class gradient_radial(ToolDef):
text = "Radial Gradient"
icon = None
widget = None
keymap = (
("paint.weight_gradient",
dict(type='RADIAL'),
dict(type='EVT_TWEAK_A', value='ANY')),
)
class _defs_edit_armature:
class roll(ToolDef):
text = "Roll"
icon = None
widget = None
keymap = (
("transform.transform",
dict(release_confirm=True, mode='BONE_ROLL'),
dict(type='EVT_TWEAK_A', value='ANY'),),
)
class extrude_cursor(ToolDef):
text = "Extrude Cursor",
icon = "ops.armature.extrude",
widget = None,
keymap = (
("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
)
class _defs_edit_mesh:
class rip_region(ToolDef):
text = "Rip Region"
icon = "ops.mesh.rip"
widget = None
keymap = (
("mesh.rip_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class rip_edge(ToolDef):
text = "Rip Edge"
icon = "ops.mesh.rip_edge"
widget = None
keymap = (
("mesh.rip_edge_edge_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class poly_build(ToolDef):
text = "Poly Build"
icon = "ops.mesh.polybuild_hover"
widget = None
keymap = (
("mesh.polybuild_face_at_cursor_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS')),
("mesh.polybuild_split_at_cursor_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)),
("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)),
)
class edge_slide(ToolDef):
text = "Edge Slide"
icon = "ops.transform.edge_slide"
widget = None
keymap = (
("transform.edge_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')
),
)
class vert_slide(ToolDef):
text = "Vertex Slide"
icon = "ops.transform.vert_slide"
widget = None
keymap = (
("transform.vert_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class spin(ToolDef):
text = "Spin"
icon = "ops.mesh.spin"
widget = None
keymap = (
("mesh.spin", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class spin_duplicate(ToolDef):
text = "Spin (Duplicate)"
icon = "ops.mesh.spin.duplicate"
widget = None
keymap = (
("mesh.spin", dict(dupli=True),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class inset(ToolDef):
text = "Inset Faces"
icon = "ops.mesh.inset"
widget = None
keymap = (
("mesh.inset", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class extrude(ToolDef):
text = "Extrude Region"
icon = "ops.view3d.edit_mesh_extrude"
widget = None
keymap = (
("view3d.edit_mesh_extrude", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class extrude_individual(ToolDef):
text = "Extrude Individual"
icon = "ops.view3d.edit_mesh_extrude_individual"
widget = None
keymap = (
("mesh.extrude_faces_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class vertex_smooth(ToolDef):
text = "Smooth"
icon = "ops.mesh.vertices_smooth"
widget = None
keymap = (
("mesh.vertices_smooth", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class vertex_randomize(ToolDef):
text = "Randomize"
icon = "ops.transform.vertex_random"
widget = None
keymap = (
("transform.vertex_random", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class shrink_fatten(ToolDef):
text = "Shrink/Fatten"
icon = "ops.transform.shrink_fatten"
widget = None
keymap = (
("transform.shrink_fatten", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class push_pull(ToolDef):
text = "Push/Pull"
icon = "ops.transform.push_pull"
widget = None
keymap = (
("transform.push_pull", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class knife(ToolDef):
text = "Knife"
icon = "ops.mesh.knife_tool"
widget = None
keymap = (
("mesh.knife_tool",
dict(wait_for_input=False, use_occlude_geometry=True, only_selected=False),
dict(type='ACTIONMOUSE', value='PRESS')),
)
class bisect(ToolDef):
text = "Bisect"
icon = "ops.mesh.bisect"
widget = None
keymap = (
("mesh.bisect",
dict(),
dict(type='EVT_TWEAK_A', value='ANY')),
)
class extrude_cursor(ToolDef):
text = "Extrude Cursor"
icon = None
widget = None
keymap = (
("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
)
class _defs_edit_curve:
class draw(ToolDef):
text = "Draw"
icon = None
widget = None
keymap = (
("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
)
class extrude_cursor(ToolDef):
text = "Extrude Cursor"
icon = None
widget = None
keymap = (
("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
)
@ -53,104 +378,25 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
# for reuse
_tools_transform = (
dict(
text="Translate",
icon="ops.transform.translate",
widget="TRANSFORM_WGT_manipulator",
keymap=(
("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
),
),
dict(
text="Rotate",
icon="ops.transform.rotate",
widget="TRANSFORM_WGT_manipulator",
keymap=(
("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
),
),
_defs_transform.translate,
_defs_transform.rotate,
(
dict(
text="Scale",
icon="ops.transform.resize",
widget="TRANSFORM_WGT_manipulator",
keymap=(
("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
),
),
dict(
text="Scale Cage",
icon="ops.transform.resize.cage",
widget="VIEW3D_WGT_xform_cage",
keymap=None,
),
_defs_transform.scale,
_defs_transform.scale_cage,
),
None,
dict(
text="Ruler/Protractor",
icon="ops.view3d.ruler",
widget="VIEW3D_WGT_ruler",
keymap=(
("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
),
),
# DEBUGGING ONLY
# ("Pixel Test", "tool_icon.pixeltest", None, (("wm.splash", dict(), dict(type='ACTIONMOUSE', value='PRESS')),)),
_defs_view3d_generic.ruler,
)
_tools = {
None: [
dict(
text="Cursor",
icon="ops.generic.cursor",
widget=None,
keymap=(
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
),
),
_defs_view3d_generic.cursor,
# 'Select' Group
(
dict(
text="Select Border",
icon="ops.generic.select_border",
widget=None,
keymap=(
("view3d.select_border",
dict(deselect=False),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_border",
dict(deselect=True),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
),
),
dict(
text="Select Circle",
icon="ops.generic.select_circle",
widget=None,
keymap=(
("view3d.select_circle",
dict(deselect=False),
dict(type='ACTIONMOUSE', value='PRESS')),
("view3d.select_circle",
dict(deselect=True),
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
),
),
dict(
text="Select Lasso",
icon="ops.generic.select_lasso",
widget=None,
keymap=(
("view3d.select_lasso",
dict(deselect=False),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_lasso",
dict(deselect=True),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
),
),
_defs_view3d_select.border,
_defs_view3d_select.circle,
_defs_view3d_select.lasso,
),
# End group.
],
@ -163,262 +409,65 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
'PAINT_WEIGHT': [
# TODO, override brush events
(
dict(
text="Linear Gradient",
icon=None,
widget=None,
keymap=(
("paint.weight_gradient", dict(type='LINEAR'),
dict(type='EVT_TWEAK_A', value='ANY')),
),
),
dict(
text="Radial Gradient",
icon=None,
widget=None,
keymap=(
("paint.weight_gradient",
dict(type='RADIAL'),
dict(type='EVT_TWEAK_A', value='ANY')),
),
),
_defs_weight_paint.gradient_linear,
_defs_weight_paint.gradient_radial,
),
],
'EDIT_ARMATURE': [
*_tools_transform,
dict(
text="Roll",
icon=None,
widget=None,
keymap=(
("transform.transform",
dict(release_confirm=True, mode='BONE_ROLL'),
dict(type='EVT_TWEAK_A', value='ANY'),),
),
),
_defs_edit_armature.roll,
None,
dict(
text="Extrude Cursor",
icon="ops.armature.extrude",
widget=None,
keymap=(
("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_armature.extrude_cursor,
],
'EDIT_MESH': [
*_tools_transform,
None,
(
dict(
text="Rip Region",
icon="ops.mesh.rip",
widget=None,
keymap=(
("mesh.rip_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
_defs_edit_mesh.rip_region,
_defs_edit_mesh.rip_edge,
),
),
dict(
text="Rip Edge",
icon="ops.mesh.rip_edge",
widget=None,
keymap=(
("mesh.rip_edge_edge_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
),
dict(
text="Poly Build",
icon="ops.mesh.polybuild_hover",
widget=None,
keymap=(
("mesh.polybuild_face_at_cursor_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS')),
("mesh.polybuild_split_at_cursor_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)),
("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)),
),
),
_defs_edit_mesh.poly_build,
# 'Slide' Group
(
dict(
text="Edge Slide",
icon="ops.transform.edge_slide",
widget=None,
keymap=(
("transform.edge_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Vertex Slide",
icon="ops.transform.vert_slide",
widget=None,
keymap=(
("transform.vert_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_mesh.edge_slide,
_defs_edit_mesh.vert_slide,
),
# End group.
(
dict(
text="Spin",
icon="ops.mesh.spin",
widget=None,
keymap=(
("mesh.spin", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Spin (Duplicate)",
icon="ops.mesh.spin.duplicate",
widget=None,
keymap=(
("mesh.spin", dict(dupli=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_mesh.spin,
_defs_edit_mesh.spin_duplicate,
),
_defs_edit_mesh.inset,
dict(
text="Inset Faces",
icon="ops.mesh.inset",
widget=None,
keymap=(
("mesh.inset", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
(
_defs_edit_mesh.extrude,
_defs_edit_mesh.extrude_individual,
),
(
dict(
text="Extrude Region",
icon="ops.view3d.edit_mesh_extrude",
widget=None,
keymap=(
("view3d.edit_mesh_extrude", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Extrude Individual",
icon="ops.view3d.edit_mesh_extrude_individual",
widget=None,
keymap=(
("mesh.extrude_faces_move", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_mesh.vertex_smooth,
_defs_edit_mesh.vertex_randomize,
),
(
dict(
text="Randomize",
icon="ops.transform.vertex_random",
widget=None,
keymap=(
("transform.vertex_random", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Smooth",
icon="ops.mesh.vertices_smooth",
widget=None,
keymap=(
("mesh.vertices_smooth", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_mesh.shrink_fatten,
_defs_edit_mesh.push_pull,
),
(
dict(
text="Shrink/Fatten",
icon="ops.transform.shrink_fatten",
widget=None,
keymap=(
("transform.shrink_fatten", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Push/Pull",
icon="ops.transform.push_pull",
widget=None,
keymap=(
("transform.push_pull", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
),
# Knife Group
(
dict(
text="Knife",
icon="ops.mesh.knife_tool",
widget=None,
keymap=(
("mesh.knife_tool",
dict(wait_for_input=False, use_occlude_geometry=True, only_selected=False),
dict(type='ACTIONMOUSE', value='PRESS')),
),
),
None,
dict(
text="Bisect",
icon="ops.mesh.bisect",
widget=None,
keymap=(
("mesh.bisect",
dict(),
dict(type='EVT_TWEAK_A', value='ANY')),
),
),
),
# End group.
dict(
text="Extrude Cursor",
icon=None,
widget=None,
keymap=(
("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
_defs_edit_mesh.knife,
_defs_edit_mesh.bisect,
),
_defs_edit_mesh.extrude_cursor,
],
'EDIT_CURVE': [
*_tools_transform,
None,
dict(
text="Draw",
icon=None,
widget=None,
keymap=(
("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
),
),
dict(
text="Extrude Cursor",
icon=None,
widget=None,
keymap=(
("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
),
_defs_edit_curve.draw,
_defs_edit_curve.extrude_cursor,
],
}