"Bug" & usability fix, own collection.
authorTon Roosendaal <ton@blender.org>
Sat, 27 Apr 2013 12:54:45 +0000 (12:54 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 27 Apr 2013 12:54:45 +0000 (12:54 +0000)
Color Pickers in Blender support precision editing with holding Shift key.
Unfortunately, on first click the picker cursor moves to the mouse position,
making the precision dragging quite useless.

Now, if you hold Shift, the picker editing will only apply the delta motion
of your mouse drags, making it much nicer for fine tuning of color grades
in Sequencer or Compositor.

source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_widgets.c

index 055cceeb4ea313645c6ce8b663ddb9fbf3005015..5dcce43d1c71b687403c74919b065abee53f3ed3 100644 (file)
@@ -3707,7 +3707,29 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
                ui_block_to_display_space_v3(but->block, rgb);
 
        rgb_to_hsv_compat_v(rgb, hsv);
-
+       
+       /* only apply the delta motion, not absolute */
+       if (shift) {
+               rcti rect_i;
+               float xpos, ypos, hsvo[3];
+               
+               BLI_rcti_rctf_copy(&rect_i, &but->rect);
+               
+               /* calculate original hsv again */
+               copy_v3_v3(rgb, data->origvec);
+               if (color_profile && (int)but->a1 != UI_GRAD_SV)
+                       ui_block_to_display_space_v3(but->block, rgb);
+               
+               copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
+               rgb_to_hsv_compat_v(rgb, hsvo);
+               
+               /* and original position */
+               ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
+               
+               mx_fl = xpos - (data->dragstartx - mx_fl);
+               my_fl = ypos - (data->dragstarty - my_fl);
+       }
+       
        /* relative position within box */
        x = ((float)mx_fl - but->rect.xmin) / BLI_rctf_size_x(&but->rect);
        y = ((float)my_fl - but->rect.ymin) / BLI_rctf_size_y(&but->rect);
@@ -3924,7 +3946,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float
        float hsv[3];
        
        ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
-
+       
 #ifdef USE_CONT_MOUSE_CORRECT
        if (ui_is_a_warp_but(but)) {
                /* OK but can go outside bounds */
@@ -3953,7 +3975,21 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float
                if (hsv[2] == 0.f) hsv[2] = 0.0001f;
        }
 
-
+       /* only apply the delta motion, not absolute */
+       if (shift) {
+               float xpos, ypos, hsvo[3];
+               
+               /* calculate original hsv again */
+               copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
+               rgb_to_hsv_compat_v(data->origvec, hsvo);
+               /* and original position */
+               ui_hsvcircle_pos_from_vals(but, &rect, hsvo, &xpos, &ypos);
+               
+               mx_fl = xpos - (data->dragstartx - mx_fl);
+               my_fl = ypos - (data->dragstarty - my_fl);
+               
+       }
+       
        ui_hsvcircle_vals_from_pos(hsv, hsv + 1, &rect, mx_fl, my_fl);
 
        if (but->flag & UI_BUT_COLOR_CUBIC)
index 9b5c2d9522d76ef2fa0f08640ca33847c91422b9..0543c6ccc4f0789a810d206fe2daa8a570f3dd5f 100644 (file)
@@ -386,6 +386,8 @@ extern void ui_set_but_vectorf(uiBut *but, const float vec[3]);
 
 extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
                                        const float mx, const float my);
+extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos);
+extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
 
 extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision);
 extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen);
index 37a31a7670d63d09027209f99eee8957f281b837..211d0533c0e273ba53180860319dc3626a2a9b8b 100644 (file)
@@ -1941,19 +1941,38 @@ void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rec
        *val_rad = atan2f(m_delta[0], m_delta[1]) / (2.0f * (float)M_PI) + 0.5f;
 }
 
+/* cursor in hsv circle, in float units -1 to 1, to map on radius */
+void ui_hsvcircle_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos)
+{
+       /* duplication of code... well, simple is better now */
+       const float centx = BLI_rcti_cent_x_fl(rect);
+       const float centy = BLI_rcti_cent_y_fl(rect);
+       float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
+       float ang, radius_t;
+       
+       ang = 2.0f * (float)M_PI * hsv[0] + 0.5f * (float)M_PI;
+       
+       if (but->flag & UI_BUT_COLOR_CUBIC)
+               radius_t = (1.0f - powf(1.0f - hsv[1], 3.0f));
+       else
+               radius_t = hsv[1];
+       
+       radius = CLAMPIS(radius_t, 0.0f, 1.0f) * radius;
+       *xpos = centx + cosf(-ang) * radius;
+       *ypos = centy + sinf(-ang) * radius;
+}
+
 static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
 {
        const int tot = 64;
        const float radstep = 2.0f * (float)M_PI / (float)tot;
-
        const float centx = BLI_rcti_cent_x_fl(rect);
        const float centy = BLI_rcti_cent_y_fl(rect);
        float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
 
        /* gouraud triangle fan */
        const float *hsv_ptr = ui_block_hsv_get(but->block);
-       float ang = 0.0f;
-       float cursor_radius;
+       float xpos, ypos, ang = 0.0f;
        float rgb[3], hsvo[3], hsv[3], col[3], colcent[3];
        int a;
        int color_profile = but->block->color_profile;
@@ -2017,15 +2036,9 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
        glPopMatrix();
 
        /* cursor */
-       ang = 2.0f * (float)M_PI * hsvo[0] + 0.5f * (float)M_PI;
-
-       if (but->flag & UI_BUT_COLOR_CUBIC)
-               cursor_radius = (1.0f - powf(1.0f - hsvo[1], 3.0f));
-       else
-               cursor_radius = hsvo[1];
+       ui_hsvcircle_pos_from_vals(but, rect, hsvo, &xpos, &ypos);
 
-       radius = CLAMPIS(cursor_radius, 0.0f, 1.0f) * radius;
-       ui_hsv_cursor(centx + cosf(-ang) * radius, centy + sinf(-ang) * radius);
+       ui_hsv_cursor(xpos, ypos);
 }
 
 /* ************ custom buttons, old stuff ************** */
@@ -2168,7 +2181,35 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
        
 }
 
+void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp)
+{
+       float x, y;
+       
+       switch ((int)but->a1) {
+               case UI_GRAD_SV:
+                       x = hsv[2]; y = hsv[1]; break;
+               case UI_GRAD_HV:
+                       x = hsv[0]; y = hsv[2]; break;
+               case UI_GRAD_HS:
+                       x = hsv[0]; y = hsv[1]; break;
+               case UI_GRAD_H:
+                       x = hsv[0]; y = 0.5; break;
+               case UI_GRAD_S:
+                       x = hsv[1]; y = 0.5; break;
+               case UI_GRAD_V:
+                       x = hsv[2]; y = 0.5; break;
+               case UI_GRAD_V_ALT:
+                       x = 0.5f;
+                       /* exception only for value strip - use the range set in but->min/max */
+                       y = (hsv[2] - but->softmin ) / (but->softmax - but->softmin);
+                       break;
+       }
+       
+       /* cursor */
+       *xp = rect->xmin + x * BLI_rcti_size_x(rect);
+       *yp = rect->ymin + y * BLI_rcti_size_y(rect);
 
+}
 
 static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
 {
@@ -2191,25 +2232,8 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
        rgb_to_hsv_compat_v(rgb, hsv_n);
        
        ui_draw_gradient(rect, hsv_n, but->a1, 1.0f);
-       
-       switch ((int)but->a1) {
-               case UI_GRAD_SV:
-                       x = hsv_n[2]; y = hsv_n[1]; break;
-               case UI_GRAD_HV:
-                       x = hsv_n[0]; y = hsv_n[2]; break;
-               case UI_GRAD_HS:
-                       x = hsv_n[0]; y = hsv_n[1]; break;
-               case UI_GRAD_H:
-                       x = hsv_n[0]; y = 0.5; break;
-               case UI_GRAD_S:
-                       x = hsv_n[1]; y = 0.5; break;
-               case UI_GRAD_V:
-                       x = hsv_n[2]; y = 0.5; break;
-       }
-       
-       /* cursor */
-       x = rect->xmin + x * BLI_rcti_size_x(rect);
-       y = rect->ymin + y * BLI_rcti_size_y(rect);
+
+       ui_hsvcube_pos_from_vals(but, rect, hsv_n, &x, &y);
        CLAMP(x, rect->xmin + 3.0f, rect->xmax - 3.0f);
        CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);