code cleanup: favor braces when blocks have mixed brace use.
[blender.git] / source / blender / editors / interface / interface_widgets.c
index 39d90de..78b6d25 100644 (file)
@@ -119,7 +119,7 @@ typedef struct uiWidgetType {
        void (*state)(struct uiWidgetType *, int state);
        void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign);
        void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign);
-       void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *);
+       void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *,  rcti *);
        
 } uiWidgetType;
 
@@ -218,13 +218,16 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
        glDisable(GL_BLEND);
 }
 
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad)
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha)
 {
        float color[4];
        int j;
        
        glEnable(GL_BLEND);
        glGetFloatv(GL_CURRENT_COLOR, color);
+       if (use_alpha) {
+               color[3] = 0.5f;
+       }
        color[3] *= 0.125f;
        glColor4fv(color);
        
@@ -251,7 +254,7 @@ static void widget_init(uiWidgetBase *wtb)
 
 /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
 /* return tot */
-static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step)
+static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
 {
        float vec[WIDGET_CURVE_RESOLU][2];
        float minx, miny, maxx, maxy;
@@ -261,7 +264,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
        
        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;
@@ -329,14 +332,14 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r
 }
 
 /* this call has 1 extra arg to allow mask outline */
-static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi)
+static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi)
 {
        float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
        float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
-       float minxi = minx + 1.0f; /* boundbox inner */
-       float maxxi = maxx - 1.0f;
-       float minyi = miny + 1.0f;
-       float maxyi = maxy - 1.0f;
+       float minxi = minx + U.pixelsize; /* boundbox inner */
+       float maxxi = maxx - U.pixelsize;
+       float minyi = miny + U.pixelsize;
+       float maxyi = maxy - U.pixelsize;
        float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; /* for uv, can divide by zero */
        float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
        int a, tot = 0, minsize;
@@ -346,13 +349,13 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
                          (roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) == (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ? 1 : 2;
 
        minsize = min_ii(BLI_rcti_size_x(rect) * hnum,
-                      BLI_rcti_size_y(rect) * vnum);
+                        BLI_rcti_size_y(rect) * vnum);
        
        if (2.0f * rad > minsize)
                rad = 0.5f * minsize;
 
        if (2.0f * (radi + 1.0f) > minsize)
-               radi = 0.5f * minsize - 1.0f;
+               radi = 0.5f * minsize - U.pixelsize;
        
        /* mult */
        for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
@@ -479,14 +482,14 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl
        wt->totvert = tot;
 }
 
-static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad)
+static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad)
 {
-       round_box__edges(wt, roundboxalign, rect, rad, rad - 1.0f);
+       round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
 }
 
 
 /* based on button rect, return scaled array of triangles */
-static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
 {
        float centx, centy, sizex, sizey, minsize;
        int a, i1 = 0, i2 = 1;
@@ -521,7 +524,7 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha
        tria->index = num_tria_face;
 }
 
-static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
 {
        float centx, centy, sizex, sizey, minsize;
        int a, i1 = 0, i2 = 1;
@@ -564,21 +567,16 @@ static void widget_trias_draw(uiWidgetTrias *tria)
        glDisableClientState(GL_VERTEX_ARRAY);
 }
 
-static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
 {
-       float centx, centy, size, asp;
+       float centx, centy, size;
        int a;
                
        /* center position and size */
-       centx = rect->xmax - 0.5f * BLI_rcti_size_y(rect);
-       centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
+       centx = rect->xmax - 0.32f * BLI_rcti_size_y(rect);
+       centy = rect->ymin + 0.50f * BLI_rcti_size_y(rect);
        size = 0.4f * (float)BLI_rcti_size_y(rect);
        
-       /* XXX exception */
-       asp = ((float)BLI_rcti_size_x(rect)) / ((float)BLI_rcti_size_y(rect));
-       if (asp > 1.2f && asp < 2.6f)
-               centx = rect->xmax - 0.4f * (float)BLI_rcti_size_y(rect);
-       
        for (a = 0; a < 6; a++) {
                tria->vec[a][0] = size * menu_tria_vert[a][0] + centx;
                tria->vec[a][1] = size * menu_tria_vert[a][1] + centy;
@@ -588,7 +586,7 @@ static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
        tria->index = menu_tria_face;
 }
 
-static void widget_check_trias(uiWidgetTrias *tria, rcti *rect)
+static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
 {
        float centx, centy, size;
        int a;
@@ -833,7 +831,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
 
 #define PREVIEW_PAD 4
 
-static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect)
+static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect)
 {
        int w, h, size;
 
@@ -861,9 +859,9 @@ static int ui_but_draw_menu_icon(uiBut *but)
 
 /* icons have been standardized... and this call draws in untransformed coordinates */
 
-static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
+static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti *rect)
 {
-       int xs = 0, ys = 0;
+       float xs = 0.0f, ys = 0.0f;
        float aspect, height;
        
        if (but->flag & UI_ICON_PREVIEW) {
@@ -874,21 +872,9 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
        /* this icon doesn't need draw... */
        if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return;
        
-       /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
-       aspect = but->block->aspect;
-       if (aspect != but->aspect) {
-               /* prevent scaling up icon in pupmenu */
-               if (aspect < 1.0f) {
-                       height = UI_DPI_ICON_SIZE;
-                       aspect = 1.0f;
-                       
-               }
-               else 
-                       height = UI_DPI_ICON_SIZE / aspect;
-       }
-       else
-               height = UI_DPI_ICON_SIZE;
-       
+       aspect = but->block->aspect / UI_DPI_FAC;
+       height = ICON_DEFAULT_HEIGHT / aspect;
+
        /* calculate blend color */
        if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) {
                if (but->flag & UI_SELECT) {}
@@ -902,32 +888,40 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
        glEnable(GL_BLEND);
        
        if (icon && icon != ICON_BLANK1) {
+               float ofs = 1.0f / aspect;
+               
                if (but->flag & UI_ICON_LEFT) {
                        if (but->type == BUT_TOGDUAL) {
                                if (but->drawstr[0]) {
-                                       xs = rect->xmin - 1;
+                                       xs = rect->xmin - ofs;
                                }
                                else {
-                                       xs = (rect->xmin + rect->xmax - height) / 2;
+                                       xs = (rect->xmin + rect->xmax - height) / 2.0f;
                                }
                        }
                        else if (but->block->flag & UI_BLOCK_LOOP) {
-                               if (but->type == SEARCH_MENU)
-                                       xs = rect->xmin + 4;
+                               if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
+                                       xs = rect->xmin + 4.0f * ofs;
                                else
-                                       xs = rect->xmin + 1;
+                                       xs = rect->xmin + ofs;
                        }
                        else if ((but->type == ICONROW) || (but->type == ICONTEXTROW)) {
-                               xs = rect->xmin + 3;
+                               xs = rect->xmin + 3.0f * ofs;
                        }
                        else {
-                               xs = rect->xmin + 4;
+                               xs = rect->xmin + 4.0f * ofs;
                        }
-                       ys = (rect->ymin + rect->ymax - height) / 2;
+                       ys = (rect->ymin + rect->ymax - height) / 2.0f;
                }
                else {
-                       xs = (rect->xmin + rect->xmax - height) / 2;
-                       ys = (rect->ymin + rect->ymax - height) / 2;
+                       xs = (rect->xmin + rect->xmax - height) / 2.0f;
+                       ys = (rect->ymin + rect->ymax - height) / 2.0f;
+               }
+
+               /* force positions to integers, for zoom levels near 1. draws icons crisp. */
+               if (aspect > 0.95f && aspect < 1.05f) {
+                       xs = (int)(xs + 0.1f);
+                       ys = (int)(ys + 0.1f);
                }
                
                /* to indicate draggable */
@@ -940,8 +934,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
        }
 
        if (ui_but_draw_menu_icon(but)) {
-               xs = rect->xmax - UI_DPI_ICON_SIZE - 1;
-               ys = (rect->ymin + rect->ymax - height) / 2;
+               xs = rect->xmax - UI_DPI_ICON_SIZE - aspect;
+               ys = (rect->ymin + rect->ymax - height) / 2.0f;
                
                UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha);
        }
@@ -971,7 +965,7 @@ static void ui_text_clip_give_next_off(uiBut *but)
  * \note Sets but->ofs to make sure text is correctly visible.
  * \note Clips right in some cases, this function could be cleaned up.
  */
-static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 {
        int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
        int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1000,7 +994,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect)
 /**
  * Cut off the text, taking into account the cursor location (text display while editing).
  */
-static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 {
        int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
        int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1044,6 +1038,8 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
                                ui_text_clip_give_prev_off(but);
                        len = strlen(but->drawstr);
                        bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->drawstr, but->drawstr + len));
+                       if (bytes < 0)
+                               bytes = 1;
                        but->drawstr[len - bytes] = 0;
                }
 
@@ -1062,7 +1058,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect)
  *
  * \note deals with ': ' especially for number buttons
  */
-static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, rcti *rect)
+static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 {
        int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10;
        int okwidth = BLI_rcti_size_x(rect) - border;
@@ -1276,9 +1272,12 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
 /* draws text and icons for buttons */
 static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
 {
-       if (but == NULL) {
+       char password_str[UI_MAX_DRAW_STR];
+
+       if (but == NULL)
                return;
-       }
+
+       ui_button_text_password_hide(password_str, but, FALSE);
 
        /* clip but->drawstr to fit in available space */
        if (but->editstr && but->pos >= 0) {
@@ -1287,13 +1286,15 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
        else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) {
                ui_text_clip_right_label(fstyle, but, rect);
        }
-       else if (ELEM(but->type, TEX, SEARCH_MENU)) {
+       else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
                ui_text_clip_left(fstyle, but, rect);
        }
        else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
                ui_text_clip_left(fstyle, but, rect);
        }
-       else but->ofs = 0;
+       else {
+               but->ofs = 0;
+       }
 
        /* check for button text label */
        if (but->type == ICONTEXTROW) {
@@ -1324,19 +1325,32 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
 
                if (but->flag & UI_HAS_ICON) {
                        widget_draw_icon(but, but->icon + but->iconadd, 1.0f, rect);
+                       
+                       /* icons default draw 0.8f x height */
+                       rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect));
 
-                       rect->xmin += (int)((float)UI_icon_get_width(but->icon + but->iconadd) * UI_DPI_ICON_FAC);
-
-                       if (but->editstr || (but->flag & UI_TEXT_LEFT))
-                               rect->xmin += 5;
+                       if (but->editstr || (but->flag & UI_TEXT_LEFT)) {
+                               rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
+                       }
+               }
+               else if ((but->flag & UI_TEXT_LEFT)) {
+                       rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
+               }
+               
+               /* unlink icon for this button type */
+               if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) {
+                       rcti temp = *rect;
+                       
+                       temp.xmin = temp.xmax - BLI_rcti_size_y(rect);
+                       widget_draw_icon(but, ICON_X, 1.0f, &temp);
                }
-               else if ((but->flag & UI_TEXT_LEFT))
-                       rect->xmin += 5;
 
                /* always draw text for textbutton cursor */
                widget_draw_text(fstyle, wcol, but, rect);
 
        }
+
+       ui_button_text_password_hide(password_str, but, TRUE);
 }
 
 
@@ -1785,11 +1799,19 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
 {
        wt->wcol = *(wt->wcol_theme);
        
-       if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
-               wt->wcol.text[0] = 0.5f * (wt->wcol.text[0] + wt->wcol.text_sel[0]);
-               wt->wcol.text[1] = 0.5f * (wt->wcol.text[1] + wt->wcol.text_sel[1]);
-               wt->wcol.text[2] = 0.5f * (wt->wcol.text[2] + wt->wcol.text_sel[2]);
+       /* active and disabled (not so common) */
+       if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
+               widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
+               /* draw the backdrop at low alpha, helps navigating with keys
+                * when disabled items are active */
+               copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+               wt->wcol.inner[3] = 64;
+       }
+       /* regular disabled */
+       else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+               widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
        }
+       /* regular active */
        else if (state & UI_ACTIVE) {
                copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
                copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
@@ -1800,38 +1822,45 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
 /* ************ menu backdrop ************************* */
 
 /* outside of rect, rad to left/bottom/right */
-static void widget_softshadow(rcti *rect, int roundboxalign, float radin, 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 (2.0f * radout > 0.2f * BLI_rcti_size_y(&rect1))
+       if (radout > 0.2f * BLI_rcti_size_y(&rect1))
                rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1);
        else
-               rect1.ymax -= 2.0f * radout;
+               rect1.ymax -= radout;
        
        /* 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.15;
-       alphastep = 0.67;
+       /* 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); /* add + 2 for getting a complete soft rect. Now it skips top edge to allow transparent menus */
        }
 
        glDisableClientState(GL_VERTEX_ARRAY);
@@ -1851,17 +1880,17 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
        }
        else if (direction == UI_DOWN) {
                roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
-               rect->ymin -= 4.0;
+               rect->ymin -= 0.1f * U.widget_unit;
        }
        else if (direction == UI_TOP) {
                roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
-               rect->ymax += 4.0;
+               rect->ymax += 0.1f * U.widget_unit;
        }
        
        glEnable(GL_BLEND);
-       widget_softshadow(rect, roundboxalign, 5.0f, 8.0f);
+       widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit);
        
-       round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+       round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit);
        wtb.emboss = 0;
        widgetbase_draw(&wtb, wcol);
        
@@ -1876,12 +1905,12 @@ static void ui_hsv_cursor(float x, float y)
        glTranslatef(x, y, 0.0f);
        
        glColor3f(1.0f, 1.0f, 1.0f);
-       glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f, 8);
+       glutil_draw_filled_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 8);
        
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
        glColor3f(0.0f, 0.0f, 0.0f);
-       glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f, 12);
+       glutil_draw_lined_arc(0.0f, M_PI * 2.0, 3.0f * U.pixelsize, 12);
        glDisable(GL_BLEND);
        glDisable(GL_LINE_SMOOTH);
        
@@ -1905,7 +1934,7 @@ void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rec
 
 static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
 {
-       const int tot = 32;
+       const int tot = 64;
        const float radstep = 2.0f * (float)M_PI / (float)tot;
 
        const float centx = BLI_rcti_cent_x_fl(rect);
@@ -1993,9 +2022,9 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
 /* ************ custom buttons, old stuff ************** */
 
 /* draws in resolution of 20x4 colors */
-void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha)
+void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
 {
-       const float color_step = (type == UI_GRAD_H) ? 0.02 : 0.05f;
+       const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f;
        int a;
        float h = hsv[0], s = hsv[1], v = hsv[2];
        float dx, dy, sx1, sx2, sy;
@@ -2052,7 +2081,7 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa
        
        /* old below */
        
-       for (dx = 0.0f; dx < 1.0f; dx += color_step) {
+       for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */
                /* previous color */
                copy_v3_v3(col0[0], col1[0]);
                copy_v3_v3(col0[1], col1[1]);
@@ -2107,7 +2136,7 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa
                sx1 = rect->xmin +  dx               * BLI_rcti_size_x(rect);
                sx2 = rect->xmin + (dx + color_step) * BLI_rcti_size_x(rect);
                sy = rect->ymin;
-               dy = BLI_rcti_size_y(rect) / 3.0;
+               dy = (float)BLI_rcti_size_y(rect) / 3.0f;
                
                glBegin(GL_QUADS);
                for (a = 0; a < 3; a++, sy += dy) {
@@ -2132,16 +2161,24 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa
 
 
 
-static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
+static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
 {
        float rgb[3];
        float x = 0.0f, y = 0.0f;
        float *hsv = ui_block_hsv_get(but->block);
        float hsv_n[3];
+       int color_profile = but->block->color_profile;
+       
+       if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
+               color_profile = FALSE;
        
        copy_v3_v3(hsv_n, hsv);
        
        ui_get_but_vectorf(but, rgb);
+       
+       if (color_profile && (int)but->a1 != UI_GRAD_SV)
+               ui_block_to_display_space_v3(but->block, rgb);
+       
        rgb_to_hsv_compat_v(rgb, hsv_n);
        
        ui_draw_gradient(rect, hsv_n, but->a1, 1.0f);
@@ -2175,10 +2212,10 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
 }
 
 /* vertical 'value' slider, using new widget code */
-static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
+static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
 {
        uiWidgetBase wtb;
-       float rad = 0.5f * BLI_rcti_size_x(rect);
+       const float rad = 0.5f * BLI_rcti_size_x(rect);
        float x, y;
        float rgb[3], hsv[3], v, range;
        int color_profile = but->block->color_profile;
@@ -2223,7 +2260,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
 
 
 /* ************ separator, for menus etc ***************** */
-static void ui_draw_separator(rcti *rect,  uiWidgetColors *wcol)
+static void ui_draw_separator(const rcti *rect,  uiWidgetColors *wcol)
 {
        int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1;
        unsigned char col[4];
@@ -2244,7 +2281,7 @@ static void ui_draw_separator(rcti *rect,  uiWidgetColors *wcol)
 static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
        uiWidgetBase wtb;
-       float rad = 0.5f * BLI_rcti_size_y(rect);
+       const float rad = 0.5f * BLI_rcti_size_y(rect);
        float textofs = rad * 0.75f;
 
        if (state & UI_SELECT)
@@ -2268,7 +2305,7 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round
        rect->xmax -= textofs;
 }
 
-int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
+int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
 {
        float dist, vec[4][2];
 
@@ -2292,7 +2329,7 @@ int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol)
 }
 
 #define LINK_RESOL  24
-void ui_draw_link_bezier(rcti *rect)
+void ui_draw_link_bezier(const rcti *rect)
 {
        float coord_array[LINK_RESOL + 1][2];
        
@@ -2305,7 +2342,7 @@ void ui_draw_link_bezier(rcti *rect)
 
                glEnableClientState(GL_VERTEX_ARRAY);
                glVertexPointer(2, GL_FLOAT, 0, coord_array);
-               glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL);
+               glDrawArrays(GL_LINE_STRIP, 0, LINK_RESOL + 1);
                glDisableClientState(GL_VERTEX_ARRAY);
 
                glDisable(GL_BLEND);
@@ -2315,18 +2352,18 @@ void ui_draw_link_bezier(rcti *rect)
 }
 
 /* function in use for buttons and for view2d sliders */
-void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state)
+void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
 {
        uiWidgetBase wtb;
-       float rad;
        int horizontal;
+       float rad;
        short outline = 0;
 
        widget_init(&wtb);
 
        /* determine horizontal/vertical */
        horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
-       
+
        if (horizontal)
                rad = 0.5f * BLI_rcti_size_y(rect);
        else
@@ -2402,7 +2439,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
        value = ui_get_but_val(but);
 
        size = (but->softmax + but->a1 - but->softmin);
-       size = MAX2(size, 2);
+       size = max_ff(size, 2.0f);
        
        /* position */
        rect1 = *rect;
@@ -2440,7 +2477,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
 
                        if (rect1.ymax > rect->ymax) {
                                rect1.ymax = rect->ymax;
-                               rect1.ymin = MAX2(rect1.ymax - min, rect->ymin);
+                               rect1.ymin = max_ii(rect1.ymax - min, rect->ymin);
                        }
                }
        }
@@ -2533,14 +2570,15 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
                fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin);
                
                /* left part of slider, always rounded */
-               rect1.xmax = rect1.xmin + ceil(offs + 1.0f);
+               rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize);
                round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs);
                wtb1.outline = 0;
                widgetbase_draw(&wtb1, wcol);
                
                /* right part of slider, interpolate roundness */
                rect1.xmax = rect1.xmin + fac + offs;
-               rect1.xmin +=  floor(offs - 1.0f);
+               rect1.xmin +=  floor(offs - U.pixelsize);
+               
                if (rect1.xmax + offs > rect->xmax)
                        offs *= (rect1.xmax + offs - rect->xmax) / offs;
                else 
@@ -2570,12 +2608,14 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
 static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
        uiWidgetBase wtb;
-       float col[4];
+       float rad, col[4];
        int color_profile = but->block->color_profile;
        
        col[3] = 1.0f;
 
        if (but->rnaprop) {
+               BLI_assert(but->rnaindex == -1);
+
                if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
                        color_profile = FALSE;
 
@@ -2587,7 +2627,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+       rad = 0.25f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
                
        ui_get_but_vectorf(but, col);
 
@@ -2601,7 +2642,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
                rect->ymin += SWATCH_KEYED_BORDER;
                rect->ymax -= SWATCH_KEYED_BORDER;
                
-               round_box_edges(&wtb, roundboxalign, rect, 5.0f);
+               round_box_edges(&wtb, roundboxalign, rect, rad);
        }
        
        if (color_profile)
@@ -2616,16 +2657,23 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
        
 }
 
+static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+{
+       ui_draw_but_NORMAL(but, wcol, rect);
+}
+
 static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
 {
        if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
                uiWidgetBase wtb;
-       
+               float rad;
+               
                widget_init(&wtb);
                wtb.outline = 0;
                
                /* rounded */
-               round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f);
+               rad = 0.5f * BLI_rcti_size_y(rect);
+               round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
                widgetbase_draw(&wtb, wcol);
        }
 }
@@ -2634,6 +2682,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti
 static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        
        if (state & UI_SELECT)
                SWAP(short, wcol->shadetop, wcol->shadedown);
@@ -2641,7 +2690,8 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
        
        widgetbase_draw(&wtb, wcol);
 
@@ -2651,11 +2701,13 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
 static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
        
        /* decoration */
        widget_menu_trias(&wtb.tria1, rect);
@@ -2663,17 +2715,19 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
        widgetbase_draw(&wtb, wcol);
        
        /* text space, arrows are about 0.6 height of button */
-       rect->xmax -= (6*BLI_rcti_size_y(rect))/10;
+       rect->xmax -= (6 * BLI_rcti_size_y(rect)) / 10;
 }
 
 static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
        
        /* decoration */
        widgetbase_draw(&wtb, wcol);
@@ -2684,11 +2738,13 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat
        /* silly node link button hacks */
        uiWidgetBase wtb;
        uiWidgetColors wcol_backup = *wcol;
+       float rad;
        
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
 
        wcol->inner[0] += 15;
        wcol->inner[1] += 15;
@@ -2706,7 +2762,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int
 {
        if (state & UI_ACTIVE) {
                uiWidgetBase wtb;
-               float rad = 0.25f * BLI_rcti_size_y(rect);  /* 4.0f */
+               const float rad = 0.2f * U.widget_unit;
 
                widget_init(&wtb);
 
@@ -2733,12 +2789,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
 static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
 {
        uiWidgetBase wtb;
+       float rad;
        
        widget_init(&wtb);
        
        /* rounded, but no outline */
        wtb.outline = 0;
-       round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
        
        widgetbase_draw(&wtb, wcol);
 }
@@ -2747,6 +2805,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
 {
        uiWidgetBase wtb;
        rcti recttemp = *rect;
+       float rad;
        int delta;
        
        widget_init(&wtb);
@@ -2762,7 +2821,8 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
        recttemp.ymax -= delta;
        
        /* half rounded */
-       round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
        
        /* decoration */
        if (state & UI_SELECT) {
@@ -2779,11 +2839,13 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
 static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
        
        widgetbase_draw(&wtb, wcol);
 
@@ -2792,6 +2854,7 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
 static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        char old_col[3];
        
        widget_init(&wtb);
@@ -2806,7 +2869,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
        }
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
        
        widgetbase_draw(&wtb, wcol);
        
@@ -2821,12 +2885,14 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
 static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
+       float rad;
        
        widget_init(&wtb);
        
        /* half rounded */
-       round_box_edges(&wtb, roundboxalign, rect, 4.0f);
-               
+       rad = 0.2f * U.widget_unit;
+       round_box_edges(&wtb, roundboxalign, rect, rad);
+       
        widgetbase_draw(&wtb, wcol);
 
 }
@@ -2834,7 +2900,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int
 static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
 {
        uiWidgetBase wtb;
-       float rad = 5.0f;  /* 0.5f * BLI_rcti_size_y(rect); */
+       const float rad = 0.25f * U.widget_unit;
        
        widget_init(&wtb);
        
@@ -2847,6 +2913,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
 static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
 {
        uiWidgetBase wtb;
+       const float rad = 0.25f * U.widget_unit;
        unsigned char col[4];
        
        /* state copy! */
@@ -2862,12 +2929,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
                UI_GetThemeColor3ubv(TH_BACK, col);
                glColor3ubv(col);
                
-               round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0);
+               round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
                widgetbase_outline(&wtb);
        }
        
        /* outline */
-       round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f);
+       round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
        wtb.outline = 1;
        wtb.inner = 0;
        widgetbase_draw(&wtb, &wt->wcol);
@@ -2875,7 +2942,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
 }
 
 
-static void widget_disabled(rcti *rect)
+static void widget_disabled(const rcti *rect)
 {
        float col[4];
        
@@ -3023,6 +3090,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
                        break;
                        
                case UI_WTYPE_NORMAL:
+                       wt.custom = widget_normal;
                        break;
 
                case UI_WTYPE_SCROLL:
@@ -3055,9 +3123,9 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
                
                /* ui_block_position has this correction too, keep in sync */
                if (but->flag & UI_BUT_ALIGN_TOP)
-                       rect->ymax += 1;
+                       rect->ymax += U.pixelsize;
                if (but->flag & UI_BUT_ALIGN_LEFT)
-                       rect->xmin -= 1;
+                       rect->xmin -= U.pixelsize;
                
                switch (but->flag & UI_BUT_ALIGN) {
                        case UI_BUT_ALIGN_TOP:
@@ -3168,7 +3236,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                        case TEX:
                                wt = widget_type(UI_WTYPE_NAME);
                                break;
-                               
+                       
+                       case SEARCH_MENU_UNLINK:
                        case SEARCH_MENU:
                                wt = widget_type(UI_WTYPE_NAME);
                                if (but->block->flag & UI_BLOCK_LOOP)
@@ -3262,7 +3331,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                                break;
                                
                        case BUT_NORMAL:
-                               ui_draw_but_NORMAL(but, &tui->wcol_regular, rect);
+                               wt = widget_type(UI_WTYPE_NORMAL);
                                break;
                                
                        case BUT_IMAGE:
@@ -3368,7 +3437,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, 5.0f, 8.0f);
+       widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
        glDisable(GL_BLEND);
 
        wt->state(wt, 0);
@@ -3387,7 +3456,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
        uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
        rcti _rect = *rect;
        char *cpoin;
-       
+
        wt->state(wt, state);
        wt->draw(&wt->wcol, rect, 0, 0);
        
@@ -3395,7 +3464,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
        fstyle->align = UI_STYLE_TEXT_LEFT;
        
        /* text location offset */
-       rect->xmin += 5;
+       rect->xmin += 0.25f * UI_UNIT_X;
        if (iconid) rect->xmin += UI_DPI_ICON_SIZE;
 
        /* cut string in 2 parts? */
@@ -3420,10 +3489,16 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
        *rect = _rect;
 
        if (iconid) {
-               int xs = rect->xmin + 4;
-               int ys = 1 + (rect->ymin + rect->ymax - UI_DPI_ICON_SIZE) / 2;
+               float height, aspect;
+               int xs = rect->xmin + 0.2f * UI_UNIT_X;
+               int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect);
+               
+               /* icons are 80% of height of button (16 pixels inside 20 height) */
+               height = 0.8f * BLI_rcti_size_y(rect);
+               aspect = ICON_DEFAULT_HEIGHT / height;
+               
                glEnable(GL_BLEND);
-               UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */
+               UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f); /* XXX scale weak get from fstyle? */
                glDisable(GL_BLEND);
        }
 }