Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/startup/bl_ui/space_topbar.py')
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py715
1 files changed, 715 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
new file mode 100644
index 00000000000..0171d98af0b
--- /dev/null
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -0,0 +1,715 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Header, Menu, Panel
+
+
+class TOPBAR_HT_upper_bar(Header):
+ bl_space_type = 'TOPBAR'
+
+ def draw(self, context):
+ region = context.region
+
+ if region.alignment == 'RIGHT':
+ self.draw_right(context)
+ else:
+ self.draw_left(context)
+
+ def draw_left(self, context):
+ layout = self.layout
+
+ window = context.window
+ screen = context.screen
+
+ layout.operator("wm.splash", text="", icon='BLENDER', emboss=False)
+
+ INFO_MT_editor_menus.draw_collapsible(context, layout)
+
+ layout.separator()
+
+ if not screen.show_fullscreen:
+ layout.template_ID_tabs(
+ window, "workspace",
+ new="workspace.workspace_add_menu",
+ unlink="workspace.workspace_delete",
+ )
+ else:
+ layout.operator(
+ "screen.back_to_previous",
+ icon='SCREEN_BACK',
+ text="Back to Previous",
+ )
+
+ def draw_right(self, context):
+ layout = self.layout
+
+ window = context.window
+ scene = window.scene
+
+ # Active workspace view-layer is retrieved through window, not through workspace.
+ layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete")
+
+ row = layout.row(align=True)
+ row.template_search(
+ window, "view_layer",
+ scene, "view_layers",
+ new="scene.view_layer_add",
+ unlink="scene.view_layer_remove")
+
+
+class TOPBAR_HT_lower_bar(Header):
+ bl_space_type = 'TOPBAR'
+ bl_region_type = 'WINDOW'
+
+ def draw(self, context):
+ layout = self.layout
+ region = context.region
+
+ if region.alignment == 'LEFT':
+ self.draw_left(context)
+ elif region.alignment == 'RIGHT':
+ self.draw_right(context)
+ else:
+ self.draw_center(context)
+
+ def draw_left(self, context):
+ layout = self.layout
+ layer = context.view_layer
+ object = layer.objects.active
+
+ # Object Mode
+ # -----------
+ object_mode = 'OBJECT' if object is None else object.mode
+ act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[object_mode]
+
+ layout.operator_menu_enum("object.mode_set", "mode", text=act_mode_item.name, icon=act_mode_item.icon)
+
+ layout.template_header_3D_mode()
+
+ def draw_center(self, context):
+ layout = self.layout
+ mode = context.mode
+
+ # Active Tool
+ # -----------
+ from .space_toolsystem_common import ToolSelectPanelHelper
+ ToolSelectPanelHelper.draw_active_tool_header(context, layout)
+
+ # Object Mode Options
+ # -------------------
+
+ # Example of how toolsettings can be accessed as pop-overs.
+
+ # TODO(campbell): editing options should be after active tool options
+ # (obviously separated for from the users POV)
+ draw_fn = getattr(_draw_left_context_mode, mode, None)
+ if draw_fn is not None:
+ draw_fn(context, layout)
+
+ # Note: general mode options should be added to 'draw_right'.
+ if mode == 'SCULPT':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+ elif mode == 'PAINT_VERTEX':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+ elif mode == 'PAINT_WEIGHT':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+ elif mode == 'PAINT_TEXTURE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+ elif mode == 'EDIT_ARMATURE':
+ pass
+ elif mode == 'EDIT_CURVE':
+ pass
+ elif mode == 'EDIT_MESH':
+ pass
+ elif mode == 'POSE':
+ pass
+ elif mode == 'PARTICLE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
+
+ def draw_right(self, context):
+ layout = self.layout
+
+ # General options, note, these _could_ display at the RHS of the draw_left callback.
+ # we just want them not to be confused with tool options.
+ mode = context.mode
+
+ if mode == 'SCULPT':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".sculpt_mode", category="")
+ elif mode == 'PAINT_VERTEX':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".vertexpaint", category="")
+ elif mode == 'PAINT_WEIGHT':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".weightpaint", category="")
+ elif mode == 'PAINT_TEXTURE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".imagepaint", category="")
+ elif mode == 'EDIT_ARMATURE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".armature_edit", category="")
+ elif mode == 'EDIT_CURVE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".curve_edit", category="")
+ elif mode == 'EDIT_MESH':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".mesh_edit", category="")
+ elif mode == 'POSE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".posemode", category="")
+ elif mode == 'PARTICLE':
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".particlemode", category="")
+
+ # 3D View Options, tsk. maybe users aren't always using 3D view?
+ toolsettings = context.tool_settings
+ scene = context.scene
+ obj = context.active_object
+
+ object_mode = 'OBJECT' if obj is None else obj.mode
+
+ # Pivot & Orientation
+ pivot_point = context.tool_settings.transform_pivot_point
+ act_pivot_point = bpy.types.ToolSettings.bl_rna.properties['transform_pivot_point'].enum_items[pivot_point]
+
+ row = layout.row(align=True)
+ row.popover(
+ space_type='TOPBAR',
+ region_type='HEADER',
+ panel_type="TOPBAR_PT_pivot_point",
+ icon=act_pivot_point.icon,
+ text="",
+ )
+
+ if obj:
+ # Proportional editing
+ if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+
+ sub = row.row(align=True)
+ sub.active = toolsettings.proportional_edit != 'DISABLED'
+ sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+
+ elif object_mode in {'EDIT', 'PARTICLE_EDIT'}:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+ sub = row.row(align=True)
+ sub.active = toolsettings.proportional_edit != 'DISABLED'
+ sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+
+ elif object_mode == 'OBJECT':
+ row = layout.row(align=True)
+ row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True)
+ sub = row.row(align=True)
+ sub.active = toolsettings.use_proportional_edit_objects
+ sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+ else:
+ # Proportional editing
+ if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+ sub = row.row(align=True)
+ sub.active = toolsettings.proportional_edit != 'DISABLED'
+ sub.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+
+ # Snap
+ show_snap = False
+ if obj is None:
+ show_snap = True
+ else:
+ if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
+ show_snap = True
+ else:
+
+ from .properties_paint_common import UnifiedPaintPanel
+ paint_settings = UnifiedPaintPanel.paint_settings(context)
+
+ if paint_settings:
+ brush = paint_settings.brush
+ if brush and brush.stroke_method == 'CURVE':
+ show_snap = True
+
+ if show_snap:
+ snap_items = bpy.types.ToolSettings.bl_rna.properties['snap_elements'].enum_items
+ for elem in toolsettings.snap_elements:
+ # TODO: Display multiple icons.
+ # (Currently only one of the enabled modes icons is displayed)
+ icon = snap_items[elem].icon
+ break
+ else:
+ icon = 'NONE'
+
+ row = layout.row(align=True)
+ row.prop(toolsettings, "use_snap", text="")
+
+ sub = row.row(align=True)
+ sub.popover(
+ space_type='TOPBAR',
+ region_type='HEADER',
+ panel_type="TOPBAR_PT_snapping",
+ icon=icon,
+ text=""
+ )
+
+ layout.prop(scene, "transform_orientation", text="")
+
+ # Command Settings (redo)
+ op = context.active_operator
+ row = layout.row()
+ row.enabled = op is not None
+ row.popover(
+ space_type='TOPBAR',
+ region_type='HEADER',
+ panel_type="TOPBAR_PT_redo",
+ text=op.name + " Settings" if op else "Command Settings",
+ )
+
+
+class _draw_left_context_mode:
+ @staticmethod
+ def SCULPT(context, layout):
+ brush = context.tool_settings.sculpt.brush
+ if brush is None:
+ return
+
+ from .properties_paint_common import UnifiedPaintPanel
+
+ UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius")
+ UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
+ layout.prop(brush, "direction", text="", expand=True)
+
+ def PAINT_TEXTURE(context, layout):
+ brush = context.tool_settings.vertex_paint.brush
+ if brush is None:
+ return
+
+ from .properties_paint_common import UnifiedPaintPanel
+
+ layout.prop(brush, "color", text="")
+ UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius")
+ UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
+
+ def PAINT_VERTEX(context, layout):
+ brush = context.tool_settings.vertex_paint.brush
+ if brush is None:
+ return
+
+ from .properties_paint_common import UnifiedPaintPanel
+
+ layout.prop(brush, "color", text="")
+ UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius")
+ UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
+
+ def PAINT_WEIGHT(context, layout):
+ brush = context.tool_settings.weight_paint.brush
+ if brush is None:
+ return
+
+ from .properties_paint_common import UnifiedPaintPanel
+
+ UnifiedPaintPanel.prop_unified_weight(layout, context, brush, "weight", slider=True, text="Weight")
+ UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius")
+ UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength")
+
+
+class TOPBAR_PT_pivot_point(Panel):
+ bl_space_type = 'TOPBAR'
+ bl_region_type = 'HEADER'
+ bl_label = "Pivot Point"
+
+ def draw(self, context):
+ toolsettings = context.tool_settings
+ obj = context.active_object
+ mode = context.mode
+
+ layout = self.layout
+ col = layout.column()
+ col.label("Pivot Point")
+ col.prop(toolsettings, "transform_pivot_point", expand=True)
+
+ col.separator()
+
+ if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}):
+ col.prop(
+ toolsettings,
+ "use_transform_pivot_point_align",
+ text="Center Points Only",
+ )
+
+
+class TOPBAR_PT_snapping(Panel):
+ bl_space_type = 'TOPBAR'
+ bl_region_type = 'HEADER'
+ bl_label = "Snapping"
+
+ def draw(self, context):
+ toolsettings = context.tool_settings
+ snap_elements = toolsettings.snap_elements
+ obj = context.active_object
+ mode = context.mode
+ object_mode = 'OBJECT' if obj is None else obj.mode
+
+ layout = self.layout
+ col = layout.column()
+ col.label("Snapping")
+ col.prop(toolsettings, "snap_elements", expand=True)
+
+ col.separator()
+ if 'INCREMENT' in snap_elements:
+ col.prop(toolsettings, "use_snap_grid_absolute")
+
+ if snap_elements != {'INCREMENT'}:
+ col.label("Target")
+ row = col.row(align=True)
+ row.prop(toolsettings, "snap_target", expand=True)
+
+ if obj:
+ if object_mode == 'EDIT':
+ col.prop(toolsettings, "use_snap_self")
+ if object_mode in {'OBJECT', 'POSE', 'EDIT'}:
+ col.prop(toolsettings, "use_snap_align_rotation", text="Align Rotation")
+
+ if 'FACE' in snap_elements:
+ col.prop(toolsettings, "use_snap_project", text="Project Elements")
+
+ if 'VOLUME' in snap_elements:
+ col.prop(toolsettings, "use_snap_peel_object")
+
+ # Auto-Merge Editing
+ if obj:
+ if (object_mode == 'EDIT' and obj.type == 'MESH'):
+ col.prop(toolsettings, "use_mesh_automerge", icon='AUTOMERGE_ON')
+
+
+class INFO_MT_editor_menus(Menu):
+ bl_idname = "INFO_MT_editor_menus"
+ bl_label = ""
+
+ def draw(self, context):
+ self.draw_menus(self.layout, context)
+
+ @staticmethod
+ def draw_menus(layout, context):
+ layout.menu("INFO_MT_file")
+ layout.menu("INFO_MT_edit")
+
+ layout.menu("INFO_MT_render")
+
+ layout.menu("INFO_MT_window")
+ layout.menu("INFO_MT_help")
+
+
+class INFO_MT_file(Menu):
+ bl_label = "File"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator_context = 'INVOKE_AREA'
+ layout.operator("wm.read_homefile", text="New", icon='NEW')
+ layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
+ layout.menu("INFO_MT_file_open_recent", icon='OPEN_RECENT')
+ layout.operator("wm.revert_mainfile", icon='FILE_REFRESH')
+ layout.operator("wm.recover_last_session", icon='RECOVER_LAST')
+ layout.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='RECOVER_AUTO')
+
+ layout.separator()
+
+ layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA'
+ layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
+
+ layout.operator_context = 'INVOKE_AREA'
+ layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS')
+ layout.operator_context = 'INVOKE_AREA'
+ layout.operator("wm.save_as_mainfile", text="Save Copy...", icon='SAVE_COPY').copy = True
+
+ layout.separator()
+
+ layout.operator_context = 'INVOKE_AREA'
+ layout.operator("wm.save_homefile", icon='SAVE_PREFS')
+ layout.operator("wm.read_factory_settings", icon='LOAD_FACTORY')
+
+ layout.separator()
+
+ layout.operator_context = 'INVOKE_AREA'
+ layout.operator("wm.link", text="Link", icon='LINK_BLEND')
+ layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ layout.menu("INFO_MT_file_previews")
+
+ layout.separator()
+
+ layout.menu("INFO_MT_file_import", icon='IMPORT')
+ layout.menu("INFO_MT_file_export", icon='EXPORT')
+
+ layout.separator()
+
+ layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA')
+
+ layout.separator()
+
+ layout.operator_context = 'EXEC_AREA'
+ if bpy.data.is_dirty and context.user_preferences.view.use_quit_dialog:
+ layout.operator_context = 'INVOKE_SCREEN' # quit dialog
+ layout.operator("wm.quit_blender", text="Quit", icon='QUIT')
+
+
+class INFO_MT_file_import(Menu):
+ bl_idname = "INFO_MT_file_import"
+ bl_label = "Import"
+
+ def draw(self, context):
+ if bpy.app.build_options.collada:
+ self.layout.operator("wm.collada_import", text="Collada (Default) (.dae)")
+ if bpy.app.build_options.alembic:
+ self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
+
+
+class INFO_MT_file_export(Menu):
+ bl_idname = "INFO_MT_file_export"
+ bl_label = "Export"
+
+ def draw(self, context):
+ if bpy.app.build_options.collada:
+ self.layout.operator("wm.collada_export", text="Collada (Default) (.dae)")
+ if bpy.app.build_options.alembic:
+ self.layout.operator("wm.alembic_export", text="Alembic (.abc)")
+
+
+class INFO_MT_file_external_data(Menu):
+ bl_label = "External Data"
+
+ def draw(self, context):
+ layout = self.layout
+
+ icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT'
+ layout.operator("file.autopack_toggle", icon=icon)
+
+ layout.separator()
+
+ pack_all = layout.row()
+ pack_all.operator("file.pack_all")
+ pack_all.active = not bpy.data.use_autopack
+
+ unpack_all = layout.row()
+ unpack_all.operator("file.unpack_all")
+ unpack_all.active = not bpy.data.use_autopack
+
+ layout.separator()
+
+ layout.operator("file.make_paths_relative")
+ layout.operator("file.make_paths_absolute")
+ layout.operator("file.report_missing_files")
+ layout.operator("file.find_missing_files")
+
+
+class INFO_MT_file_previews(Menu):
+ bl_label = "Data Previews"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.previews_ensure")
+ layout.operator("wm.previews_batch_generate")
+
+ layout.separator()
+
+ layout.operator("wm.previews_clear")
+ layout.operator("wm.previews_batch_clear")
+
+
+class INFO_MT_game(Menu):
+ bl_label = "Game"
+
+ def draw(self, context):
+ layout = self.layout
+
+ gs = context.scene.game_settings
+
+ layout.operator("view3d.game_start")
+
+ layout.separator()
+
+ layout.prop(gs, "show_debug_properties")
+ layout.prop(gs, "show_framerate_profile")
+ layout.prop(gs, "show_physics_visualization")
+ layout.prop(gs, "use_deprecation_warnings")
+ layout.prop(gs, "use_animation_record")
+ layout.separator()
+ layout.prop(gs, "use_auto_start")
+
+
+class INFO_MT_render(Menu):
+ bl_label = "Render"
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+
+ layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True
+ props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION')
+ props.animation = True
+ props.use_viewport = True
+ layout.operator("sound.mixdown", text="Render Audio", icon='PLAY_AUDIO')
+
+ layout.separator()
+
+ layout.prop_menu_enum(rd, "display_mode", text="Display Mode", icon='IMAGE_COL')
+ layout.prop(rd, "use_lock_interface", text="Lock Interface")
+
+ layout.separator()
+
+ props = layout.operator("render.opengl", text="OpenGL Render Image", icon='RENDER_STILL')
+ props.view_context = False
+ props = layout.operator("render.opengl", text="OpenGL Render Animation", icon='RENDER_ANIMATION')
+ props.view_context = False
+ props.animation = True
+ layout.menu("INFO_MT_opengl_render", icon='SETTINGS')
+
+ layout.separator()
+
+ layout.operator("render.view_show")
+ layout.operator("render.play_rendered_anim", icon='PLAY')
+
+
+class INFO_MT_opengl_render(Menu):
+ bl_label = "OpenGL Render Options"
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+ layout.prop(rd, "use_antialiasing")
+ layout.prop(rd, "use_full_sample")
+
+ layout.prop_menu_enum(rd, "antialiasing_samples")
+ layout.prop_menu_enum(rd, "alpha_mode")
+
+
+class INFO_MT_edit(Menu):
+ bl_label = "Edit"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("ed.undo")
+ layout.operator("ed.redo")
+
+ layout.separator()
+
+ layout.operator("ed.undo_history", text="Undo History...")
+
+ layout.separator()
+
+ layout.operator("screen.repeat_last")
+ layout.operator("screen.repeat_history", text="Repeat History...")
+
+ layout.separator()
+
+ layout.operator("screen.redo_last", text="Adjust Last Operation...")
+
+ layout.separator()
+
+ layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
+
+
+class INFO_MT_window(Menu):
+ bl_label = "Window"
+
+ def draw(self, context):
+ import sys
+
+ layout = self.layout
+
+ layout.operator("wm.window_new")
+ layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
+
+ layout.separator()
+
+ layout.operator("screen.screenshot")
+ layout.operator("screen.screencast")
+
+ if sys.platform[:3] == "win":
+ layout.separator()
+ layout.operator("wm.console_toggle", icon='CONSOLE')
+
+ if context.scene.render.use_multiview:
+ layout.separator()
+ layout.operator("wm.set_stereo_3d", icon='CAMERA_STEREO')
+
+
+class INFO_MT_help(Menu):
+ bl_label = "Help"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator(
+ "wm.url_open", text="Manual", icon='HELP',
+ ).url = "https://docs.blender.org/manual/en/dev/"
+ layout.operator(
+ "wm.url_open", text="Release Log", icon='URL',
+ ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2]
+ layout.separator()
+
+ layout.operator(
+ "wm.url_open", text="Blender Website", icon='URL',
+ ).url = "https://www.blender.org"
+ layout.operator(
+ "wm.url_open", text="Blender Store", icon='URL',
+ ).url = "https://store.blender.org"
+ layout.operator(
+ "wm.url_open", text="Developer Community", icon='URL',
+ ).url = "https://www.blender.org/get-involved/"
+ layout.operator(
+ "wm.url_open", text="User Community", icon='URL',
+ ).url = "https://www.blender.org/support/user-community"
+ layout.separator()
+ layout.operator(
+ "wm.url_open", text="Report a Bug", icon='URL',
+ ).url = "https://developer.blender.org/maniphest/task/edit/form/1"
+ layout.separator()
+
+ layout.operator(
+ "wm.url_open", text="Python API Reference", icon='URL',
+ ).url = bpy.types.WM_OT_doc_view._prefix
+
+ layout.operator("wm.operator_cheat_sheet", icon='TEXT')
+ layout.operator("wm.sysinfo", icon='TEXT')
+ layout.separator()
+
+ layout.operator("wm.splash", icon='BLENDER')
+
+
+classes = (
+ TOPBAR_HT_upper_bar,
+ TOPBAR_HT_lower_bar,
+ TOPBAR_PT_pivot_point,
+ TOPBAR_PT_snapping,
+ INFO_MT_editor_menus,
+ INFO_MT_file,
+ INFO_MT_file_import,
+ INFO_MT_file_export,
+ INFO_MT_file_external_data,
+ INFO_MT_file_previews,
+ INFO_MT_edit,
+ INFO_MT_game,
+ INFO_MT_render,
+ INFO_MT_opengl_render,
+ INFO_MT_window,
+ INFO_MT_help,
+)
+
+if __name__ == "__main__": # only for live edit.
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)