Merge branch 'blender-v4.0-release'
[blender-addons.git] / materials_utils / menus.py
blob2f432b4d8e1bf1a5bf7dcb4c4c306433237f25f8
1 # SPDX-FileCopyrightText: 2019-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 import bpy
7 from .functions import *
8 from .operators import *
9 from .preferences import *
11 # -----------------------------------------------------------------------------
12 # menu classes
14 class VIEW3D_MT_materialutilities_assign_material(bpy.types.Menu):
15 """Menu for choosing which material should be assigned to current selection"""
16 # The menu is filled programmatically with available materials
18 bl_idname = "VIEW3D_MT_materialutilities_assign_material"
19 bl_label = "Assign Material"
21 def draw(self, context):
22 layout = self.layout
23 layout.operator_context = 'INVOKE_REGION_WIN'
24 edit_mode = False
26 materials = bpy.data.materials.items()
28 bl_id = VIEW3D_OT_materialutilities_assign_material_object.bl_idname
29 obj = context.object
30 mu_prefs = materialutilities_get_preferences(context)
32 if (not obj is None) and obj.mode == 'EDIT':
33 bl_id = VIEW3D_OT_materialutilities_assign_material_edit.bl_idname
34 edit_mode = True
36 if len(materials) > mu_prefs.search_show_limit:
37 op = layout.operator(bl_id,
38 text = 'Search',
39 icon = 'VIEWZOOM')
40 op.material_name = ""
41 op.new_material = False
42 op.show_dialog = True
43 if not edit_mode:
44 op.override_type = mu_prefs.override_type
46 op = layout.operator(bl_id,
47 text = "Add New Material",
48 icon = 'ADD')
49 op.material_name = mu_new_material_name(mu_prefs.new_material_name)
50 op.new_material = True
51 op.show_dialog = True
52 if not edit_mode:
53 op.override_type = mu_prefs.override_type
55 layout.separator()
57 for material_name, material in materials:
58 op = layout.operator(bl_id,
59 text = material_name,
60 icon_value = material.preview.icon_id)
61 op.material_name = material_name
62 op.new_material = False
63 op.show_dialog = False
64 if not edit_mode:
65 op.override_type = mu_prefs.override_type
68 class VIEW3D_MT_materialutilities_clean_slots(bpy.types.Menu):
69 """Menu for cleaning up the material slots"""
71 bl_idname = "VIEW3D_MT_materialutilities_clean_slots"
72 bl_label = "Clean Slots"
74 def draw(self, context):
75 layout = self.layout
77 layout.label
78 layout.operator(VIEW3D_OT_materialutilities_clean_material_slots.bl_idname,
79 text = "Clean Material Slots",
80 icon = 'X')
81 layout.separator()
82 layout.operator(VIEW3D_OT_materialutilities_remove_material_slot.bl_idname,
83 text = "Remove Active Material Slot",
84 icon = 'REMOVE')
85 layout.operator(VIEW3D_OT_materialutilities_remove_all_material_slots.bl_idname,
86 text = "Remove All Material Slots",
87 icon = 'CANCEL')
90 class VIEW3D_MT_materialutilities_select_by_material(bpy.types.Menu):
91 """Menu for choosing which material should be used for selection"""
92 # The menu is filled programmatically with available materials
94 bl_idname = "VIEW3D_MT_materialutilities_select_by_material"
95 bl_label = "Select by Material"
97 def draw(self, context):
98 layout = self.layout
100 bl_id = VIEW3D_OT_materialutilities_select_by_material_name.bl_idname
101 obj = context.object
102 mu_prefs = materialutilities_get_preferences(context)
104 layout.label
106 if obj is None or obj.mode == 'OBJECT':
107 materials = bpy.data.materials.items()
109 if len(materials) > mu_prefs.search_show_limit:
110 layout.operator(bl_id,
111 text = 'Search',
112 icon = 'VIEWZOOM'
113 ).show_dialog = True
115 layout.separator()
117 #show all used materials in entire blend file
118 for material_name, material in materials:
119 # There's no point in showing materials with 0 users
120 # (It will still show materials with fake user though)
121 if material.users > 0:
122 op = layout.operator(bl_id,
123 text = material_name,
124 icon_value = material.preview.icon_id
126 op.material_name = material_name
127 op.show_dialog = False
129 elif obj.mode == 'EDIT':
130 objects = context.selected_editable_objects
131 materials_added = []
133 for obj in objects:
134 #show only the materials on this object
135 material_slots = obj.material_slots
136 for material_slot in material_slots:
137 material = material_slot.material
139 # Don't add a material that's already in the menu
140 if material.name in materials_added:
141 continue
143 op = layout.operator(bl_id,
144 text = material.name,
145 icon_value = material.preview.icon_id
147 op.material_name = material.name
148 op.show_dialog = False
150 materials_added.append(material.name)
152 class VIEW3D_MT_materialutilities_specials(bpy.types.Menu):
153 """Spcials menu for Material Utilities"""
155 bl_idname = "VIEW3D_MT_materialutilities_specials"
156 bl_label = "Specials"
158 def draw(self, context):
159 mu_prefs = materialutilities_get_preferences(context)
160 layout = self.layout
162 #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")
164 #layout.separator()
166 layout.operator(MATERIAL_OT_materialutilities_merge_base_names.bl_idname,
167 text = "Merge Base Names",
168 icon = "GREASEPENCIL")
170 layout.operator(MATERIAL_OT_materialutilities_join_objects.bl_idname,
171 text = "Join by material",
172 icon = "OBJECT_DATAMODE")
175 class VIEW3D_MT_materialutilities_main(bpy.types.Menu):
176 """Main menu for Material Utilities"""
178 bl_idname = "VIEW3D_MT_materialutilities_main"
179 bl_label = "Material Utilities"
181 def draw(self, context):
182 obj = context.object
183 mu_prefs = materialutilities_get_preferences(context)
185 layout = self.layout
186 layout.operator_context = 'INVOKE_REGION_WIN'
188 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
189 icon = 'ADD')
190 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
191 icon = 'VIEWZOOM')
192 layout.separator()
194 layout.operator(VIEW3D_OT_materialutilities_copy_material_to_others.bl_idname,
195 text = 'Copy Materials to Selected',
196 icon = 'COPY_ID')
198 layout.separator()
200 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
201 icon = 'NODE_MATERIAL')
203 layout.separator()
204 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
205 text = 'Replace Material',
206 icon = 'OVERLAY')
208 op = layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
209 text = 'Set Fake User',
210 icon = 'FAKE_USER_OFF')
211 op.fake_user = mu_prefs.fake_user
212 op.affect = mu_prefs.fake_user_affect
214 op = layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
215 text = 'Change Material Link',
216 icon = 'LINKED')
217 op.link_to = mu_prefs.link_to
218 op.affect = mu_prefs.link_to_affect
219 layout.separator()
221 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
222 icon = 'SOLO_ON')
226 def materialutilities_specials_menu(self, contxt):
227 self.layout.separator()
228 self.layout.menu(VIEW3D_MT_materialutilities_main.bl_idname)
231 def materialutilities_menu_move(self, context):
232 layout = self.layout
233 layout.operator_context = 'INVOKE_REGION_WIN'
235 layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
236 icon = 'TRIA_UP_BAR',
237 text = 'Move Slot to the Top').movement = 'TOP'
238 layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
239 icon = 'TRIA_DOWN_BAR',
240 text = 'Move Slot to the Bottom').movement = 'BOTTOM'
241 layout.separator()
243 def materialutilities_menu_functions(self, context):
244 layout = self.layout
245 layout.operator_context = 'INVOKE_REGION_WIN'
247 layout.separator()
249 layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
250 icon = 'ADD')
251 layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
252 icon = 'VIEWZOOM')
253 layout.separator()
255 layout.separator()
257 layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
258 icon = 'NODE_MATERIAL')
260 layout.separator()
261 layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
262 text = 'Replace Material',
263 icon = 'OVERLAY')
265 layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
266 text = 'Set Fake User',
267 icon = 'FAKE_USER_OFF')
269 layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
270 text = 'Change Material Link',
271 icon = 'LINKED')
272 layout.separator()
274 layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
275 icon = 'SOLO_ON')