AnimEditors UI: Move less frequently used filtering options to a "Filters" popovers
This commit is an experiment in using popovers as a place to house some of the filtering options for animation editors, in line with what's taking place in the Outliner with the filtering popover there too. Right now, the most frequently used/changed options are still available on the headers (i.e. the "Only Selected"/"Hidden"/search fields), while everything else (i.e. the per-datablock filters, which were already hidden behind a collapsed-toggle button before) now live in the popover.
This commit is contained in:
parent
c795505a2c
commit
5f545dbde8
|
@ -19,12 +19,12 @@
|
|||
# <pep8 compliant>
|
||||
|
||||
import bpy
|
||||
from bpy.types import Header, Menu
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from .space_time import *
|
||||
|
||||
|
||||
#######################################
|
||||
# DopeSheet Filtering
|
||||
# DopeSheet Filtering - Header Buttons
|
||||
|
||||
# used for DopeSheet, NLA, and Graph Editors
|
||||
def dopesheet_filter(layout, context, genericFiltersOnly=False):
|
||||
|
@ -60,49 +60,148 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
|
|||
row.prop(dopesheet, "filter_text", text="")
|
||||
row.prop(dopesheet, "use_multi_word_filter", text="")
|
||||
|
||||
if not genericFiltersOnly:
|
||||
row = layout.row(align=True)
|
||||
row.prop(dopesheet, "show_datablock_filters", text="Filters")
|
||||
#######################################
|
||||
# Dopesheet Filtering Popovers
|
||||
|
||||
if dopesheet.show_datablock_filters:
|
||||
row.prop(dopesheet, "show_scenes", text="")
|
||||
row.prop(dopesheet, "show_worlds", text="")
|
||||
row.prop(dopesheet, "show_nodes", text="")
|
||||
# Generic Layout - Used as base for filtering popovers used in all animation editors
|
||||
# Used for DopeSheet, NLA, and Graph Editors
|
||||
class DopesheetFilterPopoverBase:
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filters"
|
||||
|
||||
row.prop(dopesheet, "show_transforms", text="")
|
||||
# Generic = Affects all datatypes
|
||||
# XXX: Perhaps we want these to stay in the header instead, for easy/fast access
|
||||
@classmethod
|
||||
def draw_generic_filters(cls, context, layout):
|
||||
dopesheet = context.space_data.dopesheet
|
||||
is_nla = context.area.type == 'NLA_EDITOR'
|
||||
|
||||
if bpy.data.meshes:
|
||||
row.prop(dopesheet, "show_meshes", text="")
|
||||
if bpy.data.shape_keys:
|
||||
row.prop(dopesheet, "show_shapekeys", text="")
|
||||
if bpy.data.meshes:
|
||||
row.prop(dopesheet, "show_modifiers", text="")
|
||||
if bpy.data.materials:
|
||||
row.prop(dopesheet, "show_materials", text="")
|
||||
if bpy.data.lamps:
|
||||
row.prop(dopesheet, "show_lamps", text="")
|
||||
if bpy.data.textures:
|
||||
row.prop(dopesheet, "show_textures", text="")
|
||||
if bpy.data.cameras:
|
||||
row.prop(dopesheet, "show_cameras", text="")
|
||||
if bpy.data.curves:
|
||||
row.prop(dopesheet, "show_curves", text="")
|
||||
if bpy.data.metaballs:
|
||||
row.prop(dopesheet, "show_metaballs", text="")
|
||||
if bpy.data.lattices:
|
||||
row.prop(dopesheet, "show_lattices", text="")
|
||||
if bpy.data.armatures:
|
||||
row.prop(dopesheet, "show_armatures", text="")
|
||||
if bpy.data.particles:
|
||||
row.prop(dopesheet, "show_particles", text="")
|
||||
if bpy.data.speakers:
|
||||
row.prop(dopesheet, "show_speakers", text="")
|
||||
if bpy.data.linestyles:
|
||||
row.prop(dopesheet, "show_linestyles", text="")
|
||||
if bpy.data.grease_pencil:
|
||||
row.prop(dopesheet, "show_gpencil", text="")
|
||||
col = layout.column(align=True)
|
||||
col.prop(dopesheet, "show_only_selected", icon='NONE')
|
||||
col.prop(dopesheet, "show_hidden", icon='NONE')
|
||||
|
||||
layout.prop(dopesheet, "use_datablock_sort", text="")
|
||||
if is_nla:
|
||||
col.prop(dopesheet, "show_missing_nla", icon='NONE')
|
||||
else: # graph and dopesheet editors - F-Curves and drivers only
|
||||
col.prop(dopesheet, "show_only_errors", icon='NONE')
|
||||
|
||||
# Name/Membership Filters
|
||||
# XXX: Perhaps these should just stay in the headers (exclusively)?
|
||||
@classmethod
|
||||
def draw_search_filters(cls, context, layout, generic_filters_only=False):
|
||||
dopesheet = context.space_data.dopesheet
|
||||
is_nla = context.area.type == 'NLA_EDITOR'
|
||||
|
||||
if (not generic_filters_only) and (bpy.data.collections):
|
||||
row = layout.row(align=True)
|
||||
row.prop(dopesheet, "show_only_collection_objects", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.active = dopesheet.show_only_collection_objects
|
||||
sub.prop(dopesheet, "filter_collection", text="")
|
||||
|
||||
if not is_nla:
|
||||
row = layout.row(align=True)
|
||||
row.prop(dopesheet, "show_only_matching_fcurves", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.active = dopesheet.show_only_matching_fcurves
|
||||
sub.prop(dopesheet, "filter_fcurve_name", text="")
|
||||
sub.prop(dopesheet, "use_multi_word_filter", text="")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.prop(dopesheet, "use_filter_text", text="")
|
||||
sub = row.row(align=True)
|
||||
sub.active = dopesheet.use_filter_text
|
||||
sub.prop(dopesheet, "filter_text", text="")
|
||||
sub.prop(dopesheet, "use_multi_word_filter", text="")
|
||||
|
||||
# Standard = Present in all panels
|
||||
@classmethod
|
||||
def draw_standard_filters(cls, context, layout):
|
||||
dopesheet = context.space_data.dopesheet
|
||||
|
||||
# Object Data Filters
|
||||
layout.label("Include Sub-Object Data:")
|
||||
split = layout.split()
|
||||
|
||||
# TODO: Add per-channel/axis convenience toggles?
|
||||
col = split.column()
|
||||
col.prop(dopesheet, "show_transforms", text="Transforms")
|
||||
|
||||
col = split.column()
|
||||
col.prop(dopesheet, "show_modifiers", text="Modifiers")
|
||||
|
||||
layout.separator()
|
||||
|
||||
# datablock filters
|
||||
layout.label("Include From Types:")
|
||||
flow = layout.grid_flow(row_major=True, num_columns=2, even_rows=False, align=False)
|
||||
|
||||
flow.prop(dopesheet, "show_scenes", text="Scenes")
|
||||
flow.prop(dopesheet, "show_worlds", text="Worlds")
|
||||
flow.prop(dopesheet, "show_nodes", text="Node Trees")
|
||||
|
||||
if bpy.data.armatures:
|
||||
flow.prop(dopesheet, "show_armatures", text="Armatures")
|
||||
if bpy.data.cameras:
|
||||
flow.prop(dopesheet, "show_cameras", text="Cameras")
|
||||
if bpy.data.grease_pencil:
|
||||
flow.prop(dopesheet, "show_gpencil", text="Grease Pencil Objects")
|
||||
if bpy.data.lamps:
|
||||
flow.prop(dopesheet, "show_lamps", text="Lamps")
|
||||
if bpy.data.materials:
|
||||
flow.prop(dopesheet, "show_materials", text="Materials")
|
||||
if bpy.data.textures:
|
||||
flow.prop(dopesheet, "show_textures", text="Textures")
|
||||
if bpy.data.meshes:
|
||||
flow.prop(dopesheet, "show_meshes", text="Meshes")
|
||||
if bpy.data.shape_keys:
|
||||
flow.prop(dopesheet, "show_shapekeys", text="Shape Keys")
|
||||
if bpy.data.curves:
|
||||
flow.prop(dopesheet, "show_curves", text="Curves")
|
||||
if bpy.data.particles:
|
||||
flow.prop(dopesheet, "show_particles", text="Particles")
|
||||
if bpy.data.lattices:
|
||||
flow.prop(dopesheet, "show_lattices", text="Lattices")
|
||||
if bpy.data.linestyles:
|
||||
flow.prop(dopesheet, "show_linestyles", text="Line Styles")
|
||||
if bpy.data.metaballs:
|
||||
flow.prop(dopesheet, "show_metaballs", text="Metas")
|
||||
if bpy.data.speakers:
|
||||
flow.prop(dopesheet, "show_speakers", text="Speakers")
|
||||
|
||||
layout.separator()
|
||||
|
||||
# performance-related options (users will mostly have these enabled)
|
||||
col = layout.column(align=True)
|
||||
col.label("Options:")
|
||||
col.prop(dopesheet, "use_datablock_sort", icon='NONE')
|
||||
|
||||
|
||||
# Popover for Dopesheet Editor(s) - Dopesheet, Action, Shapekey, GPencil, Mask, etc.
|
||||
class DOPESHEET_PT_filters(DopesheetFilterPopoverBase, Panel):
|
||||
bl_space_type = 'DOPESHEET_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filters"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
dopesheet = context.space_data.dopesheet
|
||||
ds_mode = context.space_data.mode
|
||||
|
||||
layout.prop(dopesheet, "show_summary", text="Summary")
|
||||
|
||||
DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
|
||||
|
||||
if ds_mode in {'DOPESHEET', 'ACTION', 'GPENCIL'}:
|
||||
layout.separator()
|
||||
generic_filters_only = ds_mode != 'DOPESHEET'
|
||||
DopesheetFilterPopoverBase.draw_search_filters(context, layout,
|
||||
generic_filters_only=generic_filters_only)
|
||||
|
||||
if ds_mode == 'DOPESHEET':
|
||||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
|
||||
|
||||
|
||||
#######################################
|
||||
|
@ -124,12 +223,16 @@ class DOPESHEET_HT_header(Header):
|
|||
TIME_HT_editor_buttons.draw_header(context, layout)
|
||||
else:
|
||||
layout.prop(st, "ui_mode", text="")
|
||||
layout.popover(space_type='DOPESHEET_EDITOR',
|
||||
region_type='HEADER',
|
||||
panel_type="DOPESHEET_PT_filters",
|
||||
text="",
|
||||
icon='FILTER')
|
||||
DOPESHEET_MT_editor_menus.draw_collapsible(context, layout)
|
||||
DOPESHEET_HT_editor_buttons.draw_header(context, layout)
|
||||
|
||||
|
||||
# Header for "normal" dopesheet editor modes (e.g. Dope Sheet, Action, Shape Keys, etc.)
|
||||
# XXX: Temporary, until we have editor submodes in the actual editors menu
|
||||
class DOPESHEET_HT_editor_buttons(Header):
|
||||
bl_idname = "DOPESHEET_HT_editor_buttons"
|
||||
bl_space_type = 'DOPESHEET_EDITOR'
|
||||
|
@ -154,7 +257,7 @@ class DOPESHEET_HT_editor_buttons(Header):
|
|||
row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN')
|
||||
row.operator("action.stash", text="Stash", icon='FREEZE')
|
||||
|
||||
layout.prop(st.dopesheet, "show_summary", text="Summary")
|
||||
# layout.separator_spacer()
|
||||
|
||||
if st.mode == 'DOPESHEET':
|
||||
dopesheet_filter(layout, context)
|
||||
|
@ -543,6 +646,7 @@ classes = (
|
|||
DOPESHEET_MT_delete,
|
||||
DOPESHEET_MT_specials,
|
||||
DOPESHEET_MT_channel_specials,
|
||||
DOPESHEET_PT_filters,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -19,15 +19,17 @@
|
|||
# <pep8 compliant>
|
||||
|
||||
import bpy
|
||||
from bpy.types import Header, Menu
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from .space_dopesheet import (
|
||||
DopesheetFilterPopoverBase,
|
||||
dopesheet_filter,
|
||||
)
|
||||
|
||||
|
||||
class GRAPH_HT_header(Header):
|
||||
bl_space_type = 'GRAPH_EDITOR'
|
||||
|
||||
def draw(self, context):
|
||||
from .space_dopesheet import dopesheet_filter
|
||||
|
||||
layout = self.layout
|
||||
toolsettings = context.tool_settings
|
||||
|
||||
|
@ -39,6 +41,12 @@ class GRAPH_HT_header(Header):
|
|||
# Now a exposed as a sub-space type
|
||||
# layout.prop(st, "mode", text="")
|
||||
|
||||
layout.popover(space_type='GRAPH_EDITOR',
|
||||
region_type='HEADER',
|
||||
panel_type="GRAPH_PT_filters",
|
||||
text="",
|
||||
icon='FILTER')
|
||||
|
||||
GRAPH_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
||||
dopesheet_filter(layout, context)
|
||||
|
@ -72,6 +80,21 @@ class GRAPH_HT_header(Header):
|
|||
row.operator("graph.ghost_curves_create", text="", icon='GHOST_ENABLED')
|
||||
|
||||
|
||||
class GRAPH_PT_filters(DopesheetFilterPopoverBase, Panel):
|
||||
bl_space_type = 'GRAPH_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filters"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
|
||||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_search_filters(context, layout)
|
||||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
|
||||
|
||||
|
||||
class GRAPH_MT_editor_menus(Menu):
|
||||
bl_idname = "GRAPH_MT_editor_menus"
|
||||
bl_label = ""
|
||||
|
@ -382,6 +405,7 @@ classes = (
|
|||
GRAPH_MT_delete,
|
||||
GRAPH_MT_specials,
|
||||
GRAPH_MT_channel_specials,
|
||||
GRAPH_PT_filters,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -19,15 +19,17 @@
|
|||
# <pep8 compliant>
|
||||
|
||||
import bpy
|
||||
from bpy.types import Header, Menu
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from .space_dopesheet import (
|
||||
DopesheetFilterPopoverBase,
|
||||
dopesheet_filter,
|
||||
)
|
||||
|
||||
|
||||
class NLA_HT_header(Header):
|
||||
bl_space_type = 'NLA_EDITOR'
|
||||
|
||||
def draw(self, context):
|
||||
from .space_dopesheet import dopesheet_filter
|
||||
|
||||
layout = self.layout
|
||||
|
||||
st = context.space_data
|
||||
|
@ -35,6 +37,12 @@ class NLA_HT_header(Header):
|
|||
row = layout.row(align=True)
|
||||
row.template_header()
|
||||
|
||||
layout.popover(space_type='NLA_EDITOR',
|
||||
region_type='HEADER',
|
||||
panel_type="NLA_PT_filters",
|
||||
text="",
|
||||
icon='FILTER')
|
||||
|
||||
NLA_MT_editor_menus.draw_collapsible(context, layout)
|
||||
|
||||
dopesheet_filter(layout, context)
|
||||
|
@ -43,6 +51,21 @@ class NLA_HT_header(Header):
|
|||
layout.prop(st, "auto_snap", text="")
|
||||
|
||||
|
||||
class NLA_PT_filters(DopesheetFilterPopoverBase, Panel):
|
||||
bl_space_type = 'NLA_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filters"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
|
||||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_search_filters(context, layout)
|
||||
layout.separator()
|
||||
DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
|
||||
|
||||
|
||||
class NLA_MT_editor_menus(Menu):
|
||||
bl_idname = "NLA_MT_editor_menus"
|
||||
bl_label = ""
|
||||
|
@ -218,6 +241,7 @@ classes = (
|
|||
NLA_MT_marker,
|
||||
NLA_MT_add,
|
||||
NLA_MT_edit_transform,
|
||||
NLA_PT_filters,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
Loading…
Reference in New Issue