UI todo:
authorTon Roosendaal <ton@blender.org>
Thu, 20 Dec 2012 16:50:39 +0000 (16:50 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 20 Dec 2012 16:50:39 +0000 (16:50 +0000)
- 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

release/scripts/startup/bl_ui/space_userpref.py
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c

index 7c6c8dc..695e09e 100644 (file)
@@ -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()
index eaab17c..119c26b 100644 (file)
@@ -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);
 
index 60885f3..57c126c 100644 (file)
@@ -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);
index 25e35c2..4687647 100644 (file)
@@ -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);
index 3036961..4127c1b 100644 (file)
@@ -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;
index a67502d..acd789e 100644 (file)
@@ -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;
 
index dd25958..2b17249 100644 (file)
@@ -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", "");