File headers: use SPDX license identifiers
[blender-addons.git] / materials_utils / menus.py
blob3fff4a0d21ae46c6eb19247f4815fb1b52af5c0f
1 # SPDX-License-Identifier: GPL-2.0-or-later
2 import bpy
4 from .functions import *
5 from .operators import *
6 from .preferences import *
8 # -----------------------------------------------------------------------------
9 # menu classes
11 class VIEW3D_MT_materialutilities_assign_material(bpy.types.Menu):
12 """Menu for choosing which material should be assigned to current selection"""
13 # The menu is filled programmatically with available materials
15 bl_idname = "VIEW3D_MT_materialutilities_assign_material"
16 bl_label = "Assign Material"
18 def draw(self, context):
19 layout = self.layout
20 layout.operator_context = 'INVOKE_REGION_WIN'
21 edit_mode = False
23 materials = bpy.data.materials.items()
25 bl_id = VIEW3D_OT_materialutilities_assign_material_object.bl_idname
26 obj = context.object
27 mu_prefs = materialutilities_get_preferences(context)
29 if (not obj is None) and obj.mode == 'EDIT':
30 bl_id = VIEW3D_OT_materialutilities_assign_material_edit.bl_idname
31 edit_mode = True
33 if len(materials) > mu_prefs.search_show_limit:
34 op = layout.operator(bl_id,
35 text = 'Search',
36 icon = 'VIEWZOOM')
37 op.material_name = ""
38 op.new_material = False
39 op.show_dialog = True
40 if not edit_mode:
41 op.override_type = mu_prefs.override_type
43 op = layout.operator(bl_id,
44 text = "Add New Material",
45 icon = 'ADD')
46 op.material_name = mu_new_material_name(mu_prefs.new_material_name)
47 op.new_material = True
48 op.show_dialog = True
49 if not edit_mode:
50 op.override_type = mu_prefs.override_type
52 layout.separator()
54 for material_name, material in materials:
55 op = layout.operator(bl_id,
56 text = material_name,
57 icon_value = material.preview.icon_id)
58 op.material_name = material_name
59 op.new_material = False
60 op.show_dialog = False
61 if not edit_mode:
62 op.override_type = mu_prefs.override_type
65 class VIEW3D_MT_materialutilities_clean_slots(bpy.types.Menu):
66 """Menu for cleaning up the material slots"""
68 bl_idname = "VIEW3D_MT_materialutilities_clean_slots"
69 bl_label = "Clean Slots"
71 def draw(self, context):
72 layout = self.layout
74 layout.label
75 layout.operator(VIEW3D_OT_materialutilities_clean_material_slots.bl_idname,
76 text = "Clean Material Slots",
77 icon = 'X')
78 layout.separator()
79 layout.operator(VIEW3D_OT_materialutilities_remove_material_slot.bl_idname,
80 text = "Remove Active Material Slot",
81 icon = 'REMOVE')
82 layout.operator(VIEW3D_OT_materialutilities_remove_all_material_slots.bl_idname,
83 text = "Remove All Material Slots",
84 icon = 'CANCEL')
87 class VIEW3D_MT_materialutilities_select_by_material(bpy.types.Menu):
88 """Menu for choosing which material should be used for selection"""
89 # The menu is filled programmatically with available materials
91 bl_idname = "VIEW3D_MT_materialutilities_select_by_material"
92 bl_label = "Select by Material"
94 def draw(self, context):
95 layout = self.layout
97 bl_id = VIEW3D_OT_materialutilities_select_by_material_name.bl_idname
98 obj = context.object
99 mu_prefs = materialutilities_get_preferences(context)
101 layout.label
103 if obj is None or obj.mode == 'OBJECT':
104 materials = bpy.data.materials.items()
106 if len(materials) > mu_prefs.search_show_limit:
107 layout.operator(bl_id,
108 text = 'Search',
109 icon = 'VIEWZOOM'
110 ).show_dialog = True
112 layout.separator()
114 #show all used materials in entire blend file
115 for material_name, material in materials:
116 # There's no point in showing materials with 0 users
117 # (It will still show materials with fake user though)
118 if material.users > 0:
119 op = layout.operator(bl_id,
120 text = material_name,
121 icon_value = material.preview.icon_id
123 op.material_name = material_name
124 op.show_dialog = False
126 elif obj.mode == 'EDIT':
127 objects = context.selected_editable_objects
128 materials_added = []
130 for obj in objects:
131 #show only the materials on this object
132 material_slots = obj.material_slots
133 for material_slot in material_slots:
134 material = material_slot.material
136 # Don't add a material that's already in the menu
137 if material.name in materials_added:
138 continue
140 op = layout.operator(bl_id,
141 text = material.name,
142 icon_value = material.preview.icon_id
144 op.material_name = material.name
145 op.show_dialog = False
147 materials_added.append(material.name)
149 class VIEW3D_MT_materialutilities_specials(bpy.types.Menu):
150 """Spcials menu for Material Utilities"""
152 bl_idname = "VIEW3D_MT_materialutilities_specials"
153 bl_label = "Specials"
155 def draw(self, context):
156 mu_prefs = materialutilities_get_preferences(context)
157 layout = self.layout
159 #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")
161 #layout.separator()
163 layout.operator(MATERIAL_OT_materialutilities_merge_base_names.bl_idname,
164 text = "Merge Base Names",
165 icon = "GREASEPENCIL")
167 layout.operator(MATERIAL_OT_materialutilities_join_objects.bl_idname,
168 text = "Join by material",
169 icon = "OBJECT_DATAMODE")
171 layout.separator()
173 op = layout.operator(MATERIAL_OT_materialutilities_auto_smooth_angle.bl_idname,
174 text = "Set Auto Smooth",
175 icon = "SHADING_SOLID")
176 op.affect = mu_prefs.set_smooth_affect
177 op.angle = mu_prefs.auto_smooth_angle
179 class VIEW3D_MT_materialutilities_main(bpy.types.Menu):
180 """Main menu for Material Utilities"""
182 bl_idname = "VIEW3D_MT_materialutilities_main"
183 bl_label = "Material Utilities"
185 def draw(self, context):
186 obj = context.object
187 mu_prefs = materialutilities_get_preferences(context)
189 layout = self.layout
190 layout.operator_context = 'INVOKE_REGION_WIN'
192 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
193 icon = 'ADD')
194 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
195 icon = 'VIEWZOOM')
196 layout.separator()
198 layout.operator(VIEW3D_OT_materialutilities_copy_material_to_others.bl_idname,
199 text = 'Copy Materials to Selected',
200 icon = 'COPY_ID')
202 layout.separator()
204 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
205 icon = 'NODE_MATERIAL')
207 layout.separator()
208 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
209 text = 'Replace Material',
210 icon = 'OVERLAY')
212 op = layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
213 text = 'Set Fake User',
214 icon = 'FAKE_USER_OFF')
215 op.fake_user = mu_prefs.fake_user
216 op.affect = mu_prefs.fake_user_affect
218 op = layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
219 text = 'Change Material Link',
220 icon = 'LINKED')
221 op.link_to = mu_prefs.link_to
222 op.affect = mu_prefs.link_to_affect
223 layout.separator()
225 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
226 icon = 'SOLO_ON')
230 def materialutilities_specials_menu(self, contxt):
231 self.layout.separator()
232 self.layout.menu(VIEW3D_MT_materialutilities_main.bl_idname)
235 def materialutilities_menu_move(self, context):
236 layout = self.layout
237 layout.operator_context = 'INVOKE_REGION_WIN'
239 layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
240 icon = 'TRIA_UP_BAR',
241 text = 'Move Slot to the Top').movement = 'TOP'
242 layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
243 icon = 'TRIA_DOWN_BAR',
244 text = 'Move Slot to the Bottom').movement = 'BOTTOM'
245 layout.separator()
247 def materialutilities_menu_functions(self, context):
248 layout = self.layout
249 layout.operator_context = 'INVOKE_REGION_WIN'
251 layout.separator()
253 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
254 icon = 'ADD')
255 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
256 icon = 'VIEWZOOM')
257 layout.separator()
259 layout.separator()
261 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
262 icon = 'NODE_MATERIAL')
264 layout.separator()
265 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
266 text = 'Replace Material',
267 icon = 'OVERLAY')
269 layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
270 text = 'Set Fake User',
271 icon = 'FAKE_USER_OFF')
273 layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
274 text = 'Change Material Link',
275 icon = 'LINKED')
276 layout.separator()
278 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
279 icon = 'SOLO_ON')