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