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:
parent
ce148716c8
commit
ab6c7ff2ab
Notes:
blender-bot
2023-02-14 05:02:30 +01:00
Referenced by issue #57790, vertical properties menu issues
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue