add_camera_rigs: refactor and cleanup
[blender-addons.git] / space_view3d_3d_navigation.py
blob34074ad0a6fff2ac7584e4508efb5bac1c4d0a55
1 # 3D NAVIGATION TOOLBAR v1.2 - 3Dview Addon - Blender 2.5x
3 # THIS SCRIPT IS LICENSED UNDER GPL,
4 # please read the license block.
6 # ##### BEGIN GPL LICENSE BLOCK #####
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software Foundation,
20 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 # ##### END GPL LICENSE BLOCK #####
23 # contributed to by: Demohero, uriel, jbelcik, meta-androcto
25 bl_info = {
26 "name": "3D Navigation",
27 "author": "Demohero, uriel",
28 "version": (1, 2, 5),
29 "blender": (2, 80, 0),
30 "location": "View3D > Sidebar > View Tab",
31 "description": "Navigate the Camera & 3D View from the Toolshelf",
32 "warning": "",
33 "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
34 "3d_view/3d_navigation.html",
35 "category": "3D View",
38 import bpy
39 from bpy.types import (
40 AddonPreferences,
41 Operator,
42 Panel,
44 from bpy.props import StringProperty
47 # main class of this toolbar
49 # re-ordered (reversed) Orbit Operators
50 class VIEW3D_OT_OrbitUpView1(Operator):
51 bl_idname = "opr.orbit_up_view1"
52 bl_label = "Orbit Up View"
53 bl_description = "Orbit the view towards you"
55 def execute(self, context):
56 bpy.ops.view3d.view_orbit(type='ORBITUP')
57 return {'FINISHED'}
60 class VIEW3D_OT_OrbitLeftView1(Operator):
61 bl_idname = "opr.orbit_left_view1"
62 bl_label = "Orbit Left View"
63 bl_description = "Orbit the view around to your Right"
65 def execute(self, context):
66 bpy.ops.view3d.view_orbit(type='ORBITLEFT')
67 return {'FINISHED'}
70 class VIEW3D_OT_OrbitRightView1(Operator):
71 bl_idname = "opr.orbit_right_view1"
72 bl_label = "Orbit Right View"
73 bl_description = "Orbit the view around to your Left"
75 def execute(self, context):
76 bpy.ops.view3d.view_orbit(type='ORBITRIGHT')
77 return {'FINISHED'}
80 class VIEW3D_OT_OrbitDownView1(Operator):
81 bl_idname = "opr.orbit_down_view1"
82 bl_label = "Orbit Down View"
83 bl_description = "Orbit the view away from you"
85 def execute(self, context):
86 bpy.ops.view3d.view_orbit(type='ORBITDOWN')
87 return {'FINISHED'}
90 # re-ordered (reversed) Pan Operators
91 # just pass the enum from the VIEW3D_PT_pan_navigation1 Panel
92 class VIEW3D_OT_PanUpViewsAll(Operator):
93 bl_idname = "opr.pan_up_views_all"
94 bl_label = "Pan View"
95 bl_description = "Pan the 3D View"
97 panning: StringProperty(
98 default="PANUP",
99 options={"HIDDEN"}
102 def execute(self, context):
103 try:
104 bpy.ops.view3d.view_pan("INVOKE_REGION_WIN", type=self.panning)
105 except Exception as e:
106 self.report({"WARNING"},
107 "Pan Views could not be completed. Operation Cancelled")
108 print("\n[3D Navigation]\nOperator: opr.pan_up_views_all\n {}\n".format(e))
110 return {"CANCELLED"}
112 return {'FINISHED'}
115 # Zoom Operators
116 class VIEW3D_OT_ZoomInView1(Operator):
117 bl_idname = "opr.zoom_in_view1"
118 bl_label = "Zoom In View"
119 bl_description = "Zoom In the View/Camera View"
121 def execute(self, context):
122 bpy.ops.view3d.zoom(delta=1)
123 return {'FINISHED'}
126 class VIEW3D_OT_ZoomOutView1(Operator):
127 bl_idname = "opr.zoom_out_view1"
128 bl_label = "Zoom Out View"
129 bl_description = "Zoom out In the View/Camera View"
131 def execute(self, context):
132 bpy.ops.view3d.zoom(delta=-1)
133 return {'FINISHED'}
136 # Roll Operators
137 class VIEW3D_OT_RollLeftView1(Operator):
138 bl_idname = "opr.roll_left_view1"
139 bl_label = "Roll Left View"
140 bl_description = "Roll the view Left"
142 def execute(self, context):
143 bpy.ops.view3d.view_roll(angle=-0.261799)
144 return {'FINISHED'}
147 class VIEW3D_OT_RollRightView1(Operator):
148 bl_idname = "opr.roll_right_view1"
149 bl_label = "Roll Right View"
150 bl_description = "Roll the view Right"
152 def execute(self, context):
153 bpy.ops.view3d.view_roll(angle=0.261799)
154 return {'FINISHED'}
157 # View Operators
158 class VIEW3D_OT_LeftViewpoint1(Operator):
159 bl_idname = "opr.left_viewpoint1"
160 bl_label = "Left Viewpoint"
161 bl_description = "View from the Left"
163 def execute(self, context):
164 bpy.ops.view3d.view_axis(type='LEFT')
165 return {'FINISHED'}
168 class VIEW3D_OT_RightViewpoint1(Operator):
169 bl_idname = "opr.right_viewpoint1"
170 bl_label = "Right Viewpoint"
171 bl_description = "View from the Right"
173 def execute(self, context):
174 bpy.ops.view3d.view_axis(type='RIGHT')
175 return {'FINISHED'}
178 class VIEW3D_OT_FrontViewpoint1(Operator):
179 bl_idname = "opr.front_viewpoint1"
180 bl_label = "Front Viewpoint"
181 bl_description = "View from the Front"
183 def execute(self, context):
184 bpy.ops.view3d.view_axis(type='FRONT')
185 return {'FINISHED'}
188 class VIEW3D_OT_BackViewpoint1(Operator):
189 bl_idname = "opr.back_viewpoint1"
190 bl_label = "Back Viewpoint"
191 bl_description = "View from the Back"
193 def execute(self, context):
194 bpy.ops.view3d.view_axis(type='BACK')
195 return {'FINISHED'}
198 class VIEW3D_OT_TopViewpoint1(Operator):
199 bl_idname = "opr.top_viewpoint1"
200 bl_label = "Top Viewpoint"
201 bl_description = "View from the Top"
203 def execute(self, context):
204 bpy.ops.view3d.view_axis(type='TOP')
205 return {'FINISHED'}
208 class VIEW3D_OT_BottomViewpoint1(Operator):
209 bl_idname = "opr.bottom_viewpoint1"
210 bl_label = "Bottom Viewpoint"
211 bl_description = "View from the Bottom"
213 def execute(self, context):
214 bpy.ops.view3d.view_axis(type='BOTTOM')
215 return {'FINISHED'}
218 # Panel class of this toolbar
219 class VIEW3D_PT_3dnavigationPanel(Panel):
220 bl_space_type = "VIEW_3D"
221 bl_region_type = "UI"
222 bl_label = "3D Nav"
223 bl_category = "View"
224 bl_options = {'DEFAULT_CLOSED'}
226 def draw(self, context):
227 layout = self.layout
228 view = context.space_data
230 # Triple buttons
231 col = layout.column(align=True)
232 col.operator("view3d.localview", text="View Global / Local")
233 col.operator("view3d.view_persportho", text="View Persp / Ortho")
234 col.operator("view3d.view_camera", text="View Camera", icon='CAMERA_DATA')
236 # group of 6 buttons
237 col = layout.column(align=True)
238 col.label(text="Align view from:", icon="VIEW3D")
239 row = col.row()
240 row.operator("view3d.view_axis", text="Front").type = 'FRONT'
241 row.operator("view3d.view_axis", text="Back").type = 'BACK'
242 row = col.row()
243 row.operator("view3d.view_axis", text="Left").type = 'LEFT'
244 row.operator("view3d.view_axis", text="Right").type = 'RIGHT'
245 row = col.row()
246 row.operator("view3d.view_axis", text="Top").type = 'TOP'
247 row.operator("view3d.view_axis", text="Bottom").type = 'BOTTOM'
249 # group of 2 buttons
250 col = layout.column(align=True)
251 col.label(text="Lock View to Object:", icon="LOCKED")
252 col.prop(view, "lock_object", text="")
253 col.operator("view3d.view_selected", text="View to Selected")
255 col = layout.column(align=True)
256 col.label(text="Cursor:", icon='PIVOT_CURSOR')
257 row = col.row(align=True)
258 row.operator("view3d.snap_cursor_to_center", text="World Origin")
259 row.operator("view3d.view_center_cursor", text="View")
260 col.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected")
263 class VIEW3D_PT_3dnavigationPanel2(Panel):
264 bl_space_type = "VIEW_3D"
265 bl_region_type = "UI"
266 bl_label = "Pan Orbit Zoom Roll"
267 bl_category = "View"
268 bl_options = {'DEFAULT_CLOSED'}
270 def draw(self, context):
271 layout = self.layout
272 layout.label(text="Screen View Perspective")
274 row = layout.row()
275 row.label(text="Pan:")
276 row = layout.row()
278 row.operator("opr.pan_up_views_all", text="Up",
279 icon="TRIA_UP").panning = "PANDOWN"
280 row.operator("opr.pan_up_views_all", text="Down",
281 icon="TRIA_DOWN").panning = "PANUP"
283 row = layout.row()
284 row.operator("opr.pan_up_views_all", text="Left",
285 icon="BACK").panning = "PANRIGHT"
286 row.operator("opr.pan_up_views_all", text="Right",
287 icon="FORWARD").panning = "PANLEFT"
289 row = layout.row()
290 row.label(text="Orbit:")
291 row = layout.row()
292 row.operator("opr.orbit_down_view1", text="Up", icon="TRIA_UP")
293 row.operator("opr.orbit_up_view1", text="Down", icon="TRIA_DOWN")
295 row = layout.row()
296 row.operator("opr.orbit_right_view1", text="Left", icon="BACK")
297 row.operator("opr.orbit_left_view1", text="Right", icon="FORWARD")
299 row = layout.row()
300 row.label(text="Zoom:")
301 row = layout.row()
302 row.operator("opr.zoom_in_view1", text="In", icon='ADD')
303 row.operator("opr.zoom_out_view1", text="Out", icon='REMOVE')
305 row = layout.row()
306 row.label(text="Roll:")
307 row = layout.row()
308 row.operator("opr.roll_left_view1", text="Left", icon="LOOP_BACK")
309 row.operator("opr.roll_right_view1", text="Right", icon="LOOP_FORWARDS")
312 # Add-ons Preferences Update Panel
314 # Define Panel classes for updating
315 panels = (
316 VIEW3D_PT_3dnavigationPanel,
317 VIEW3D_PT_3dnavigationPanel2,
321 def update_panel(self, context):
322 message = ": Updating Panel locations has failed"
323 try:
324 for panel in panels:
325 if "bl_rna" in panel.__dict__:
326 bpy.utils.unregister_class(panel)
328 for panel in panels:
329 panel.bl_category = context.preferences.addons[__name__].preferences.category
330 bpy.utils.register_class(panel)
332 except Exception as e:
333 print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
334 pass
337 class NavAddonPreferences(AddonPreferences):
338 # this must match the addon name, use '__package__'
339 # when defining this in a submodule of a python package.
340 bl_idname = __name__
342 category: StringProperty(
343 name="Tab Category",
344 description="Choose a name for the category of the panel",
345 default="View",
346 update=update_panel
349 def draw(self, context):
350 layout = self.layout
352 row = layout.row()
353 col = row.column()
354 col.label(text="Tab Category:")
355 col.prop(self, "category", text="")
358 classes = (
359 VIEW3D_PT_3dnavigationPanel,
360 VIEW3D_PT_3dnavigationPanel2,
361 VIEW3D_OT_OrbitUpView1,
362 VIEW3D_OT_OrbitLeftView1,
363 VIEW3D_OT_OrbitRightView1,
364 VIEW3D_OT_OrbitDownView1,
365 VIEW3D_OT_ZoomInView1,
366 VIEW3D_OT_ZoomOutView1,
367 VIEW3D_OT_RollLeftView1,
368 VIEW3D_OT_RollRightView1,
369 VIEW3D_OT_LeftViewpoint1,
370 VIEW3D_OT_RightViewpoint1,
371 VIEW3D_OT_FrontViewpoint1,
372 VIEW3D_OT_BackViewpoint1,
373 VIEW3D_OT_TopViewpoint1,
374 VIEW3D_OT_BottomViewpoint1,
375 VIEW3D_OT_PanUpViewsAll,
376 NavAddonPreferences,
380 # Register
381 def register():
382 for cls in classes:
383 bpy.utils.register_class(cls)
384 update_panel(None, bpy.context)
387 def unregister():
388 for cls in classes:
389 bpy.utils.unregister_class(cls)
392 if __name__ == "__main__":
393 register()