space_topbar.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  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. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import Header, Menu, Panel
  21. class TOPBAR_HT_upper_bar(Header):
  22. bl_space_type = 'TOPBAR'
  23. def draw(self, context):
  24. region = context.region
  25. if region.alignment == 'RIGHT':
  26. self.draw_right(context)
  27. else:
  28. self.draw_left(context)
  29. def draw_left(self, context):
  30. layout = self.layout
  31. window = context.window
  32. screen = context.screen
  33. TOPBAR_MT_editor_menus.draw_collapsible(context, layout)
  34. layout.separator()
  35. if not screen.show_fullscreen:
  36. layout.template_ID_tabs(
  37. window, "workspace",
  38. new="workspace.add",
  39. menu="TOPBAR_MT_workspace_menu",
  40. )
  41. else:
  42. layout.operator(
  43. "screen.back_to_previous",
  44. icon='SCREEN_BACK',
  45. text="Back to Previous",
  46. )
  47. def draw_right(self, context):
  48. layout = self.layout
  49. window = context.window
  50. screen = context.screen
  51. scene = window.scene
  52. # If statusbar is hidden, still show messages at the top
  53. if not screen.show_statusbar:
  54. layout.template_reports_banner()
  55. layout.template_running_jobs()
  56. # Active workspace view-layer is retrieved through window, not through workspace.
  57. layout.template_ID(window, "scene", new="scene.new", unlink="scene.delete")
  58. row = layout.row(align=True)
  59. row.template_search(
  60. window, "view_layer",
  61. scene, "view_layers",
  62. new="scene.view_layer_add",
  63. unlink="scene.view_layer_remove")
  64. class TOPBAR_PT_gpencil_layers(Panel):
  65. bl_space_type = 'VIEW_3D'
  66. bl_region_type = 'HEADER'
  67. bl_label = "Layers"
  68. bl_ui_units_x = 14
  69. @classmethod
  70. def poll(cls, context):
  71. if context.gpencil_data is None:
  72. return False
  73. ob = context.object
  74. if ob is not None and ob.type == 'GPENCIL':
  75. return True
  76. return False
  77. def draw(self, context):
  78. layout = self.layout
  79. gpd = context.gpencil_data
  80. # Grease Pencil data...
  81. if (gpd is None) or (not gpd.layers):
  82. layout.operator("gpencil.layer_add", text="New Layer")
  83. else:
  84. self.draw_layers(context, layout, gpd)
  85. def draw_layers(self, context, layout, gpd):
  86. row = layout.row()
  87. col = row.column()
  88. layer_rows = 10
  89. col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index",
  90. rows=layer_rows, sort_reverse=True, sort_lock=True)
  91. gpl = context.active_gpencil_layer
  92. if gpl:
  93. srow = col.row(align=True)
  94. srow.prop(gpl, "blend_mode", text="Blend")
  95. srow = col.row(align=True)
  96. srow.prop(gpl, "opacity", text="Opacity", slider=True)
  97. srow.prop(gpl, "mask_layer", text="",
  98. icon='MOD_MASK' if gpl.mask_layer else 'LAYER_ACTIVE')
  99. srow = col.row(align=True)
  100. srow.prop(gpl, "use_solo_mode", text="Show Only On Keyframed")
  101. col = row.column()
  102. sub = col.column(align=True)
  103. sub.operator("gpencil.layer_add", icon='ADD', text="")
  104. sub.operator("gpencil.layer_remove", icon='REMOVE', text="")
  105. gpl = context.active_gpencil_layer
  106. if gpl:
  107. sub.menu("GPENCIL_MT_layer_context_menu", icon='DOWNARROW_HLT', text="")
  108. if len(gpd.layers) > 1:
  109. col.separator()
  110. sub = col.column(align=True)
  111. sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
  112. sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
  113. col.separator()
  114. sub = col.column(align=True)
  115. sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
  116. sub.operator("gpencil.layer_isolate", icon='HIDE_OFF', text="").affect_visibility = True
  117. class TOPBAR_MT_editor_menus(Menu):
  118. bl_idname = "TOPBAR_MT_editor_menus"
  119. bl_label = ""
  120. def draw(self, _context):
  121. layout = self.layout
  122. layout.menu("TOPBAR_MT_app", text="", icon='BLENDER')
  123. layout.menu("TOPBAR_MT_file")
  124. layout.menu("TOPBAR_MT_edit")
  125. layout.menu("TOPBAR_MT_render")
  126. layout.menu("TOPBAR_MT_window")
  127. layout.menu("TOPBAR_MT_help")
  128. class TOPBAR_MT_app(Menu):
  129. bl_label = "Blender"
  130. def draw(self, _context):
  131. layout = self.layout
  132. layout.operator("wm.splash")
  133. layout.separator()
  134. layout.menu("TOPBAR_MT_app_support")
  135. layout.separator()
  136. layout.menu("TOPBAR_MT_app_about")
  137. layout.separator()
  138. layout.operator("preferences.app_template_install", text="Install Application Template...")
  139. class TOPBAR_MT_file(Menu):
  140. bl_label = "File"
  141. def draw(self, context):
  142. layout = self.layout
  143. layout.operator_context = 'INVOKE_AREA'
  144. layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE_NEW')
  145. layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
  146. layout.menu("TOPBAR_MT_file_open_recent")
  147. layout.operator("wm.revert_mainfile")
  148. layout.menu("TOPBAR_MT_file_recover")
  149. layout.separator()
  150. layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA'
  151. layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
  152. layout.operator_context = 'INVOKE_AREA'
  153. layout.operator("wm.save_as_mainfile", text="Save As...")
  154. layout.operator_context = 'INVOKE_AREA'
  155. layout.operator("wm.save_as_mainfile", text="Save Copy...").copy = True
  156. layout.separator()
  157. layout.operator_context = 'INVOKE_AREA'
  158. layout.operator("wm.link", text="Link...", icon='LINK_BLEND')
  159. layout.operator("wm.append", text="Append...", icon='APPEND_BLEND')
  160. layout.menu("TOPBAR_MT_file_previews")
  161. layout.separator()
  162. layout.menu("TOPBAR_MT_file_import", icon='IMPORT')
  163. layout.menu("TOPBAR_MT_file_export", icon='EXPORT')
  164. layout.separator()
  165. layout.menu("TOPBAR_MT_file_external_data")
  166. layout.separator()
  167. layout.menu("TOPBAR_MT_file_defaults")
  168. layout.separator()
  169. layout.operator("wm.quit_blender", text="Quit", icon='QUIT')
  170. class TOPBAR_MT_file_new(Menu):
  171. bl_label = "New File"
  172. @staticmethod
  173. def app_template_paths():
  174. import os
  175. template_paths = bpy.utils.app_template_paths()
  176. # expand template paths
  177. app_templates = []
  178. for path in template_paths:
  179. for d in os.listdir(path):
  180. if d.startswith(("__", ".")):
  181. continue
  182. template = os.path.join(path, d)
  183. if os.path.isdir(template):
  184. # template_paths_expand.append(template)
  185. app_templates.append(d)
  186. return sorted(app_templates)
  187. @staticmethod
  188. def draw_ex(layout, _context, *, use_splash=False, use_more=False):
  189. layout.operator_context = 'INVOKE_DEFAULT'
  190. # Limit number of templates in splash screen, spill over into more menu.
  191. paths = TOPBAR_MT_file_new.app_template_paths()
  192. splash_limit = 5
  193. if use_splash:
  194. icon = 'FILE_NEW'
  195. show_more = len(paths) > (splash_limit - 1)
  196. if show_more:
  197. paths = paths[:splash_limit - 2]
  198. elif use_more:
  199. icon = 'FILE_NEW'
  200. paths = paths[splash_limit - 2:]
  201. show_more = False
  202. else:
  203. icon = 'NONE'
  204. show_more = False
  205. # Draw application templates.
  206. if not use_more:
  207. props = layout.operator("wm.read_homefile", text="General", icon=icon)
  208. props.app_template = ""
  209. for d in paths:
  210. props = layout.operator(
  211. "wm.read_homefile",
  212. text=bpy.path.display_name(d),
  213. icon=icon,
  214. )
  215. props.app_template = d
  216. layout.operator_context = 'EXEC_DEFAULT'
  217. if show_more:
  218. layout.menu("TOPBAR_MT_templates_more", text="...")
  219. def draw(self, context):
  220. TOPBAR_MT_file_new.draw_ex(self.layout, context)
  221. class TOPBAR_MT_file_recover(Menu):
  222. bl_label = "Recover"
  223. def draw(self, _context):
  224. layout = self.layout
  225. layout.operator("wm.recover_last_session", text="Last Session")
  226. layout.operator("wm.recover_auto_save", text="Auto Save...")
  227. class TOPBAR_MT_file_defaults(Menu):
  228. bl_label = "Defaults"
  229. def draw(self, context):
  230. layout = self.layout
  231. prefs = context.preferences
  232. layout.operator_context = 'INVOKE_AREA'
  233. if any(bpy.utils.app_template_paths()):
  234. app_template = prefs.app_template
  235. else:
  236. app_template = None
  237. if app_template:
  238. layout.label(text=bpy.path.display_name(app_template, has_ext=False))
  239. layout.operator("wm.save_homefile")
  240. props = layout.operator("wm.read_factory_settings")
  241. if app_template:
  242. props.app_template = app_template
  243. class TOPBAR_MT_app_about(Menu):
  244. bl_label = "About"
  245. def draw(self, _context):
  246. layout = self.layout
  247. layout.operator(
  248. "wm.url_open", text="Release Notes", icon='URL',
  249. ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2]
  250. layout.separator()
  251. layout.operator(
  252. "wm.url_open", text="Blender Website", icon='URL',
  253. ).url = "https://www.blender.org/"
  254. layout.operator(
  255. "wm.url_open", text="Credits", icon='URL',
  256. ).url = "https://www.blender.org/about/credits/"
  257. layout.separator()
  258. layout.operator(
  259. "wm.url_open", text="License", icon='URL',
  260. ).url = "https://www.blender.org/about/license/"
  261. class TOPBAR_MT_app_support(Menu):
  262. bl_label = "Support Blender"
  263. def draw(self, _context):
  264. layout = self.layout
  265. layout.operator(
  266. "wm.url_open", text="Development Fund", icon='FUND',
  267. ).url = "https://fund.blender.org"
  268. layout.separator()
  269. layout.operator(
  270. "wm.url_open", text="Blender Store", icon='URL',
  271. ).url = "https://store.blender.org"
  272. class TOPBAR_MT_templates_more(Menu):
  273. bl_label = "Templates"
  274. def draw(self, context):
  275. bpy.types.TOPBAR_MT_file_new.draw_ex(self.layout, context, use_more=True)
  276. class TOPBAR_MT_file_import(Menu):
  277. bl_idname = "TOPBAR_MT_file_import"
  278. bl_label = "Import"
  279. def draw(self, _context):
  280. if bpy.app.build_options.collada:
  281. self.layout.operator("wm.collada_import", text="Collada (Default) (.dae)")
  282. if bpy.app.build_options.alembic:
  283. self.layout.operator("wm.alembic_import", text="Alembic (.abc)")
  284. self.layout.operator("wm.obj_import_c", text="Wavefront (.obj)")
  285. self.layout.operator("wm.stl_import_c", text="STL (.stl)")
  286. class TOPBAR_MT_file_export(Menu):
  287. bl_idname = "TOPBAR_MT_file_export"
  288. bl_label = "Export"
  289. def draw(self, _context):
  290. if bpy.app.build_options.collada:
  291. self.layout.operator("wm.collada_export", text="Collada (Default) (.dae)")
  292. if bpy.app.build_options.alembic:
  293. self.layout.operator("wm.alembic_export", text="Alembic (.abc)")
  294. self.layout.operator("wm.obj_export_c", text="Wavefront (.obj)")
  295. self.layout.operator("wm.stl_export_c", text="STL (.stl)")
  296. class TOPBAR_MT_file_external_data(Menu):
  297. bl_label = "External Data"
  298. def draw(self, _context):
  299. layout = self.layout
  300. icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT'
  301. layout.operator("file.autopack_toggle", icon=icon)
  302. layout.separator()
  303. pack_all = layout.row()
  304. pack_all.operator("file.pack_all")
  305. pack_all.active = not bpy.data.use_autopack
  306. unpack_all = layout.row()
  307. unpack_all.operator("file.unpack_all")
  308. unpack_all.active = not bpy.data.use_autopack
  309. layout.separator()
  310. layout.operator("file.make_paths_relative")
  311. layout.operator("file.make_paths_absolute")
  312. layout.operator("file.report_missing_files")
  313. layout.operator("file.find_missing_files")
  314. class TOPBAR_MT_file_previews(Menu):
  315. bl_label = "Data Previews"
  316. def draw(self, _context):
  317. layout = self.layout
  318. layout.operator("wm.previews_ensure")
  319. layout.operator("wm.previews_batch_generate")
  320. layout.separator()
  321. layout.operator("wm.previews_clear")
  322. layout.operator("wm.previews_batch_clear")
  323. class TOPBAR_MT_render(Menu):
  324. bl_label = "Render"
  325. def draw(self, context):
  326. layout = self.layout
  327. rd = context.scene.render
  328. layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True
  329. props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION')
  330. props.animation = True
  331. props.use_viewport = True
  332. layout.separator()
  333. layout.operator("sound.mixdown", text="Render Audio...")
  334. layout.separator()
  335. layout.operator("render.view_show", text="View Render")
  336. layout.operator("render.play_rendered_anim", text="View Animation")
  337. layout.prop_menu_enum(rd, "display_mode", text="Display Mode")
  338. layout.separator()
  339. layout.prop(rd, "use_lock_interface", text="Lock Interface")
  340. class TOPBAR_MT_edit(Menu):
  341. bl_label = "Edit"
  342. def draw(self, context):
  343. layout = self.layout
  344. layout.operator("ed.undo")
  345. layout.operator("ed.redo")
  346. layout.separator()
  347. layout.operator("ed.undo_history", text="Undo History...")
  348. layout.separator()
  349. layout.operator("screen.repeat_last")
  350. layout.operator("screen.repeat_history", text="Repeat History...")
  351. layout.separator()
  352. layout.operator("screen.redo_last", text="Adjust Last Operation...")
  353. layout.separator()
  354. layout.operator("wm.search_menu", text="Operator Search...", icon='VIEWZOOM')
  355. layout.separator()
  356. # Mainly to expose shortcut since this depends on the context.
  357. props = layout.operator("wm.call_panel", text="Rename Active Item...")
  358. props.name = "TOPBAR_PT_name"
  359. props.keep_open = False
  360. layout.separator()
  361. # Should move elsewhere (impacts outliner & 3D view).
  362. tool_settings = context.tool_settings
  363. layout.prop(tool_settings, "lock_object_mode")
  364. layout.separator()
  365. layout.operator("screen.userpref_show", text="Preferences...", icon='PREFERENCES')
  366. class TOPBAR_MT_window(Menu):
  367. bl_label = "Window"
  368. def draw(self, context):
  369. import sys
  370. layout = self.layout
  371. layout.operator("wm.window_new")
  372. layout.operator("wm.window_new_main")
  373. layout.separator()
  374. layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER')
  375. layout.separator()
  376. layout.operator("screen.workspace_cycle", text="Next Workspace").direction = 'NEXT'
  377. layout.operator("screen.workspace_cycle", text="Previous Workspace").direction = 'PREV'
  378. layout.separator()
  379. layout.prop(context.screen, "show_statusbar")
  380. layout.separator()
  381. layout.operator("screen.screenshot")
  382. if sys.platform[:3] == "win":
  383. layout.separator()
  384. layout.operator("wm.console_toggle", icon='CONSOLE')
  385. if context.scene.render.use_multiview:
  386. layout.separator()
  387. layout.operator("wm.set_stereo_3d")
  388. class TOPBAR_MT_help(Menu):
  389. bl_label = "Help"
  390. def draw(self, context):
  391. # If 'url_prefill_from_blender' becomes slow it could be made into a separate operator
  392. # to avoid constructing the bug report just to show this menu.
  393. from bl_ui_utils.bug_report_url import url_prefill_from_blender
  394. layout = self.layout
  395. show_developer = context.preferences.view.show_developer_ui
  396. if bpy.app.version_cycle in {'rc', 'release'}:
  397. manual_version = '%d.%d' % bpy.app.version[:2]
  398. else:
  399. manual_version = 'dev'
  400. layout.operator(
  401. "wm.url_open", text="Manual", icon='HELP',
  402. ).url = "https://docs.blender.org/manual/en/" + manual_version + "/"
  403. layout.operator(
  404. "wm.url_open", text="Tutorials", icon='URL',
  405. ).url = "https://www.blender.org/tutorials"
  406. layout.operator(
  407. "wm.url_open", text="Support", icon='URL',
  408. ).url = "https://www.blender.org/support"
  409. layout.separator()
  410. layout.operator(
  411. "wm.url_open", text="User Communities", icon='URL',
  412. ).url = "https://www.blender.org/community/"
  413. layout.operator(
  414. "wm.url_open", text="Developer Community", icon='URL',
  415. ).url = "https://devtalk.blender.org"
  416. layout.separator()
  417. layout.operator(
  418. "wm.url_open", text="Python API Reference", icon='URL',
  419. ).url = bpy.types.WM_OT_doc_view._prefix
  420. if show_developer:
  421. layout.operator(
  422. "wm.url_open", text="Developer Documentation", icon='URL',
  423. ).url = "https://wiki.blender.org/wiki/Main_Page"
  424. layout.operator("wm.operator_cheat_sheet", icon='TEXT')
  425. layout.separator()
  426. layout.operator(
  427. "wm.url_open", text="Report a Bug", icon='URL',
  428. ).url = url_prefill_from_blender()
  429. layout.separator()
  430. layout.operator("wm.sysinfo")
  431. class TOPBAR_MT_file_context_menu(Menu):
  432. bl_label = "File Context Menu"
  433. def draw(self, _context):
  434. layout = self.layout
  435. layout.operator_context = 'INVOKE_AREA'
  436. layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE_NEW')
  437. layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
  438. layout.separator()
  439. layout.operator("wm.link", text="Link...", icon='LINK_BLEND')
  440. layout.operator("wm.append", text="Append...", icon='APPEND_BLEND')
  441. layout.separator()
  442. layout.menu("TOPBAR_MT_file_import", icon='IMPORT')
  443. layout.menu("TOPBAR_MT_file_export", icon='EXPORT')
  444. layout.separator()
  445. layout.operator("screen.userpref_show", text="Preferences...", icon='PREFERENCES')
  446. class TOPBAR_MT_workspace_menu(Menu):
  447. bl_label = "Workspace"
  448. def draw(self, _context):
  449. layout = self.layout
  450. layout.operator("workspace.duplicate", text="Duplicate", icon='DUPLICATE')
  451. if len(bpy.data.workspaces) > 1:
  452. layout.operator("workspace.delete", text="Delete", icon='REMOVE')
  453. layout.separator()
  454. layout.operator("workspace.reorder_to_front", text="Reorder to Front", icon='TRIA_LEFT_BAR')
  455. layout.operator("workspace.reorder_to_back", text="Reorder to Back", icon='TRIA_RIGHT_BAR')
  456. layout.separator()
  457. # For key binding discoverability.
  458. props = layout.operator("screen.workspace_cycle", text="Previous Workspace")
  459. props.direction = 'PREV'
  460. props = layout.operator("screen.workspace_cycle", text="Next Workspace")
  461. props.direction = 'NEXT'
  462. # Grease Pencil Object - Primitive curve
  463. class TOPBAR_PT_gpencil_primitive(Panel):
  464. bl_space_type = 'VIEW_3D'
  465. bl_region_type = 'HEADER'
  466. bl_label = "Primitives"
  467. def draw(self, context):
  468. settings = context.tool_settings.gpencil_sculpt
  469. layout = self.layout
  470. # Curve
  471. layout.template_curve_mapping(settings, "thickness_primitive_curve", brush=True)
  472. # Grease Pencil Fill
  473. class TOPBAR_PT_gpencil_fill(Panel):
  474. bl_space_type = 'VIEW_3D'
  475. bl_region_type = 'HEADER'
  476. bl_label = "Advanced"
  477. def draw(self, context):
  478. paint = context.tool_settings.gpencil_paint
  479. brush = paint.brush
  480. gp_settings = brush.gpencil_settings
  481. layout = self.layout
  482. # Fill
  483. row = layout.row(align=True)
  484. row.prop(gp_settings, "fill_factor", text="Resolution")
  485. if gp_settings.fill_draw_mode != 'STROKE':
  486. row = layout.row(align=True)
  487. row.prop(gp_settings, "show_fill", text="Ignore Transparent Strokes")
  488. row = layout.row(align=True)
  489. row.prop(gp_settings, "fill_threshold", text="Threshold")
  490. # Only a popover
  491. class TOPBAR_PT_name(Panel):
  492. bl_space_type = 'TOPBAR' # dummy
  493. bl_region_type = 'HEADER'
  494. bl_label = "Rename Active Item"
  495. bl_ui_units_x = 14
  496. def draw(self, context):
  497. layout = self.layout
  498. # Edit first editable button in popup
  499. def row_with_icon(layout, icon):
  500. row = layout.row()
  501. row.activate_init = True
  502. row.label(icon=icon)
  503. return row
  504. mode = context.mode
  505. scene = context.scene
  506. space = context.space_data
  507. space_type = None if (space is None) else space.type
  508. found = False
  509. if space_type == 'SEQUENCE_EDITOR':
  510. layout.label(text="Sequence Strip Name")
  511. item = getattr(scene.sequence_editor, "active_strip")
  512. if item:
  513. row = row_with_icon(layout, 'SEQUENCE')
  514. row.prop(item, "name", text="")
  515. found = True
  516. elif space_type == 'NODE_EDITOR':
  517. layout.label(text="Node Label")
  518. item = context.active_node
  519. if item:
  520. row = row_with_icon(layout, 'NODE')
  521. row.prop(item, "label", text="")
  522. found = True
  523. else:
  524. if mode == 'POSE' or (mode == 'WEIGHT_PAINT' and context.pose_object):
  525. layout.label(text="Bone Name")
  526. item = context.active_pose_bone
  527. if item:
  528. row = row_with_icon(layout, 'BONE_DATA')
  529. row.prop(item, "name", text="")
  530. found = True
  531. elif mode == 'EDIT_ARMATURE':
  532. layout.label(text="Bone Name")
  533. item = context.active_bone
  534. if item:
  535. row = row_with_icon(layout, 'BONE_DATA')
  536. row.prop(item, "name", text="")
  537. found = True
  538. else:
  539. layout.label(text="Object Name")
  540. item = context.object
  541. if item:
  542. row = row_with_icon(layout, 'OBJECT_DATA')
  543. row.prop(item, "name", text="")
  544. found = True
  545. if not found:
  546. row = row_with_icon(layout, 'ERROR')
  547. row.label(text="No active item")
  548. classes = (
  549. TOPBAR_HT_upper_bar,
  550. TOPBAR_MT_file_context_menu,
  551. TOPBAR_MT_workspace_menu,
  552. TOPBAR_MT_editor_menus,
  553. TOPBAR_MT_app,
  554. TOPBAR_MT_app_about,
  555. TOPBAR_MT_app_support,
  556. TOPBAR_MT_file,
  557. TOPBAR_MT_file_new,
  558. TOPBAR_MT_file_recover,
  559. TOPBAR_MT_file_defaults,
  560. TOPBAR_MT_templates_more,
  561. TOPBAR_MT_file_import,
  562. TOPBAR_MT_file_export,
  563. TOPBAR_MT_file_external_data,
  564. TOPBAR_MT_file_previews,
  565. TOPBAR_MT_edit,
  566. TOPBAR_MT_render,
  567. TOPBAR_MT_window,
  568. TOPBAR_MT_help,
  569. TOPBAR_PT_gpencil_layers,
  570. TOPBAR_PT_gpencil_primitive,
  571. TOPBAR_PT_gpencil_fill,
  572. TOPBAR_PT_name,
  573. )
  574. if __name__ == "__main__": # only for live edit.
  575. from bpy.utils import register_class
  576. for cls in classes:
  577. register_class(cls)