Files
test2/scripts/startup/bl_ui/space_topbar.py
Sergey Sharybin 03806d0b67 Re-design of submodules used in blender.git
This commit implements described in the #104573.

The goal is to fix the confusion of the submodule hashes change, which are not
ideal for any of the supported git-module configuration (they are either always
visible causing confusion, or silently staged and committed, also causing
confusion).

This commit replaces submodules with a checkout of addons and addons_contrib,
covered by the .gitignore, and locale and developer tools are moved to the
main repository.

This also changes the paths:
- /release/scripts are moved to the /scripts
- /source/tools are moved to the /tools
- /release/datafiles/locale is moved to /locale

This is done to avoid conflicts when using bisect, and also allow buildbot to
automatically "recover" wgen building older or newer branches/patches.

Running `make update` will initialize the local checkout to the changed
repository configuration.

Another aspect of the change is that the make update will support Github style
of remote organization (origin remote pointing to thy fork, upstream remote
pointing to the upstream blender/blender.git).

Pull Request #104755
2023-02-21 16:39:58 +01:00

967 lines
30 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Header, Menu, Panel
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,
)
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
TOPBAR_MT_editor_menus.draw_collapsible(context, layout)
layout.separator()
if not screen.show_fullscreen:
layout.template_ID_tabs(
window, "workspace",
new="workspace.add",
menu="TOPBAR_MT_workspace_menu",
)
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
screen = context.screen
scene = window.scene
# If statusbar is hidden, still show messages at the top
if not screen.show_statusbar:
layout.template_reports_banner()
layout.template_running_jobs()
# 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_PT_tool_settings_extra(Panel):
"""
Popover panel for adding extra options that don't fit in the tool settings header
"""
bl_idname = "TOPBAR_PT_tool_settings_extra"
bl_region_type = 'HEADER'
bl_space_type = 'TOPBAR'
bl_label = "Extra Options"
def draw(self, context):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
layout = self.layout
# Get the active tool
space_type, mode = ToolSelectPanelHelper._tool_key_from_context(
context)
cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
item, tool, _ = cls._tool_get_active(
context, space_type, mode, with_icon=True)
if item is None:
return
# Draw the extra settings
item.draw_settings(context, layout, tool, extra=True)
class TOPBAR_PT_tool_fallback(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Layers"
bl_ui_units_x = 8
def draw(self, context):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
layout = self.layout
tool_settings = context.tool_settings
ToolSelectPanelHelper.draw_fallback_tool_items(layout, context)
if tool_settings.workspace_tool_type == 'FALLBACK':
tool = context.tool
ToolSelectPanelHelper.draw_active_tool_fallback(
context, layout, tool)
class TOPBAR_PT_gpencil_layers(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Layers"
bl_ui_units_x = 14
@classmethod
def poll(cls, context):
if context.gpencil_data is None:
return False
ob = context.object
if ob is not None and ob.type == 'GPENCIL':
return True
return False
def draw(self, context):
layout = self.layout
gpd = context.gpencil_data
# Grease Pencil data...
if (gpd is None) or (not gpd.layers):
layout.operator("gpencil.layer_add", text="New Layer")
else:
self.draw_layers(context, layout, gpd)
def draw_layers(self, context, layout, gpd):
row = layout.row()
col = row.column()
layer_rows = 10
col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index",
rows=layer_rows, sort_reverse=True, sort_lock=True)
gpl = context.active_gpencil_layer
if gpl:
srow = col.row(align=True)
srow.prop(gpl, "blend_mode", text="Blend")
srow = col.row(align=True)
srow.prop(gpl, "opacity", text="Opacity", slider=True)
srow.prop(gpl, "use_mask_layer", text="",
icon='MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE')
srow = col.row(align=True)
srow.prop(gpl, "use_lights")
col = row.column()
sub = col.column(align=True)
sub.operator("gpencil.layer_add", icon='ADD', text="")
sub.operator("gpencil.layer_remove", icon='REMOVE', text="")
gpl = context.active_gpencil_layer
if gpl:
sub.menu("GPENCIL_MT_layer_context_menu",
icon='DOWNARROW_HLT', text="")
if len(gpd.layers) > 1:
col.separator()
sub = col.column(align=True)
sub.operator("gpencil.layer_move",
icon='TRIA_UP', text="").type = 'UP'
sub.operator("gpencil.layer_move",
icon='TRIA_DOWN', text="").type = 'DOWN'
col.separator()
sub = col.column(align=True)
sub.operator("gpencil.layer_isolate", icon='HIDE_OFF',
text="").affect_visibility = True
sub.operator("gpencil.layer_isolate", icon='LOCKED',
text="").affect_visibility = False
class TOPBAR_MT_editor_menus(Menu):
bl_idname = "TOPBAR_MT_editor_menus"
bl_label = ""
def draw(self, context):
layout = self.layout
# Allow calling this menu directly (this might not be a header area).
if getattr(context.area, "show_menus", False):
layout.menu("TOPBAR_MT_blender", text="", icon='BLENDER')
else:
layout.menu("TOPBAR_MT_blender", text="Blender")
layout.menu("TOPBAR_MT_file")
layout.menu("TOPBAR_MT_edit")
layout.menu("TOPBAR_MT_render")
layout.menu("TOPBAR_MT_window")
layout.menu("TOPBAR_MT_help")
class TOPBAR_MT_blender(Menu):
bl_label = "Blender"
def draw(self, _context):
layout = self.layout
layout.operator("wm.splash")
layout.operator("wm.splash_about")
layout.separator()
layout.operator("preferences.app_template_install",
text="Install Application Template...")
layout.separator()
layout.menu("TOPBAR_MT_blender_system")
class TOPBAR_MT_file_cleanup(Menu):
bl_label = "Clean Up"
def draw(self, _context):
layout = self.layout
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = True
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = True
op_props.do_recursive = True
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
op_props.do_local_ids = False
op_props.do_linked_ids = True
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
op_props.do_local_ids = False
op_props.do_linked_ids = True
op_props.do_recursive = True
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = False
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = False
op_props.do_recursive = True
class TOPBAR_MT_file(Menu):
bl_label = "File"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.menu("TOPBAR_MT_file_open_recent")
layout.operator("wm.revert_mainfile")
layout.menu("TOPBAR_MT_file_recover")
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...")
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.save_as_mainfile", text="Save Copy...").copy = True
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("TOPBAR_MT_file_previews")
layout.separator()
layout.menu("TOPBAR_MT_file_import", icon='IMPORT')
layout.menu("TOPBAR_MT_file_export", icon='EXPORT')
layout.separator()
layout.menu("TOPBAR_MT_file_external_data")
layout.menu("TOPBAR_MT_file_cleanup")
layout.separator()
layout.menu("TOPBAR_MT_file_defaults")
layout.separator()
layout.operator("wm.quit_blender", text="Quit", icon='QUIT')
class TOPBAR_MT_file_new(Menu):
bl_label = "New File"
@staticmethod
def app_template_paths():
import os
template_paths = bpy.utils.app_template_paths()
# Expand template paths.
# Use a set to avoid duplicate user/system templates.
# This is a corner case, but users managed to do it! #76849.
app_templates = set()
for path in template_paths:
for d in os.listdir(path):
if d.startswith(("__", ".")):
continue
template = os.path.join(path, d)
if os.path.isdir(template):
app_templates.add(d)
return sorted(app_templates)
@staticmethod
def draw_ex(layout, _context, *, use_splash=False, use_more=False):
layout.operator_context = 'INVOKE_DEFAULT'
# Limit number of templates in splash screen, spill over into more menu.
paths = TOPBAR_MT_file_new.app_template_paths()
splash_limit = 5
if use_splash:
icon = 'FILE_NEW'
show_more = len(paths) > (splash_limit - 1)
if show_more:
paths = paths[:splash_limit - 2]
elif use_more:
icon = 'FILE_NEW'
paths = paths[splash_limit - 2:]
show_more = False
else:
icon = 'NONE'
show_more = False
# Draw application templates.
if not use_more:
props = layout.operator(
"wm.read_homefile", text="General", icon=icon)
props.app_template = ""
for d in paths:
props = layout.operator(
"wm.read_homefile",
text=bpy.path.display_name(iface_(d)),
icon=icon,
)
props.app_template = d
layout.operator_context = 'EXEC_DEFAULT'
if show_more:
layout.menu("TOPBAR_MT_templates_more", text="...")
def draw(self, context):
TOPBAR_MT_file_new.draw_ex(self.layout, context)
class TOPBAR_MT_file_recover(Menu):
bl_label = "Recover"
def draw(self, _context):
layout = self.layout
layout.operator("wm.recover_last_session", text="Last Session")
layout.operator("wm.recover_auto_save", text="Auto Save...")
class TOPBAR_MT_file_defaults(Menu):
bl_label = "Defaults"
def draw(self, context):
layout = self.layout
prefs = context.preferences
layout.operator_context = 'INVOKE_AREA'
if any(bpy.utils.app_template_paths()):
app_template = prefs.app_template
else:
app_template = None
if app_template:
layout.label(
text=iface_(bpy.path.display_name(app_template, has_ext=False),
i18n_contexts.id_workspace), translate=False)
layout.operator("wm.save_homefile")
if app_template:
display_name = bpy.path.display_name(iface_(app_template))
props = layout.operator("wm.read_factory_settings",
text="Load Factory Blender Settings")
props.app_template = app_template
props = layout.operator("wm.read_factory_settings",
text=iface_("Load Factory %s Settings",
i18n_contexts.operator_default) % display_name,
translate=False)
props.app_template = app_template
props.use_factory_startup_app_template_only = True
del display_name
else:
layout.operator("wm.read_factory_settings")
# Include technical operators here which would otherwise have no way for users to access.
class TOPBAR_MT_blender_system(Menu):
bl_label = "System"
def draw(self, _context):
layout = self.layout
layout.operator("script.reload")
layout.separator()
layout.operator("wm.memory_statistics")
layout.operator("wm.debug_menu")
layout.operator_menu_enum("wm.redraw_timer", "type")
layout.separator()
layout.operator("screen.spacedata_cleanup")
class TOPBAR_MT_templates_more(Menu):
bl_label = "Templates"
def draw(self, context):
bpy.types.TOPBAR_MT_file_new.draw_ex(
self.layout, context, use_more=True)
class TOPBAR_MT_file_import(Menu):
bl_idname = "TOPBAR_MT_file_import"
bl_label = "Import"
bl_owner_use_filter = False
def draw(self, _context):
if bpy.app.build_options.collada:
self.layout.operator("wm.collada_import", text="Collada (.dae)")
if bpy.app.build_options.alembic:
self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
if bpy.app.build_options.usd:
self.layout.operator(
"wm.usd_import", text="Universal Scene Description (.usd*)")
if bpy.app.build_options.io_gpencil:
self.layout.operator("wm.gpencil_import_svg", text="SVG as Grease Pencil")
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_import", text="Wavefront (.obj)")
if bpy.app.build_options.io_stl:
self.layout.operator("wm.stl_import", text="STL (.stl) (experimental)")
class TOPBAR_MT_file_export(Menu):
bl_idname = "TOPBAR_MT_file_export"
bl_label = "Export"
bl_owner_use_filter = False
def draw(self, _context):
if bpy.app.build_options.collada:
self.layout.operator("wm.collada_export", text="Collada (.dae)")
if bpy.app.build_options.alembic:
self.layout.operator("wm.alembic_export", text="Alembic (.abc)")
if bpy.app.build_options.usd:
self.layout.operator(
"wm.usd_export", text="Universal Scene Description (.usd, .usdc, .usda)")
if bpy.app.build_options.io_gpencil:
# Pugixml lib dependency
if bpy.app.build_options.pugixml:
self.layout.operator("wm.gpencil_export_svg", text="Grease Pencil as SVG")
# Haru lib dependency
if bpy.app.build_options.haru:
self.layout.operator("wm.gpencil_export_pdf", text="Grease Pencil as PDF")
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_export", text="Wavefront (.obj)")
class TOPBAR_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)
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.pack_libraries")
layout.operator("file.unpack_libraries")
layout.separator()
layout.operator("file.make_paths_relative")
layout.operator("file.make_paths_absolute")
layout.separator()
layout.operator("file.report_missing_files")
layout.operator("file.find_missing_files")
class TOPBAR_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 TOPBAR_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.separator()
layout.operator("sound.mixdown", text="Render Audio...")
layout.separator()
layout.operator("render.view_show", text="View Render")
layout.operator("render.play_rendered_anim", text="View Animation")
layout.separator()
layout.prop(rd, "use_lock_interface", text="Lock Interface")
class TOPBAR_MT_edit(Menu):
bl_label = "Edit"
def draw(self, context):
layout = self.layout
show_developer = context.preferences.view.show_developer_ui
layout.operator("ed.undo")
layout.operator("ed.redo")
layout.separator()
layout.menu("TOPBAR_MT_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("wm.search_menu", text="Menu Search...", icon='VIEWZOOM')
if show_developer:
layout.operator("wm.search_operator", text="Operator Search...", icon='VIEWZOOM')
layout.separator()
# Mainly to expose shortcut since this depends on the context.
props = layout.operator("wm.call_panel", text="Rename Active Item...")
props.name = "TOPBAR_PT_name"
props.keep_open = False
layout.operator("wm.batch_rename", text="Batch Rename...")
layout.separator()
# Should move elsewhere (impacts outliner & 3D view).
tool_settings = context.tool_settings
layout.prop(tool_settings, "lock_object_mode")
layout.separator()
layout.operator("screen.userpref_show",
text="Preferences...", icon='PREFERENCES')
class TOPBAR_MT_window(Menu):
bl_label = "Window"
def draw(self, context):
import sys
layout = self.layout
operator_context_default = layout.operator_context
layout.operator("wm.window_new")
layout.operator("wm.window_new_main")
layout.separator()
layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
layout.separator()
layout.operator("screen.workspace_cycle",
text="Next Workspace").direction = 'NEXT'
layout.operator("screen.workspace_cycle",
text="Previous Workspace").direction = 'PREV'
layout.separator()
layout.prop(context.screen, "show_statusbar")
layout.separator()
layout.operator("screen.screenshot")
# Showing the status in the area doesn't work well in this case.
# - From the top-bar, the text replaces the file-menu (not so bad but strange).
# - From menu-search it replaces the area that the user may want to screen-shot.
# Setting the context to screen causes the status to show in the global status-bar.
layout.operator_context = 'INVOKE_SCREEN'
layout.operator("screen.screenshot_area")
layout.operator_context = operator_context_default
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")
class TOPBAR_MT_help(Menu):
bl_label = "Help"
def draw(self, context):
layout = self.layout
show_developer = context.preferences.view.show_developer_ui
layout.operator("wm.url_open_preset", text="Manual",
icon='HELP').type = 'MANUAL'
layout.operator(
"wm.url_open", text="Tutorials", icon='URL',
).url = "https://www.blender.org/tutorials"
layout.operator(
"wm.url_open", text="Support", icon='URL',
).url = "https://www.blender.org/support"
layout.separator()
layout.operator(
"wm.url_open", text="User Communities", icon='URL',
).url = "https://www.blender.org/community/"
layout.operator(
"wm.url_open", text="Developer Community", icon='URL',
).url = "https://devtalk.blender.org"
layout.separator()
layout.operator(
"wm.url_open_preset", text="Python API Reference", icon='URL',
).type = 'API'
if show_developer:
layout.operator(
"wm.url_open", text="Developer Documentation", icon='URL',
).url = "https://wiki.blender.org/wiki/Main_Page"
layout.operator("wm.operator_cheat_sheet", icon='TEXT')
layout.separator()
layout.operator("wm.url_open_preset",
text="Report a Bug", icon='URL').type = 'BUG'
layout.separator()
layout.operator("wm.sysinfo")
class TOPBAR_MT_file_context_menu(Menu):
bl_label = "File Context Menu"
def draw(self, _context):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
layout.menu("TOPBAR_MT_file_new", text="New", text_ctxt=i18n_contexts.id_windowmanager, icon='FILE_NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.separator()
layout.operator("wm.link", text="Link...", icon='LINK_BLEND')
layout.operator("wm.append", text="Append...", icon='APPEND_BLEND')
layout.separator()
layout.menu("TOPBAR_MT_file_import", icon='IMPORT')
layout.menu("TOPBAR_MT_file_export", icon='EXPORT')
layout.separator()
layout.operator("screen.userpref_show",
text="Preferences...", icon='PREFERENCES')
class TOPBAR_MT_workspace_menu(Menu):
bl_label = "Workspace"
def draw(self, _context):
layout = self.layout
layout.operator("workspace.duplicate",
text="Duplicate", icon='DUPLICATE')
if len(bpy.data.workspaces) > 1:
layout.operator("workspace.delete", text="Delete", icon='REMOVE')
layout.separator()
layout.operator("workspace.reorder_to_front",
text="Reorder to Front", icon='TRIA_LEFT_BAR')
layout.operator("workspace.reorder_to_back",
text="Reorder to Back", icon='TRIA_RIGHT_BAR')
layout.separator()
# For key binding discoverability.
props = layout.operator("screen.workspace_cycle",
text="Previous Workspace")
props.direction = 'PREV'
props = layout.operator(
"screen.workspace_cycle", text="Next Workspace")
props.direction = 'NEXT'
# Grease Pencil Object - Primitive curve
class TOPBAR_PT_gpencil_primitive(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Primitives"
def draw(self, context):
settings = context.tool_settings.gpencil_sculpt
layout = self.layout
# Curve
layout.template_curve_mapping(
settings, "thickness_primitive_curve", brush=True)
# Only a popover
class TOPBAR_PT_name(Panel):
bl_space_type = 'TOPBAR' # dummy
bl_region_type = 'HEADER'
bl_label = "Rename Active Item"
bl_ui_units_x = 14
def draw(self, context):
layout = self.layout
# Edit first editable button in popup
def row_with_icon(layout, icon):
row = layout.row()
row.activate_init = True
row.label(icon=icon)
return row
mode = context.mode
space = context.space_data
space_type = None if (space is None) else space.type
found = False
if space_type == 'SEQUENCE_EDITOR':
layout.label(text="Sequence Strip Name")
item = context.active_sequence_strip
if item:
row = row_with_icon(layout, 'SEQUENCE')
row.prop(item, "name", text="")
found = True
elif space_type == 'NODE_EDITOR':
layout.label(text="Node Label")
item = context.active_node
if item:
row = row_with_icon(layout, 'NODE')
row.prop(item, "label", text="")
found = True
elif space_type == 'NLA_EDITOR':
layout.label(text="NLA Strip Name")
item = next(
(strip for strip in context.selected_nla_strips if strip.active), None)
if item:
row = row_with_icon(layout, 'NLA')
row.prop(item, "name", text="")
found = True
else:
if mode == 'POSE' or (mode == 'WEIGHT_PAINT' and context.pose_object):
layout.label(text="Bone Name")
item = context.active_pose_bone
if item:
row = row_with_icon(layout, 'BONE_DATA')
row.prop(item, "name", text="")
found = True
elif mode == 'EDIT_ARMATURE':
layout.label(text="Bone Name")
item = context.active_bone
if item:
row = row_with_icon(layout, 'BONE_DATA')
row.prop(item, "name", text="")
found = True
else:
layout.label(text="Object Name")
item = context.object
if item:
row = row_with_icon(layout, 'OBJECT_DATA')
row.prop(item, "name", text="")
found = True
if not found:
row = row_with_icon(layout, 'ERROR')
row.label(text="No active item")
class TOPBAR_PT_name_marker(Panel):
bl_space_type = 'TOPBAR' # dummy
bl_region_type = 'HEADER'
bl_label = "Rename Marker"
bl_ui_units_x = 14
@staticmethod
def is_using_pose_markers(context):
sd = context.space_data
return (sd.type == 'DOPESHEET_EDITOR' and sd.mode in {'ACTION', 'SHAPEKEY'} and
sd.show_pose_markers and sd.action)
@staticmethod
def get_selected_marker(context):
if TOPBAR_PT_name_marker.is_using_pose_markers(context):
markers = context.space_data.action.pose_markers
else:
markers = context.scene.timeline_markers
for marker in markers:
if marker.select:
return marker
return None
@staticmethod
def row_with_icon(layout, icon):
row = layout.row()
row.activate_init = True
row.label(icon=icon)
return row
def draw(self, context):
layout = self.layout
layout.label(text="Marker Name")
scene = context.scene
if scene.tool_settings.lock_markers:
row = self.row_with_icon(layout, 'ERROR')
label = "Markers are locked"
row.label(text=label)
return
marker = self.get_selected_marker(context)
if marker is None:
row = self.row_with_icon(layout, 'ERROR')
row.label(text="No active marker")
return
icon = 'TIME'
if marker.camera is not None:
icon = 'CAMERA_DATA'
elif self.is_using_pose_markers(context):
icon = 'ARMATURE_DATA'
row = self.row_with_icon(layout, icon)
row.prop(marker, "name", text="")
classes = (
TOPBAR_HT_upper_bar,
TOPBAR_MT_file_context_menu,
TOPBAR_MT_workspace_menu,
TOPBAR_MT_editor_menus,
TOPBAR_MT_blender,
TOPBAR_MT_blender_system,
TOPBAR_MT_file,
TOPBAR_MT_file_new,
TOPBAR_MT_file_recover,
TOPBAR_MT_file_defaults,
TOPBAR_MT_templates_more,
TOPBAR_MT_file_import,
TOPBAR_MT_file_export,
TOPBAR_MT_file_external_data,
TOPBAR_MT_file_cleanup,
TOPBAR_MT_file_previews,
TOPBAR_MT_edit,
TOPBAR_MT_render,
TOPBAR_MT_window,
TOPBAR_MT_help,
TOPBAR_PT_tool_fallback,
TOPBAR_PT_tool_settings_extra,
TOPBAR_PT_gpencil_layers,
TOPBAR_PT_gpencil_primitive,
TOPBAR_PT_name,
TOPBAR_PT_name_marker,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)