Fix add-ons with Python 3.12 by replacing "imp" with "importlib"
[blender-addons.git] / space_view3d_pie_menus / pie_modes_menu.py
blob2f39822be60bcda2408156334729adffb7955f37
1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 bl_info = {
6 "name": "Hotkey: 'Ctrl Tab'",
7 "description": "Switch between 3d view object/edit modes",
8 "author": "pitiwazou, meta-androcto, italic",
9 "version": (0, 1, 2),
10 "blender": (2, 80, 0),
11 "location": "3D View",
12 "warning": "",
13 "doc_url": "",
14 "category": "Mode Switch Pie"
17 import bpy
18 from bpy.types import (
19 Menu,
20 Operator
24 class PIE_OT_ClassObject(Operator):
25 bl_idname = "class.object"
26 bl_label = "Class Object"
27 bl_description = "Edit/Object Mode Switch"
28 bl_options = {'REGISTER', 'UNDO'}
30 def execute(self, context):
31 if context.object.mode == "OBJECT":
32 bpy.ops.object.mode_set(mode="EDIT")
33 else:
34 bpy.ops.object.mode_set(mode="OBJECT")
35 return {'FINISHED'}
38 class PIE_OT_ClassTexturePaint(Operator):
39 bl_idname = "class.pietexturepaint"
40 bl_label = "Class Texture Paint"
41 bl_description = "Texture Paint"
42 bl_options = {'REGISTER', 'UNDO'}
44 def execute(self, context):
45 if context.object.mode == "EDIT":
46 bpy.ops.object.mode_set(mode="OBJECT")
47 bpy.ops.paint.texture_paint_toggle()
48 else:
49 bpy.ops.paint.texture_paint_toggle()
50 return {'FINISHED'}
53 class PIE_OT_ClassWeightPaint(Operator):
54 bl_idname = "class.pieweightpaint"
55 bl_label = "Class Weight Paint"
56 bl_description = "Weight Paint"
57 bl_options = {'REGISTER', 'UNDO'}
59 def execute(self, context):
60 if context.object.mode == "EDIT":
61 bpy.ops.object.mode_set(mode="OBJECT")
62 bpy.ops.paint.weight_paint_toggle()
63 else:
64 bpy.ops.paint.weight_paint_toggle()
65 return {'FINISHED'}
68 class PIE_OT_ClassVertexPaint(Operator):
69 bl_idname = "class.pievertexpaint"
70 bl_label = "Class Vertex Paint"
71 bl_description = "Vertex Paint"
72 bl_options = {'REGISTER', 'UNDO'}
74 def execute(self, context):
75 if context.object.mode == "EDIT":
76 bpy.ops.object.mode_set(mode="OBJECT")
77 bpy.ops.paint.vertex_paint_toggle()
78 else:
79 bpy.ops.paint.vertex_paint_toggle()
80 return {'FINISHED'}
83 class PIE_OT_ClassParticleEdit(Operator):
84 bl_idname = "class.pieparticleedit"
85 bl_label = "Class Particle Edit"
86 bl_description = "Particle Edit (must have active particle system)"
87 bl_options = {'REGISTER', 'UNDO'}
89 def execute(self, context):
90 if context.object.mode == "EDIT":
91 bpy.ops.object.mode_set(mode="OBJECT")
92 bpy.ops.particle.particle_edit_toggle()
93 else:
94 bpy.ops.particle.particle_edit_toggle()
95 return {'FINISHED'}
98 # Set Mode Operator #
99 class PIE_OT_SetObjectModePie(Operator):
100 bl_idname = "object.set_object_mode_pie"
101 bl_label = "Set the object interactive mode"
102 bl_description = "I set the interactive mode of object"
103 bl_options = {'REGISTER'}
105 mode: bpy.props.StringProperty(name="Interactive mode", default="OBJECT")
107 def execute(self, context):
108 if (context.active_object):
109 try:
110 bpy.ops.object.mode_set(mode=self.mode)
111 except TypeError:
112 msg = context.active_object.name + " It is not possible to enter into the interactive mode"
113 self.report(type={"WARNING"}, message=msg)
114 else:
115 self.report(type={"WARNING"}, message="There is no active object")
116 return {'FINISHED'}
119 # Edit Selection Modes
120 class PIE_OT_ClassVertex(Operator):
121 bl_idname = "class.vertex"
122 bl_label = "Class Vertex"
123 bl_description = "Vert Select Mode"
124 bl_options = {'REGISTER', 'UNDO'}
126 def execute(self, context):
127 if context.object.mode != "EDIT":
128 bpy.ops.object.mode_set(mode="EDIT")
129 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
130 if bpy.ops.mesh.select_mode != "EDGE, FACE":
131 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
132 return {'FINISHED'}
135 class PIE_OT_ClassEdge(Operator):
136 bl_idname = "class.edge"
137 bl_label = "Class Edge"
138 bl_description = "Edge Select Mode"
139 bl_options = {'REGISTER', 'UNDO'}
141 def execute(self, context):
142 if context.object.mode != "EDIT":
143 bpy.ops.object.mode_set(mode="EDIT")
144 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
145 if bpy.ops.mesh.select_mode != "VERT, FACE":
146 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
147 return {'FINISHED'}
150 class PIE_OT_ClassFace(Operator):
151 bl_idname = "class.face"
152 bl_label = "Class Face"
153 bl_description = "Face Select Mode"
154 bl_options = {'REGISTER', 'UNDO'}
156 def execute(self, context):
157 if context.object.mode != "EDIT":
158 bpy.ops.object.mode_set(mode="EDIT")
159 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
160 if bpy.ops.mesh.select_mode != "VERT, EDGE":
161 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
162 return {'FINISHED'}
165 class PIE_OT_VertsEdgesFaces(Operator):
166 bl_idname = "verts.edgesfaces"
167 bl_label = "Verts Edges Faces"
168 bl_description = "Vert/Edge/Face Select Mode"
169 bl_options = {'REGISTER', 'UNDO'}
171 def execute(self, context):
172 if context.object.mode != "EDIT":
173 bpy.ops.object.mode_set(mode="EDIT")
174 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
175 if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
176 bpy.ops.object.mode_set(mode="EDIT")
177 bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
178 bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
179 bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
180 return {'FINISHED'}
183 # Menus
184 class PIE_MT_ObjectEditotherModes(Menu):
185 """Edit/Object Others modes"""
186 bl_idname = "MENU_MT_objecteditmodeothermodes"
187 bl_label = "Edit Selection Modes"
189 def draw(self, context):
190 layout = self.layout
191 pie = layout.menu_pie()
192 box = pie.split().column()
194 box.operator("class.vertex", text="Vertex", icon='VERTEXSEL')
195 box.operator("class.edge", text="Edge", icon='EDGESEL')
196 box.operator("class.face", text="Face", icon='FACESEL')
197 box.operator("verts.edgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
200 class PIE_MT_ObjectEditMode(Menu):
201 """Modes Switch"""
202 bl_idname = "PIE_MT_objecteditmode"
203 bl_label = "Mode Switch (Ctrl Tab)"
205 def draw(self, context):
206 layout = self.layout
207 ob = context.object
208 # No Object Selected #
209 if not ob or not ob.select_get():
210 message = "No Active Object Selected"
211 pie = layout.menu_pie()
212 pie.separator()
213 pie.separator()
214 pie.separator()
215 box = pie.box()
216 box.label(text=message, icon="INFO")
218 elif ob and ob.type == 'MESH' and ob.mode in {
219 'OBJECT', 'SCULPT', 'VERTEX_PAINT',
220 'WEIGHT_PAINT', 'TEXTURE_PAINT',
221 'PARTICLE_EDIT', 'GPENCIL_EDIT',
223 pie = layout.menu_pie()
224 # 4 - LEFT
225 pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT')
226 # 6 - RIGHT
227 pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT')
228 # 2 - BOTTOM
229 pie.menu("MENU_MT_objecteditmodeothermodes", text="Edit Modes", icon='EDITMODE_HLT')
230 # 8 - TOP
231 pie.operator("class.object", text="Object/Edit Toggle", icon='OBJECT_DATAMODE')
232 # 7 - TOP - LEFT
233 pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT')
234 # 9 - TOP - RIGHT
235 pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT')
236 # 1 - BOTTOM - LEFT
237 pie.separator()
238 # 3 - BOTTOM - RIGHT
239 if context.object.particle_systems:
240 pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE')
241 else:
242 pie.separator()
244 elif ob and ob.type == 'MESH' and ob.mode in {'EDIT'}:
245 pie = layout.menu_pie()
246 # 4 - LEFT
247 pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT')
248 # 6 - RIGHT
249 pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT')
250 # 2 - BOTTOM
251 pie.menu("MENU_MT_objecteditmodeothermodes", text="Edit Modes", icon='EDITMODE_HLT')
252 # 8 - TOP
253 pie.operator("class.object", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
254 # 7 - TOP - LEFT
255 pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT')
256 # 9 - TOP - RIGHT
257 pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT')
258 # 1 - BOTTOM - LEFT
259 pie.separator()
260 # 3 - BOTTOM - RIGHT
261 if context.object.particle_systems:
262 pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE')
263 else:
264 pie.separator()
266 elif ob and ob.type == 'CURVE':
267 pie = layout.menu_pie()
268 # 4 - LEFT
269 pie.separator()
270 # 6 - RIGHT
271 pie.separator()
272 # 2 - BOTTOM
273 pie.separator()
274 # 8 - TOP
275 pie.operator("object.editmode_toggle", text="Edit/Object", icon='OBJECT_DATAMODE')
276 # 7 - TOP - LEFT
277 pie.separator()
278 # 9 - TOP - RIGHT
279 pie.separator()
280 # 1 - BOTTOM - LEFT
281 pie.separator()
282 # 3 - BOTTOM - RIGHT
283 pie.separator()
285 elif ob and ob.type == 'ARMATURE':
286 pie = layout.menu_pie()
287 # 4 - LEFT
288 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE").mode = "OBJECT"
289 # 6 - RIGHT
290 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Pose", icon="POSE_HLT").mode = "POSE"
291 # 2 - BOTTOM
292 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT").mode = "EDIT"
293 # 8 - TOP
294 pie.operator("object.editmode_toggle", text="Edit Mode", icon='OBJECT_DATAMODE')
295 # 7 - TOP - LEFT
296 pie.separator()
297 # 9 - TOP - RIGHT
298 pie.separator()
299 # 1 - BOTTOM - LEFT
300 pie.separator()
301 # 3 - BOTTOM - RIGHT
302 pie.separator()
304 elif ob and ob.type == 'FONT':
305 pie = layout.menu_pie()
306 pie.separator()
307 pie.separator()
308 pie.separator()
309 pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
310 pie.separator()
311 pie.separator()
312 pie.separator()
313 # 3 - BOTTOM - RIGHT
314 pie.separator()
316 elif ob and ob.type == 'SURFACE':
317 pie = layout.menu_pie()
318 pie.separator()
319 pie.separator()
320 pie.separator()
321 pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
322 pie.separator()
323 pie.separator()
324 pie.separator()
325 # 3 - BOTTOM - RIGHT
326 pie.separator()
328 elif ob and ob.type == 'META':
329 pie = layout.menu_pie()
330 pie.separator()
331 pie.separator()
332 pie.separator()
333 pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
334 pie.separator()
335 pie.separator()
336 pie.separator()
337 # 3 - BOTTOM - RIGHT
338 pie.separator()
340 elif ob and ob.type == 'LATTICE':
341 pie = layout.menu_pie()
342 pie.separator()
343 pie.separator()
344 pie.separator()
345 pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE')
346 pie.separator()
347 pie.separator()
348 pie.separator()
350 if ob and ob.type == 'GPENCIL':
351 pie = layout.menu_pie()
352 # 4 - LEFT
353 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Sculpt",
354 icon="SCULPTMODE_HLT").mode = "SCULPT_GPENCIL"
355 # 6 - RIGHT
356 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Draw", icon="GREASEPENCIL").mode = "PAINT_GPENCIL"
357 # 2 - BOTTOM
358 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT").mode = "EDIT_GPENCIL"
359 # 8 - TOP
360 pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE").mode = "OBJECT"
361 # 7 - TOP - LEFT
362 pie.separator()
363 # 9 - TOP - RIGHT
364 pie.separator()
365 # 1 - BOTTOM - LEFT
366 pie.separator()
367 # 3 - BOTTOM - RIGHT
368 pie.operator(
369 PIE_OT_SetObjectModePie.bl_idname,
370 text="Weight Paint",
371 icon="WPAINT_HLT").mode = "WEIGHT_GPENCIL"
373 elif ob and ob.type in {"LIGHT", "CAMERA", "EMPTY", "SPEAKER"}:
374 message = "Active Object has only Object Mode available"
375 pie = layout.menu_pie()
376 pie.separator()
377 pie.separator()
378 pie.separator()
379 box = pie.box()
380 box.label(text=message, icon="INFO")
383 classes = (
384 PIE_MT_ObjectEditMode,
385 PIE_OT_ClassObject,
386 PIE_OT_ClassVertex,
387 PIE_OT_ClassEdge,
388 PIE_OT_ClassFace,
389 PIE_MT_ObjectEditotherModes,
390 PIE_OT_ClassTexturePaint,
391 PIE_OT_ClassWeightPaint,
392 PIE_OT_ClassVertexPaint,
393 PIE_OT_ClassParticleEdit,
394 PIE_OT_VertsEdgesFaces,
395 PIE_OT_SetObjectModePie,
398 addon_keymaps = []
401 def register():
402 for cls in classes:
403 bpy.utils.register_class(cls)
405 wm = bpy.context.window_manager
406 if wm.keyconfigs.addon:
407 # Select Mode
408 km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
409 kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True)
410 kmi.properties.name = "PIE_MT_objecteditmode"
411 addon_keymaps.append((km, kmi))
413 km = wm.keyconfigs.addon.keymaps.new(name='Grease Pencil Stroke Edit Mode')
414 kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True)
415 kmi.properties.name = "PIE_MT_objecteditmode"
416 addon_keymaps.append((km, kmi))
419 def unregister():
420 for cls in classes:
421 bpy.utils.unregister_class(cls)
423 wm = bpy.context.window_manager
424 kc = wm.keyconfigs.addon
425 if kc:
426 for km, kmi in addon_keymaps:
427 km.keymap_items.remove(kmi)
428 addon_keymaps.clear()
431 if __name__ == "__main__":
432 register()