From f4697b392d48302fc5df70208c22f4678150c702 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Apr 2018 12:14:46 +0200 Subject: [PATCH] Tool System: change internal definitions (again) Was using classes to define tools, however this makes it awkward to dynamically generate them (we can do it, but its not very "Pythonic"). Move to a named tuple. --- .../startup/bl_ui/space_toolsystem_common.py | 124 ++-- .../startup/bl_ui/space_toolsystem_toolbar.py | 666 ++++++++++-------- 2 files changed, 451 insertions(+), 339 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index af248df8698..1ae9a15b6a3 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -59,47 +59,73 @@ def _keymap_fn_from_seq(keymap_data): def _item_is_fn(item): - return (not (type(item) is type and issubclass(item, ToolDef)) and callable(item)) + return (not (type(item) is ToolDef) and callable(item)) -class ToolDef: +from collections import namedtuple +ToolDef = namedtuple( + "ToolDef", + ( + # The name to display in the interface. + "text", + # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon. + "icon", + # An optional manipulator group to activate when the tool is set or None for no widget. + "widget", + # Optional keymap for tool, either: + # - A function that populates a keymaps passed in as an argument. + # - A tuple filled with triple's of: + # ``(operator_id, operator_properties, keymap_item_args)``. + # + # Warning: currently 'from_dict' this is a list of one item, + # so internally we can swap the keymap function for the keymap it's self. + # This isn't very nice and may change, tool definitions shouldn't care about this. + "keymap", + # Optional data-block assosiated with this tool. + # (Typically brush name, usage depends on mode, we could use for non-brush ID's in other modes). + "data_block", + # Optional draw settings (operator options, toolsettings). + "draw_settings", + ) +) +del namedtuple + +def from_dict(kw_args): """ - 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. + Use so each tool can avoid defining all members of the named tuple. + Also convert the keymap from a tuple into a function + (since keymap is a callback). """ - __slots__ = () + kw = { + "icon": None, + "widget": None, + "keymap": None, + "data_block": None, + "draw_settings": None, + } + kw.update(kw_args) - def __new__(cls, *args, **kwargs): - raise RuntimeError("%s should not be instantiated" % cls) + keymap = kw["keymap"] + if kw["keymap"] is None: + pass + elif type(keymap) is tuple: + keymap = [_keymap_fn_from_seq(keymap)] + else: + keymap = [keymap] + kw["keymap"] = keymap + return ToolDef(**kw) - 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(not (cls.keymap is None and cls.widget is None and cls.data_block is None)) +def from_fn(fn): + """ + Use as decorator so we can define functions. + """ + return ToolDef.from_dict(fn()) - 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 - # Optional keymap for tool, either: - # - A function that populates a keymaps passed in as an argument. - # - A tuple filled with triple's of: - # ``(operator_id, operator_properties, keymap_item_args)``. - keymap = None - # Optional data-block assosiated with this tool. - # (Typically brush name, usage depends on mode, we could use for non-brush ID's in other modes). - data_block = None - # Optional draw settings (operator options, toolsettings). - draw_settings = None +ToolDef.from_dict = from_dict +ToolDef.from_fn = from_fn +del from_dict +del from_fn class ToolSelectPanelHelper: @@ -169,14 +195,11 @@ class ToolSelectPanelHelper: icon_name = item.icon mp_idname = item.widget datablock_idname = item.data_block - keymap_fn = item.keymap - if keymap_fn is None: - km, km_idname = (None, None) + keymap = item.keymap + if keymap is None: + km_idname = None else: - km_test = cls._tool_keymap.get((context_mode, text)) - if km_test is None and context_mode is not None: - km_test = cls._tool_keymap[None, text] - km, km_idname = km_test + km_idname = keymap[0].name return (km_idname, mp_idname, datablock_idname), icon_name @staticmethod @@ -198,23 +221,21 @@ class ToolSelectPanelHelper: ( props.keymap or None or None, props.manipulator_group or None, - props.data_block, + props.data_block or None, ), props.index, ) @classmethod def _km_action_simple(cls, kc, context_mode, text, keymap_fn): - if context_mode is None: context_mode = "All" km_idname = f"{cls.keymap_prefix} {context_mode}, {text}" km = kc.keymaps.get(km_idname) - if km is not None: - return km, km_idname - km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW') - keymap_fn(km) - return km, km_idname + if km is None: + km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW') + keymap_fn[0](km) + keymap_fn[0] = km @classmethod def register(cls): @@ -226,9 +247,6 @@ class ToolSelectPanelHelper: # This needs some careful consideration. kc = wm.keyconfigs.user - # {context_mode: {tool_name: (keymap, keymap_idname, manipulator_group_idname), ...}, ...} - cls._tool_keymap = {} - # Track which tool-group was last used for non-active groups. # Blender stores the active tool-group index. # @@ -248,11 +266,10 @@ class ToolSelectPanelHelper: if item is None or _item_is_fn(item): continue keymap_data = item.keymap - if keymap_data is not None: + if keymap_data is not None and callable(keymap_data[0]): 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 + cls._km_action_simple(kc, context_mode, text, keymap_data) # ------------------------------------------------------------------------- @@ -487,7 +504,6 @@ class WM_MT_toolsystem_submenu(Menu): item = item_group[index_button] tool_def, icon_name = cls._tool_vars_from_def(item, context_mode) is_active = (tool_def == tool_def_button) - print(tool_def, tool_def_button) if is_active: return cls, item_group, index_button return None, None, -1 diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c3d58d49142..036d248667e 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -31,377 +31,475 @@ from .space_toolsystem_common import ( ToolDef, ) - class _defs_view3d_generic: - - class cursor(ToolDef): - text = "Cursor" - icon = "ops.generic.cursor" - widget = None - - keymap = ( + @ToolDef.from_fn + def cursor(): + return dict( + text="Cursor", + icon="ops.generic.cursor", + keymap=( ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='CLICK')), - ) + ), + ) - class ruler(ToolDef): - text = "Ruler/Protractor" - icon = "ops.view3d.ruler" - widget = "VIEW3D_WGT_ruler" - keymap = ( + @ToolDef.from_fn + def ruler(): + return dict( + 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 = "Move" - icon = "ops.transform.translate" - widget = "TRANSFORM_WGT_manipulator" - keymap = ( + @ToolDef.from_fn + def translate(): + return dict( + text="Move", + icon="ops.transform.translate", + widget="TRANSFORM_WGT_manipulator", + keymap=( ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def rotate(): + return 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')), + ), ) - 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')), + @ToolDef.from_fn + def scale(): + return 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')), + ), ) - 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')), + @ToolDef.from_fn + def scale_cage(): + return dict( + text="Scale Cage", + icon="ops.transform.resize.cage", + widget="VIEW3D_WGT_xform_cage", ) - class scale_cage(ToolDef): - text = "Scale Cage" - icon = "ops.transform.resize.cage" - widget = "VIEW3D_WGT_xform_cage" - keymap = None - - class transform(ToolDef): - text = "Transform" - icon = "ops.transform.transform" - widget = "TRANSFORM_WGT_manipulator" - # No favorites, only for manipulators! - keymap = () - + @ToolDef.from_fn + def transform(): + return dict( + text="Transform", + icon="ops.transform.transform", + widget="TRANSFORM_WGT_manipulator", + # No keymap default action, only for manipulators! + ) 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)), + @ToolDef.from_fn + def border(): + return 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)), + ), ) - 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)), + @ToolDef.from_fn + def circle(): + 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)), + ), ) - 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)), + @ToolDef.from_fn + def lasso(): + return 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)), + ), ) - # ----------------------------------------------------------------------------- # 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')), + @ToolDef.from_fn + def gradient_linear(): + return dict( + 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')), + @ToolDef.from_fn + def gradient_radial(): + return dict( + 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 = "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 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'),), + ), ) - class extrude(ToolDef): - text = "Extrude", - icon = "ops.armature.extrude_move", - widget = None, - keymap = ( - ("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def extrude(): + return dict( + text="Extrude", + icon="ops.armature.extrude_move", + widget=None, + keymap=( + ("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), ) - class extrude_cursor(ToolDef): - text = "Extrude to Cursor", - icon = "ops.armature.extrude_cursor", - widget = None, - keymap = ( - ("armature.click_extrude", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + @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')), + ), ) - 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')), + @ToolDef.from_fn + def rip_region(): + return dict( + 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')), + @ToolDef.from_fn + def rip_edge(): + return dict( + 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)), + @ToolDef.from_fn + def poly_build(): + return 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)), + ), ) - 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') - ), + @ToolDef.from_fn + def edge_slide(): + 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') + ), + ), ) - 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')), + @ToolDef.from_fn + def vert_slide(): + 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')), + ), ) - class spin(ToolDef): - text = "Spin" - icon = "ops.mesh.spin" - widget = None - keymap = ( - ("mesh.spin", dict(), - dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def spin(): + return dict( + 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')), + @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')), + ), ) - class inset(ToolDef): - text = "Inset Faces" - icon = "ops.mesh.inset" - widget = None - keymap = ( - ("mesh.inset", dict(release_confirm=True), - dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def inset(): + return dict( + text="Inset Faces", + icon="ops.mesh.inset", + widget=None, + keymap=( + ("mesh.inset", dict(release_confirm=True), + dict(type='ACTIONMOUSE', value='PRESS')), + ), ) - class bevel(ToolDef): - text = "Bevel" - icon = "ops.mesh.bevel" - widget = None - keymap = ( - ("mesh.bevel", dict(), - dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def bevel(): + return dict( + text="Bevel", + icon="ops.mesh.bevel", + widget=None, + keymap=( + ("mesh.bevel", dict(), + dict(type='ACTIONMOUSE', value='PRESS')), + ), ) - class extrude(ToolDef): - text = "Extrude Region" - icon = "ops.mesh.extrude_region_move" - widget = None - keymap = ( - ("mesh.extrude_region_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), - dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def extrude(): + return dict( + text="Extrude Region", + icon="ops.mesh.extrude_region_move", + widget=None, + keymap=( + ("mesh.extrude_region_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), + dict(type='ACTIONMOUSE', value='PRESS')), + ), ) - class extrude_individual(ToolDef): - 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='ACTIONMOUSE', value='PRESS')), + @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='ACTIONMOUSE', value='PRESS')), + ), ) - class extrude_cursor(ToolDef): - 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 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')), + ), ) - class loopcut_slide(ToolDef): - text = "Loop Cut" - icon = "ops.mesh.loopcut_slide" - widget = None - keymap = ( - ("mesh.loopcut_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + @ToolDef.from_fn + def loopcut_slide(): + return dict( + text="Loop Cut", + icon="ops.mesh.loopcut_slide", + widget=None, + keymap=( + ("mesh.loopcut_slide", dict(), dict(type='ACTIONMOUSE', value='PRESS')), + ), ) - class offset_edge_loops_slide(ToolDef): - 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 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')), + ), ) - class vertex_smooth(ToolDef): - text = "Smooth" - icon = "ops.mesh.vertices_smooth" - widget = None - keymap = ( - ("mesh.vertices_smooth", 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')), + ), ) - class vertex_randomize(ToolDef): - text = "Randomize" - icon = "ops.transform.vertex_random" - widget = None - keymap = ( - ("transform.vertex_random", 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')), + ), ) - 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')), + @ToolDef.from_fn + def shrink_fatten(): + 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')), + ), ) - 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')), + @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')), + ), ) - class knife(ToolDef): - text = "Knife" - icon = "ops.mesh.knife_tool" - widget = None - keymap = ( - ("mesh.knife_tool", - dict(wait_for_input=False), - dict(type='ACTIONMOUSE', value='PRESS')), - ) - - @classmethod + @ToolDef.from_fn + def knife(): def draw_settings(cls, context, layout): - wm = context.window_manager - props = wm.operator_properties_last("mesh.knife_tool") + wm=context.window_manager + props=wm.operator_properties_last("mesh.knife_tool") layout.prop(props, "use_occlude_geometry") layout.prop(props, "only_selected") - class bisect(ToolDef): - text = "Bisect" - icon = "ops.mesh.bisect" - widget = None - keymap = ( - ("mesh.bisect", - dict(), - dict(type='EVT_TWEAK_A', value='ANY')), + 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(): + return dict( + text="Bisect", + icon="ops.mesh.bisect", + widget=None, + keymap=( + ("mesh.bisect", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) 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')), + @ToolDef.from_fn + def draw(): + return dict( + 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')), + @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')), + ), ) - class _defs_sculpt: @staticmethod @@ -413,9 +511,7 @@ class _defs_sculpt: sculpt_tool = brush.sculpt_tool name = brush.name brush_categories.setdefault(sculpt_tool, []).append( - type( - "DynToolDef", - (ToolDef,), + ToolDef.from_dict( dict( text=name, icon="brush.sculpt." + sculpt_tool.lower(),