1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
22 "name": "Hotkey: 'Ctrl Tab'",
23 "description": "Switch between 3d view object/edit modes",
24 "author": "pitiwazou, meta-androcto, italic",
26 "blender": (2, 80, 0),
27 "location": "3D View",
30 "category": "Mode Switch Pie"
34 from bpy
.types
import (
40 class PIE_OT_ClassObject(Operator
):
41 bl_idname
= "class.object"
42 bl_label
= "Class Object"
43 bl_description
= "Edit/Object Mode Switch"
44 bl_options
= {'REGISTER', 'UNDO'}
46 def execute(self
, context
):
47 if context
.object.mode
== "OBJECT":
48 bpy
.ops
.object.mode_set(mode
="EDIT")
50 bpy
.ops
.object.mode_set(mode
="OBJECT")
54 class PIE_OT_ClassTexturePaint(Operator
):
55 bl_idname
= "class.pietexturepaint"
56 bl_label
= "Class Texture Paint"
57 bl_description
= "Texture Paint"
58 bl_options
= {'REGISTER', 'UNDO'}
60 def execute(self
, context
):
61 if context
.object.mode
== "EDIT":
62 bpy
.ops
.object.mode_set(mode
="OBJECT")
63 bpy
.ops
.paint
.texture_paint_toggle()
65 bpy
.ops
.paint
.texture_paint_toggle()
69 class PIE_OT_ClassWeightPaint(Operator
):
70 bl_idname
= "class.pieweightpaint"
71 bl_label
= "Class Weight Paint"
72 bl_description
= "Weight Paint"
73 bl_options
= {'REGISTER', 'UNDO'}
75 def execute(self
, context
):
76 if context
.object.mode
== "EDIT":
77 bpy
.ops
.object.mode_set(mode
="OBJECT")
78 bpy
.ops
.paint
.weight_paint_toggle()
80 bpy
.ops
.paint
.weight_paint_toggle()
84 class PIE_OT_ClassVertexPaint(Operator
):
85 bl_idname
= "class.pievertexpaint"
86 bl_label
= "Class Vertex Paint"
87 bl_description
= "Vertex Paint"
88 bl_options
= {'REGISTER', 'UNDO'}
90 def execute(self
, context
):
91 if context
.object.mode
== "EDIT":
92 bpy
.ops
.object.mode_set(mode
="OBJECT")
93 bpy
.ops
.paint
.vertex_paint_toggle()
95 bpy
.ops
.paint
.vertex_paint_toggle()
99 class PIE_OT_ClassParticleEdit(Operator
):
100 bl_idname
= "class.pieparticleedit"
101 bl_label
= "Class Particle Edit"
102 bl_description
= "Particle Edit (must have active particle system)"
103 bl_options
= {'REGISTER', 'UNDO'}
105 def execute(self
, context
):
106 if context
.object.mode
== "EDIT":
107 bpy
.ops
.object.mode_set(mode
="OBJECT")
108 bpy
.ops
.particle
.particle_edit_toggle()
110 bpy
.ops
.particle
.particle_edit_toggle()
114 # Set Mode Operator #
115 class PIE_OT_SetObjectModePie(Operator
):
116 bl_idname
= "object.set_object_mode_pie"
117 bl_label
= "Set the object interactive mode"
118 bl_description
= "I set the interactive mode of object"
119 bl_options
= {'REGISTER'}
121 mode
: bpy
.props
.StringProperty(name
="Interactive mode", default
="OBJECT")
123 def execute(self
, context
):
124 if (context
.active_object
):
126 bpy
.ops
.object.mode_set(mode
=self
.mode
)
128 msg
= context
.active_object
.name
+ " It is not possible to enter into the interactive mode"
129 self
.report(type={"WARNING"}, message
=msg
)
131 self
.report(type={"WARNING"}, message
="There is no active object")
135 # Edit Selection Modes
136 class PIE_OT_ClassVertex(Operator
):
137 bl_idname
= "class.vertex"
138 bl_label
= "Class Vertex"
139 bl_description
= "Vert Select Mode"
140 bl_options
= {'REGISTER', 'UNDO'}
142 def execute(self
, context
):
143 if context
.object.mode
!= "EDIT":
144 bpy
.ops
.object.mode_set(mode
="EDIT")
145 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='VERT')
146 if bpy
.ops
.mesh
.select_mode
!= "EDGE, FACE":
147 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='VERT')
151 class PIE_OT_ClassEdge(Operator
):
152 bl_idname
= "class.edge"
153 bl_label
= "Class Edge"
154 bl_description
= "Edge Select Mode"
155 bl_options
= {'REGISTER', 'UNDO'}
157 def execute(self
, context
):
158 if context
.object.mode
!= "EDIT":
159 bpy
.ops
.object.mode_set(mode
="EDIT")
160 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='EDGE')
161 if bpy
.ops
.mesh
.select_mode
!= "VERT, FACE":
162 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='EDGE')
166 class PIE_OT_ClassFace(Operator
):
167 bl_idname
= "class.face"
168 bl_label
= "Class Face"
169 bl_description
= "Face Select Mode"
170 bl_options
= {'REGISTER', 'UNDO'}
172 def execute(self
, context
):
173 if context
.object.mode
!= "EDIT":
174 bpy
.ops
.object.mode_set(mode
="EDIT")
175 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='FACE')
176 if bpy
.ops
.mesh
.select_mode
!= "VERT, EDGE":
177 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='FACE')
181 class PIE_OT_VertsEdgesFaces(Operator
):
182 bl_idname
= "verts.edgesfaces"
183 bl_label
= "Verts Edges Faces"
184 bl_description
= "Vert/Edge/Face Select Mode"
185 bl_options
= {'REGISTER', 'UNDO'}
187 def execute(self
, context
):
188 if context
.object.mode
!= "EDIT":
189 bpy
.ops
.object.mode_set(mode
="EDIT")
190 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='VERT')
191 if bpy
.ops
.mesh
.select_mode
!= "VERT, EDGE, FACE":
192 bpy
.ops
.object.mode_set(mode
="EDIT")
193 bpy
.ops
.mesh
.select_mode(use_extend
=False, use_expand
=False, type='VERT')
194 bpy
.ops
.mesh
.select_mode(use_extend
=True, use_expand
=False, type='EDGE')
195 bpy
.ops
.mesh
.select_mode(use_extend
=True, use_expand
=False, type='FACE')
200 class PIE_MT_ObjectEditotherModes(Menu
):
201 """Edit/Object Others modes"""
202 bl_idname
= "MENU_MT_objecteditmodeothermodes"
203 bl_label
= "Edit Selection Modes"
205 def draw(self
, context
):
207 pie
= layout
.menu_pie()
208 box
= pie
.split().column()
210 box
.operator("class.vertex", text
="Vertex", icon
='VERTEXSEL')
211 box
.operator("class.edge", text
="Edge", icon
='EDGESEL')
212 box
.operator("class.face", text
="Face", icon
='FACESEL')
213 box
.operator("verts.edgesfaces", text
="Vertex/Edges/Faces", icon
='OBJECT_DATAMODE')
216 class PIE_MT_ObjectEditMode(Menu
):
218 bl_idname
= "PIE_MT_objecteditmode"
219 bl_label
= "Mode Switch (Ctrl Tab)"
221 def draw(self
, context
):
224 # No Object Selected #
225 if not ob
or not ob
.select_get():
226 message
= "No Active Object Selected"
227 pie
= layout
.menu_pie()
232 box
.label(text
=message
, icon
="INFO")
234 elif ob
and ob
.type == 'MESH' and ob
.mode
in {'OBJECT', 'SCULPT', 'VERTEX_PAINT',
235 'WEIGHT_PAINT', 'TEXTURE_PAINT',
236 'PARTICLE_EDIT', 'GPENCIL_EDIT'}:
237 pie
= layout
.menu_pie()
239 pie
.operator("class.pieweightpaint", text
="Weight Paint", icon
='WPAINT_HLT')
241 pie
.operator("class.pietexturepaint", text
="Texture Paint", icon
='TPAINT_HLT')
243 pie
.menu("MENU_MT_objecteditmodeothermodes", text
="Edit Modes", icon
='EDITMODE_HLT')
245 pie
.operator("class.object", text
="Object/Edit Toggle", icon
='OBJECT_DATAMODE')
247 pie
.operator("sculpt.sculptmode_toggle", text
="Sculpt", icon
='SCULPTMODE_HLT')
249 pie
.operator("class.pievertexpaint", text
="Vertex Paint", icon
='VPAINT_HLT')
253 if context
.object.particle_systems
:
254 pie
.operator("class.pieparticleedit", text
="Particle Edit", icon
='PARTICLEMODE')
258 elif ob
and ob
.type == 'MESH' and ob
.mode
in {'EDIT'}:
259 pie
= layout
.menu_pie()
261 pie
.operator("class.pieweightpaint", text
="Weight Paint", icon
='WPAINT_HLT')
263 pie
.operator("class.pietexturepaint", text
="Texture Paint", icon
='TPAINT_HLT')
265 pie
.menu("MENU_MT_objecteditmodeothermodes", text
="Edit Modes", icon
='EDITMODE_HLT')
267 pie
.operator("class.object", text
="Edit/Object Toggle", icon
='OBJECT_DATAMODE')
269 pie
.operator("sculpt.sculptmode_toggle", text
="Sculpt", icon
='SCULPTMODE_HLT')
271 pie
.operator("class.pievertexpaint", text
="Vertex Paint", icon
='VPAINT_HLT')
275 if context
.object.particle_systems
:
276 pie
.operator("class.pieparticleedit", text
="Particle Edit", icon
='PARTICLEMODE')
280 elif ob
and ob
.type == 'CURVE':
281 pie
= layout
.menu_pie()
289 pie
.operator("object.editmode_toggle", text
="Edit/Object", icon
='OBJECT_DATAMODE')
299 elif ob
and ob
.type == 'ARMATURE':
300 pie
= layout
.menu_pie()
302 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Object", icon
="OBJECT_DATAMODE").mode
= "OBJECT"
304 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Pose", icon
="POSE_HLT").mode
= "POSE"
306 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Edit", icon
="EDITMODE_HLT").mode
= "EDIT"
308 pie
.operator("object.editmode_toggle", text
="Edit Mode", icon
='OBJECT_DATAMODE')
318 elif ob
and ob
.type == 'FONT':
319 pie
= layout
.menu_pie()
323 pie
.operator("object.editmode_toggle", text
="Edit/Object Toggle", icon
='OBJECT_DATAMODE')
330 elif ob
and ob
.type == 'SURFACE':
331 pie
= layout
.menu_pie()
335 pie
.operator("object.editmode_toggle", text
="Edit/Object Toggle", icon
='OBJECT_DATAMODE')
342 elif ob
and ob
.type == 'META':
343 pie
= layout
.menu_pie()
347 pie
.operator("object.editmode_toggle", text
="Edit/Object Toggle", icon
='OBJECT_DATAMODE')
354 elif ob
and ob
.type == 'LATTICE':
355 pie
= layout
.menu_pie()
359 pie
.operator("object.editmode_toggle", text
="Edit/Object Toggle", icon
='OBJECT_DATAMODE')
364 if ob
and ob
.type == 'GPENCIL':
365 pie
= layout
.menu_pie()
367 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Sculpt", icon
="SCULPTMODE_HLT").mode
= "SCULPT_GPENCIL"
369 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Draw", icon
="GREASEPENCIL").mode
= "PAINT_GPENCIL"
371 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Edit", icon
="EDITMODE_HLT").mode
= "EDIT_GPENCIL"
373 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Object", icon
="OBJECT_DATAMODE").mode
= "OBJECT"
381 pie
.operator(PIE_OT_SetObjectModePie
.bl_idname
, text
="Weight Paint", icon
="WPAINT_HLT").mode
= "WEIGHT_GPENCIL"
385 elif ob
and ob
.type in {"LIGHT", "CAMERA", "EMPTY", "SPEAKER"}:
386 message
= "Active Object has only Object Mode available"
387 pie
= layout
.menu_pie()
392 box
.label(text
=message
, icon
="INFO")
396 PIE_MT_ObjectEditMode
,
401 PIE_MT_ObjectEditotherModes
,
402 PIE_OT_ClassTexturePaint
,
403 PIE_OT_ClassWeightPaint
,
404 PIE_OT_ClassVertexPaint
,
405 PIE_OT_ClassParticleEdit
,
406 PIE_OT_VertsEdgesFaces
,
407 PIE_OT_SetObjectModePie
,
415 bpy
.utils
.register_class(cls
)
417 wm
= bpy
.context
.window_manager
418 if wm
.keyconfigs
.addon
:
420 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Object Non-modal')
421 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl
=True)
422 kmi
.properties
.name
= "PIE_MT_objecteditmode"
423 addon_keymaps
.append((km
, kmi
))
425 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Grease Pencil Stroke Edit Mode')
426 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl
=True)
427 kmi
.properties
.name
= "PIE_MT_objecteditmode"
428 addon_keymaps
.append((km
, kmi
))
433 bpy
.utils
.unregister_class(cls
)
435 wm
= bpy
.context
.window_manager
436 kc
= wm
.keyconfigs
.addon
438 for km
, kmi
in addon_keymaps
:
439 km
.keymap_items
.remove(kmi
)
440 addon_keymaps
.clear()
443 if __name__
== "__main__":