Add tabs as standard button types
NOTE: This is really a backend-only implementation, nothing is changed in the UI Adds a tab button-type and the basic drawing and handling code for it. More work needs to be done on it, but idea is to get in ready for usage in the topbar. Differential Revision: https://developer.blender.org/D1371
This commit is contained in:
parent
a96008f3aa
commit
2977a8cd21
|
@ -256,6 +256,7 @@ typedef enum {
|
|||
UI_BTYPE_CHECKBOX = (13 << 9), /* similar to toggle, display a 'tick' */
|
||||
UI_BTYPE_CHECKBOX_N = (14 << 9),
|
||||
UI_BTYPE_COLOR = (15 << 9),
|
||||
UI_BTYPE_TAB = (16 << 9),
|
||||
UI_BTYPE_SCROLL = (18 << 9),
|
||||
UI_BTYPE_BLOCK = (19 << 9),
|
||||
UI_BTYPE_LABEL = (20 << 9),
|
||||
|
|
|
@ -1463,6 +1463,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
|
|||
break;
|
||||
case UI_BTYPE_ROW:
|
||||
case UI_BTYPE_LISTROW:
|
||||
case UI_BTYPE_TAB:
|
||||
UI_GET_BUT_VALUE_INIT(but, *value);
|
||||
/* support for rna enum buts */
|
||||
if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
|
||||
|
|
|
@ -110,9 +110,9 @@ enum {
|
|||
|
||||
bool ui_but_can_align(const uiBut *but)
|
||||
{
|
||||
return (
|
||||
!ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE) &&
|
||||
(BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
|
||||
const bool btype_can_align = !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N,
|
||||
UI_BTYPE_TAB, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE);
|
||||
return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -464,6 +464,93 @@ void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const flo
|
|||
|
||||
/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
|
||||
|
||||
/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
|
||||
void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3])
|
||||
{
|
||||
VertexFormat *format = immVertexFormat();
|
||||
unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
|
||||
unsigned int col = add_attrib(format, "color", GL_UNSIGNED_BYTE, 3, NORMALIZE_INT_TO_FLOAT);
|
||||
/* add a 1px offset, looks nicer */
|
||||
const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
|
||||
const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
|
||||
int a;
|
||||
float vec[4][2] = {
|
||||
{0.195, 0.02},
|
||||
{0.55, 0.169},
|
||||
{0.831, 0.45},
|
||||
{0.98, 0.805},
|
||||
};
|
||||
|
||||
|
||||
/* mult */
|
||||
for (a = 0; a < 4; a++) {
|
||||
mul_v2_fl(vec[a], rad);
|
||||
}
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
|
||||
immBeginAtMost(PRIM_LINE_STRIP, 25);
|
||||
|
||||
immAttrib3ubv(col, highlight);
|
||||
|
||||
/* start with corner left-top */
|
||||
if (roundboxtype & UI_CNR_TOP_LEFT) {
|
||||
immVertex2f(pos, minx, maxy - rad);
|
||||
for (a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
|
||||
}
|
||||
immVertex2f(pos, minx + rad, maxy);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, minx, maxy);
|
||||
}
|
||||
|
||||
/* corner right-top */
|
||||
if (roundboxtype & UI_CNR_TOP_RIGHT) {
|
||||
immVertex2f(pos, maxx - rad, maxy);
|
||||
for (a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
|
||||
}
|
||||
immVertex2f(pos, maxx, maxy - rad);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, maxx, maxy);
|
||||
}
|
||||
|
||||
immAttrib3ubv(col, highlight_fade);
|
||||
|
||||
/* corner right-bottom */
|
||||
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
|
||||
immVertex2f(pos, maxx, miny + rad);
|
||||
for (a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
|
||||
}
|
||||
immVertex2f(pos, maxx - rad, miny);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, maxx, miny);
|
||||
}
|
||||
|
||||
/* corner left-bottom */
|
||||
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
|
||||
immVertex2f(pos, minx + rad, miny);
|
||||
for (a = 0; a < 4; a++) {
|
||||
immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
|
||||
}
|
||||
immVertex2f(pos, minx, miny + rad);
|
||||
}
|
||||
else {
|
||||
immVertex2f(pos, minx, miny);
|
||||
}
|
||||
|
||||
immAttrib3ubv(col, highlight);
|
||||
|
||||
/* back to corner left-top */
|
||||
immVertex2f(pos, minx, roundboxtype & UI_CNR_TOP_LEFT ? maxy - rad : maxy);
|
||||
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
|
||||
{
|
||||
#ifdef WITH_HEADLESS
|
||||
|
|
|
@ -2094,6 +2094,7 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
|
|||
break;
|
||||
case UI_BTYPE_ROW:
|
||||
case UI_BTYPE_LISTROW:
|
||||
case UI_BTYPE_TAB:
|
||||
ui_apply_but_ROW(C, block, but, data);
|
||||
break;
|
||||
case UI_BTYPE_SCROLL:
|
||||
|
@ -3835,6 +3836,18 @@ static int ui_do_but_KEYEVT(
|
|||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static int ui_do_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_RELEASE) {
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
|
||||
{
|
||||
int x = mouse_xy[0], y = mouse_xy[1];
|
||||
|
@ -7078,6 +7091,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
|
|||
case UI_BTYPE_HOTKEY_EVENT:
|
||||
retval = ui_do_but_HOTKEYEVT(C, but, data, event);
|
||||
break;
|
||||
case UI_BTYPE_TAB:
|
||||
retval = ui_do_but_TAB(C, but, data, event);
|
||||
break;
|
||||
case UI_BTYPE_BUT_TOGGLE:
|
||||
case UI_BTYPE_TOGGLE:
|
||||
case UI_BTYPE_ICON_TOGGLE:
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef enum {
|
|||
UI_WTYPE_NUMBER,
|
||||
UI_WTYPE_SLIDER,
|
||||
UI_WTYPE_EXEC,
|
||||
UI_WTYPE_TAB,
|
||||
UI_WTYPE_TOOLTIP,
|
||||
|
||||
/* strings */
|
||||
|
@ -639,6 +640,8 @@ extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, floa
|
|||
|
||||
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
|
||||
|
||||
|
||||
void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3]);
|
||||
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
|
||||
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
|
||||
void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
|
||||
|
|
|
@ -1671,6 +1671,9 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
|
|||
widget_draw_text(fstyle, wcol, but, rect);
|
||||
|
||||
ui_but_text_password_hide(password_str, but, true);
|
||||
|
||||
/* if a widget uses font shadow it has to be deactivated now */
|
||||
BLF_disable(fstyle->uifont_id, BLF_SHADOW);
|
||||
}
|
||||
|
||||
#undef UI_TEXT_CLIP_MARGIN
|
||||
|
@ -1929,6 +1932,19 @@ static struct uiWidgetColors wcol_list_item = {
|
|||
0, 0
|
||||
};
|
||||
|
||||
struct uiWidgetColors wcol_tab = {
|
||||
{255, 255, 255, 255},
|
||||
{83, 83, 83, 255},
|
||||
{114, 114, 114, 255},
|
||||
{90, 90, 90, 255},
|
||||
|
||||
{0, 0, 0, 255},
|
||||
{0, 0, 0, 255},
|
||||
|
||||
0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
/* free wcol struct to play with */
|
||||
static struct uiWidgetColors wcol_tmp = {
|
||||
{0, 0, 0, 255},
|
||||
|
@ -1951,6 +1967,7 @@ void ui_widget_color_init(ThemeUI *tui)
|
|||
tui->wcol_tool = wcol_tool;
|
||||
tui->wcol_text = wcol_text;
|
||||
tui->wcol_radio = wcol_radio;
|
||||
tui->wcol_tab = wcol_tab;
|
||||
tui->wcol_option = wcol_option;
|
||||
tui->wcol_toggle = wcol_toggle;
|
||||
tui->wcol_num = wcol_num;
|
||||
|
@ -3464,6 +3481,44 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
|
|||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
|
||||
static void widget_tab(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
|
||||
{
|
||||
const uiStyle *style = UI_style_get();
|
||||
const float rad = 0.15f * U.widget_unit;
|
||||
const int fontid = style->widget.uifont_id;
|
||||
const bool is_active = (but->flag & UI_SELECT);
|
||||
|
||||
uiWidgetBase wtb;
|
||||
unsigned char theme_col_tab_highlight[3];
|
||||
|
||||
/* create outline highlight colors */
|
||||
if (is_active) {
|
||||
interp_v3_v3v3_uchar(theme_col_tab_highlight, (unsigned char *)wcol->inner_sel,
|
||||
(unsigned char *)wcol->outline, 0.2f);
|
||||
}
|
||||
else {
|
||||
interp_v3_v3v3_uchar(theme_col_tab_highlight, (unsigned char *)wcol->inner,
|
||||
(unsigned char *)wcol->outline, 0.12f);
|
||||
}
|
||||
|
||||
widget_init(&wtb);
|
||||
|
||||
/* half rounded */
|
||||
round_box_edges(&wtb, roundboxalign, rect, rad);
|
||||
|
||||
/* draw inner */
|
||||
wtb.draw_outline = 0;
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
/* draw outline (3d look) */
|
||||
ui_draw_but_TAB_outline(rect, rad, theme_col_tab_highlight, (unsigned char *)wcol->inner);
|
||||
|
||||
/* text shadow */
|
||||
BLF_enable(fontid, BLF_SHADOW);
|
||||
BLF_shadow(fontid, 3, (const float[4]){1.0f, 1.0f, 1.0f, 0.25f});
|
||||
BLF_shadow_offset(fontid, 0, -1);
|
||||
}
|
||||
|
||||
static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
|
||||
{
|
||||
uiWidgetBase wtb;
|
||||
|
@ -3551,6 +3606,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
|
|||
wt.draw = widget_roundbut;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_TAB:
|
||||
wt.custom = widget_tab;
|
||||
wt.wcol_theme = &btheme->tui.wcol_tab;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_TOOLTIP:
|
||||
wt.wcol_theme = &btheme->tui.wcol_tooltip;
|
||||
wt.draw = widget_menu_back;
|
||||
|
@ -3805,7 +3865,11 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
|
|||
if (but->block->flag & UI_BLOCK_LOOP)
|
||||
wt->wcol_theme = &btheme->tui.wcol_menu_back;
|
||||
break;
|
||||
|
||||
|
||||
case UI_BTYPE_TAB:
|
||||
wt = widget_type(UI_WTYPE_TAB);
|
||||
break;
|
||||
|
||||
case UI_BTYPE_BUT_TOGGLE:
|
||||
case UI_BTYPE_TOGGLE:
|
||||
case UI_BTYPE_TOGGLE_N:
|
||||
|
|
|
@ -2871,7 +2871,23 @@ void init_userdef_do_versions(void)
|
|||
* (keep this block even if it becomes empty).
|
||||
*/
|
||||
{
|
||||
|
||||
/* interface_widgets.c */
|
||||
struct uiWidgetColors wcol_tab = {
|
||||
{255, 255, 255, 255},
|
||||
{83, 83, 83, 255},
|
||||
{114, 114, 114, 255},
|
||||
{90, 90, 90, 255},
|
||||
|
||||
{0, 0, 0, 255},
|
||||
{0, 0, 0, 255},
|
||||
|
||||
0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
btheme->tui.wcol_tab = wcol_tab;
|
||||
}
|
||||
}
|
||||
|
||||
if (U.pixelsize == 0.0f)
|
||||
|
|
|
@ -161,7 +161,7 @@ typedef struct ThemeUI {
|
|||
/* Interface Elements (buttons, menus, icons) */
|
||||
uiWidgetColors wcol_regular, wcol_tool, wcol_text;
|
||||
uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
|
||||
uiWidgetColors wcol_num, wcol_numslider;
|
||||
uiWidgetColors wcol_num, wcol_numslider, wcol_tab;
|
||||
uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item, wcol_tooltip;
|
||||
uiWidgetColors wcol_box, wcol_scroll, wcol_progress, wcol_list_item, wcol_pie_menu;
|
||||
|
||||
|
|
Loading…
Reference in New Issue