From 566d35036961dbe2c786b70a2972ca77055420a6 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 20 Dec 2012 16:50:39 +0000 Subject: [PATCH] UI todo: - Recoded soft shadow drawing for menus, giving better predictable results (and round off nicer on top side, was looking bad still) - Brought it under DPI control - Added Theme setting to control size and strength for it. Max size 24 pix: http://wiki.blender.org/index.php/File:MenuShadow.png --- .../scripts/startup/bl_ui/space_userpref.py | 22 ++++++ source/blender/editors/include/UI_resources.h | 3 + .../editors/interface/interface_regions.c | 71 ++++++++++--------- .../editors/interface/interface_widgets.c | 36 +++++----- source/blender/editors/interface/resources.c | 20 ++++++ source/blender/makesdna/DNA_userdef_types.h | 6 ++ source/blender/makesrna/intern/rna_userdef.c | 10 +++ 7 files changed, 120 insertions(+), 48 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 7c6c8dce954..695e09ee025 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -686,6 +686,28 @@ class USERPREF_PT_theme(Panel): col.separator() ui = theme.user_interface + + col.label("Menu Shadow:") + + row = col.row() + + subsplit = row.split(percentage=0.95) + + padding = subsplit.split(percentage=0.15) + colsub = padding.column() + colsub = padding.column() + colsub.row().prop(ui, "menu_shadow_fac") + + subsplit = row.split(percentage=0.85) + + padding = subsplit.split(percentage=0.15) + colsub = padding.column() + colsub = padding.column() + colsub.row().prop(ui, "menu_shadow_width") + + col.separator() + col.separator() + col.label("Icons:") row = col.row() diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index eaab17c4137..119c26b2fd5 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -287,6 +287,9 @@ void UI_SetTheme(int spacetype, int regionid); // get current theme struct bTheme *UI_GetTheme(void); +// return shadow width outside menus and popups */ +int UI_ThemeMenuShadowWidth(void); + /* only for buttons in theme editor! */ const unsigned char *UI_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 60885f311ca..57c126c31c5 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -73,8 +73,6 @@ #include "interface_intern.h" #define B_NOP -1 -#define MENU_SHADOW_SIDE 8 -#define MENU_SHADOW_BOTTOM 10 #define MENU_TOP 8 /*********************** Menu Data Parsing ********************* */ @@ -693,16 +691,20 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } /* widget rect, in region coords */ - data->bbox.xmin = MENU_SHADOW_SIDE; - data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE; - data->bbox.ymin = MENU_SHADOW_BOTTOM; - data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM; - - /* region bigger for shadow */ - ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE; - ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE; - ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM; - ar->winrct.ymax = rect_i.ymax + MENU_TOP; + { + int width = UI_ThemeMenuShadowWidth(); + + data->bbox.xmin = width; + data->bbox.xmax = BLI_rcti_size_x(&rect_i) + width; + data->bbox.ymin = width; + data->bbox.ymax = BLI_rcti_size_y(&rect_i) + width; + + /* region bigger for shadow */ + ar->winrct.xmin = rect_i.xmin - width; + ar->winrct.xmax = rect_i.xmax + width; + ar->winrct.ymin = rect_i.ymin - width; + ar->winrct.ymax = rect_i.ymax + MENU_TOP; + } /* adds subwindow */ ED_region_init(C, ar); @@ -1140,16 +1142,17 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) /* compute position */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { + int width = UI_ThemeMenuShadowWidth(); /* this case is search menu inside other menu */ /* we copy region size */ ar->winrct = butregion->winrct; /* widget rect, in region coords */ - data->bbox.xmin = MENU_SHADOW_SIDE; - data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - MENU_SHADOW_SIDE; - data->bbox.ymin = MENU_SHADOW_BOTTOM; - data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - MENU_SHADOW_BOTTOM; + data->bbox.xmin = width; + data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - width; + data->bbox.ymin = width; + data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - width; /* check if button is lower half */ if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) { @@ -1161,6 +1164,8 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) } else { const int searchbox_width = uiSearchBoxWidth(); + const int shadow_width = UI_ThemeMenuShadowWidth(); + rect_fl.xmin = but->rect.xmin - 5; /* align text with button */ rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */ rect_fl.ymax = but->rect.ymin; @@ -1212,15 +1217,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) } /* widget rect, in region coords */ - data->bbox.xmin = MENU_SHADOW_SIDE; - data->bbox.xmax = BLI_rcti_size_x(&rect_i) + MENU_SHADOW_SIDE; - data->bbox.ymin = MENU_SHADOW_BOTTOM; - data->bbox.ymax = BLI_rcti_size_y(&rect_i) + MENU_SHADOW_BOTTOM; + data->bbox.xmin = shadow_width; + data->bbox.xmax = BLI_rcti_size_x(&rect_i) + shadow_width; + data->bbox.ymin = shadow_width; + data->bbox.ymax = BLI_rcti_size_y(&rect_i) + shadow_width; /* region bigger for shadow */ - ar->winrct.xmin = rect_i.xmin - MENU_SHADOW_SIDE; - ar->winrct.xmax = rect_i.xmax + MENU_SHADOW_SIDE; - ar->winrct.ymin = rect_i.ymin - MENU_SHADOW_BOTTOM; + ar->winrct.xmin = rect_i.xmin - shadow_width; + ar->winrct.xmax = rect_i.xmax + shadow_width; + ar->winrct.ymin = rect_i.ymin - shadow_width; ar->winrct.ymax = rect_i.ymax; } @@ -1522,6 +1527,7 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar) static void ui_popup_block_clip(wmWindow *window, uiBlock *block) { + int width = UI_ThemeMenuShadowWidth(); int winx, winy; if (block->flag & UI_BLOCK_NO_WIN_CLIP) { @@ -1532,13 +1538,13 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) winy = WM_window_pixels_y(window); // wm_window_get_size(window, &winx, &winy); - if (block->rect.xmin < MENU_SHADOW_SIDE) - block->rect.xmin = MENU_SHADOW_SIDE; - if (block->rect.xmax > winx - MENU_SHADOW_SIDE) - block->rect.xmax = winx - MENU_SHADOW_SIDE; + if (block->rect.xmin < width) + block->rect.xmin = width; + if (block->rect.xmax > winx - width) + block->rect.xmax = winx - width; - if (block->rect.ymin < MENU_SHADOW_BOTTOM) - block->rect.ymin = MENU_SHADOW_BOTTOM; + if (block->rect.ymin < width) + block->rect.ymin = width; if (block->rect.ymax > winy - MENU_TOP) block->rect.ymax = winy - MENU_TOP; } @@ -1590,6 +1596,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut uiBlock *block; uiPopupBlockHandle *handle; uiSafetyRct *saferct; + int width = UI_ThemeMenuShadowWidth(); /* create handle */ handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle"); @@ -1658,9 +1665,9 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* the block and buttons were positioned in window space as in 2.4x, now * these menu blocks are regions so we bring it back to region space. * additionally we add some padding for the menu shadow or rounded menus */ - ar->winrct.xmin = block->rect.xmin - MENU_SHADOW_SIDE; - ar->winrct.xmax = block->rect.xmax + MENU_SHADOW_SIDE; - ar->winrct.ymin = block->rect.ymin - MENU_SHADOW_BOTTOM; + ar->winrct.xmin = block->rect.xmin - width; + ar->winrct.xmax = block->rect.xmax + width; + ar->winrct.ymin = block->rect.ymin - width; ar->winrct.ymax = block->rect.ymax + MENU_TOP; ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 25e35c2e8ff..4687647223a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -261,7 +261,7 @@ static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, if (2.0f * rad > BLI_rcti_size_y(rect)) rad = 0.5f * BLI_rcti_size_y(rect); - + minx = rect->xmin - step; miny = rect->ymin - step; maxx = rect->xmax + step; @@ -1799,13 +1799,19 @@ static void widget_state_menu_item(uiWidgetType *wt, int state) /* ************ menu backdrop ************************* */ /* outside of rect, rad to left/bottom/right */ -static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin, const float radout) +static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin) { + bTheme *btheme = UI_GetTheme(); uiWidgetBase wtb; rcti rect1 = *rect; - float alpha, alphastep; + float alphastep; int step, totvert; - float quad_strip[WIDGET_SIZE_MAX * 2][2]; + float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2]; + const float radout = UI_ThemeMenuShadowWidth(); + + /* disabled shadow */ + if (radout == 0.0f) + return; /* prevent tooltips to not show round shadow */ if (radout > 0.2f * BLI_rcti_size_y(&rect1)) @@ -1816,24 +1822,22 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r /* inner part */ totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f); - /* inverse linear shadow alpha */ - alpha = 0.15f; - if (U.pixelsize > 1.0f) - alphastep = 0.78f; - else - alphastep = 0.67f; + /* we draw a number of increasing size alpha quad strips */ + alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout; glEnableClientState(GL_VERTEX_ARRAY); - for (step = 1; step <= radout; step++, alpha *= alphastep) { + for (step = 1; step <= (int)radout; step++) { + float expfac = sqrt(step / radout); + round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step); - glColor4f(0.0f, 0.0f, 0.0f, alpha); + glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac)); - widget_verts_to_quad_strip_open(&wtb, totvert, quad_strip); + widget_verts_to_quad_strip(&wtb, totvert, quad_strip); glVertexPointer(2, GL_FLOAT, 0, quad_strip); - glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2); + glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2 + 2); } glDisableClientState(GL_VERTEX_ARRAY); @@ -1861,7 +1865,7 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir } glEnable(GL_BLEND); - widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit, 0.4f * U.widget_unit); + widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit); round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit); wtb.emboss = 0; @@ -3409,7 +3413,7 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) uiWidgetType *wt = widget_type(UI_WTYPE_BOX); glEnable(GL_BLEND); - widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit, 0.4f * U.widget_unit); + widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit); glDisable(GL_BLEND); wt->state(wt, 0); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 3036961d279..4127c1b9abc 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -677,6 +677,9 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255); rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255); + btheme->tui.menu_shadow_fac = 0.5f; + btheme->tui.menu_shadow_width = 12; + /* Bone Color Sets */ ui_theme_init_boneColorSets(btheme); @@ -1259,6 +1262,12 @@ void UI_ThemeClearColor(int colorid) glClearColor(col[0], col[1], col[2], 0.0); } +int UI_ThemeMenuShadowWidth(void) +{ + bTheme *btheme = UI_GetTheme(); + return (int)(btheme->tui.menu_shadow_width * UI_DPI_FAC); +} + void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3], const char axis) { unsigned char col[3]; @@ -2061,6 +2070,17 @@ void init_userdef_do_versions(void) } } + if (bmain->versionfile < 266) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* rna definition limits fac to 0.01 */ + if (btheme->tui.menu_shadow_fac == 0.0f) { + btheme->tui.menu_shadow_fac = 0.5f; + btheme->tui.menu_shadow_width = 12; + } + } + } if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a67502d9283..acd789e7aae 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -161,6 +161,12 @@ typedef struct ThemeUI { uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */ + /* fac: 0 - 1 for blend factor, width in pixels */ + float menu_shadow_fac; + short menu_shadow_width; + + short pad; + char iconfile[256]; // FILE_MAXFILE length float icon_alpha; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index dd25958ffa8..2b17249e4fe 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -760,6 +760,16 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_property_ui_text(prop, "State Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "menu_shadow_fac", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Menu Shadow Strength", "Blending factor for menu shadows"); + RNA_def_property_range(prop, 0.01f, 1.0f); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "menu_shadow_width", PROP_INT, PROP_NONE); + RNA_def_property_ui_text(prop, "Menu Shadow Width", "Width of menu shadows in standard pixels, set to zero to disable it"); + RNA_def_property_range(prop, 0.0f, 24.0f); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "iconfile"); RNA_def_property_ui_text(prop, "Icon File", "");