Merge branch 'master' into blender2.8
[blender.git] / release / scripts / startup / bl_ui / space_info.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from bpy.types import Header, Menu
22
23
24 class INFO_HT_header(Header):
25     bl_space_type = 'INFO'
26
27     def draw(self, context):
28         layout = self.layout
29
30         window = context.window
31         workspace = context.workspace
32         screen = context.screen
33         scene = context.scene
34         layer = context.render_layer
35         rd = scene.render
36
37         row = layout.row(align=True)
38         row.template_header()
39
40         INFO_MT_editor_menus.draw_collapsible(context, layout)
41
42         layout.separator()
43
44         if screen.show_fullscreen:
45             layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous")
46             layout.separator()
47         else:
48             layout.template_ID(window, "workspace", new="workspace.workspace_add_menu", unlink="workspace.workspace_delete")
49             layout.template_search_preview(window, "screen", workspace, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6)
50
51         if hasattr(workspace, 'object_mode'):
52             act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[workspace.object_mode]
53         else:
54             act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[layer.objects.active.mode]
55         layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
56
57         layout.template_search(workspace, "render_layer", scene, "render_layers")
58
59         layout.separator()
60
61         layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete")
62
63         if rd.has_multiple_engines:
64             layout.prop(rd, "engine", text="")
65
66         layout.separator()
67
68         layout.template_running_jobs()
69
70         layout.template_reports_banner()
71
72         row = layout.row(align=True)
73
74         if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
75             row.label("Auto-run disabled", icon='ERROR')
76             if bpy.data.is_saved:
77                 props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
78                 props.use_scripts = True
79
80             row.operator("script.autoexec_warn_clear", text="Ignore")
81
82             # include last so text doesn't push buttons out of the header
83             row.label(bpy.app.autoexec_fail_message)
84             return
85
86         row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
87         row.label(text=scene.statistics(context.render_layer), translate=False)
88
89
90 class INFO_MT_editor_menus(Menu):
91     bl_idname = "INFO_MT_editor_menus"
92     bl_label = ""
93
94     def draw(self, context):
95         self.draw_menus(self.layout, context)
96
97     @staticmethod
98     def draw_menus(layout, context):
99         scene = context.scene
100         rd = scene.render
101
102         layout.menu("INFO_MT_file")
103
104         if rd.use_game_engine:
105             layout.menu("INFO_MT_game")
106         else:
107             layout.menu("INFO_MT_render")
108
109         layout.menu("INFO_MT_window")
110         layout.menu("INFO_MT_help")
111
112
113 class INFO_MT_file(Menu):
114     bl_label = "File"
115
116     def draw(self, context):
117         layout = self.layout
118
119         layout.operator_context = 'INVOKE_AREA'
120         layout.operator("wm.read_homefile", text="New", icon='NEW')
121         layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
122         layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT')
123         layout.operator("wm.revert_mainfile", icon='FILE_REFRESH')
124         layout.operator("wm.recover_last_session", icon='RECOVER_LAST')
125         layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO')
126
127         layout.separator()
128
129         layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA'
130         layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
131
132         layout.operator_context = 'INVOKE_AREA'
133         layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS')
134         layout.operator_context = 'INVOKE_AREA'
135         layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True
136
137         layout.separator()
138
139         layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
140
141         layout.operator_context = 'INVOKE_AREA'
142         layout.operator("wm.save_homefile", icon='SAVE_PREFS')
143         layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY')
144
145         if any(bpy.utils.app_template_paths()):
146             app_template = context.user_preferences.app_template
147             if app_template:
148                 layout.operator(
149                     "wm.read_factory_settings",
150                     text="Load Factory Template Settings",
151                     icon='LOAD_FACTORY',
152                 ).app_template = app_template
153             del app_template
154
155         layout.menu("USERPREF_MT_app_templates", icon='FILE_BLEND')
156
157         layout.separator()
158
159         layout.operator_context = 'INVOKE_AREA'
160         layout.operator("wm.link", text="Link", icon='LINK_BLEND')
161         layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
162         layout.menu("INFO_MT_file_previews")
163
164         layout.separator()
165
166         layout.menu("INFO_MT_file_import", icon='IMPORT')
167         layout.menu("INFO_MT_file_export", icon='EXPORT')
168
169         layout.separator()
170
171         layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA')
172
173         layout.separator()
174
175         layout.operator_context = 'EXEC_AREA'
176         if bpy.data.is_dirty and context.user_preferences.view.use_quit_dialog:
177             layout.operator_context = 'INVOKE_SCREEN'  # quit dialog
178         layout.operator("wm.quit_blender", text="Quit", icon='QUIT')
179
180
181 class INFO_MT_file_import(Menu):
182     bl_idname = "INFO_MT_file_import"
183     bl_label = "Import"
184
185     def draw(self, context):
186         if bpy.app.build_options.collada:
187             self.layout.operator("wm.collada_import", text="Collada (Default) (.dae)")
188         if bpy.app.build_options.alembic:
189             self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
190
191
192 class INFO_MT_file_export(Menu):
193     bl_idname = "INFO_MT_file_export"
194     bl_label = "Export"
195
196     def draw(self, context):
197         if bpy.app.build_options.collada:
198             self.layout.operator("wm.collada_export", text="Collada (Default) (.dae)")
199         if bpy.app.build_options.alembic:
200             self.layout.operator("wm.alembic_export", text="Alembic (.abc)")
201
202
203 class INFO_MT_file_external_data(Menu):
204     bl_label = "External Data"
205
206     def draw(self, context):
207         layout = self.layout
208
209         icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT'
210         layout.operator("file.autopack_toggle", icon=icon)
211
212         layout.separator()
213
214         pack_all = layout.row()
215         pack_all.operator("file.pack_all")
216         pack_all.active = not bpy.data.use_autopack
217
218         unpack_all = layout.row()
219         unpack_all.operator("file.unpack_all")
220         unpack_all.active = not bpy.data.use_autopack
221
222         layout.separator()
223
224         layout.operator("file.make_paths_relative")
225         layout.operator("file.make_paths_absolute")
226         layout.operator("file.report_missing_files")
227         layout.operator("file.find_missing_files")
228
229
230 class INFO_MT_file_previews(Menu):
231     bl_label = "Data Previews"
232
233     def draw(self, context):
234         layout = self.layout
235
236         layout.operator("wm.previews_ensure")
237         layout.operator("wm.previews_batch_generate")
238
239         layout.separator()
240
241         layout.operator("wm.previews_clear")
242         layout.operator("wm.previews_batch_clear")
243
244
245 class INFO_MT_game(Menu):
246     bl_label = "Game"
247
248     def draw(self, context):
249         layout = self.layout
250
251         gs = context.scene.game_settings
252
253         layout.operator("view3d.game_start")
254
255         layout.separator()
256
257         layout.prop(gs, "show_debug_properties")
258         layout.prop(gs, "show_framerate_profile")
259         layout.prop(gs, "show_physics_visualization")
260         layout.prop(gs, "use_deprecation_warnings")
261         layout.prop(gs, "use_animation_record")
262         layout.separator()
263         layout.prop(gs, "use_auto_start")
264
265
266 class INFO_MT_render(Menu):
267     bl_label = "Render"
268
269     def draw(self, context):
270         layout = self.layout
271
272         layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True
273         props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION')
274         props.animation = True
275         props.use_viewport = True
276
277         layout.separator()
278
279         layout.operator("render.opengl", text="OpenGL Render Image")
280         layout.operator("render.opengl", text="OpenGL Render Animation").animation = True
281         layout.menu("INFO_MT_opengl_render")
282
283         layout.separator()
284
285         layout.operator("render.view_show")
286         layout.operator("render.play_rendered_anim", icon='PLAY')
287
288
289 class INFO_MT_opengl_render(Menu):
290     bl_label = "OpenGL Render Options"
291
292     def draw(self, context):
293         layout = self.layout
294
295         rd = context.scene.render
296         layout.prop(rd, "use_antialiasing")
297         layout.prop(rd, "use_full_sample")
298
299         layout.prop_menu_enum(rd, "antialiasing_samples")
300         layout.prop_menu_enum(rd, "alpha_mode")
301
302
303 class INFO_MT_window(Menu):
304     bl_label = "Window"
305
306     def draw(self, context):
307         import sys
308
309         layout = self.layout
310
311         layout.operator("wm.window_new")
312         layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
313
314         layout.separator()
315
316         layout.operator("screen.screenshot")
317         layout.operator("screen.screencast")
318
319         if sys.platform[:3] == "win":
320             layout.separator()
321             layout.operator("wm.console_toggle", icon='CONSOLE')
322
323         if context.scene.render.use_multiview:
324             layout.separator()
325             layout.operator("wm.set_stereo_3d", icon='CAMERA_STEREO')
326
327
328 class INFO_MT_help(Menu):
329     bl_label = "Help"
330
331     def draw(self, context):
332         layout = self.layout
333
334         layout.operator(
335                 "wm.url_open", text="Manual", icon='HELP',
336                 ).url = "https://docs.blender.org/manual/en/dev/"
337         layout.operator(
338                 "wm.url_open", text="Release Log", icon='URL',
339                 ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2]
340         layout.separator()
341
342         layout.operator(
343                 "wm.url_open", text="Blender Website", icon='URL',
344                 ).url = "https://www.blender.org"
345         layout.operator(
346                 "wm.url_open", text="Blender Store", icon='URL',
347                 ).url = "https://store.blender.org"
348         layout.operator(
349                 "wm.url_open", text="Developer Community", icon='URL',
350                 ).url = "https://www.blender.org/get-involved/"
351         layout.operator(
352                 "wm.url_open", text="User Community", icon='URL',
353                 ).url = "https://www.blender.org/support/user-community"
354         layout.separator()
355         layout.operator(
356                 "wm.url_open", text="Report a Bug", icon='URL',
357                 ).url = "https://developer.blender.org/maniphest/task/edit/form/1"
358         layout.separator()
359
360         layout.operator(
361                 "wm.url_open", text="Python API Reference", icon='URL',
362                 ).url = bpy.types.WM_OT_doc_view._prefix
363
364         layout.operator("wm.operator_cheat_sheet", icon='TEXT')
365         layout.operator("wm.sysinfo", icon='TEXT')
366         layout.separator()
367
368         layout.operator("wm.splash", icon='BLENDER')
369
370
371 classes = (
372     INFO_HT_header,
373     INFO_MT_editor_menus,
374     INFO_MT_file,
375     INFO_MT_file_import,
376     INFO_MT_file_export,
377     INFO_MT_file_external_data,
378     INFO_MT_file_previews,
379     INFO_MT_game,
380     INFO_MT_render,
381     INFO_MT_opengl_render,
382     INFO_MT_window,
383     INFO_MT_help,
384 )
385
386 if __name__ == "__main__":  # only for live edit.
387     from bpy.utils import register_class
388     for cls in classes:
389         register_class(cls)