UI: Vertical Properties Editor Tabs

Moves the Properties editor context switching to a vertical tabs region.

Design Task: T54951
Differential Revison: D3840

The tabs are regular widgets, unlike the 'old' toolshelf tabs. This means they
give mouse hover feedback, have tooltips, support the right-click menu, etc.
Also, when vertical screen space gets tight, the tabs can be scrolled, they
don't shrink like the toolshelf ones.
The tab region is slightly larger than the header. The tabs are scaled up
accordingly. This makes them nicely readable.

The header is quite empty now. As shown in T54951, we wanted to have a search
button there. This should be added next.

Implementation Notes:

* Added a new region type, RGN_TYPE_NAVIGATION.
* Having the tabs in a separate region allows scrolling of the tab-bar, unlike
  the toolshelf tabs. We might want to remove the scrollbars though.
* Added a new region flag RGN_FLAG_PREFSIZE_OR_HIDDEN, to ensure the tab region
  is either hidden or has a fixed size.
* Added some additional flags to support fine-tuning the layout in panel and
  layout code.
* Bumps subversion.
This commit is contained in:
Julian Eisel 2018-10-29 21:34:14 +01:00
parent ce148716c8
commit ab6c7ff2ab
Notes: blender-bot 2023-02-14 05:02:30 +01:00
Referenced by issue #57790, vertical properties menu issues
16 changed files with 117 additions and 13 deletions

View File

@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Header
from bpy.types import Header, Panel
class PROPERTIES_HT_header(Header):
@ -27,16 +27,29 @@ class PROPERTIES_HT_header(Header):
def draw(self, context):
layout = self.layout
view = context.space_data
row = layout.row()
row.template_header()
row.prop(view, "context", expand=True, icon_only=True)
class PROPERTIES_PT_navigation_bar(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'NAVIGATION_BAR'
bl_label = "Navigation Bar"
bl_options = {'HIDE_HEADER'}
def draw(self, context):
layout = self.layout
view = context.space_data
layout.scale_x = 1.4
layout.scale_y = 1.4
layout.prop_tabs_enum(view, "context", icon_only=True)
classes = (
PROPERTIES_HT_header,
PROPERTIES_PT_navigation_bar,
)
if __name__ == "__main__": # only for live edit.

View File

@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 280
#define BLENDER_SUBVERSION 28
#define BLENDER_SUBVERSION 29
/* Several breakages with 280, e.g. collections vs layers */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0

View File

@ -2179,4 +2179,30 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 280, 29)) {
for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_BUTS) {
ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
ARegion *ar = MEM_callocN(sizeof(ARegion), "navigation bar for properties");
ARegion *ar_header = NULL;
for (ar_header = regionbase->first; ar_header; ar_header = ar_header->next) {
if (ar_header->regiontype == RGN_TYPE_HEADER) {
break;
}
}
BLI_assert(ar_header);
BLI_insertlinkafter(regionbase, ar_header, ar);
ar->regiontype = RGN_TYPE_NAV_BAR;
ar->alignment = RGN_ALIGN_LEFT;
}
}
}
}
}
}

View File

@ -81,8 +81,12 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme)
if (!USER_VERSION_ATLEAST(280, 28)) {
copy_v4_v4_char(btheme->tact.ds_ipoline, U_theme_default.tact.ds_ipoline);
}
#undef USER_VERSION_ATLEAST
if (!USER_VERSION_ATLEAST(280, 29)) {
copy_v4_v4_char(btheme->tbuts.navigation_bar, U_theme_default.ttopbar.header);
}
#undef USER_VERSION_ATLEAST
}
/* patching UserDef struct and Themes */

View File

@ -915,6 +915,7 @@ void UI_exit(void);
#define UI_LAYOUT_MENU 2
#define UI_LAYOUT_TOOLBAR 3
#define UI_LAYOUT_PIEMENU 4
#define UI_LAYOUT_VERT_BAR 5
#define UI_UNIT_X ((void)0, U.widget_unit)
#define UI_UNIT_Y ((void)0, U.widget_unit)

View File

@ -4260,7 +4260,7 @@ uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int s
root->opcontext = WM_OP_INVOKE_REGION_WIN;
layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
layout->item.type = ITEM_LAYOUT_ROOT;
layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT;
/* Only used when 'UI_ITEM_PROP_SEP' is set. */
layout->item.flag = UI_ITEM_PROP_DECORATE;

View File

@ -134,7 +134,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
return BUT_VERTICAL;
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
return BUT_VERTICAL;
else if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HUD))
else if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HUD, RGN_TYPE_NAV_BAR))
return BUT_VERTICAL;
return 0;

View File

@ -181,6 +181,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->list;
else if (theme_regionid == RGN_TYPE_HEADER)
cp = ts->header;
else if (theme_regionid == RGN_TYPE_NAV_BAR)
cp = ts->navigation_bar;
else
cp = ts->button;

View File

@ -1159,7 +1159,11 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, rct
int prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex);
int prefsizey;
if (ar->regiontype == RGN_TYPE_HEADER) {
if (ar->flag & RGN_FLAG_PREFSIZE_OR_HIDDEN) {
prefsizex = UI_DPI_FAC * ar->type->prefsizex;
prefsizey = UI_DPI_FAC * ar->type->prefsizey;
}
else if (ar->regiontype == RGN_TYPE_HEADER) {
prefsizey = ED_area_headersize();
}
else if (ED_area_is_global(sa)) {
@ -2020,14 +2024,21 @@ static void ed_panel_draw(
short panelContext;
/* panel context can either be toolbar region or normal panels region */
if (ar->regiontype == RGN_TYPE_TOOLS)
if (pt->flag & PNL_LAYOUT_VERT_BAR) {
panelContext = UI_LAYOUT_VERT_BAR;
}
else if (ar->regiontype == RGN_TYPE_TOOLS) {
panelContext = UI_LAYOUT_TOOLBAR;
else
}
else {
panelContext = UI_LAYOUT_PANEL;
}
panel->layout = UI_block_layout(
block, UI_LAYOUT_VERTICAL, panelContext,
style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
(pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : style->panelspace, 0,
(pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : w - 2 * style->panelspace,
em, 0, style);
pt->draw(C, panel);

View File

@ -1251,7 +1251,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
for (ar = newa->regionbase.first; ar; ar = ar->next) {
ar->flagfullscreen = ar->flag;
if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_TOOLS)) {
if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR)) {
ar->flag |= RGN_FLAG_HIDDEN;
}
}

View File

@ -3585,6 +3585,7 @@ static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
ar->alignment = RGN_ALIGN_LEFT;
ED_area_tag_redraw(CTX_wm_area(C));
WM_event_add_mousemove(C);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
return OPERATOR_FINISHED;

View File

@ -75,6 +75,13 @@ static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
/* navigation bar */
ar = MEM_callocN(sizeof(ARegion), "navigation bar for buts");
BLI_addtail(&sbuts->regionbase, ar);
ar->regiontype = RGN_TYPE_NAV_BAR;
ar->alignment = RGN_ALIGN_LEFT;
#if 0
/* context region */
ar = MEM_callocN(sizeof(ARegion), "context region for buts");
@ -390,6 +397,21 @@ static void buttons_header_region_message_subscribe(
}
}
static void buttons_navigation_bar_region_init(wmWindowManager *wm, ARegion *ar)
{
ar->flag |= RGN_FLAG_PREFSIZE_OR_HIDDEN;
ED_region_panels_init(wm, ar);
ar->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
}
static void buttons_navigation_bar_region_draw(const bContext *C, ARegion *ar)
{
for (PanelType *pt = ar->type->paneltypes.first; pt; pt = pt->next) {
pt->flag |= PNL_LAYOUT_VERT_BAR;
}
ED_region_panels(C, ar);
}
/* draw a certain button set only if properties area is currently
* showing that button set, to reduce unnecessary drawing. */
static void buttons_area_redraw(ScrArea *sa, short buttons)
@ -680,5 +702,14 @@ void ED_spacetype_buttons(void)
art->message_subscribe = buttons_header_region_message_subscribe;
BLI_addhead(&st->regiontypes, art);
/* regions: navigation bar */
art = MEM_callocN(sizeof(ARegionType), "spacetype nav buttons region");
art->regionid = RGN_TYPE_NAV_BAR;
art->prefsizex = AREAMINX - 3; /* XXX Works and looks best, should we update AREAMINX accordingly? */
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
art->init = buttons_navigation_bar_region_init;
art->draw = buttons_navigation_bar_region_draw;
BLI_addhead(&st->regiontypes, art);
BKE_spacetype_register(st);
}

View File

@ -420,6 +420,7 @@ enum {
/* paneltype flag */
#define PNL_DEFAULT_CLOSED 1
#define PNL_NO_HEADER 2
#define PNL_LAYOUT_VERT_BAR 4
/* Fallback panel category (only for old scripts which need updating) */
#define PNL_CATEGORY_FALLBACK "Misc"
@ -473,6 +474,8 @@ enum {
RGN_TYPE_TOOL_PROPS = 6,
RGN_TYPE_PREVIEW = 7,
RGN_TYPE_HUD = 8,
/* Region to navigate the main region from (RGN_TYPE_WINDOW). */
RGN_TYPE_NAV_BAR = 9,
};
/* use for function args */
#define RGN_TYPE_ANY -1
@ -503,6 +506,8 @@ enum {
RGN_FLAG_DYNAMIC_SIZE = (1 << 2),
/* Region data is NULL'd on read, never written. */
RGN_FLAG_TEMP_REGIONDATA = (1 << 3),
/* The region must either use its prefsizex/y or be hidden. */
RGN_FLAG_PREFSIZE_OR_HIDDEN = (1 << 4),
};
/* region do_draw */

View File

@ -243,6 +243,10 @@ typedef struct ThemeSpace {
char list_text[4];
char list_text_hi[4];
/* navigation bar regions */
char navigation_bar[4]; /* region background */
int pad2;
/* float panel */
/* char panel[4]; unused */
/* char panel_title[4]; unused */

View File

@ -46,6 +46,7 @@ const EnumPropertyItem rna_enum_region_type_items[] = {
{RGN_TYPE_TOOLS, "TOOLS", 0, "Tools", ""},
{RGN_TYPE_TOOL_PROPS, "TOOL_PROPS", 0, "Tool Properties", ""},
{RGN_TYPE_PREVIEW, "PREVIEW", 0, "Preview", ""},
{RGN_TYPE_NAV_BAR, "NAVIGATION_BAR", 0, "Navigation Bar", ""},
{0, NULL, 0, NULL, NULL}
};

View File

@ -1325,6 +1325,11 @@ static void rna_def_userdef_theme_space_common(StructRNA *srna)
RNA_def_property_ui_text(prop, "Region Text Highlight", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "navigation_bar", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Navigation Bar Background", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
/* tabs */
prop = RNA_def_property(srna, "tab_active", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);