UI: preset popover buttons in panel headers.

Moves the preset into a menu for the panel header, so it can be changed
without opening the panel and takes up less space. Two remaining issues:

* For long lists the add new preset button can be scrolled off screen.
* We should support showing the name of the chosen preset in the panel
  header, but the current preset system does not support detecting which
  preset is used.

Differential Revision: https://developer.blender.org/D3366
This commit is contained in:
2018-04-27 13:50:26 +02:00
parent 1664ccb675
commit 7a10cfe7fe
20 changed files with 291 additions and 172 deletions

View File

@@ -19,9 +19,15 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Operator
from bpy.types import Menu, Operator, Panel, WindowManager
from bpy.props import StringProperty, BoolProperty
# For preset popover menu
WindowManager.preset_name = StringProperty(
name="Preset Name",
description="Name for new preset",
default="New Preset"
)
class AddPresetBase:
"""Base preset class, only for subclassing
@@ -40,6 +46,10 @@ class AddPresetBase:
maxlen=64,
options={'SKIP_SAVE'},
)
remove_name = BoolProperty(
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
)
remove_active = BoolProperty(
default=False,
options={'HIDDEN', 'SKIP_SAVE'},
@@ -48,6 +58,7 @@ class AddPresetBase:
# needed for mix-ins
order = [
"name",
"remove_name",
"remove_active",
]
@@ -85,11 +96,17 @@ class AddPresetBase:
else:
ext = ".py"
if not self.remove_active:
name = self.name.strip()
name = self.name.strip()
if not (self.remove_name or self.remove_active):
if not name:
return {'FINISHED'}
# Reset preset name
wm = bpy.data.window_managers[0]
if name == wm.preset_name:
wm.preset_name = 'New Preset'
filename = self.as_filename(name)
target_path = os.path.join("presets", self.preset_subdir)
@@ -155,15 +172,16 @@ class AddPresetBase:
preset_menu_class.bl_label = bpy.path.display_name(filename)
else:
preset_active = preset_menu_class.bl_label
if self.remove_active:
name = preset_menu_class.bl_label
# fairly sloppy but convenient.
filepath = bpy.utils.preset_find(preset_active,
filepath = bpy.utils.preset_find(name,
self.preset_subdir,
ext=ext)
if not filepath:
filepath = bpy.utils.preset_find(preset_active,
filepath = bpy.utils.preset_find(name,
self.preset_subdir,
display_name=True,
ext=ext)
@@ -194,7 +212,7 @@ class AddPresetBase:
self.name = self.as_filename(self.name.strip())
def invoke(self, context, event):
if not self.remove_active:
if not (self.remove_active or self.remove_name):
wm = context.window_manager
return wm.invoke_props_dialog(self)
else:
@@ -241,6 +259,40 @@ class ExecutePreset(Operator):
return {'FINISHED'}
class PresetMenu(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'HEADER'
bl_label = "Presets"
path_menu = Menu.path_menu
@classmethod
def draw_panel_header(cls, layout):
layout.emboss = 'NONE'
layout.popover(cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text='')
@classmethod
def draw_menu(cls, layout, text=None):
if text == None:
text = cls.bl_label
layout.popover(cls.bl_space_type,
cls.bl_region_type,
cls.__name__,
icon='PRESET',
text=text)
def draw(self, context):
layout = self.layout
layout.emboss = 'PULLDOWN_MENU'
layout.operator_context = 'EXEC_DEFAULT'
Menu.draw_preset(self, context)
class AddPresetRender(AddPresetBase, Operator):
"""Add or remove a Render Preset"""
bl_idname = "render.preset_add"
@@ -385,35 +437,6 @@ class AddPresetHairDynamics(AddPresetBase, Operator):
]
class AddPresetSunSky(AddPresetBase, Operator):
"""Add or remove a Sky & Atmosphere Preset"""
bl_idname = "lamp.sunsky_preset_add"
bl_label = "Add Sunsky Preset"
preset_menu = "LAMP_MT_sunsky_presets"
preset_defines = [
"sky = bpy.context.lamp.sky"
]
preset_values = [
"sky.atmosphere_extinction",
"sky.atmosphere_inscattering",
"sky.atmosphere_turbidity",
"sky.backscattered_light",
"sky.horizon_brightness",
"sky.spread",
"sky.sun_brightness",
"sky.sun_intensity",
"sky.sun_size",
"sky.sky_blend",
"sky.sky_blend_type",
"sky.sky_color_space",
"sky.sky_exposure",
]
preset_subdir = "sunsky"
class AddPresetInteraction(AddPresetBase, Operator):
"""Add or remove an Application Interaction Preset"""
bl_idname = "wm.interaction_preset_add"
@@ -665,7 +688,6 @@ classes = (
AddPresetOperator,
AddPresetRender,
AddPresetSafeAreas,
AddPresetSunSky,
AddPresetTrackingCamera,
AddPresetTrackingSettings,
AddPresetTrackingTrackColor,