Application Templates: make templates more prominent in the UI.

The goal here is to make app templates usable for default templates
that we can ship with Blender. These only have a custom startup.blend
currently and so are quite limited compared to app templates that fully
customize Blender.

But still it seems like the same kind of concept where we should be
sharing the code and UI. It is useful to be able to save a startup.blend
per template, and I can imagine some scripting being useful in the future
as well.

Changes made:

* File > New and Ctrl+N now list the templates, replacing a separate
  Application Templates menu that was not as easy to discover.
* File menu now shows name of active template above Save Startup File
  and Load Factory Settings to indicate these are saved/loaded per
  template.
* The "Default" template was renamed to "General".
* Workspaces can now be added from any of the template startup.blend
  files when clicking the (+) button in the topbar.

* User preferences are now fully shared between app templates, unless
  the template includes a custom userpref.blend. I think this will be
  useful in general, not all app templates need their own keymaps for
  example.
* Previously Save User Preferences would save the current app template
  and then Blender would start using that template by default. I've
  disabled this, to me it seems it was unintentional, or at least not
  clear at all that saving user preferences also makes the current

Differential Revision: https://developer.blender.org/D3690
This commit is contained in:
2018-08-28 15:12:14 +02:00
parent b08d9f036e
commit 84f21c170d
12 changed files with 264 additions and 124 deletions

View File

@@ -47,7 +47,7 @@ class TOPBAR_HT_upper_bar(Header):
if not screen.show_fullscreen:
layout.template_ID_tabs(
window, "workspace",
new="workspace.add_menu",
new="workspace.add",
menu="TOPBAR_MT_workspace_menu",
)
else:
@@ -287,7 +287,7 @@ class TOPBAR_MT_file(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.read_homefile", text="New", icon='NEW')
layout.menu("TOPBAR_MT_file_new", text="New", icon='NEW')
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.menu("TOPBAR_MT_file_open_recent")
layout.operator("wm.revert_mainfile")
@@ -305,10 +305,27 @@ class TOPBAR_MT_file(Menu):
layout.operator("wm.save_as_mainfile", text="Save Copy...").copy = True
layout.separator()
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.save_homefile")
layout.operator("wm.read_factory_settings")
if any(bpy.utils.app_template_paths()):
app_template = context.user_preferences.app_template
else:
app_template = None
if app_template:
layout.label(text=bpy.path.display_name(app_template))
layout.operator("wm.save_homefile")
layout.operator(
"wm.read_factory_settings",
text="Load Factory Settings",
).app_template = app_template
else:
layout.operator("wm.save_homefile")
layout.operator("wm.read_factory_settings")
layout.separator()
layout.operator("wm.app_template_install", text="Install Application Template...")
layout.separator()
@@ -334,6 +351,49 @@ class TOPBAR_MT_file(Menu):
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
app_templates = []
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):
# template_paths_expand.append(template)
app_templates.append(d)
return sorted(app_templates)
def draw_ex(self, context, *, use_splash=False, use_default=False):
layout = self.layout
# now draw the presets
layout.operator_context = 'EXEC_DEFAULT'
if use_default:
props = layout.operator("wm.read_homefile", text="General")
props.app_template = ""
for d in TOPBAR_MT_file_new.app_template_paths():
props = layout.operator(
"wm.read_homefile",
text=bpy.path.display_name(d),
)
props.app_template = d
def draw(self, context):
self.draw_ex(context, use_splash=False, use_default=True)
class TOPBAR_MT_file_import(Menu):
bl_idname = "TOPBAR_MT_file_import"
bl_label = "Import"
@@ -647,6 +707,7 @@ classes = (
TOPBAR_MT_workspace_menu,
TOPBAR_MT_editor_menus,
TOPBAR_MT_file,
TOPBAR_MT_file_new,
TOPBAR_MT_file_import,
TOPBAR_MT_file_export,
TOPBAR_MT_file_external_data,

View File

@@ -81,60 +81,12 @@ class USERPREF_MT_interaction_presets(Menu):
draw = Menu.draw_preset
class USERPREF_MT_app_templates(Menu):
bl_label = "Application Templates"
preset_subdir = "app_templates"
def draw_ex(self, context, *, use_splash=False, use_default=False, use_install=False):
import os
layout = self.layout
# now draw the presets
layout.operator_context = 'EXEC_DEFAULT'
if use_default:
props = layout.operator("wm.read_homefile", text="Default")
props.use_splash = True
props.app_template = ""
layout.separator()
template_paths = bpy.utils.app_template_paths()
# expand template paths
app_templates = []
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):
# template_paths_expand.append(template)
app_templates.append(d)
for d in sorted(app_templates):
props = layout.operator(
"wm.read_homefile",
text=bpy.path.display_name(d),
)
props.use_splash = True
props.app_template = d
if use_install:
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
props = layout.operator("wm.app_template_install")
def draw(self, context):
self.draw_ex(context, use_splash=False, use_default=True, use_install=True)
class USERPREF_MT_templates_splash(Menu):
bl_label = "Startup Templates"
preset_subdir = "templates"
def draw(self, context):
USERPREF_MT_app_templates.draw_ex(self, context, use_splash=True, use_default=True)
bpy.types.TOPBAR_MT_file_new.draw_ex(self, context, use_splash=True, use_default=True)
class USERPREF_MT_appconfigs(Menu):
@@ -1650,7 +1602,6 @@ classes = (
USERPREF_PT_tabs,
USERPREF_MT_interaction_presets,
USERPREF_MT_templates_splash,
USERPREF_MT_app_templates,
USERPREF_MT_appconfigs,
USERPREF_MT_splash,
USERPREF_MT_splash_footer,