UI: Add tab filter popover to vertical tabs
This adds unobtrusive tab button for selecting displayed tabs to the tabs region. The idea is, that this way, the filter is much more discoverable than it being hidden in options popover. The button is grayed out, when all tabs are visible. To only draw arrow, is achieved by setting `UILayout.emboss` to `NONE` or `NONE_OR_STATUS` Pull Request: https://projects.blender.org/blender/blender/pulls/135132
This commit is contained in:
committed by
Richard Antalik
parent
43654059ba
commit
a82f3a0fe0
@@ -10,32 +10,36 @@ from bpy.app.translations import (
|
||||
)
|
||||
|
||||
|
||||
tab_list = [
|
||||
("show_properties_tool", "Tool", 'TOOL_SETTINGS'),
|
||||
("show_properties_render", "Render", 'SCENE'),
|
||||
("show_properties_output", "Output", 'OUTPUT'),
|
||||
("show_properties_view_layer", "View Layer", 'RENDERLAYERS'),
|
||||
("show_properties_scene", "Scene", 'SCENE_DATA'),
|
||||
("show_properties_world", "World", 'WORLD'),
|
||||
("show_properties_collection", "Collection", 'OUTLINER_COLLECTION'),
|
||||
("show_properties_object", "Object", 'OBJECT_DATA'),
|
||||
("show_properties_modifiers", "Modifiers", 'MODIFIER'),
|
||||
("show_properties_effects", "Effects", 'SHADERFX'),
|
||||
("show_properties_particles", "Particles", 'PARTICLES'),
|
||||
("show_properties_physics", "Physics", 'PHYSICS'),
|
||||
("show_properties_constraints", "Constraints", 'CONSTRAINT'),
|
||||
("show_properties_data", "Data", 'MESH_DATA'),
|
||||
("show_properties_bone", "Bone", 'BONE_DATA'),
|
||||
("show_properties_bone_constraints", "Bone Constraints", 'CONSTRAINT_BONE'),
|
||||
("show_properties_material", "Material", 'MATERIAL'),
|
||||
("show_properties_texture", "Texture", 'TEXTURE'),
|
||||
("show_properties_strip", "Strip", 'SEQ_SEQUENCER'),
|
||||
("show_properties_strip_modifier", "Strip Modifiers", 'SEQ_STRIP_MODIFIER'),
|
||||
]
|
||||
|
||||
|
||||
class PROPERTIES_HT_header(Header):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
|
||||
@staticmethod
|
||||
def _search_poll(space):
|
||||
return (space.show_properties_tool or
|
||||
space.show_properties_render or
|
||||
space.show_properties_output or
|
||||
space.show_properties_view_layer or
|
||||
space.show_properties_scene or
|
||||
space.show_properties_world or
|
||||
space.show_properties_collection or
|
||||
space.show_properties_object or
|
||||
space.show_properties_modifiers or
|
||||
space.show_properties_effects or
|
||||
space.show_properties_particles or
|
||||
space.show_properties_physics or
|
||||
space.show_properties_constraints or
|
||||
space.show_properties_data or
|
||||
space.show_properties_bone or
|
||||
space.show_properties_bone_constraints or
|
||||
space.show_properties_material or
|
||||
space.show_properties_texture or
|
||||
space.show_properties_strip or
|
||||
space.show_properties_strip_modifier
|
||||
)
|
||||
return any(getattr(space, tab_info[0]) for tab_info in tab_list)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -64,6 +68,10 @@ class PROPERTIES_HT_header(Header):
|
||||
layout.popover(panel="PROPERTIES_PT_options", text="")
|
||||
|
||||
|
||||
def has_hidden_tabs(space):
|
||||
return not all(getattr(space, tab_info[0]) for tab_info in tab_list)
|
||||
|
||||
|
||||
class PROPERTIES_PT_navigation_bar(Panel):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'NAVIGATION_BAR'
|
||||
@@ -85,6 +93,17 @@ class PROPERTIES_PT_navigation_bar(Panel):
|
||||
else:
|
||||
layout.prop_tabs_enum(view, "context", icon_only=True)
|
||||
|
||||
# Scale sub layout to make the popover button smaller and use separator to
|
||||
# offset it, such that it is centered.
|
||||
sub = layout.row(align=True)
|
||||
sub.alignment = 'CENTER'
|
||||
sub.emboss = 'NONE'
|
||||
sub.scale_x = 0.8
|
||||
sub.scale_y = 0.8
|
||||
sub.separator(factor=0.7)
|
||||
sub.popover(panel="PROPERTIES_PT_visibility", text="")
|
||||
sub.active = has_hidden_tabs(view)
|
||||
|
||||
|
||||
class PROPERTIES_PT_options(Panel):
|
||||
"""Show options for the properties editor"""
|
||||
@@ -101,40 +120,6 @@ class PROPERTIES_PT_options(Panel):
|
||||
col.label(text="Sync with Outliner")
|
||||
col.row().prop(space, "outliner_sync", expand=True)
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.use_property_decorate = False
|
||||
|
||||
visible_tabs = [
|
||||
("show_properties_tool", "Tool", 'TOOL_SETTINGS'),
|
||||
("show_properties_render", "Render", 'SCENE'),
|
||||
("show_properties_output", "Output", 'OUTPUT'),
|
||||
("show_properties_view_layer", "View Layer", 'RENDERLAYERS'),
|
||||
("show_properties_scene", "Scene", 'SCENE_DATA'),
|
||||
("show_properties_world", "World", 'WORLD'),
|
||||
("show_properties_collection", "Collection", 'GROUP'),
|
||||
("show_properties_object", "Object", 'OBJECT_DATA'),
|
||||
("show_properties_modifiers", "Modifiers", 'MODIFIER'),
|
||||
("show_properties_effects", "Effects", 'SHADERFX'),
|
||||
("show_properties_particles", "Particles", 'PARTICLES'),
|
||||
("show_properties_physics", "Physics", 'PHYSICS'),
|
||||
("show_properties_constraints", "Constraints", 'CONSTRAINT'),
|
||||
("show_properties_data", "Data", 'MESH_DATA'),
|
||||
("show_properties_bone", "Bone", 'BONE_DATA'),
|
||||
("show_properties_bone_constraints", "Bone Constraints", 'CONSTRAINT_BONE'),
|
||||
("show_properties_material", "Material", 'MATERIAL'),
|
||||
("show_properties_texture", "Texture", 'TEXTURE'),
|
||||
("show_properties_strip", "Strip", 'SEQ_SEQUENCER'),
|
||||
("show_properties_strip_modifier", "Strip Modifiers", 'SEQ_STRIP_MODIFIER')
|
||||
]
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Visible Tabs")
|
||||
for prop, name, icon in visible_tabs:
|
||||
row = col.row(align=True)
|
||||
row.label(text=iface_(name), icon=icon)
|
||||
row.prop(space, prop, text="")
|
||||
|
||||
|
||||
class PropertiesAnimationMixin:
|
||||
"""Mix-in class for Animation panels.
|
||||
@@ -188,10 +173,30 @@ class PropertiesAnimationMixin:
|
||||
anim.draw_action_and_slot_selector_for_id(layout, animated_id)
|
||||
|
||||
|
||||
class PROPERTIES_PT_visibility(Panel):
|
||||
"""Choose visibility of tabs in the properties editor"""
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Visibility"
|
||||
|
||||
def draw(self, context):
|
||||
space = context.space_data
|
||||
layout = self.layout
|
||||
layout.use_property_decorate = False
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Visible Tabs")
|
||||
for prop, name, icon in tab_list:
|
||||
row = col.row(align=True)
|
||||
row.label(text=iface_(name), icon=icon)
|
||||
row.prop(space, prop, text="")
|
||||
|
||||
|
||||
classes = (
|
||||
PROPERTIES_HT_header,
|
||||
PROPERTIES_PT_navigation_bar,
|
||||
PROPERTIES_PT_options,
|
||||
PROPERTIES_PT_visibility,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
||||
@@ -3049,6 +3049,12 @@ void uiLayout::popover(const bContext *C,
|
||||
uiBut *but = ui_item_menu(
|
||||
layout, name, icon, ui_item_paneltype_func, pt, nullptr, TIP_(pt->description), true);
|
||||
but->type = ButType::Popover;
|
||||
|
||||
/* Override button size when there is no icon or label. */
|
||||
if (layout->root()->type == blender::ui::LayoutType::VerticalBar && !icon && name.is_empty()) {
|
||||
but->rect.xmax = but->rect.xmin + UI_UNIT_X;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
but->flag |= UI_BUT_DISABLED;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,8 @@ struct uiWidgetStateInfo {
|
||||
int but_flag;
|
||||
/** Copy of #uiBut.drawflag (possibly with overrides for drawing). */
|
||||
int but_drawflag;
|
||||
/** Copy of #uiBut.emboss. */
|
||||
blender::ui::EmbossType emboss;
|
||||
|
||||
/** Show that holding the button opens a menu. */
|
||||
bool has_hold_action : 1;
|
||||
@@ -3709,7 +3711,7 @@ static void widget_numbut(uiBut *but,
|
||||
|
||||
static void widget_menubut(uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo * /*state*/,
|
||||
const uiWidgetStateInfo *state,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
{
|
||||
@@ -3724,6 +3726,12 @@ static void widget_menubut(uiWidgetColors *wcol,
|
||||
/* copy size and center to 2nd tria */
|
||||
wtb.tria2 = wtb.tria1;
|
||||
|
||||
if (ELEM(state->emboss, blender::ui::EmbossType::NoneOrStatus, blender::ui::EmbossType::None)) {
|
||||
wtb.draw_inner = false;
|
||||
wtb.draw_outline = false;
|
||||
wtb.draw_emboss = false;
|
||||
}
|
||||
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
/* text space, arrows are about 0.6 height of button */
|
||||
@@ -5019,6 +5027,22 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
|
||||
return roundbox;
|
||||
}
|
||||
|
||||
static uiWidgetType *popover_widget_type(uiBut *but, rcti *rect)
|
||||
{
|
||||
/* We could use a flag for this, but for now just check size,
|
||||
* add up/down arrows if there is room. */
|
||||
if ((but->str.empty() && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
|
||||
/* disable for brushes also */
|
||||
(but->flag & UI_BUT_ICON_PREVIEW))
|
||||
{
|
||||
/* No arrows. */
|
||||
return widget_type(UI_WTYPE_MENU_ICON_RADIO);
|
||||
}
|
||||
|
||||
/* With menu arrows. */
|
||||
return widget_type(UI_WTYPE_MENU_RADIO);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -5068,6 +5092,9 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
|
||||
case ButType::PreviewTile:
|
||||
wt = widget_type(UI_WTYPE_PREVIEW_TILE);
|
||||
break;
|
||||
case ButType::Popover:
|
||||
wt = popover_widget_type(but, rect);
|
||||
break;
|
||||
case ButType::NodeSocket:
|
||||
wt = widget_type(UI_WTYPE_NODESOCKET);
|
||||
break;
|
||||
@@ -5184,21 +5211,8 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
|
||||
wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
|
||||
}
|
||||
else {
|
||||
/* with menu arrows */
|
||||
|
||||
/* We could use a flag for this, but for now just check size,
|
||||
* add up/down arrows if there is room. */
|
||||
if ((but->str.empty() && but->icon &&
|
||||
(BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
|
||||
/* disable for brushes also */
|
||||
(but->flag & UI_BUT_ICON_PREVIEW))
|
||||
{
|
||||
/* no arrows */
|
||||
wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
|
||||
}
|
||||
else {
|
||||
wt = widget_type(UI_WTYPE_MENU_RADIO);
|
||||
}
|
||||
/* Popover button. */
|
||||
wt = popover_widget_type(but, rect);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -5322,6 +5336,7 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
|
||||
uiWidgetStateInfo state = {0};
|
||||
state.but_flag = but->flag;
|
||||
state.but_drawflag = but->drawflag;
|
||||
state.emboss = but->emboss;
|
||||
|
||||
/* Override selected flag for drawing. */
|
||||
if (but->flag & UI_SELECT_DRAW) {
|
||||
|
||||
Reference in New Issue
Block a user