From e70b309dac3f6aae5cb42a7a90ce0f407350060f Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Thu, 20 Jul 2017 16:25:36 +1000 Subject: brush menus: bug fixes/update by imaginer T52124 --- space_view3d_brush_menus/__init__.py | 6 +- space_view3d_brush_menus/brush_menu.py | 491 ++++++++++++++---------------- space_view3d_brush_menus/brushes.py | 197 ++++++------ space_view3d_brush_menus/curve_menu.py | 46 +-- space_view3d_brush_menus/dyntopo_menu.py | 78 ++--- space_view3d_brush_menus/stroke_menu.py | 150 ++++++--- space_view3d_brush_menus/symmetry_menu.py | 58 ++-- space_view3d_brush_menus/texture_menu.py | 259 +++++++++------- space_view3d_brush_menus/utils_core.py | 72 +---- 9 files changed, 699 insertions(+), 658 deletions(-) (limited to 'space_view3d_brush_menus') diff --git a/space_view3d_brush_menus/__init__.py b/space_view3d_brush_menus/__init__.py index a591187c..9446083a 100644 --- a/space_view3d_brush_menus/__init__.py +++ b/space_view3d_brush_menus/__init__.py @@ -23,8 +23,8 @@ bl_info = { "name": "Sculpt/Paint Brush Menus", "description": "Fast access to brushes & tools in Sculpt and Paint Modes", "author": "Ryan Inch (Imaginer)", - "version": (1, 1, 4), - "blender": (2, 7, 8), + "version": (1, 1, 5), + "blender": (2, 78, 0), "location": "Alt V in Sculpt/Paint Modes", "warning": '', "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" @@ -109,7 +109,7 @@ def register(): # register hotkeys wm = bpy.context.window_manager - modes = ['Sculpt', 'Vertex Paint', 'Weight Paint', 'Image Paint', 'Particle'] + modes = ('Sculpt', 'Vertex Paint', 'Weight Paint', 'Image Paint', 'Particle') for mode in modes: km = wm.keyconfigs.addon.keymaps.new(name=mode) diff --git a/space_view3d_brush_menus/brush_menu.py b/space_view3d_brush_menus/brush_menu.py index 6940304e..4568c225 100644 --- a/space_view3d_brush_menus/brush_menu.py +++ b/space_view3d_brush_menus/brush_menu.py @@ -7,62 +7,9 @@ from bpy.types import ( ) from bpy.props import BoolProperty from . import utils_core +from . import brushes from bl_ui.properties_paint_common import UnifiedPaintPanel - -def get_current_brush_icon(tool): - if utils_core.get_mode() == utils_core.sculpt: - icons = {"BLOB": 'BRUSH_BLOB', - "CLAY": 'BRUSH_CLAY', - "CLAY_STRIPS": 'BRUSH_CLAY_STRIPS', - "CREASE": 'BRUSH_CREASE', - "DRAW": 'BRUSH_SCULPT_DRAW', - "FILL": 'BRUSH_FILL', - "FLATTEN": 'BRUSH_FLATTEN', - "GRAB": 'BRUSH_GRAB', - "INFLATE": 'BRUSH_INFLATE', - "LAYER": 'BRUSH_LAYER', - "MASK": 'BRUSH_MASK', - "NUDGE": 'BRUSH_NUDGE', - "PINCH": 'BRUSH_PINCH', - "ROTATE": 'BRUSH_ROTATE', - "SCRAPE": 'BRUSH_SCRAPE', - "SIMPLIFY": 'BRUSH_SUBTRACT', - "SMOOTH": 'BRUSH_SMOOTH', - "SNAKE_HOOK": 'BRUSH_SNAKE_HOOK', - "THUMB": 'BRUSH_THUMB'} - - elif utils_core.get_mode() == utils_core.vertex_paint: - icons = {"ADD": 'BRUSH_ADD', - "BLUR": 'BRUSH_BLUR', - "DARKEN": 'BRUSH_DARKEN', - "LIGHTEN": 'BRUSH_LIGHTEN', - "MIX": 'BRUSH_MIX', - "MUL": 'BRUSH_MULTIPLY', - "SUB": 'BRUSH_SUBTRACT'} - - elif utils_core.get_mode() == utils_core.weight_paint: - icons = {"ADD": 'BRUSH_ADD', - "BLUR": 'BRUSH_BLUR', - "DARKEN": 'BRUSH_DARKEN', - "LIGHTEN": 'BRUSH_LIGHTEN', - "MIX": 'BRUSH_MIX', - "MUL": 'BRUSH_MULTIPLY', - "SUB": 'BRUSH_SUBTRACT'} - - elif utils_core.get_mode() == utils_core.texture_paint: - icons = {"CLONE": 'BRUSH_CLONE', - "DRAW": 'BRUSH_TEXDRAW', - "FILL": 'BRUSH_TEXFILL', - "MASK": 'BRUSH_TEXMASK', - "SMEAR": 'BRUSH_SMEAR', - "SOFTEN": 'BRUSH_SOFTEN'} - - icon = icons[tool] - - return icon - - class BrushOptionsMenu(Menu): bl_label = "Brush Options" bl_idname = "VIEW3D_MT_sv3_brush_options" @@ -70,163 +17,161 @@ class BrushOptionsMenu(Menu): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, utils_core.vertex_paint, - utils_core.weight_paint, utils_core.texture_paint, - utils_core.particle_edit + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' ) - def draw_brushes(self, menu, h_brush, ico, context): + def draw_brushes(self, layout, h_brush, ico, context): if utils_core.addon_settings(lists=True) == 'popup' or not h_brush: - menu.add_item().operator( + layout.row().operator( "view3d.sv3_brush_menu_popup", text="Brush", icon=ico ) else: - menu.add_item().menu( + layout.row().menu( "VIEW3D_MT_sv3_brushes_menu", text="Brush", icon=ico ) def draw(self, context): - menu = utils_core.Menu(self) + mode = utils_core.get_mode() + layout = self.layout - if utils_core.get_mode() == utils_core.sculpt: - self.sculpt(menu, context) + if mode == 'SCULPT': + self.sculpt(mode, layout, context) - elif utils_core.get_mode() in (utils_core.vertex_paint, - utils_core.weight_paint): - self.vw_paint(menu, context) + elif mode in ('VERTEX_PAINT', 'WEIGHT_PAINT'): + self.vw_paint(mode, layout, context) - elif utils_core.get_mode() == utils_core.texture_paint: - self.texpaint(menu, context) + elif mode == 'TEXTURE_PAINT': + self.texpaint(mode, layout, context) else: - self.particle(menu, context) + self.particle(layout, context) - def sculpt(self, menu, context): + def sculpt(self, mode, layout, context): has_brush = utils_core.get_brush_link(context, types="brush") - icons = get_current_brush_icon(has_brush.sculpt_tool) if \ + icons = brushes.brush_icon[mode][has_brush.sculpt_tool] if \ has_brush else "BRUSH_DATA" - self.draw_brushes(menu, has_brush, icons, context) + self.draw_brushes(layout, has_brush, icons, context) - menu.add_item().menu(BrushRadiusMenu.bl_idname) + layout.row().menu(BrushRadiusMenu.bl_idname) if has_brush: # if the active brush is unlinked these menus don't do anything - menu.add_item().menu(BrushStrengthMenu.bl_idname) - menu.add_item().menu(BrushAutosmoothMenu.bl_idname) - menu.add_item().menu(BrushModeMenu.bl_idname) - menu.add_item().menu("VIEW3D_MT_sv3_texture_menu") - menu.add_item().menu("VIEW3D_MT_sv3_stroke_options") - menu.add_item().menu("VIEW3D_MT_sv3_brush_curve_menu") + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushAutosmoothMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") - menu.add_item().menu("VIEW3D_MT_sv3_dyntopo") - menu.add_item().menu("VIEW3D_MT_sv3_master_symmetry_menu") + layout.row().menu("VIEW3D_MT_sv3_dyntopo") + layout.row().menu("VIEW3D_MT_sv3_master_symmetry_menu") - def vw_paint(self, menu, context): + def vw_paint(self, mode, layout, context): has_brush = utils_core.get_brush_link(context, types="brush") - icons = get_current_brush_icon(has_brush.vertex_tool) if \ + icons = brushes.brush_icon[mode][has_brush.vertex_tool] if \ has_brush else "BRUSH_DATA" - if utils_core.get_mode() == utils_core.vertex_paint: - menu.add_item().operator(ColorPickerPopup.bl_idname, icon="COLOR") - menu.add_item().separator() + if mode == 'VERTEX_PAINT': + layout.row().operator(ColorPickerPopup.bl_idname, icon="COLOR") + layout.row().separator() - self.draw_brushes(menu, has_brush, icons, context) + self.draw_brushes(layout, has_brush, icons, context) - if utils_core.get_mode() == utils_core.vertex_paint: - menu.add_item().menu(BrushRadiusMenu.bl_idname) + if mode == 'VERTEX_PAINT': + layout.row().menu(BrushRadiusMenu.bl_idname) if has_brush: # if the active brush is unlinked these menus don't do anything - menu.add_item().menu(BrushStrengthMenu.bl_idname) - menu.add_item().menu(BrushModeMenu.bl_idname) - menu.add_item().menu("VIEW3D_MT_sv3_texture_menu") - menu.add_item().menu("VIEW3D_MT_sv3_stroke_options") - menu.add_item().menu("VIEW3D_MT_sv3_brush_curve_menu") + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") - if utils_core.get_mode() == utils_core.weight_paint: - menu.add_item().menu(BrushWeightMenu.bl_idname) - menu.add_item().menu(BrushRadiusMenu.bl_idname) + if mode == 'WEIGHT_PAINT': + layout.row().menu(BrushWeightMenu.bl_idname) + layout.row().menu(BrushRadiusMenu.bl_idname) if has_brush: # if the active brush is unlinked these menus don't do anything - menu.add_item().menu(BrushStrengthMenu.bl_idname) - menu.add_item().menu(BrushModeMenu.bl_idname) - menu.add_item().menu("VIEW3D_MT_sv3_stroke_options") - menu.add_item().menu("VIEW3D_MT_sv3_brush_curve_menu") + layout.row().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") - def texpaint(self, menu, context): + def texpaint(self, mode, layout, context): toolsettings = context.tool_settings.image_paint if context.image_paint_object and not toolsettings.detect_data(): - menu.add_item().label("Missing Data", icon="INFO") - menu.add_item().label("See Tool Shelf", icon="BACK") + layout.row().label("Missing Data", icon="INFO") + layout.row().label("See Tool Shelf", icon="BACK") else: has_brush = utils_core.get_brush_link(context, types="brush") if has_brush and has_brush.image_tool in {'DRAW', 'FILL'} and \ has_brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}: - menu.add_item().operator(ColorPickerPopup.bl_idname, icon="COLOR") - menu.add_item().separator() + layout.row().operator(ColorPickerPopup.bl_idname, icon="COLOR") + layout.row().separator() - icons = get_current_brush_icon(has_brush.image_tool) if \ + icons = brushes.brush_icon[mode][has_brush.image_tool] if \ has_brush else "BRUSH_DATA" - self.draw_brushes(menu, has_brush, icons, context) + self.draw_brushes(layout, has_brush, icons, context) if has_brush: # if the active brush is unlinked these menus don't do anything if has_brush and has_brush.image_tool in {'MASK'}: - menu.add_item().menu(BrushWeightMenu.bl_idname, text="Mask Value") + layout.row().menu(BrushWeightMenu.bl_idname, text="Mask Value") if has_brush and has_brush.image_tool not in {'FILL'}: - menu.add_item().menu(BrushRadiusMenu.bl_idname) + layout.row().menu(BrushRadiusMenu.bl_idname) - menu.add_item().menu(BrushStrengthMenu.bl_idname) + layout.row().menu(BrushStrengthMenu.bl_idname) if has_brush and has_brush.image_tool in {'DRAW'}: - menu.add_item().menu(BrushModeMenu.bl_idname) + layout.row().menu(BrushModeMenu.bl_idname) + + layout.row().menu("VIEW3D_MT_sv3_texture_menu") + layout.row().menu("VIEW3D_MT_sv3_stroke_options") + layout.row().menu("VIEW3D_MT_sv3_brush_curve_menu") - menu.add_item().menu("VIEW3D_MT_sv3_texture_menu") - menu.add_item().menu("VIEW3D_MT_sv3_stroke_options") - menu.add_item().menu("VIEW3D_MT_sv3_brush_curve_menu") + layout.row().menu("VIEW3D_MT_sv3_master_symmetry_menu") - menu.add_item().menu("VIEW3D_MT_sv3_master_symmetry_menu") + def particle(self, layout, context): + particle_edit = context.tool_settings.particle_edit - def particle(self, menu, context): - if context.tool_settings.particle_edit.tool == 'NONE': - menu.add_item().label("No Brush Selected", icon="INFO") - menu.add_item().separator() - menu.add_item().menu("VIEW3D_MT_sv3_brushes_menu", + if particle_edit.tool == 'NONE': + layout.row().label("No Brush Selected", icon="INFO") + layout.row().separator() + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", text="Select Brush", icon="BRUSH_DATA") else: - menu.add_item().menu("VIEW3D_MT_sv3_brushes_menu", + layout.row().menu("VIEW3D_MT_sv3_brushes_menu", icon="BRUSH_DATA") - menu.add_item().menu(BrushRadiusMenu.bl_idname) + layout.row().menu(BrushRadiusMenu.bl_idname) - if context.tool_settings.particle_edit.tool != 'ADD': - menu.add_item().menu(BrushStrengthMenu.bl_idname) + if particle_edit.tool != 'ADD': + layout.row().menu(BrushStrengthMenu.bl_idname) else: - menu.add_item().menu(ParticleCountMenu.bl_idname) - menu.add_item().separator() - menu.add_item().prop(context.tool_settings.particle_edit, - "use_default_interpolate", toggle=True) + layout.row().menu(ParticleCountMenu.bl_idname) + layout.row().separator() + layout.row().prop(particle_edit, "use_default_interpolate", toggle=True) - menu.add_item().prop(context.tool_settings.particle_edit.brush, - "steps", slider=True) - menu.add_item().prop(context.tool_settings.particle_edit, - "default_key_count", slider=True) + layout.row().prop(particle_edit.brush, "steps", slider=True) + layout.row().prop(particle_edit, "default_key_count", slider=True) - if context.tool_settings.particle_edit.tool == 'LENGTH': - menu.add_item().separator() - menu.add_item().menu(ParticleLengthMenu.bl_idname) + if particle_edit.tool == 'LENGTH': + layout.row().separator() + layout.row().menu(ParticleLengthMenu.bl_idname) - if context.tool_settings.particle_edit.tool == 'PUFF': - menu.add_item().separator() - menu.add_item().menu(ParticlePuffMenu.bl_idname) - menu.add_item().prop(context.tool_settings.particle_edit.brush, - "use_puff_volume", toggle=True) + if particle_edit.tool == 'PUFF': + layout.row().separator() + layout.row().menu(ParticlePuffMenu.bl_idname) + layout.row().prop(particle_edit.brush, "use_puff_volume", toggle=True) class BrushRadiusMenu(Menu): @@ -234,43 +179,43 @@ class BrushRadiusMenu(Menu): bl_idname = "VIEW3D_MT_sv3_brush_radius_menu" bl_description = "Change the size of the brushes" - def init(self, context): - if utils_core.get_mode() == utils_core.particle_edit: - settings = [["100", 100], - ["70", 70], - ["50", 50], - ["30", 30], - ["20", 20], - ["10", 10]] + def init(self): + if utils_core.get_mode() == 'PARTICLE_EDIT': + settings = (("100", 100), + ("70", 70), + ("50", 50), + ("30", 30), + ("20", 20), + ("10", 10)) datapath = "tool_settings.particle_edit.brush.size" - proppath = context.tool_settings.particle_edit.brush + proppath = bpy.context.tool_settings.particle_edit.brush else: - settings = [["200", 200], - ["150", 150], - ["100", 100], - ["50", 50], - ["35", 35], - ["10", 10]] + settings = (("200", 200), + ("150", 150), + ("100", 100), + ("50", 50), + ("35", 35), + ("10", 10)) datapath = "tool_settings.unified_paint_settings.size" - proppath = context.tool_settings.unified_paint_settings + proppath = bpy.context.tool_settings.unified_paint_settings return settings, datapath, proppath def draw(self, context): - settings, datapath, proppath = self.init(context) - menu = utils_core.Menu(self) + settings, datapath, proppath = self.init() + layout = self.layout # add the top slider - menu.add_item().prop(proppath, "size", slider=True) - menu.add_item().separator() + layout.row().prop(proppath, "size", slider=True) + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], + layout.row(), settings[i][0], settings[i][1], datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) @@ -280,52 +225,53 @@ class BrushStrengthMenu(Menu): bl_label = "Strength" bl_idname = "VIEW3D_MT_sv3_brush_strength_menu" - def init(self, context): - settings = [["1.0", 1.0], - ["0.7", 0.7], - ["0.5", 0.5], - ["0.3", 0.3], - ["0.2", 0.2], - ["0.1", 0.1]] + def init(self): + mode = utils_core.get_mode() + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) - proppath = utils_core.get_brush_link(context, types="brush") + proppath = utils_core.get_brush_link(bpy.context, types="brush") - if utils_core.get_mode() == utils_core.sculpt: + if mode == 'SCULPT': datapath = "tool_settings.sculpt.brush.strength" - elif utils_core.get_mode() == utils_core.vertex_paint: + elif mode == 'VERTEX_PAINT': datapath = "tool_settings.vertex_paint.brush.strength" - elif utils_core.get_mode() == utils_core.weight_paint: + elif mode == 'WEIGHT_PAINT': datapath = "tool_settings.weight_paint.brush.strength" - elif utils_core.get_mode() == utils_core.texture_paint: + elif mode == 'TEXTURE_PAINT': datapath = "tool_settings.image_paint.brush.strength" else: datapath = "tool_settings.particle_edit.brush.strength" - proppath = context.tool_settings.particle_edit.brush + proppath = bpy.context.tool_settings.particle_edit.brush return settings, datapath, proppath def draw(self, context): - settings, datapath, proppath = self.init(context) - menu = utils_core.Menu(self) + settings, datapath, proppath = self.init() + layout = self.layout # add the top slider if proppath: - menu.add_item().prop(proppath, "strength", slider=True) - menu.add_item().separator() + layout.row().prop(proppath, "strength", slider=True) + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], + layout.row(), settings[i][0], settings[i][1], datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") class BrushModeMenu(Menu): @@ -333,41 +279,51 @@ class BrushModeMenu(Menu): bl_idname = "VIEW3D_MT_sv3_brush_mode_menu" def init(self): + mode = utils_core.get_mode() has_brush = utils_core.get_brush_link(bpy.context, types="brush") - if utils_core.get_mode() == utils_core.sculpt: + if mode == 'SCULPT': enum = has_brush.bl_rna.properties['sculpt_plane'].enum_items if \ has_brush else None path = "tool_settings.sculpt.brush.sculpt_plane" - - elif utils_core.get_mode() == utils_core.texture_paint: + + elif mode == 'VERTEX_PAINT': + enum = has_brush.bl_rna.properties['vertex_tool'].enum_items if \ + has_brush else None + path = "tool_settings.vertex_paint.brush.vertex_tool" + + elif mode == 'WEIGHT_PAINT': + enum = has_brush.bl_rna.properties['vertex_tool'].enum_items if \ + has_brush else None + path = "tool_settings.weight_paint.brush.vertex_tool" + + elif mode == 'TEXTURE_PAINT': enum = has_brush.bl_rna.properties['blend'].enum_items if \ has_brush else None path = "tool_settings.image_paint.brush.blend" else: - enum = has_brush.bl_rna.properties['vertex_tool'].enum_items if \ - has_brush else None - path = "tool_settings.vertex_paint.brush.vertex_tool" + enum = None + path = "" return enum, path def draw(self, context): enum, path = self.init() - menu = utils_core.Menu(self) + layout = self.layout colum_n = utils_core.addon_settings(lists=False) - menu.add_item().label(text="Brush Mode") - menu.add_item().separator() + layout.row().label(text="Brush Mode") + layout.row().separator() if enum: - if utils_core.get_mode() == utils_core.texture_paint: - column_flow = menu.add_item("column_flow", columns=colum_n) + if utils_core.get_mode() == 'TEXTURE_PAINT': + column_flow = layout.column_flow(columns=colum_n) # add all the brush modes to the menu for brush in enum: utils_core.menuprop( - menu.add_item(parent=column_flow), brush.name, + column_flow.row(), brush.name, brush.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) @@ -375,12 +331,12 @@ class BrushModeMenu(Menu): # add all the brush modes to the menu for brush in enum: utils_core.menuprop( - menu.add_item(), brush.name, + layout.row(), brush.name, brush.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") class BrushAutosmoothMenu(Menu): @@ -388,74 +344,80 @@ class BrushAutosmoothMenu(Menu): bl_idname = "VIEW3D_MT_sv3_brush_autosmooth_menu" def init(self): - settings = [["1.0", 1.0], - ["0.7", 0.7], - ["0.5", 0.5], - ["0.3", 0.3], - ["0.2", 0.2], - ["0.1", 0.1]] + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) return settings def draw(self, context): settings = self.init() - menu = utils_core.Menu(self) + layout = self.layout has_brush = utils_core.get_brush_link(context, types="brush") if has_brush: # add the top slider - menu.add_item().prop(has_brush, "auto_smooth_factor", slider=True) - menu.add_item().separator() + layout.row().prop(has_brush, "auto_smooth_factor", slider=True) + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], + layout.row(), settings[i][0], settings[i][1], "tool_settings.sculpt.brush.auto_smooth_factor", icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No Smooth options available", icon="INFO") + layout.row().label("No Smooth options available", icon="INFO") class BrushWeightMenu(Menu): bl_label = "Weight" bl_idname = "VIEW3D_MT_sv3_brush_weight_menu" - def draw(self, context): - if utils_core.get_mode() == utils_core.weight_paint: - brush = context.tool_settings.unified_paint_settings + def init(self): + settings = (("1.0", 1.0), + ("0.7", 0.7), + ("0.5", 0.5), + ("0.3", 0.3), + ("0.2", 0.2), + ("0.1", 0.1)) + + if utils_core.get_mode() == 'WEIGHT_PAINT': + brush = bpy.context.tool_settings.unified_paint_settings brushstr = "tool_settings.unified_paint_settings.weight" name = "Weight" + else: - brush = context.tool_settings.image_paint.brush + brush = bpy.context.tool_settings.image_paint.brush brushstr = "tool_settings.image_paint.brush.weight" name = "Mask Value" - menu = utils_core.Menu(self) - settings = [["1.0", 1.0], - ["0.7", 0.7], - ["0.5", 0.5], - ["0.3", 0.3], - ["0.2", 0.2], - ["0.1", 0.1]] + return settings, brush, brushstr, name + + def draw(self, context): + settings, brush, brushstr, name = self.init() + layout = self.layout + if brush: # add the top slider - menu.add_item().prop(brush, - "weight", text=name, slider=True) - menu.add_item().separator() + layout.row().prop(brush, "weight", text=name, slider=True) + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], + layout.row(), settings[i][0], settings[i][1], brushstr, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brush available", icon="INFO") + layout.row().label("No brush available", icon="INFO") class ParticleCountMenu(Menu): @@ -463,28 +425,28 @@ class ParticleCountMenu(Menu): bl_idname = "VIEW3D_MT_sv3_particle_count_menu" def init(self): - settings = [["50", 50], - ["25", 25], - ["10", 10], - ["5", 5], - ["3", 3], - ["1", 1]] + settings = (("50", 50), + ("25", 25), + ("10", 10), + ("5", 5), + ("3", 3), + ("1", 1)) return settings def draw(self, context): settings = self.init() - menu = utils_core.Menu(self) + layout = self.layout # add the top slider - menu.add_item().prop(context.tool_settings.particle_edit.brush, + layout.row().prop(context.tool_settings.particle_edit.brush, "count", slider=True) - menu.add_item().separator() + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], + layout.row(), settings[i][0], settings[i][1], "tool_settings.particle_edit.brush.count", icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' @@ -496,14 +458,14 @@ class ParticleLengthMenu(Menu): bl_idname = "VIEW3D_MT_sv3_particle_length_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout path = "tool_settings.particle_edit.brush.length_mode" # add the menu items for item in context.tool_settings.particle_edit.brush. \ bl_rna.properties['length_mode'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' @@ -515,14 +477,14 @@ class ParticlePuffMenu(Menu): bl_idname = "VIEW3D_MT_sv3_particle_puff_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout path = "tool_settings.particle_edit.brush.puff_mode" # add the menu items for item in context.tool_settings.particle_edit.brush. \ bl_rna.properties['puff_mode'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' @@ -551,7 +513,14 @@ class FlipColorsAll(Operator): color.hsv = orig_sec secondary_color.hsv = orig_prim else: - bpy.ops.paint.brush_colors_flip() + color = context.tool_settings.image_paint.brush.color + secondary_color = context.tool_settings.image_paint.brush.secondary_color + + orig_prim = color.hsv + orig_sec = secondary_color.hsv + + color.hsv = orig_sec + secondary_color.hsv = orig_prim return {'FINISHED'} @@ -570,46 +539,52 @@ class ColorPickerPopup(Operator): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.vertex_paint, - utils_core.texture_paint + 'VERTEX_PAINT', + 'TEXTURE_PAINT' ) def check(self, context): return True - def draw(self, context): - menu = utils_core.Menu(self) - - if utils_core.get_mode() == utils_core.texture_paint: - settings = context.tool_settings.image_paint + def init(self): + if utils_core.get_mode() == 'TEXTURE_PAINT': + settings = bpy.context.tool_settings.image_paint brush = getattr(settings, "brush", None) else: - settings = context.tool_settings.vertex_paint + settings = bpy.context.tool_settings.vertex_paint brush = settings.brush brush = getattr(settings, "brush", None) + return settings, brush + + def draw(self, context): + layout = self.layout + settings, brush = self.init() + + if brush: - menu.add_item().template_color_picker(brush, "color", value_slider=True) - menu.add_item("row", align=True).prop(brush, "color", text="") - menu.current_item.prop(brush, "secondary_color", text="") + layout.row().template_color_picker(brush, "color", value_slider=True) + prim_sec_row = layout.row(align=True) + prim_sec_row.prop(brush, "color", text="") + prim_sec_row.prop(brush, "secondary_color", text="") - if utils_core.get_mode() == utils_core.vertex_paint: - menu.current_item.operator( + if utils_core.get_mode() == 'VERTEX_PAINT': + prim_sec_row.operator( FlipColorsAll.bl_idname, icon='FILE_REFRESH', text="" ).is_tex = False else: - menu.current_item.operator( + prim_sec_row.operator( FlipColorsAll.bl_idname, icon='FILE_REFRESH', text="" ).is_tex = True if settings.palette: - menu.add_item("column").template_palette(settings, "palette", color=True) + layout.column().template_palette(settings, "palette", color=True) - menu.add_item().template_ID(settings, "palette", new="palette.new") + layout.row().template_ID(settings, "palette", new="palette.new") else: - menu.add_item().label("No brushes currently available", icon="INFO") + layout.row().label("No brushes currently available", icon="INFO") return @@ -625,10 +600,10 @@ class BrushMenuPopup(Operator): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.vertex_paint, - utils_core.texture_paint, - utils_core.sculpt, - utils_core.weight_paint + 'VERTEX_PAINT', + 'TEXTURE_PAINT', + 'SCULPT', + 'WEIGHT_PAINT' ) def check(self, context): diff --git a/space_view3d_brush_menus/brushes.py b/space_view3d_brush_menus/brushes.py index 280b0367..9073eb48 100644 --- a/space_view3d_brush_menus/brushes.py +++ b/space_view3d_brush_menus/brushes.py @@ -5,149 +5,162 @@ from bpy.types import Menu from . import utils_core from bl_ui.properties_paint_common import UnifiedPaintPanel +# Particle Tools + +particle_tools = ( + ("None", 'NONE'), + ("Comb", 'COMB'), + ("Smooth", 'SMOOTH'), + ("Add", 'ADD'), + ("Length", 'LENGTH'), + ("Puff", 'PUFF'), + ("Cut", 'CUT'), + ("Weight", 'WEIGHT') +) + +# Brush Datapaths + +brush_datapath = { + 'SCULPT': "tool_settings.sculpt.brush", + 'VERTEX_PAINT': "tool_settings.vertex_paint.brush", + 'WEIGHT_PAINT': "tool_settings.weight_paint.brush", + 'TEXTURE_PAINT': "tool_settings.image_paint.brush", + 'PARTICLE_EDIT': "tool_settings.particle_edit.tool" +} + +# Brush Icons + +brush_icon = { + 'SCULPT': { + "BLOB": 'BRUSH_BLOB', + "CLAY": 'BRUSH_CLAY', + "CLAY_STRIPS": 'BRUSH_CLAY_STRIPS', + "CREASE": 'BRUSH_CREASE', + "DRAW": 'BRUSH_SCULPT_DRAW', + "FILL": 'BRUSH_FILL', + "FLATTEN": 'BRUSH_FLATTEN', + "GRAB": 'BRUSH_GRAB', + "INFLATE": 'BRUSH_INFLATE', + "LAYER": 'BRUSH_LAYER', + "MASK": 'BRUSH_MASK', + "NUDGE": 'BRUSH_NUDGE', + "PINCH": 'BRUSH_PINCH', + "ROTATE": 'BRUSH_ROTATE', + "SCRAPE": 'BRUSH_SCRAPE', + "SIMPLIFY": 'BRUSH_SUBTRACT', + "SMOOTH": 'BRUSH_SMOOTH', + "SNAKE_HOOK": 'BRUSH_SNAKE_HOOK', + "THUMB": 'BRUSH_THUMB' + }, + + 'VERTEX_PAINT': { + "ADD": 'BRUSH_ADD', + "BLUR": 'BRUSH_BLUR', + "DARKEN": 'BRUSH_DARKEN', + "LIGHTEN": 'BRUSH_LIGHTEN', + "MIX": 'BRUSH_MIX', + "MUL": 'BRUSH_MULTIPLY', + "SUB": 'BRUSH_SUBTRACT' + }, + + 'WEIGHT_PAINT': { + "ADD": 'BRUSH_ADD', + "BLUR": 'BRUSH_BLUR', + "DARKEN": 'BRUSH_DARKEN', + "LIGHTEN": 'BRUSH_LIGHTEN', + "MIX": 'BRUSH_MIX', + "MUL": 'BRUSH_MULTIPLY', + "SUB": 'BRUSH_SUBTRACT' + }, + + 'TEXTURE_PAINT': { + "CLONE": 'BRUSH_CLONE', + "DRAW": 'BRUSH_TEXDRAW', + "FILL": 'BRUSH_TEXFILL', + "MASK": 'BRUSH_TEXMASK', + "SMEAR": 'BRUSH_SMEAR', + "SOFTEN": 'BRUSH_SOFTEN' + } +} + class BrushesMenu(Menu): bl_label = "Brush" bl_idname = "VIEW3D_MT_sv3_brushes_menu" - def init(self): - if utils_core.get_mode() == utils_core.sculpt: - datapath = "tool_settings.sculpt.brush" - icon = {"BLOB": 'BRUSH_BLOB', - "CLAY": 'BRUSH_CLAY', - "CLAY_STRIPS": 'BRUSH_CLAY_STRIPS', - "CREASE": 'BRUSH_CREASE', - "DRAW": 'BRUSH_SCULPT_DRAW', - "FILL": 'BRUSH_FILL', - "FLATTEN": 'BRUSH_FLATTEN', - "GRAB": 'BRUSH_GRAB', - "INFLATE": 'BRUSH_INFLATE', - "LAYER": 'BRUSH_LAYER', - "MASK": 'BRUSH_MASK', - "NUDGE": 'BRUSH_NUDGE', - "PINCH": 'BRUSH_PINCH', - "ROTATE": 'BRUSH_ROTATE', - "SCRAPE": 'BRUSH_SCRAPE', - "SIMPLIFY": 'BRUSH_SUBTRACT', - "SMOOTH": 'BRUSH_SMOOTH', - "SNAKE_HOOK": 'BRUSH_SNAKE_HOOK', - "THUMB": 'BRUSH_THUMB'} - elif utils_core.get_mode() == utils_core.vertex_paint: - datapath = "tool_settings.vertex_paint.brush" - icon = {"ADD": 'BRUSH_ADD', - "BLUR": 'BRUSH_BLUR', - "DARKEN": 'BRUSH_DARKEN', - "LIGHTEN": 'BRUSH_LIGHTEN', - "MIX": 'BRUSH_MIX', - "MUL": 'BRUSH_MULTIPLY', - "SUB": 'BRUSH_SUBTRACT'} - elif utils_core.get_mode() == utils_core.weight_paint: - datapath = "tool_settings.weight_paint.brush" - icon = {"ADD": 'BRUSH_ADD', - "BLUR": 'BRUSH_BLUR', - "DARKEN": 'BRUSH_DARKEN', - "LIGHTEN": 'BRUSH_LIGHTEN', - "MIX": 'BRUSH_MIX', - "MUL": 'BRUSH_MULTIPLY', - "SUB": 'BRUSH_SUBTRACT'} - elif utils_core.get_mode() == utils_core.texture_paint: - datapath = "tool_settings.image_paint.brush" - icon = {"CLONE": 'BRUSH_CLONE', - "DRAW": 'BRUSH_TEXDRAW', - "FILL": 'BRUSH_TEXFILL', - "MASK": 'BRUSH_TEXMASK', - "SMEAR": 'BRUSH_SMEAR', - "SOFTEN": 'BRUSH_SOFTEN'} - elif utils_core.get_mode() == utils_core.particle_edit: - datapath = "tool_settings.particle_edit.tool" - icon = None - else: - datapath = "" - - return datapath, icon - def draw(self, context): - datapath, icon = self.init() - menu = utils_core.Menu(self) + mode = utils_core.get_mode() + layout = self.layout settings = UnifiedPaintPanel.paint_settings(context) colum_n = utils_core.addon_settings(lists=False) - menu.add_item().label(text="Brush") - menu.add_item().separator() + layout.row().label(text="Brush") + layout.row().separator() has_brush = utils_core.get_brush_link(context, types="brush") - current_brush = eval("bpy.context.{}".format(datapath)) if has_brush else None + current_brush = eval("bpy.context.{}".format(brush_datapath[mode])) if has_brush else None # get the current brush's name - if current_brush and utils_core.get_mode() != utils_core.particle_edit: + if current_brush and utils_core.get_mode() != 'PARTICLE_EDIT': current_brush = current_brush.name - if utils_core.get_mode() == utils_core.particle_edit: - particle_tools = [["None", 'NONE'], - ["Comb", 'COMB'], - ["Smooth", 'SMOOTH'], - ["Add", 'ADD'], - ["Length", 'LENGTH'], - ["Puff", 'PUFF'], - ["Cut", 'CUT'], - ["Weight", 'WEIGHT']] - + if mode == 'PARTICLE_EDIT': # if you are in particle edit mode add the menu items for particle mode for tool in particle_tools: utils_core.menuprop( - menu.add_item(), tool[0], tool[1], datapath, + layout.row(), tool[0], tool[1], brush_datapath[mode], icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - column_flow = menu.add_item("column_flow", columns=colum_n) + column_flow = layout.column_flow(columns=colum_n) if utils_core.addon_settings(lists=True) == 'template': - self.layout.template_ID_preview(settings, "brush", - new="brush.add", rows=3, cols=colum_n) + layout.template_ID_preview(settings, "brush", + new="brush.add", rows=3, cols=colum_n) else: # iterate over all the brushes for item in bpy.data.brushes: - if utils_core.get_mode() == utils_core.sculpt: + if mode == 'SCULPT': if item.use_paint_sculpt: # if you are in sculpt mode and the brush # is a sculpt brush add the brush to the menu utils_core.menuprop( - menu.add_item(parent=column_flow), item.name, + column_flow.row(), item.name, 'bpy.data.brushes["%s"]' % item.name, - datapath, icon=icon[item.sculpt_tool], - disable=True, custom_disable_exp=[item.name, current_brush], + brush_datapath[mode], icon=brush_icon[mode][item.sculpt_tool], + disable=True, custom_disable_exp=(item.name, current_brush), path=True ) - if utils_core.get_mode() == utils_core.vertex_paint: + if mode == 'VERTEX_PAINT': if item.use_paint_vertex: # if you are in vertex paint mode and the brush # is a vertex paint brush add the brush to the menu utils_core.menuprop( - menu.add_item(parent=column_flow), item.name, + column_flow.row(), item.name, 'bpy.data.brushes["%s"]' % item.name, - datapath, icon=icon[item.vertex_tool], - disable=True, custom_disable_exp=[item.name, current_brush], + brush_datapath[mode], icon=brush_icon[mode][item.vertex_tool], + disable=True, custom_disable_exp=(item.name, current_brush), path=True ) - if utils_core.get_mode() == utils_core.weight_paint: + if mode == 'WEIGHT_PAINT': if item.use_paint_weight: # if you are in weight paint mode and the brush # is a weight paint brush add the brush to the menu utils_core.menuprop( - menu.add_item(parent=column_flow), item.name, + column_flow.row(), item.name, 'bpy.data.brushes["%s"]' % item.name, - datapath, icon=icon[item.vertex_tool], - disable=True, custom_disable_exp=[item.name, current_brush], + brush_datapath[mode], icon=brush_icon[mode][item.vertex_tool], + disable=True, custom_disable_exp=(item.name, current_brush), path=True ) - if utils_core.get_mode() == utils_core.texture_paint: + if utils_core.get_mode() == 'TEXTURE_PAINT': if item.use_paint_image: # if you are in texture paint mode and the brush # is a texture paint brush add the brush to the menu utils_core.menuprop( - menu.add_item(parent=column_flow), item.name, + column_flow.row(), item.name, 'bpy.data.brushes["%s"]' % item.name, - datapath, icon=icon[item.image_tool], - disable=True, custom_disable_exp=[item.name, current_brush], + brush_datapath[mode], icon=brush_icon[mode][item.image_tool], + disable=True, custom_disable_exp=(item.name, current_brush), path=True ) diff --git a/space_view3d_brush_menus/curve_menu.py b/space_view3d_brush_menus/curve_menu.py index 32d488bd..3c3282ec 100644 --- a/space_view3d_brush_menus/curve_menu.py +++ b/space_view3d_brush_menus/curve_menu.py @@ -14,27 +14,27 @@ class BrushCurveMenu(Menu): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, utils_core.vertex_paint, - utils_core.weight_paint, utils_core.texture_paint, - utils_core.particle_edit + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' ) def draw(self, context): - menu = utils_core.Menu(self) - curves = [["Smooth", "SMOOTH", "SMOOTHCURVE"], - ["Sphere", "ROUND", "SPHERECURVE"], - ["Root", "ROOT", "ROOTCURVE"], - ["Sharp", "SHARP", "SHARPCURVE"], - ["Linear", "LINE", "LINCURVE"], - ["Constant", "MAX", "NOCURVE"]] + layout = self.layout + curves = (("Smooth", "SMOOTH", "SMOOTHCURVE"), + ("Sphere", "ROUND", "SPHERECURVE"), + ("Root", "ROOT", "ROOTCURVE"), + ("Sharp", "SHARP", "SHARPCURVE"), + ("Linear", "LINE", "LINCURVE"), + ("Constant", "MAX", "NOCURVE")) # add the top slider - menu.add_item().operator(CurvePopup.bl_idname, icon="RNDCURVE") - menu.add_item().separator() + layout.row().operator(CurvePopup.bl_idname, icon="RNDCURVE") + layout.row().separator() # add the rest of the menu items for curve in curves: - item = menu.add_item().operator("brush.curve_preset", + item = layout.row().operator("brush.curve_preset", text=curve[0], icon=curve[2]) item.shape = curve[1] @@ -47,25 +47,25 @@ class CurvePopup(Operator): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, utils_core.vertex_paint, - utils_core.weight_paint, utils_core.texture_paint + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT' ) def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout has_brush = utils_core.get_brush_link(context, types="brush") - if utils_core.get_mode() == utils_core.sculpt or \ - utils_core.get_mode() == utils_core.vertex_paint or \ - utils_core.get_mode() == utils_core.weight_paint or \ - utils_core.get_mode() == utils_core.texture_paint: + if utils_core.get_mode() == 'SCULPT' or \ + utils_core.get_mode() == 'VERTEX_PAINT' or \ + utils_core.get_mode() == 'WEIGHT_PAINT' or \ + utils_core.get_mode() == 'TEXTURE_PAINT': if has_brush: - menu.add_item("column").template_curve_mapping(has_brush, + layout.column().template_curve_mapping(has_brush, "curve", brush=True) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") def execute(self, context): return context.window_manager.invoke_popup(self, width=180) diff --git a/space_view3d_brush_menus/dyntopo_menu.py b/space_view3d_brush_menus/dyntopo_menu.py index bab317f6..acc216d0 100644 --- a/space_view3d_brush_menus/dyntopo_menu.py +++ b/space_view3d_brush_menus/dyntopo_menu.py @@ -11,34 +11,34 @@ class DynTopoMenu(Menu): @classmethod def poll(self, context): - return utils_core.get_mode() == utils_core.sculpt + return utils_core.get_mode() == 'SCULPT' def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout if context.object.use_dynamic_topology_sculpting: - menu.add_item().operator("sculpt.dynamic_topology_toggle", + layout.row().operator("sculpt.dynamic_topology_toggle", "Disable Dynamic Topology") - menu.add_item().separator() + layout.row().separator() - menu.add_item().menu(DynDetailMenu.bl_idname) - menu.add_item().menu(DetailMethodMenu.bl_idname) + layout.row().menu(DynDetailMenu.bl_idname) + layout.row().menu(DetailMethodMenu.bl_idname) - menu.add_item().separator() + layout.row().separator() - menu.add_item().operator("sculpt.optimize") + layout.row().operator("sculpt.optimize") if context.tool_settings.sculpt.detail_type_method == 'CONSTANT': - menu.add_item().operator("sculpt.detail_flood_fill") + layout.row().operator("sculpt.detail_flood_fill") - menu.add_item().menu(SymmetrizeMenu.bl_idname) - menu.add_item().prop(context.tool_settings.sculpt, + layout.row().menu(SymmetrizeMenu.bl_idname) + layout.row().prop(context.tool_settings.sculpt, "use_smooth_shading", toggle=True) else: - menu.add_item() - menu.current_item.operator_context = 'INVOKE_DEFAULT' - menu.current_item.operator("sculpt.dynamic_topology_toggle", + row = layout.row() + row.operator_context = 'INVOKE_DEFAULT' + row.operator("sculpt.dynamic_topology_toggle", "Enable Dynamic Topology") @@ -47,8 +47,12 @@ class DynDetailMenu(Menu): bl_idname = "VIEW3D_MT_sv3_dyn_detail" def init(self): - settings = [["40", 40], ["30", 30], ["20", 20], - ["10", 10], ["5", 5], ["1", 1]] + settings = (("40", 40), + ("30", 30), + ("20", 20), + ("10", 10), + ("5", 5), + ("1", 1)) if bpy.context.tool_settings.sculpt.detail_type_method == 'RELATIVE': datapath = "tool_settings.sculpt.detail_size" @@ -62,17 +66,17 @@ class DynDetailMenu(Menu): def draw(self, context): settings, datapath, slider_setting = self.init() - menu = utils_core.Menu(self) + layout = self.layout # add the top slider - menu.add_item().prop(context.tool_settings.sculpt, + layout.row().prop(context.tool_settings.sculpt, slider_setting, slider=True) - menu.add_item().separator() + layout.row().separator() # add the rest of the menu items for i in range(len(settings)): utils_core.menuprop( - menu.add_item(), settings[i][0], settings[i][1], datapath, + layout.row(), settings[i][0], settings[i][1], datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) @@ -83,38 +87,38 @@ class DetailMethodMenu(Menu): bl_idname = "VIEW3D_MT_sv3_detail_method_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout refine_path = "tool_settings.sculpt.detail_refine_method" type_path = "tool_settings.sculpt.detail_type_method" - refine_items = [["Subdivide Edges", 'SUBDIVIDE'], - ["Collapse Edges", 'COLLAPSE'], - ["Subdivide Collapse", 'SUBDIVIDE_COLLAPSE']] + refine_items = (("Subdivide Edges", 'SUBDIVIDE'), + ("Collapse Edges", 'COLLAPSE'), + ("Subdivide Collapse", 'SUBDIVIDE_COLLAPSE')) - type_items = [["Relative Detail", 'RELATIVE'], - ["Constant Detail", 'CONSTANT']] + type_items = (("Relative Detail", 'RELATIVE'), + ("Constant Detail", 'CONSTANT')) - menu.add_item().label("Refine") - menu.add_item().separator() + layout.row().label("Refine") + layout.row().separator() # add the refine menu items for item in refine_items: utils_core.menuprop( - menu.add_item(), item[0], item[1], + layout.row(), item[0], item[1], refine_path, disable=True, icon='RADIOBUT_OFF', disable_icon='RADIOBUT_ON' ) - menu.add_item().label("") + layout.row().label("") - menu.add_item().label("Type") - menu.add_item().separator() + layout.row().label("Type") + layout.row().separator() # add the type menu items for item in type_items: utils_core.menuprop( - menu.add_item(), item[0], item[1], + layout.row(), item[0], item[1], type_path, disable=True, icon='RADIOBUT_OFF', disable_icon='RADIOBUT_ON' ) @@ -125,18 +129,18 @@ class SymmetrizeMenu(Menu): bl_idname = "VIEW3D_MT_sv3_symmetrize_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout path = "tool_settings.sculpt.symmetrize_direction" # add the the symmetrize operator to the menu - menu.add_item().operator("sculpt.symmetrize") - menu.add_item().separator() + layout.row().operator("sculpt.symmetrize") + layout.row().separator() # add the rest of the menu items for item in context.tool_settings.sculpt. \ bl_rna.properties['symmetrize_direction'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, + layout.row(), item.name, item.identifier, path, disable=True, icon='RADIOBUT_OFF', disable_icon='RADIOBUT_ON' ) diff --git a/space_view3d_brush_menus/stroke_menu.py b/space_view3d_brush_menus/stroke_menu.py index c2163999..258056e7 100644 --- a/space_view3d_brush_menus/stroke_menu.py +++ b/space_view3d_brush_menus/stroke_menu.py @@ -3,15 +3,45 @@ import bpy from bpy.types import Menu from . import utils_core +from .brushes import brush_datapath -airbrush = 'AIRBRUSH' -anchored = 'ANCHORED' -space = 'SPACE' -drag_dot = 'DRAG_DOT' -dots = 'DOTS' -line = 'LINE' -curve = 'CURVE' +# stroke methods: 'AIRBRUSH' 'ANCHORED' 'SPACE' 'DRAG_DOT' 'DOTS' 'LINE' 'CURVE' +class PaintCurvesMenu(Menu): + bl_label = "Paint Curves" + bl_idname = "VIEW3D_MT_sv3_paint_curves_menu" + + def draw(self, context): + mode = utils_core.get_mode() + layout = self.layout + colum_n = utils_core.addon_settings(lists=False) + + layout.row().label(text="Paint Curves") + layout.row().separator() + + has_brush = utils_core.get_brush_link(context, types="brush") + + has_current_curve = has_brush.paint_curve if has_brush else None + current_curve = has_current_curve.name if has_current_curve else '' + + column_flow = layout.column_flow(columns=colum_n) + + if len(bpy.data.paint_curves) != 0: + for x, item in enumerate(bpy.data.paint_curves): + utils_core.menuprop( + column_flow.row(), + item.name, + 'bpy.data.paint_curves["%s"]' % item.name, + brush_datapath[mode] + ".paint_curve", + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON', + custom_disable_exp=(item.name, current_curve), + path=True + ) + + else: + layout.row().label("No Paint Curves Available", icon="INFO") class StrokeOptionsMenu(Menu): bl_label = "Stroke Options" @@ -20,21 +50,27 @@ class StrokeOptionsMenu(Menu): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, utils_core.vertex_paint, - utils_core.weight_paint, utils_core.texture_paint, - utils_core.particle_edit + 'SCULPT', 'VERTEX_PAINT', + 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'PARTICLE_EDIT' ) def init(self): has_brush = utils_core.get_brush_link(bpy.context, types="brush") - if utils_core.get_mode() == utils_core.sculpt: + if utils_core.get_mode() == 'SCULPT': settings = bpy.context.tool_settings.sculpt - elif utils_core.get_mode() == utils_core.texture_paint: + elif utils_core.get_mode() == 'VERTEX_PAINT': + settings = bpy.context.tool_settings.vertex_paint + + elif utils_core.get_mode() == 'WEIGHT_PAINT': + settings = bpy.context.tool_settings.weight_paint + + elif utils_core.get_mode() == 'TEXTURE_PAINT': settings = bpy.context.tool_settings.image_paint else: - settings = bpy.context.tool_settings.vertex_paint + settings = None stroke_method = has_brush.stroke_method if has_brush else None @@ -42,48 +78,64 @@ class StrokeOptionsMenu(Menu): def draw(self, context): settings, brush, stroke_method = self.init() - menu = utils_core.Menu(self) + layout = self.layout - menu.add_item().menu(StrokeMethodMenu.bl_idname) - menu.add_item().separator() + layout.row().menu(StrokeMethodMenu.bl_idname) + layout.row().separator() if stroke_method: - if stroke_method == space and brush: - menu.add_item().prop(brush, "spacing", + + if stroke_method in ('SPACE', 'LINE') and brush: + layout.row().prop(brush, "spacing", text=utils_core.PIW + "Spacing", slider=True) - elif stroke_method == airbrush and brush: - menu.add_item().prop(brush, "rate", + elif stroke_method == 'AIRBRUSH' and brush: + layout.row().prop(brush, "rate", text=utils_core.PIW + "Rate", slider=True) - elif stroke_method == anchored and brush: - menu.add_item().prop(brush, "use_edge_to_edge") + elif stroke_method == 'ANCHORED' and brush: + layout.row().prop(brush, "use_edge_to_edge") + + elif stroke_method == 'CURVE' and brush: + has_current_curve = brush.paint_curve if brush else None + current_curve = has_current_curve.name if has_current_curve else 'No Curve Selected' + + layout.row().menu(PaintCurvesMenu.bl_idname, text=current_curve, + icon='CURVE_BEZCURVE') + layout.row().operator("paintcurve.new", icon='ZOOMIN') + layout.row().operator("paintcurve.draw") + + layout.row().separator() + + layout.row().prop(brush, "spacing", + text=utils_core.PIW + "Spacing", + slider=True) else: pass - if utils_core.get_mode() == utils_core.sculpt and stroke_method in (drag_dot, anchored): + if utils_core.get_mode() == 'SCULPT' and stroke_method in ('DRAG_DOT', 'ANCHORED'): pass else: if brush: - menu.add_item().prop(brush, "jitter", - text=utils_core.PIW + "Jitter", slider=True) + layout.row().prop(brush, "jitter", + text=utils_core.PIW + "Jitter", slider=True) - menu.add_item().prop(settings, "input_samples", - text=utils_core.PIW + "Input Samples", slider=True) + layout.row().prop(settings, "input_samples", + text=utils_core.PIW + "Input Samples", slider=True) - if stroke_method in [dots, space, airbrush] and brush: - menu.add_item().separator() + if stroke_method in ('DOTS', 'SPACE', 'AIRBRUSH') and brush: + layout.row().separator() - menu.add_item().prop(brush, "use_smooth_stroke", toggle=True) + layout.row().prop(brush, "use_smooth_stroke", toggle=True) if brush.use_smooth_stroke: - menu.add_item().prop(brush, "smooth_stroke_radius", - text=utils_core.PIW + "Radius", slider=True) - menu.add_item().prop(brush, "smooth_stroke_factor", - text=utils_core.PIW + "Factor", slider=True) + layout.row().prop(brush, "smooth_stroke_radius", + text=utils_core.PIW + "Radius", slider=True) + layout.row().prop(brush, "smooth_stroke_factor", + text=utils_core.PIW + "Factor", slider=True) else: - menu.add_item().label("No Stroke Options available", icon="INFO") + layout.row().label("No Stroke Options available", icon="INFO") class StrokeMethodMenu(Menu): @@ -92,36 +144,42 @@ class StrokeMethodMenu(Menu): def init(self): has_brush = utils_core.get_brush_link(bpy.context, types="brush") - if utils_core.get_mode() == utils_core.sculpt: + if utils_core.get_mode() == 'SCULPT': path = "tool_settings.sculpt.brush.stroke_method" - elif utils_core.get_mode() == utils_core.texture_paint: + elif utils_core.get_mode() == 'VERTEX_PAINT': + path = "tool_settings.vertex_paint.brush.stroke_method" + + elif utils_core.get_mode() == 'WEIGHT_PAINT': + path = "tool_settings.weight_paint.brush.stroke_method" + + elif utils_core.get_mode() == 'TEXTURE_PAINT': path = "tool_settings.image_paint.brush.stroke_method" else: - path = "tool_settings.vertex_paint.brush.stroke_method" + path = "" return has_brush, path def draw(self, context): brush, path = self.init() - menu = utils_core.Menu(self) + layout = self.layout - menu.add_item().label(text="Stroke Method") - menu.add_item().separator() + layout.row().label(text="Stroke Method") + layout.row().separator() if brush: # add the menu items dynamicaly based on values in enum property for tool in brush.bl_rna.properties['stroke_method'].enum_items: - if tool.identifier in [anchored, drag_dot] and \ - utils_core.get_mode() in [utils_core.vertex_paint, - utils_core.weight_paint]: + if tool.identifier in ('ANCHORED', 'DRAG_DOT') and \ + utils_core.get_mode() in ('VERTEX_PAINT', + 'WEIGHT_PAINT'): continue utils_core.menuprop( - menu.add_item(), tool.name, tool.identifier, path, + layout.row(), tool.name, tool.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No Stroke Method available", icon="INFO") + layout.row().label("No Stroke Method available", icon="INFO") diff --git a/space_view3d_brush_menus/symmetry_menu.py b/space_view3d_brush_menus/symmetry_menu.py index 6762ddb6..d0c5023c 100644 --- a/space_view3d_brush_menus/symmetry_menu.py +++ b/space_view3d_brush_menus/symmetry_menu.py @@ -11,25 +11,25 @@ class MasterSymmetryMenu(Menu): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, - utils_core.texture_paint + 'SCULPT', + 'TEXTURE_PAINT' ) def draw(self, context): - menu = utils_core.Menu(self) - - if utils_core.get_mode() == utils_core.texture_paint: - menu.add_item().prop(context.tool_settings.image_paint, - "use_symmetry_x", toggle=True) - menu.add_item().prop(context.tool_settings.image_paint, - "use_symmetry_y", toggle=True) - menu.add_item().prop(context.tool_settings.image_paint, - "use_symmetry_z", toggle=True) + layout = self.layout + + if utils_core.get_mode() == 'TEXTURE_PAINT': + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_x", toggle=True) + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_y", toggle=True) + layout.row().prop(context.tool_settings.image_paint, + "use_symmetry_z", toggle=True) else: - menu.add_item().menu(SymmetryMenu.bl_idname) - menu.add_item().menu(SymmetryRadialMenu.bl_idname) - menu.add_item().prop(context.tool_settings.sculpt, - "use_symmetry_feather", toggle=True) + layout.row().menu(SymmetryMenu.bl_idname) + layout.row().menu(SymmetryRadialMenu.bl_idname) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_feather", toggle=True) class SymmetryMenu(Menu): @@ -37,17 +37,17 @@ class SymmetryMenu(Menu): bl_idname = "VIEW3D_MT_sv3_symmetry_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout - menu.add_item().label(text="Symmetry") - menu.add_item().separator() + layout.row().label(text="Symmetry") + layout.row().separator() - menu.add_item().prop(context.tool_settings.sculpt, - "use_symmetry_x", toggle=True) - menu.add_item().prop(context.tool_settings.sculpt, - "use_symmetry_y", toggle=True) - menu.add_item().prop(context.tool_settings.sculpt, - "use_symmetry_z", toggle=True) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_x", toggle=True) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_y", toggle=True) + layout.row().prop(context.tool_settings.sculpt, + "use_symmetry_z", toggle=True) class SymmetryRadialMenu(Menu): @@ -55,10 +55,10 @@ class SymmetryRadialMenu(Menu): bl_idname = "VIEW3D_MT_sv3_symmetry_radial_menu" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout - menu.add_item().label(text="Radial") - menu.add_item().separator() + layout.row().label(text="Radial") + layout.row().separator() - menu.add_item("column").prop(context.tool_settings.sculpt, - "radial_symmetry", text="", slider=True) + layout.column().prop(context.tool_settings.sculpt, + "radial_symmetry", text="", slider=True) diff --git a/space_view3d_brush_menus/texture_menu.py b/space_view3d_brush_menus/texture_menu.py index d961410b..31125bbb 100644 --- a/space_view3d_brush_menus/texture_menu.py +++ b/space_view3d_brush_menus/texture_menu.py @@ -12,142 +12,161 @@ class TextureMenu(Menu): @classmethod def poll(self, context): return utils_core.get_mode() in ( - utils_core.sculpt, - utils_core.vertex_paint, - utils_core.texture_paint + 'SCULPT', + 'VERTEX_PAINT', + 'TEXTURE_PAINT' ) def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout - if utils_core.get_mode() == utils_core.sculpt: - self.sculpt(menu, context) + if utils_core.get_mode() == 'SCULPT': + self.sculpt(layout, context) - elif utils_core.get_mode() == utils_core.vertex_paint: - self.vertpaint(menu, context) + elif utils_core.get_mode() == 'VERTEX_PAINT': + self.vertpaint(layout, context) else: - self.texpaint(menu, context) + self.texpaint(layout, context) - def sculpt(self, menu, context): + def sculpt(self, layout, context): has_brush = utils_core.get_brush_link(context, types="brush") tex_slot = has_brush.texture_slot if has_brush else None # Menus - menu.add_item().menu(Textures.bl_idname) - menu.add_item().menu(TextureMapMode.bl_idname) - menu.add_item().separator() + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) + layout.row().separator() # Checkboxes if tex_slot: if tex_slot.map_mode != '3D': - if tex_slot.map_mode in ['RANDOM', 'VIEW_PLANE', 'AREA_PLANE']: - menu.add_item().prop(tex_slot, "use_rake", toggle=True) - menu.add_item().prop(tex_slot, "use_random", toggle=True) + if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE', 'AREA_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) # Sliders - menu.add_item().prop(tex_slot, "angle", - text=utils_core.PIW + "Angle", slider=True) + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) - if tex_slot.tex_paint_map_mode in ['RANDOM', 'VIEW_PLANE'] and tex_slot.use_random: - menu.add_item().prop(tex_slot, "random_angle", - text=utils_core.PIW + "Random Angle", slider=True) + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) # Operator if tex_slot.tex_paint_map_mode == 'STENCIL': - menu.add_item().operator("brush.stencil_reset_transform") + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + layout.row().operator("brush.stencil_reset_transform") + else: - menu.add_item().label("No Texture Slot available", icon="INFO") + layout.row().label("No Texture Slot available", icon="INFO") - def vertpaint(self, menu, context): + def vertpaint(self, layout, context): has_brush = utils_core.get_brush_link(context, types="brush") tex_slot = has_brush.texture_slot if has_brush else None # Menus - menu.add_item().menu(Textures.bl_idname) - menu.add_item().menu(TextureMapMode.bl_idname) + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) # Checkboxes - if tex_slot and tex_slot.tex_paint_map_mode != '3D': + if tex_slot: + if tex_slot.tex_paint_map_mode != '3D': + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) - if tex_slot.tex_paint_map_mode in ['RANDOM', 'VIEW_PLANE']: - menu.add_item().prop(tex_slot, "use_rake", toggle=True) - menu.add_item().prop(tex_slot, "use_random", toggle=True) + # Sliders + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) - # Sliders - menu.add_item().prop(tex_slot, "angle", - text=utils_core.PIW + "Angle", slider=True) + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) - if tex_slot.tex_paint_map_mode in ['RANDOM', 'VIEW_PLANE'] and tex_slot.use_random: - menu.add_item().prop(tex_slot, "random_angle", - text=utils_core.PIW + "Random Angle", slider=True) + # Operator + if tex_slot.tex_paint_map_mode == 'STENCIL': + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + layout.row().operator("brush.stencil_reset_transform") - # Operator - if tex_slot.tex_paint_map_mode == 'STENCIL': - menu.add_item().operator("brush.stencil_reset_transform") else: - menu.add_item().label("No Texture Slot available", icon="INFO") + layout.row().label("No Texture Slot available", icon="INFO") - def texpaint(self, menu, context): + def texpaint(self, layout, context): has_brush = utils_core.get_brush_link(context, types="brush") tex_slot = has_brush.texture_slot if has_brush else None mask_tex_slot = has_brush.mask_texture_slot if has_brush else None # Texture Section - menu.add_item().label(text="Texture", icon='TEXTURE') + layout.row().label(text="Texture", icon='TEXTURE') # Menus - menu.add_item().menu(Textures.bl_idname) - menu.add_item().menu(TextureMapMode.bl_idname) + layout.row().menu(Textures.bl_idname) + layout.row().menu(TextureMapMode.bl_idname) # Checkboxes - if tex_slot and tex_slot.tex_paint_map_mode != '3D': - if tex_slot.tex_paint_map_mode in ['RANDOM', 'VIEW_PLANE']: - menu.add_item().prop(tex_slot, "use_rake", toggle=True) - menu.add_item().prop(tex_slot, "use_random", toggle=True) + if tex_slot: + if tex_slot.tex_paint_map_mode != '3D': + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(tex_slot, "use_rake", toggle=True) + layout.row().prop(tex_slot, "use_random", toggle=True) - # Sliders - menu.add_item().prop(tex_slot, "angle", - text=utils_core.PIW + "Angle", slider=True) + # Sliders + layout.row().prop(tex_slot, "angle", + text=utils_core.PIW + "Angle", slider=True) - if tex_slot.tex_paint_map_mode in ['RANDOM', 'VIEW_PLANE'] and tex_slot.use_random: - menu.add_item().prop(tex_slot, "random_angle", - text=utils_core.PIW + "Random Angle", slider=True) + if tex_slot.tex_paint_map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random: + layout.row().prop(tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) - # Operator - if tex_slot.tex_paint_map_mode == 'STENCIL': - menu.add_item().operator("brush.stencil_reset_transform") + # Operator + if tex_slot.tex_paint_map_mode == 'STENCIL': + if has_brush.texture and has_brush.texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") - menu.add_item().separator() + layout.row().operator("brush.stencil_reset_transform") + + else: + layout.row().label("No Texture Slot available", icon="INFO") + + layout.row().separator() # Texture Mask Section - menu.add_item().label(text="Texture Mask", icon='MOD_MASK') + layout.row().label(text="Texture Mask", icon='MOD_MASK') # Menus - menu.add_item().menu(MaskTextures.bl_idname) - menu.add_item().menu(MaskMapMode.bl_idname) + layout.row().menu(MaskTextures.bl_idname) + layout.row().menu(MaskMapMode.bl_idname) + layout.row().menu(MaskPressureModeMenu.bl_idname) # Checkboxes if mask_tex_slot: - if mask_tex_slot.mask_map_mode in ['RANDOM', 'VIEW_PLANE']: - menu.add_item().prop(mask_tex_slot, "use_rake", toggle=True) - menu.add_item().prop(mask_tex_slot, "use_random", toggle=True) + if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE'): + layout.row().prop(mask_tex_slot, "use_rake", toggle=True) + layout.row().prop(mask_tex_slot, "use_random", toggle=True) # Sliders - menu.add_item().prop(mask_tex_slot, "angle", - text=utils_core.PIW + "Angle", icon_value=5, slider=True) + layout.row().prop(mask_tex_slot, "angle", + text=utils_core.PIW + "Angle", icon_value=5, slider=True) - if mask_tex_slot.mask_map_mode in ['RANDOM', 'VIEW_PLANE'] and \ - mask_tex_slot.use_random: - menu.add_item().prop(mask_tex_slot, "random_angle", - text=utils_core.PIW + "Random Angle", slider=True) + if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE') and mask_tex_slot.use_random: + layout.row().prop(mask_tex_slot, "random_angle", + text=utils_core.PIW + "Random Angle", slider=True) # Operator if mask_tex_slot.mask_map_mode == 'STENCIL': - prop = menu.add_item().operator("brush.stencil_reset_transform") + if has_brush.mask_texture and has_brush.mask_texture.type == 'IMAGE': + layout.row().operator("brush.stencil_fit_image_aspect") + + prop = layout.row().operator("brush.stencil_reset_transform") prop.mask = True + else: - menu.add_item().label("Mask Texture not available", icon="INFO") + layout.row().label("Mask Texture not available", icon="INFO") class Textures(Menu): @@ -155,13 +174,13 @@ class Textures(Menu): bl_idname = "VIEW3D_MT_sv3_texture_list" def init(self): - if utils_core.get_mode() == utils_core.sculpt: + if utils_core.get_mode() == 'SCULPT': datapath = "tool_settings.sculpt.brush.texture" - elif utils_core.get_mode() == utils_core.vertex_paint: + elif utils_core.get_mode() == 'VERTEX_PAINT': datapath = "tool_settings.vertex_paint.brush.texture" - elif utils_core.get_mode() == utils_core.texture_paint: + elif utils_core.get_mode() == 'TEXTURE_PAINT': datapath = "tool_settings.image_paint.brush.texture" else: @@ -174,30 +193,30 @@ class Textures(Menu): has_brush = utils_core.get_brush_link(context, types="brush") current_texture = eval("bpy.context.{}".format(datapath)) if \ has_brush else None - menu = utils_core.Menu(self) + layout = self.layout # get the current texture's name if current_texture: current_texture = current_texture.name - menu.add_item().label(text="Brush Texture") - menu.add_item().separator() + layout.row().label(text="Brush Texture") + layout.row().separator() # add an item to set the texture to None - utils_core.menuprop(menu.add_item(), "None", "None", + utils_core.menuprop(layout.row(), "None", "None", datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON', - custom_disable_exp=[None, current_texture], + custom_disable_exp=(None, current_texture), path=True) # add the menu items for item in bpy.data.textures: - utils_core.menuprop(menu.add_item(), item.name, + utils_core.menuprop(layout.row(), item.name, 'bpy.data.textures["%s"]' % item.name, datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON', - custom_disable_exp=[item.name, current_texture], + custom_disable_exp=(item.name, current_texture), path=True) @@ -206,33 +225,33 @@ class TextureMapMode(Menu): bl_idname = "VIEW3D_MT_sv3_texture_map_mode" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout has_brush = utils_core.get_brush_link(context, types="brush") - menu.add_item().label(text="Brush Mapping") - menu.add_item().separator() + layout.row().label(text="Brush Mapping") + layout.row().separator() if has_brush: - if utils_core.get_mode() == utils_core.sculpt: + if utils_core.get_mode() == 'SCULPT': path = "tool_settings.sculpt.brush.texture_slot.map_mode" # add the menu items for item in has_brush. \ texture_slot.bl_rna.properties['map_mode'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) - elif utils_core.get_mode() == utils_core.vertex_paint: + elif utils_core.get_mode() == 'VERTEX_PAINT': path = "tool_settings.vertex_paint.brush.texture_slot.tex_paint_map_mode" # add the menu items for item in has_brush. \ texture_slot.bl_rna.properties['tex_paint_map_mode'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' @@ -244,13 +263,13 @@ class TextureMapMode(Menu): for item in has_brush. \ texture_slot.bl_rna.properties['tex_paint_map_mode'].enum_items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") class MaskTextures(Menu): @@ -258,14 +277,14 @@ class MaskTextures(Menu): bl_idname = "VIEW3D_MT_sv3_mask_texture_list" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout datapath = "tool_settings.image_paint.brush.mask_texture" has_brush = utils_core.get_brush_link(context, types="brush") current_texture = eval("bpy.context.{}".format(datapath)) if \ has_brush else None - menu.add_item().label(text="Mask Texture") - menu.add_item().separator() + layout.row().label(text="Mask Texture") + layout.row().separator() if has_brush: # get the current texture's name @@ -274,24 +293,24 @@ class MaskTextures(Menu): # add an item to set the texture to None utils_core.menuprop( - menu.add_item(), "None", "None", + layout.row(), "None", "None", datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON', - custom_disable_exp=[None, current_texture], + custom_disable_exp=(None, current_texture), path=True ) # add the menu items for item in bpy.data.textures: utils_core.menuprop( - menu.add_item(), item.name, 'bpy.data.textures["%s"]' % item.name, + layout.row(), item.name, 'bpy.data.textures["%s"]' % item.name, datapath, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON', - custom_disable_exp=[item.name, current_texture], + custom_disable_exp=(item.name, current_texture), path=True ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") class MaskMapMode(Menu): @@ -299,25 +318,25 @@ class MaskMapMode(Menu): bl_idname = "VIEW3D_MT_sv3_mask_map_mode" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout path = "tool_settings.image_paint.brush.mask_texture_slot.mask_map_mode" has_brush = utils_core.get_brush_link(context, types="brush") - menu.add_item().label(text="Mask Mapping") - menu.add_item().separator() + layout.row().label(text="Mask Mapping") + layout.row().separator() if has_brush: items = has_brush. \ mask_texture_slot.bl_rna.properties['mask_map_mode'].enum_items # add the menu items for item in items: utils_core.menuprop( - menu.add_item(), item.name, item.identifier, path, + layout.row(), item.name, item.identifier, path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") class TextureAngleSource(Menu): @@ -325,16 +344,16 @@ class TextureAngleSource(Menu): bl_idname = "VIEW3D_MT_sv3_texture_angle_source" def draw(self, context): - menu = utils_core.Menu(self) + layout = self.layout has_brush = utils_core.get_brush_link(context, types="brush") if has_brush: - if utils_core.get_mode() == utils_core.sculpt: + if utils_core.get_mode() == 'SCULPT': items = has_brush. \ bl_rna.properties['texture_angle_source_random'].enum_items path = "tool_settings.sculpt.brush.texture_angle_source_random" - elif utils_core.get_mode() == utils_core.vertex_paint: + elif utils_core.get_mode() == 'VERTEX_PAINT': items = has_brush. \ bl_rna.properties['texture_angle_source_random'].enum_items path = "tool_settings.vertex_paint.brush.texture_angle_source_random" @@ -347,10 +366,32 @@ class TextureAngleSource(Menu): # add the menu items for item in items: utils_core.menuprop( - menu.add_item(), item[0], item[1], path, + layout.row(), item[0], item[1], path, icon='RADIOBUT_OFF', disable=True, disable_icon='RADIOBUT_ON' ) else: - menu.add_item().label("No brushes available", icon="INFO") + layout.row().label("No brushes available", icon="INFO") + +class MaskPressureModeMenu(Menu): + bl_label = "Mask Pressure Mode" + bl_idname = "VIEW3D_MT_sv3_mask_pressure_mode_menu" + + def draw(self, context): + layout = self.layout + path = "tool_settings.image_paint.brush.use_pressure_masking" + + layout.row().label(text="Mask Pressure Mode") + layout.row().separator() + + # add the menu items + for item in context.tool_settings.image_paint.brush. \ + bl_rna.properties['use_pressure_masking'].enum_items: + utils_core.menuprop( + layout.row(), item.name, item.identifier, path, + icon='RADIOBUT_OFF', + disable=True, + disable_icon='RADIOBUT_ON' + ) + diff --git a/space_view3d_brush_menus/utils_core.py b/space_view3d_brush_menus/utils_core.py index ecac6073..dd9448a1 100644 --- a/space_view3d_brush_menus/utils_core.py +++ b/space_view3d_brush_menus/utils_core.py @@ -2,17 +2,9 @@ import bpy -object_mode = 'OBJECT' -edit = 'EDIT' -sculpt = 'SCULPT' -vertex_paint = 'VERTEX_PAINT' -weight_paint = 'WEIGHT_PAINT' -texture_paint = 'TEXTURE_PAINT' -particle_edit = 'PARTICLE_EDIT' -pose = 'POSE' -gpencil_edit = 'GPENCIL_EDIT' get_addon_name = 'space_view3d_brush_menus' +# Property Icon Width PIW = ' ' @@ -21,16 +13,16 @@ def get_brush_link(context, types="brush"): tool_settings = context.tool_settings has_brush = None - if get_mode() == sculpt: + if get_mode() == 'SCULPT': datapath = tool_settings.sculpt - elif get_mode() == vertex_paint: + elif get_mode() == 'VERTEX_PAINT': datapath = tool_settings.vertex_paint - elif get_mode() == weight_paint: + elif get_mode() == 'WEIGHT_PAINT': datapath = tool_settings.weight_paint - elif get_mode() == texture_paint: + elif get_mode() == 'TEXTURE_PAINT': datapath = tool_settings.image_paint else: datapath = None @@ -59,58 +51,16 @@ def error_handlers(self, op_name, error, reports="ERROR", func=False): print("\n[Sculpt/Paint Brush Menus]\n{}: {}\nError: {}\n".format(is_func, op_name, error)) -class Menu(): - def __init__(self, menu): - self.layout = menu.layout - self.items = {} - self.current_item = None - - def add_item(self, ui_type="row", parent=None, name=None, **kwargs): - # set the parent layout - if parent: - layout = parent - else: - layout = self.layout - - # set unique identifier for new items - if not name: - name = len(self.items) + 1 - - # create and return a ui layout - if ui_type == "row": - self.current_item = self.items[name] = layout.row(**kwargs) - - return self.current_item - - elif ui_type == "column": - self.current_item = self.items[name] = layout.column(**kwargs) - - return self.current_item - - elif ui_type == "column_flow": - self.current_item = self.items[name] = layout.column_flow(**kwargs) - - return self.current_item - - elif ui_type == "box": - self.current_item = self.items[name] = layout.box(**kwargs) - - return self.current_item - - elif ui_type == "split": - self.current_item = self.items[name] = layout.split(**kwargs) - - return self.current_item - else: - print("Unknown Type") - - +# Object modes: +# 'OBJECT' 'EDIT' 'SCULPT' +# 'VERTEX_PAINT' 'WEIGHT_PAINT' 'TEXTURE_PAINT' +# 'PARTICLE_EDIT' 'POSE' 'GPENCIL_EDIT' def get_mode(): try: if bpy.context.gpencil_data and \ - bpy.context.object.mode == object_mode and \ + bpy.context.object.mode == 'OBJECT' and \ bpy.context.scene.grease_pencil.use_stroke_edit_mode: - return gpencil_edit + return 'GPENCIL_EDIT' else: return bpy.context.object.mode except: -- cgit v1.2.3