blender-addons/materials_utils/menus.py
Campbell Barton e8da6131fd License headers: use SPDX-FileCopyrightText for all addons
Move copyright text to SPDX-FileCopyrightText or set to the
Blender Foundation so "make check_licenses" now runs without warnings.
2023-06-15 16:54:05 +10:00

283 lines
10 KiB
Python

# SPDX-FileCopyrightText: 2019-2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from .functions import *
from .operators import *
from .preferences import *
# -----------------------------------------------------------------------------
# menu classes
class VIEW3D_MT_materialutilities_assign_material(bpy.types.Menu):
"""Menu for choosing which material should be assigned to current selection"""
# The menu is filled programmatically with available materials
bl_idname = "VIEW3D_MT_materialutilities_assign_material"
bl_label = "Assign Material"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
edit_mode = False
materials = bpy.data.materials.items()
bl_id = VIEW3D_OT_materialutilities_assign_material_object.bl_idname
obj = context.object
mu_prefs = materialutilities_get_preferences(context)
if (not obj is None) and obj.mode == 'EDIT':
bl_id = VIEW3D_OT_materialutilities_assign_material_edit.bl_idname
edit_mode = True
if len(materials) > mu_prefs.search_show_limit:
op = layout.operator(bl_id,
text = 'Search',
icon = 'VIEWZOOM')
op.material_name = ""
op.new_material = False
op.show_dialog = True
if not edit_mode:
op.override_type = mu_prefs.override_type
op = layout.operator(bl_id,
text = "Add New Material",
icon = 'ADD')
op.material_name = mu_new_material_name(mu_prefs.new_material_name)
op.new_material = True
op.show_dialog = True
if not edit_mode:
op.override_type = mu_prefs.override_type
layout.separator()
for material_name, material in materials:
op = layout.operator(bl_id,
text = material_name,
icon_value = material.preview.icon_id)
op.material_name = material_name
op.new_material = False
op.show_dialog = False
if not edit_mode:
op.override_type = mu_prefs.override_type
class VIEW3D_MT_materialutilities_clean_slots(bpy.types.Menu):
"""Menu for cleaning up the material slots"""
bl_idname = "VIEW3D_MT_materialutilities_clean_slots"
bl_label = "Clean Slots"
def draw(self, context):
layout = self.layout
layout.label
layout.operator(VIEW3D_OT_materialutilities_clean_material_slots.bl_idname,
text = "Clean Material Slots",
icon = 'X')
layout.separator()
layout.operator(VIEW3D_OT_materialutilities_remove_material_slot.bl_idname,
text = "Remove Active Material Slot",
icon = 'REMOVE')
layout.operator(VIEW3D_OT_materialutilities_remove_all_material_slots.bl_idname,
text = "Remove All Material Slots",
icon = 'CANCEL')
class VIEW3D_MT_materialutilities_select_by_material(bpy.types.Menu):
"""Menu for choosing which material should be used for selection"""
# The menu is filled programmatically with available materials
bl_idname = "VIEW3D_MT_materialutilities_select_by_material"
bl_label = "Select by Material"
def draw(self, context):
layout = self.layout
bl_id = VIEW3D_OT_materialutilities_select_by_material_name.bl_idname
obj = context.object
mu_prefs = materialutilities_get_preferences(context)
layout.label
if obj is None or obj.mode == 'OBJECT':
materials = bpy.data.materials.items()
if len(materials) > mu_prefs.search_show_limit:
layout.operator(bl_id,
text = 'Search',
icon = 'VIEWZOOM'
).show_dialog = True
layout.separator()
#show all used materials in entire blend file
for material_name, material in materials:
# There's no point in showing materials with 0 users
# (It will still show materials with fake user though)
if material.users > 0:
op = layout.operator(bl_id,
text = material_name,
icon_value = material.preview.icon_id
)
op.material_name = material_name
op.show_dialog = False
elif obj.mode == 'EDIT':
objects = context.selected_editable_objects
materials_added = []
for obj in objects:
#show only the materials on this object
material_slots = obj.material_slots
for material_slot in material_slots:
material = material_slot.material
# Don't add a material that's already in the menu
if material.name in materials_added:
continue
op = layout.operator(bl_id,
text = material.name,
icon_value = material.preview.icon_id
)
op.material_name = material.name
op.show_dialog = False
materials_added.append(material.name)
class VIEW3D_MT_materialutilities_specials(bpy.types.Menu):
"""Spcials menu for Material Utilities"""
bl_idname = "VIEW3D_MT_materialutilities_specials"
bl_label = "Specials"
def draw(self, context):
mu_prefs = materialutilities_get_preferences(context)
layout = self.layout
#layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")
#layout.separator()
layout.operator(MATERIAL_OT_materialutilities_merge_base_names.bl_idname,
text = "Merge Base Names",
icon = "GREASEPENCIL")
layout.operator(MATERIAL_OT_materialutilities_join_objects.bl_idname,
text = "Join by material",
icon = "OBJECT_DATAMODE")
layout.separator()
op = layout.operator(MATERIAL_OT_materialutilities_auto_smooth_angle.bl_idname,
text = "Set Auto Smooth",
icon = "SHADING_SOLID")
op.affect = mu_prefs.set_smooth_affect
op.angle = mu_prefs.auto_smooth_angle
class VIEW3D_MT_materialutilities_main(bpy.types.Menu):
"""Main menu for Material Utilities"""
bl_idname = "VIEW3D_MT_materialutilities_main"
bl_label = "Material Utilities"
def draw(self, context):
obj = context.object
mu_prefs = materialutilities_get_preferences(context)
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
icon = 'ADD')
layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
icon = 'VIEWZOOM')
layout.separator()
layout.operator(VIEW3D_OT_materialutilities_copy_material_to_others.bl_idname,
text = 'Copy Materials to Selected',
icon = 'COPY_ID')
layout.separator()
layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
icon = 'NODE_MATERIAL')
layout.separator()
layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
text = 'Replace Material',
icon = 'OVERLAY')
op = layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
text = 'Set Fake User',
icon = 'FAKE_USER_OFF')
op.fake_user = mu_prefs.fake_user
op.affect = mu_prefs.fake_user_affect
op = layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
text = 'Change Material Link',
icon = 'LINKED')
op.link_to = mu_prefs.link_to
op.affect = mu_prefs.link_to_affect
layout.separator()
layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
icon = 'SOLO_ON')
def materialutilities_specials_menu(self, contxt):
self.layout.separator()
self.layout.menu(VIEW3D_MT_materialutilities_main.bl_idname)
def materialutilities_menu_move(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
icon = 'TRIA_UP_BAR',
text = 'Move Slot to the Top').movement = 'TOP'
layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
icon = 'TRIA_DOWN_BAR',
text = 'Move Slot to the Bottom').movement = 'BOTTOM'
layout.separator()
def materialutilities_menu_functions(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.separator()
layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
icon = 'ADD')
layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
icon = 'VIEWZOOM')
layout.separator()
layout.separator()
layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
icon = 'NODE_MATERIAL')
layout.separator()
layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
text = 'Replace Material',
icon = 'OVERLAY')
layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
text = 'Set Fake User',
icon = 'FAKE_USER_OFF')
layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
text = 'Change Material Link',
icon = 'LINKED')
layout.separator()
layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
icon = 'SOLO_ON')