Files
blender/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py

1849 lines
57 KiB
Python
Raw Normal View History

# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# For now group all tools together
# we may want to move these into per space-type files.
#
# For now keep this in a single file since it's an area that may change,
# so avoid making changes all over the place.
import bpy
from bpy.types import Panel
from .space_toolsystem_common import (
ToolSelectPanelHelper,
ToolDef,
)
2018-05-07 21:38:43 +02:00
def generate_from_brushes_ex(
context, *,
icon_prefix,
brush_test_attr,
brush_category_attr,
brush_category_layout,
):
# Categories
brush_categories = {}
if context.mode != 'GPENCIL_PAINT':
for brush in context.blend_data.brushes:
if getattr(brush, brush_test_attr) and brush.gpencil_settings is None:
category = getattr(brush, brush_category_attr)
name = brush.name
brush_categories.setdefault(category, []).append(
ToolDef.from_dict(
dict(
text=name,
icon=icon_prefix + category.lower(),
data_block=name,
)
)
)
else:
def draw_settings(context, layout, tool):
_defs_gpencil_paint.draw_settings_common(context, layout, tool)
for brush_type in brush_category_layout:
for brush in context.blend_data.brushes:
if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]:
category = brush_type[0]
name = brush.name
text = name
# XXX, disabled since changing the brush needs to sync back to the tool.
"""
# rename default brushes for tool bar
if name.startswith("Draw "):
text = name.replace("Draw ", "")
elif name.startswith("Eraser "):
text = name.replace("Eraser ", "")
elif name.startswith("Fill "):
text = name.replace(" Area", "")
else:
text = name
"""
# Define icon.
icon_name = {
'PENCIL': 'draw_pencil',
'PEN': 'draw_pen',
'INK': 'draw_ink',
'INKNOISE': 'draw_noise',
'BLOCK': 'draw_block',
'MARKER': 'draw_marker',
'FILL': 'draw_fill',
'SOFT': 'draw.eraser_soft',
'HARD': 'draw.eraser_hard',
'STROKE': 'draw.eraser_stroke',
}[category]
brush_categories.setdefault(category, []).append(
ToolDef.from_dict(
dict(
text=text,
icon=icon_prefix + icon_name,
data_block=name,
widget=None,
operator="gpencil.draw",
draw_settings=draw_settings,
)
)
)
def tools_from_brush_group(groups):
assert(type(groups) is tuple)
if len(groups) == 1:
tool_defs = tuple(brush_categories.pop(groups[0], ()))
else:
tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ()))
if len(tool_defs) > 1:
return (tool_defs,)
else:
return tool_defs
# Each item below is a single toolbar entry:
# Grouped for multiple or none if no brushes are found.
tool_defs = tuple(
tool_def
for category in brush_category_layout
for tool_def in tools_from_brush_group(category)
)
# Ensure we use all types.
2018-04-30 21:57:51 +02:00
if brush_categories:
print(brush_categories)
assert(len(brush_categories) == 0)
return tool_defs
def generate_from_enum_ex(
context, *,
icon_prefix,
data,
attr,
):
tool_defs = []
for enum in data.rna_type.properties[attr].enum_items_static:
name = enum.name
identifier = enum.identifier
tool_defs.append(
ToolDef.from_dict(
dict(
text=name,
icon=icon_prefix + identifier.lower(),
data_block=identifier,
)
)
)
return tuple(tool_defs)
class _defs_view3d_generic:
@ToolDef.from_fn
def cursor():
def draw_settings(context, layout, tool):
props = tool.operator_properties("view3d.cursor3d")
layout.prop(props, "use_depth")
layout.prop(props, "orientation")
return dict(
2018-05-07 21:38:43 +02:00
text="Cursor",
description=(
"Set the 3D cursor location, drag to transform"
),
2018-05-07 21:38:43 +02:00
icon="ops.generic.cursor",
keymap=(
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
("transform.translate",
dict(release_confirm=True, cursor_transform=True),
dict(type='EVT_TWEAK_A', value='ANY'),
2018-06-05 16:35:20 +02:00
),
2018-05-07 21:38:43 +02:00
),
draw_settings=draw_settings,
2018-05-07 21:38:43 +02:00
)
@ToolDef.from_fn
def cursor_click():
return dict(
text="None",
icon="ops.generic.cursor",
keymap=(
# This is a dummy keymap entry, until particle system is properly working with toolsystem.
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK', ctrl=True, alt=True, shift=True)),
),
)
@ToolDef.from_fn
def ruler():
return dict(
2018-08-23 16:50:43 +10:00
text="Measure",
description=(
"Measure distance and angles.\n"
"\u2022 Drag anywhere for new measurement.\n"
"\u2022 Drag ruler segment to measure an angle.\n"
"\u2022 Drag ruler outside the view to remove.\n"
"\u2022 Ctrl to snap.\n"
"\u2022 Shift to measure surface thickness"
),
2018-05-07 21:38:43 +02:00
icon="ops.view3d.ruler",
widget="VIEW3D_GGT_ruler",
2018-05-07 21:38:43 +02:00
keymap=(
("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
),
)
2018-08-28 21:00:25 +10:00
def _defs_annotate_factory():
class _defs_annotate:
@staticmethod
def draw_settings_common(context, layout, tool):
ts = context.tool_settings
space_type = tool.space_type
if space_type == 'VIEW_3D':
layout.separator()
row = layout.row(align=True)
row.prop(ts, "annotation_stroke_placement_view3d", text="Placement")
if ts.gpencil_stroke_placement_view3d == 'CURSOR':
row.prop(ts.gpencil_sculpt, "lockaxis")
elif ts.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}:
row.prop(ts, "use_gpencil_stroke_endpoints")
@ToolDef.from_fn
def scribble():
def draw_settings(context, layout, tool):
_defs_annotate.draw_settings_common(context, layout, tool)
return dict(
text="Annotate",
icon="ops.gpencil.draw",
cursor='PAINT_BRUSH',
keymap=(
("gpencil.annotate",
dict(mode='DRAW', wait_for_input=False),
2018-09-07 21:16:03 +10:00
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def line():
def draw_settings(context, layout, tool):
_defs_annotate.draw_settings_common(context, layout, tool)
return dict(
text="Annotate Line",
icon="ops.gpencil.draw.line",
cursor='CROSSHAIR',
keymap=(
("gpencil.annotate",
dict(mode='DRAW_STRAIGHT', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def poly():
def draw_settings(context, layout, tool):
_defs_annotate.draw_settings_common(context, layout, tool)
return dict(
text="Annotate Polygon",
icon="ops.gpencil.draw.poly",
cursor='CROSSHAIR',
keymap=(
("gpencil.annotate",
dict(mode='DRAW_POLY', wait_for_input=False),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def eraser():
def draw_settings(context, layout, tool):
# TODO: Move this setting to toolsettings
user_prefs = context.user_preferences
layout.prop(user_prefs.edit, "grease_pencil_eraser_radius", text="Radius")
return dict(
text="Annotate Eraser",
icon="ops.gpencil.draw.eraser",
cursor='CROSSHAIR', # XXX: Always show brush circle when enabled
keymap=(
("gpencil.annotate",
dict(mode='ERASER', wait_for_input=False),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
return _defs_annotate
2018-08-28 21:00:25 +10:00
# Needed so annotation gets a keymap per space type.
_defs_annotate_image = _defs_annotate_factory()
_defs_annotate_view3d = _defs_annotate_factory()
class _defs_transform:
@ToolDef.from_fn
def translate():
def draw_settings(context, layout, tool):
tool_settings = context.tool_settings
layout.prop(tool_settings, "use_gizmo_apron")
return dict(
text="Move",
# cursor='SCROLL_XY',
2018-05-07 21:38:43 +02:00
icon="ops.transform.translate",
widget="TRANSFORM_GGT_gizmo",
operator="transform.translate",
# TODO, implement as optional fallback gizmo
# keymap=(
# ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
# ),
draw_settings=draw_settings,
2018-05-07 21:38:43 +02:00
)
@ToolDef.from_fn
def rotate():
def draw_settings(context, layout, tool):
tool_settings = context.tool_settings
layout.prop(tool_settings, "use_gizmo_apron")
return dict(
text="Rotate",
# cursor='SCROLL_XY',
icon="ops.transform.rotate",
widget="TRANSFORM_GGT_gizmo",
operator="transform.rotate",
# TODO, implement as optional fallback gizmo
# keymap=(
# ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
# ),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def scale():
def draw_settings(context, layout, tool):
tool_settings = context.tool_settings
layout.prop(tool_settings, "use_gizmo_apron")
return dict(
text="Scale",
# cursor='SCROLL_XY',
icon="ops.transform.resize",
widget="TRANSFORM_GGT_gizmo",
operator="transform.resize",
# TODO, implement as optional fallback gizmo
# keymap=(
# ("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')),
# ),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def scale_cage():
return dict(
text="Scale Cage",
icon="ops.transform.resize.cage",
widget="VIEW3D_GGT_xform_cage",
operator="transform.resize",
)
@ToolDef.from_fn
def transform():
def draw_settings(context, layout, tool):
tool_settings = context.tool_settings
layout.prop(tool_settings, "use_gizmo_apron")
2018-07-29 11:54:12 +10:00
layout.prop(tool_settings, "use_gizmo_mode")
return dict(
text="Transform",
description=(
"Supports any combination of grab, rotate & scale at once"
),
icon="ops.transform.transform",
widget="TRANSFORM_GGT_gizmo",
# No keymap default action, only for gizmo!
draw_settings=draw_settings,
2018-05-07 21:38:43 +02:00
)
class _defs_view3d_select:
@ToolDef.from_fn
def border():
def draw_settings(context, layout, tool):
props = tool.operator_properties("view3d.select_border")
layout.prop(props, "mode", expand=True)
return dict(
text="Select Border",
icon="ops.generic.select_border",
widget=None,
keymap=(
("view3d.select_border",
dict(mode='ADD'),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_border",
dict(mode='SUB'),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle():
def draw_settings(context, layout, tool):
props = tool.operator_properties("view3d.select_circle")
layout.prop(props, "radius")
return 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)),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def lasso():
def draw_settings(context, layout, tool):
props = tool.operator_properties("view3d.select_lasso")
layout.prop(props, "mode", expand=True)
return dict(
text="Select Lasso",
icon="ops.generic.select_lasso",
widget=None,
keymap=(
("view3d.select_lasso",
dict(mode='ADD'),
dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_lasso",
dict(mode='SUB'),
dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
),
draw_settings=draw_settings,
)
# -----------------------------------------------------------------------------
# Object Modes (named based on context.mode)
2018-05-07 21:38:43 +02:00
class _defs_edit_armature:
@ToolDef.from_fn
def roll():
return dict(
text="Roll",
icon="ops.armature.bone.roll",
widget=None,
keymap=(
("transform.transform",
dict(release_confirm=True, mode='BONE_ROLL'),
dict(type='EVT_TWEAK_A', value='ANY'),),
),
)
@ToolDef.from_fn
def bone_envelope():
return dict(
text="Bone Envelope",
icon="ops.transform.bone_envelope",
widget=None,
keymap=(
("transform.transform",
dict(release_confirm=True, mode='BONE_ENVELOPE'),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def bone_size():
return dict(
text="Bone Size",
icon="ops.transform.bone_size",
widget=None,
keymap=(
("transform.transform",
dict(release_confirm=True, mode='BONE_SIZE'),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def extrude():
return dict(
text="Extrude",
icon="ops.armature.extrude_move",
widget=None,
keymap=(
("armature.extrude_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def extrude_cursor():
return dict(
text="Extrude to Cursor",
icon="ops.armature.extrude_cursor",
widget=None,
keymap=(
("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
2018-05-07 21:38:43 +02:00
class _defs_edit_mesh:
@ToolDef.from_fn
def cube_add():
return dict(
text="Add Cube",
2018-08-29 18:40:32 +10:00
icon="ops.mesh.primitive_cube_add_gizmo",
widget=None,
keymap=(
("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')),
("mesh.primitive_cube_add_gizmo", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def rip_region():
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.rip_move")
2018-05-11 20:22:04 +02:00
props_macro = props.MESH_OT_rip
layout.prop(props_macro, "use_fill")
return dict(
text="Rip Region",
icon="ops.mesh.rip",
widget=None,
keymap=(
2018-05-11 20:22:04 +02:00
("mesh.rip_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS')),
),
2018-05-11 20:22:04 +02:00
draw_settings=draw_settings,
)
@ToolDef.from_fn
def rip_edge():
return dict(
text="Rip Edge",
icon="ops.mesh.rip_edge",
widget=None,
keymap=(
2018-09-05 08:45:46 +10:00
("mesh.rip_edge_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def poly_build():
return dict(
text="Poly Build",
icon="ops.mesh.polybuild_hover",
widget="VIEW3D_GGT_mesh_preselect_elem",
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)),
),
)
@ToolDef.from_fn
def edge_slide():
def draw_settings(context, layout, tool):
props = tool.operator_properties("transform.edge_slide")
layout.prop(props, "correct_uv")
return dict(
text="Edge Slide",
icon="ops.transform.edge_slide",
widget=None,
keymap=(
("transform.edge_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')
2018-05-07 21:38:43 +02:00
),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def vert_slide():
def draw_settings(context, layout, tool):
props = tool.operator_properties("transform.vert_slide")
layout.prop(props, "correct_uv")
return dict(
text="Vertex Slide",
icon="ops.transform.vert_slide",
widget=None,
keymap=(
("transform.vert_slide", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def spin():
return dict(
text="Spin",
icon="ops.mesh.spin",
widget=None,
keymap=(
("mesh.spin", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def spin_duplicate():
return dict(
text="Spin (Duplicate)",
icon="ops.mesh.spin.duplicate",
widget=None,
keymap=(
("mesh.spin", dict(dupli=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def inset():
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.inset")
layout.prop(props, "use_outset")
layout.prop(props, "use_individual")
layout.prop(props, "use_even_offset")
layout.prop(props, "use_relative_offset")
return dict(
text="Inset Faces",
icon="ops.mesh.inset",
widget=None,
keymap=(
("mesh.inset", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def bevel():
2018-08-22 17:37:07 +10:00
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.bevel")
layout.prop(props, "offset_type")
layout.prop(props, "segments")
layout.prop(props, "profile", slider=True)
layout.prop(props, "vertex_only")
return dict(
text="Bevel",
icon="ops.mesh.bevel",
widget=None,
keymap=(
("mesh.bevel", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
2018-08-22 17:37:07 +10:00
draw_settings=draw_settings,
)
@ToolDef.from_fn
def extrude():
return dict(
text="Extrude Region",
icon="ops.mesh.extrude_region_move",
widget="MESH_GGT_extrude",
operator="view3d.edit_mesh_extrude_move_normal",
keymap=(
("mesh.extrude_context_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def extrude_normals():
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.extrude_region_shrink_fatten")
props_macro = props.TRANSFORM_OT_shrink_fatten
layout.prop(props_macro, "use_even_offset")
return dict(
text="Extrude Along Normals",
icon="ops.mesh.extrude_region_shrink_fatten",
widget=None,
keymap=(
("mesh.extrude_region_shrink_fatten",
dict(TRANSFORM_OT_shrink_fatten=dict(release_confirm=True)),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def extrude_individual():
return dict(
text="Extrude Individual",
icon="ops.mesh.extrude_faces_move",
widget=None,
keymap=(
("mesh.extrude_faces_move", dict(TRANSFORM_OT_shrink_fatten=dict(release_confirm=True)),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def extrude_cursor():
return dict(
text="Extrude to Cursor",
icon="ops.mesh.dupli_extrude_cursor",
widget=None,
keymap=(
("mesh.dupli_extrude_cursor", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def loopcut_slide():
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.loopcut_slide")
props_macro = props.MESH_OT_loopcut
layout.prop(props_macro, "number_cuts")
props_macro = props.TRANSFORM_OT_edge_slide
layout.prop(props_macro, "correct_uv")
return dict(
text="Loop Cut",
icon="ops.mesh.loopcut_slide",
widget="VIEW3D_GGT_mesh_preselect_edgering",
keymap=(
("mesh.loopcut_slide",
dict(TRANSFORM_OT_edge_slide=dict(release_confirm=True)),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def offset_edge_loops_slide():
return dict(
text="Offset Edge Loop Cut",
icon="ops.mesh.offset_edge_loops_slide",
widget=None,
keymap=(
("mesh.offset_edge_loops_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def vertex_smooth():
return dict(
text="Smooth",
icon="ops.mesh.vertices_smooth",
widget=None,
keymap=(
("mesh.vertices_smooth", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def vertex_randomize():
return dict(
text="Randomize",
icon="ops.transform.vertex_random",
widget=None,
keymap=(
("transform.vertex_random", dict(),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def shear():
return dict(
text="Shear",
icon="ops.transform.shear",
widget=None,
keymap=(
("transform.shear", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def tosphere():
return dict(
text="To Sphere",
icon="ops.transform.tosphere",
widget=None,
keymap=(
("transform.tosphere", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def shrink_fatten():
def draw_settings(context, layout, tool):
props = tool.operator_properties("transform.shrink_fatten")
layout.prop(props, "use_even_offset")
return dict(
text="Shrink/Fatten",
icon="ops.transform.shrink_fatten",
widget=None,
keymap=(
("transform.shrink_fatten", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def push_pull():
return dict(
text="Push/Pull",
icon="ops.transform.push_pull",
widget=None,
keymap=(
("transform.push_pull", dict(release_confirm=True),
dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def knife():
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.knife_tool")
layout.prop(props, "use_occlude_geometry")
layout.prop(props, "only_selected")
return dict(
text="Knife",
icon="ops.mesh.knife_tool",
widget=None,
keymap=(
("mesh.knife_tool",
dict(wait_for_input=False),
dict(type='ACTIONMOUSE', value='PRESS')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def bisect():
2018-09-12 06:24:15 +10:00
def draw_settings(context, layout, tool):
props = tool.operator_properties("mesh.bisect")
layout.prop(props, "use_fill")
layout.prop(props, "clear_inner")
layout.prop(props, "clear_outer")
layout.prop(props, "threshold")
return dict(
text="Bisect",
icon="ops.mesh.bisect",
widget=None,
keymap=(
("mesh.bisect",
dict(),
dict(type='EVT_TWEAK_A', value='ANY')),
),
2018-09-12 06:24:15 +10:00
draw_settings=draw_settings,
)
2018-05-07 21:38:43 +02:00
class _defs_edit_curve:
@ToolDef.from_fn
def draw():
def draw_settings(context, layout, tool):
2018-05-11 20:25:01 +02:00
# Tool settings initialize operator options.
tool_settings = context.tool_settings
cps = tool_settings.curve_paint_settings
col = layout.row()
col.prop(cps, "curve_type")
if cps.curve_type == 'BEZIER':
col.prop(cps, "error_threshold")
col.prop(cps, "fit_method")
col.prop(cps, "use_corners_detect")
col = layout.row()
col.active = cps.use_corners_detect
col.prop(cps, "corner_angle")
return dict(
text="Draw",
cursor='PAINT_BRUSH',
icon=None,
widget=None,
keymap=(
("curve.draw", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),
),
2018-05-11 20:25:01 +02:00
draw_settings=draw_settings,
)
2018-08-29 15:14:41 +10:00
@ToolDef.from_fn
def extrude():
return dict(
text="Extrude",
icon=None,
widget=None,
keymap=(
("curve.extrude_move",
dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def extrude_cursor():
return dict(
text="Extrude Cursor",
icon=None,
widget=None,
keymap=(
("curve.vertex_add", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
2018-05-07 21:38:43 +02:00
class _defs_pose:
@ToolDef.from_fn
def breakdown():
return dict(
text="Breakdowner",
icon="ops.pose.breakdowner",
widget=None,
keymap=(
("pose.breakdown", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def push():
return dict(
text="Push",
icon="ops.pose.push",
widget=None,
keymap=(
("pose.push", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def relax():
return dict(
text="Relax",
icon="ops.pose.relax",
widget=None,
keymap=(
("pose.relax", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
class _defs_particle:
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
icon_prefix="brush.particle.",
data=context.tool_settings.particle_edit,
attr="tool",
)
class _defs_sculpt:
@staticmethod
def generate_from_brushes(context):
return generate_from_brushes_ex(
context,
icon_prefix="brush.sculpt.",
brush_test_attr="use_paint_sculpt",
brush_category_attr="sculpt_tool",
brush_category_layout=(
('DRAW',),
('GRAB', 'THUMB'),
('SNAKE_HOOK',),
('BLOB', 'INFLATE'),
2018-05-07 21:38:43 +02:00
('SMOOTH', 'SCRAPE', 'FLATTEN'),
('CREASE', 'PINCH'),
('CLAY', 'CLAY_STRIPS'),
('LAYER',),
('NUDGE', 'ROTATE'),
('FILL',),
('SIMPLIFY',),
('MASK',),
)
)
@ToolDef.from_fn
def hide_border():
return dict(
text="Border Hide",
icon="ops.sculpt.border_hide",
widget=None,
keymap=(
("paint.hide_show", dict(action='HIDE'), dict(type='EVT_TWEAK_A', value='ANY')),
("paint.hide_show", dict(action='SHOW'), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
("paint.hide_show", dict(action='SHOW', area='ALL'), dict(type='SELECTMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def mask_border():
return dict(
text="Border Mask",
icon="ops.sculpt.border_mask",
widget=None,
keymap=(
("view3d.select_border", dict(mode='ADD'), dict(type='EVT_TWEAK_A', value='ANY')),
("view3d.select_border", dict(mode='SUB'), dict(type='EVT_TWEAK_A', value='ANY', ctrl=True)),
),
)
2018-08-28 21:00:25 +10:00
class _defs_vertex_paint:
@staticmethod
def poll_select_mask(context):
mesh = context.object.data
return mesh.use_paint_mask
@staticmethod
def generate_from_brushes(context):
return generate_from_brushes_ex(
context,
icon_prefix="brush.paint_vertex.",
brush_test_attr="use_paint_vertex",
brush_category_attr="vertex_tool",
brush_category_layout=(
('MIX',),
('BLUR', 'AVERAGE'),
('SMEAR',),
(
'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN',
'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT',
'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY',
2018-04-30 21:57:51 +02:00
'SATURATION', 'HUE', 'ERASE_ALPHA', 'ADD_ALPHA',
),
)
)
class _defs_texture_paint:
@staticmethod
def generate_from_brushes(context):
return generate_from_brushes_ex(
context,
icon_prefix="brush.paint_texture.",
brush_test_attr="use_paint_image",
brush_category_attr="image_tool",
brush_category_layout=(
('DRAW',),
('SOFTEN',),
('SMEAR',),
('CLONE',),
('FILL',),
('MASK',),
)
)
class _defs_weight_paint:
@staticmethod
def poll_select_mask(context):
mesh = context.object.data
return (mesh.use_paint_mask or mesh.use_paint_mask_vertex)
@staticmethod
def generate_from_brushes(context):
return generate_from_brushes_ex(
context,
icon_prefix="brush.paint_weight.",
brush_test_attr="use_paint_weight",
brush_category_attr="vertex_tool",
brush_category_layout=(
('MIX',),
('BLUR', 'AVERAGE'),
('SMEAR',),
(
'ADD', 'SUB', 'MUL', 'LIGHTEN', 'DARKEN',
'COLORDODGE', 'DIFFERENCE', 'SCREEN', 'HARDLIGHT',
'OVERLAY', 'SOFTLIGHT', 'EXCLUSION', 'LUMINOCITY',
'SATURATION', 'HUE',
),
)
)
@ToolDef.from_fn
def sample_weight():
return dict(
text="Sample Weight",
icon="ops.paint.weight_sample",
widget=None,
keymap=(
("paint.weight_sample", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def sample_weight_group():
return dict(
text="Sample Vertex Group",
icon="ops.paint.weight_sample_group",
widget=None,
keymap=(
("paint.weight_sample_group", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
),
)
@ToolDef.from_fn
def gradient():
def draw_settings(context, layout, tool):
brush = context.tool_settings.weight_paint.brush
if brush is not None:
from .properties_paint_common import UnifiedPaintPanel
UnifiedPaintPanel.prop_unified_weight(layout, context, brush, "weight", slider=True, text="Weight")
props = tool.operator_properties("paint.weight_gradient")
layout.prop(props, "type")
return dict(
text="Gradient",
icon="ops.paint.weight_gradient",
widget=None,
keymap=(
("paint.weight_gradient", dict(), dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
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)),
),
)
2018-07-31 21:06:08 +10:00
class _defs_gpencil_paint:
@staticmethod
def draw_color_selector(context, layout):
brush = context.active_gpencil_brush
gp_settings = brush.gpencil_settings
ts = context.tool_settings
row = layout.row(align=True)
2018-09-03 14:15:18 +10:00
row.prop(ts, "use_gpencil_thumbnail_list", text="", icon='IMGDISPLAY')
if ts.use_gpencil_thumbnail_list is False:
row.template_ID(gp_settings, "material", live_icon=True)
else:
row.template_greasepencil_color(gp_settings, "material", rows=3, cols=8, scale=0.8)
row.prop(gp_settings, "pin_material", text="")
@staticmethod
def draw_settings_common(context, layout, tool):
ob = context.active_object
if ob and ob.mode == 'GPENCIL_PAINT':
brush = context.active_gpencil_brush
gp_settings = brush.gpencil_settings
if gp_settings.gpencil_brush_type == 'ERASE':
row = layout.row()
row.prop(brush, "size", text="Radius")
elif gp_settings.gpencil_brush_type == 'FILL':
row = layout.row()
row.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
row.prop(brush, "size", text="Thickness")
row.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
_defs_gpencil_paint.draw_color_selector(context, layout)
row = layout.row(align=True)
row.prop(gp_settings, "gpencil_fill_draw_mode", text="")
row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
else: # bgpsettings.gpencil_brush_type == 'DRAW':
row = layout.row(align=True)
row.prop(brush, "size", text="Radius")
row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
row = layout.row(align=True)
row.prop(gp_settings, "pen_strength", slider=True)
row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
_defs_gpencil_paint.draw_color_selector(context, layout)
@staticmethod
def generate_from_brushes(context):
return generate_from_brushes_ex(
context,
icon_prefix="brush.gpencil.",
brush_test_attr="use_paint_grease_pencil",
brush_category_attr="grease_pencil_tool",
brush_category_layout=(
('PENCIL',),
('PEN',),
('INK',),
('INKNOISE',),
('BLOCK',),
('MARKER',),
('FILL',),
('SOFT',),
('HARD',),
('STROKE',),
)
)
class _defs_gpencil_edit:
@ToolDef.from_fn
def bend():
return dict(
text="Bend",
icon="ops.gpencil.edit_bend",
widget=None,
keymap=(
("transform.bend",
dict(release_confirm=True),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def mirror():
return dict(
text="Mirror",
icon="ops.gpencil.edit_mirror",
widget=None,
keymap=(
("transform.mirror",
dict(release_confirm=True),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def shear():
return dict(
text="Shear",
icon="ops.gpencil.edit_shear",
widget=None,
keymap=(
("transform.shear",
dict(release_confirm=True),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
@ToolDef.from_fn
def tosphere():
return dict(
text="To Sphere",
icon="ops.gpencil.edit_to_sphere",
widget=None,
keymap=(
("transform.tosphere",
dict(release_confirm=True),
dict(type='EVT_TWEAK_A', value='ANY')),
),
)
class _defs_gpencil_sculpt:
@staticmethod
def draw_settings_common(context, layout, tool):
ob = context.active_object
if ob and ob.mode == 'GPENCIL_SCULPT':
ts = context.tool_settings
settings = ts.gpencil_sculpt
brush = settings.brush
layout.prop(brush, "size", slider=True)
row = layout.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "use_pressure_strength", text="")
row.separator()
row.prop(ts.gpencil_sculpt, "use_select_mask", text="")
@ToolDef.from_fn
def smooth():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Smooth",
icon="ops.gpencil.sculpt_smooth",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='SMOOTH', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def thickness():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Thickness",
icon="ops.gpencil.sculpt_thickness",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='THICKNESS', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def strength():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Strength",
icon="ops.gpencil.sculpt_strength",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='STRENGTH', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def grab():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Grab",
icon="ops.gpencil.sculpt_grab",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='GRAB', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def push():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Push",
icon="ops.gpencil.sculpt_push",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='PUSH', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def twist():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Twist",
icon="ops.gpencil.sculpt_twist",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='TWIST', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def pinch():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Pinch",
icon="ops.gpencil.sculpt_pinch",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='PINCH', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def randomize():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Randomize",
icon="ops.gpencil.sculpt_randomize",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='RANDOMIZE', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def clone():
def draw_settings(context, layout, tool):
_defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
return dict(
text="Clone",
icon="ops.gpencil.sculpt_clone",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='CLONE', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
class _defs_gpencil_weight:
@staticmethod
def draw_settings_common(context, layout, tool):
ob = context.active_object
if ob and ob.mode == 'GPENCIL_WEIGHT':
settings = context.tool_settings.gpencil_sculpt
brush = settings.brush
layout.prop(brush, "size", slider=True)
row = layout.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "use_pressure_strength", text="")
@ToolDef.from_fn
def paint():
def draw_settings(context, layout, tool):
_defs_gpencil_weight.draw_settings_common(context, layout, tool)
return dict(
text="Draw",
icon="ops.gpencil.sculpt_weight",
widget=None,
keymap=(
("gpencil.brush_paint",
dict(mode='WEIGHT', wait_for_input=False),
dict(type='EVT_TWEAK_A', value='ANY')),
),
draw_settings=draw_settings,
)
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:
if context.space_data is None:
mode = 'VIEW'
else:
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_annotate = (
(
_defs_annotate_image.scribble,
_defs_annotate_image.line,
_defs_annotate_image.poly,
_defs_annotate_image.eraser,
),
)
_tools = {
None: [
# for all modes
],
'VIEW': [
*_tools_select,
*_tools_annotate,
],
'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'
bl_category = "Tools"
2018-04-24 16:04:07 +02:00
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the 'ToolSelectPanelHelper' API.
keymap_prefix = "3D View Tool:"
@classmethod
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)
else:
yield item
@classmethod
def tools_all(cls):
yield from cls._tools.items()
# for reuse
_tools_transform = (
_defs_transform.transform,
_defs_transform.translate,
_defs_transform.rotate,
2018-04-24 09:19:28 +02:00
(
_defs_transform.scale,
_defs_transform.scale_cage,
2018-04-24 09:19:28 +02:00
),
)
_tools_select = (
(
_defs_view3d_select.border,
_defs_view3d_select.circle,
_defs_view3d_select.lasso,
),
)
_tools_annotate = (
(
_defs_annotate_view3d.scribble,
_defs_annotate_view3d.line,
_defs_annotate_view3d.poly,
_defs_annotate_view3d.eraser,
),
_defs_view3d_generic.ruler,
)
_tools = {
None: [
# Don't use this! because of paint modes.
# _defs_view3d_generic.cursor,
2017-11-02 23:05:13 +11:00
# End group.
],
'OBJECT': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
*_tools_annotate,
],
'POSE': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
*_tools_annotate,
None,
(
_defs_pose.breakdown,
_defs_pose.push,
_defs_pose.relax,
),
],
'EDIT_ARMATURE': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
*_tools_annotate,
_defs_edit_armature.roll,
(
_defs_edit_armature.bone_size,
_defs_edit_armature.bone_envelope,
),
None,
(
_defs_edit_armature.extrude,
_defs_edit_armature.extrude_cursor,
),
],
'EDIT_MESH': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
*_tools_annotate,
None,
_defs_edit_mesh.cube_add,
None,
2018-04-24 15:32:11 +02:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.extrude,
_defs_edit_mesh.extrude_normals,
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.extrude_individual,
_defs_edit_mesh.extrude_cursor,
2018-04-24 15:32:11 +02:00
),
_defs_edit_mesh.inset,
_defs_edit_mesh.bevel,
(
_defs_edit_mesh.loopcut_slide,
_defs_edit_mesh.offset_edge_loops_slide,
),
2018-04-24 15:32:11 +02:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.knife,
_defs_edit_mesh.bisect,
),
_defs_edit_mesh.poly_build,
(
_defs_edit_mesh.spin,
_defs_edit_mesh.spin_duplicate,
2018-04-24 15:32:11 +02:00
),
(
_defs_edit_mesh.vertex_smooth,
_defs_edit_mesh.vertex_randomize,
2018-04-24 15:32:11 +02:00
),
2018-04-30 20:40:36 +02:00
(
_defs_edit_mesh.edge_slide,
_defs_edit_mesh.vert_slide,
),
2018-04-24 15:32:11 +02:00
(
_defs_edit_mesh.shrink_fatten,
_defs_edit_mesh.push_pull,
2018-04-24 15:32:11 +02:00
),
(
_defs_edit_mesh.shear,
_defs_edit_mesh.tosphere,
),
2017-11-02 23:05:13 +11:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.rip_region,
_defs_edit_mesh.rip_edge,
),
],
'EDIT_CURVE': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
*_tools_annotate,
None,
_defs_edit_curve.draw,
2018-08-29 15:14:41 +10:00
(
_defs_edit_curve.extrude,
_defs_edit_curve.extrude_cursor,
)
],
'PARTICLE': [
_defs_view3d_generic.cursor,
_defs_particle.generate_from_brushes,
],
'SCULPT': [
_defs_sculpt.generate_from_brushes,
None,
_defs_sculpt.hide_border,
_defs_sculpt.mask_border,
],
'PAINT_TEXTURE': [
_defs_texture_paint.generate_from_brushes,
],
'PAINT_VERTEX': [
_defs_vertex_paint.generate_from_brushes,
None,
lambda context: (
VIEW3D_PT_tools_active._tools_select
if _defs_vertex_paint.poll_select_mask(context)
else ()
),
],
'PAINT_WEIGHT': [
# TODO, check for mixed pose mode
_defs_view3d_generic.cursor,
_defs_weight_paint.generate_from_brushes,
None,
_defs_weight_paint.sample_weight,
_defs_weight_paint.sample_weight_group,
None,
lambda context: (
VIEW3D_PT_tools_active._tools_select
if _defs_weight_paint.poll_select_mask(context)
else ()
),
None,
_defs_weight_paint.gradient,
],
'GPENCIL_PAINT': [
_defs_gpencil_paint.generate_from_brushes,
],
'GPENCIL_EDIT': [
_defs_view3d_generic.cursor,
*_tools_select,
None,
*_tools_transform,
None,
_defs_gpencil_edit.bend,
_defs_gpencil_edit.mirror,
_defs_gpencil_edit.shear,
_defs_gpencil_edit.tosphere,
],
'GPENCIL_SCULPT': [
_defs_gpencil_sculpt.smooth,
_defs_gpencil_sculpt.thickness,
_defs_gpencil_sculpt.strength,
_defs_gpencil_sculpt.grab,
_defs_gpencil_sculpt.push,
_defs_gpencil_sculpt.twist,
_defs_gpencil_sculpt.pinch,
_defs_gpencil_sculpt.randomize,
_defs_gpencil_sculpt.clone,
],
'GPENCIL_WEIGHT': [
_defs_gpencil_weight.paint,
],
}
classes = (
IMAGE_PT_tools_active,
VIEW3D_PT_tools_active,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)