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