HSL color wheel implementation.

This is a standard Hue - Saturation - Lightness model
(see for instance entry on wikipedia here: https://en.wikipedia.org/wiki/HSL_and_HSV)
Note though the difference between HSV and HSL saturation, which are not the same.

The advantage of having this color selection scheme is that artists can select
shades and tints of a color easily by using the lightness slider. Also colors
are arranged on (approximated) perceived lightness on the color wheel.

Beware, Old files opened with this preference saved will crash!

Reviewers: sergey, brecht, campbellbarton

Differential Revision: https://developer.blender.org/D385
This commit is contained in:
Antonis Ryakiotakis 2014-03-12 18:58:50 +02:00
parent 35ed7486c7
commit bce924b43c
11 changed files with 255 additions and 53 deletions

View File

@ -55,6 +55,8 @@ extern "C" {
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]);
void hsl_to_rgb(float h, float c, float l, float *r, float *g, float *b);
void hsl_to_rgb_v(const float hcl[3], float r_rgb[3]);
void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace);
@ -69,6 +71,8 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]);
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll);
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]);
void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll);
void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]);
void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv);
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]);
void rgb_to_lab(float r, float g, float b, float *ll, float *la, float *lb);

View File

@ -94,12 +94,71 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
}
}
/* HSL to rgb conversion from https://en.wikipedia.org/wiki/HSL_and_HSV */
void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b)
{
float i, f, c;
h = (h - floorf(h)) * 6.0f;
c = (l > 0.5f) ? (2.0f * (1.0f - l) * s) : (2.0f * l * s);
i = floorf(h);
f = h - i;
#define x2 (c * f)
#define x1 (c * (1.0f - f))
/* faster to compare floats then int conversion */
if (i < 1.0f) {
*r = c;
*g = x2;
*b = 0;
}
else if (i < 2.0f) {
*r = x1;
*g = c;
*b = 0;
}
else if (i < 3.0f) {
*r = 0;
*g = c;
*b = x2;
}
else if (i < 4.0f) {
*r = 0;
*g = x1;
*b = c;
}
else if (i < 5.0f) {
*r = x2;
*g = 0;
*b = c;
}
else {
*r = c;
*g = 0;
*b = x1;
}
#undef x1
#undef x2
f = l - 0.5f * c;
*r += f;
*g += f;
*b += f;
}
/* convenience function for now */
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
{
hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
}
/* convenience function for now */
void hsl_to_rgb_v(const float hcl[3], float r_rgb[3])
{
hsl_to_rgb(hcl[0], hcl[1], hcl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
}
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
{
float y, u, v;
@ -315,6 +374,33 @@ void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
*ll = l;
}
void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll)
{
float orig_s = *ls;
float orig_h = *lh;
rgb_to_hsl(r, g, b, lh, ls, ll);
if (*ll <= 0.0f) {
*lh = orig_h;
*ls = orig_s;
}
else if (*ls <= 0.0f) {
*lh = orig_h;
*ls = orig_s;
}
if (*lh == 0.0f && orig_h >= 1.0f) {
*lh = 1.0f;
}
}
void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
{
rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
}
/* convenience function for now */
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
{

View File

@ -283,6 +283,7 @@ typedef enum {
#define UI_GRAD_V 5
#define UI_GRAD_V_ALT 9
#define UI_GRAD_L_ALT 10
/* Drawing
*

View File

@ -1096,7 +1096,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
block->auto_open_last = block->oldblock->auto_open_last;
block->tooltipdisabled = block->oldblock->tooltipdisabled;
copy_v3_v3(ui_block_hsv_get(block),
ui_block_hsv_get(block->oldblock));
ui_block_hsv_get(block->oldblock));
block->oldblock = NULL;
}

View File

@ -4300,7 +4300,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
if (use_display_colorspace)
ui_block_to_display_space_v3(but->block, rgb);
rgb_to_hsv_compat_v(rgb, hsv);
if (but->a1 == UI_GRAD_L_ALT)
rgb_to_hsl_compat_v(rgb, hsv);
else
rgb_to_hsv_compat_v(rgb, hsv);
/* only apply the delta motion, not absolute */
if (shift) {
@ -4315,7 +4318,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
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);
if (but->a1 == UI_GRAD_L_ALT)
rgb_to_hsl_compat_v(rgb, hsvo);
else
rgb_to_hsv_compat_v(rgb, hsvo);
/* and original position */
ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
@ -4353,11 +4359,11 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
hsv[2] = x;
break;
case UI_GRAD_V_ALT:
case UI_GRAD_L_ALT:
/* vertical 'value' strip */
/* exception only for value strip - use the range set in but->min/max */
hsv[2] = y * (but->softmax - but->softmin) + but->softmin;
break;
default:
BLI_assert(0);
@ -4370,13 +4376,16 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
}
}
hsv_to_rgb_v(hsv, rgb);
if (but->a1 == UI_GRAD_L_ALT)
hsl_to_rgb_v(hsv, rgb);
else
hsv_to_rgb_v(hsv, rgb);
if (use_display_colorspace)
ui_block_to_scene_linear_v3(but->block, rgb);
/* clamp because with color conversion we can exceed range [#34295] */
if ((int)but->a1 == UI_GRAD_V_ALT) {
if (ELEM((int)but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
clamp_axis_max_v3(rgb, but->softmax);
}
@ -4403,8 +4412,11 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
if (use_display_colorspace)
ui_block_to_display_space_v3(but->block, rgb);
rgb_to_hsv_compat_v(rgb, hsv);
if (but->a1 == UI_GRAD_L_ALT)
rgb_to_hsl_compat_v(rgb, hsv);
else
rgb_to_hsv_compat_v(rgb, hsv);
switch ((int)but->a1) {
case UI_GRAD_SV:
hsv[2] += ndof->rvec[2] * sensitivity;
@ -4428,6 +4440,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
hsv[2] += ndof->rvec[2] * sensitivity;
break;
case UI_GRAD_V_ALT:
case UI_GRAD_L_ALT:
/* vertical 'value' strip */
/* exception only for value strip - use the range set in but->min/max */
@ -4449,7 +4462,10 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
/* ndof specific: the changes above aren't clamping */
hsv_clamp_v(hsv, hsv_v_max);
hsv_to_rgb_v(hsv, rgb);
if (but->a1 == UI_GRAD_L_ALT)
hsl_to_rgb_v(hsv, rgb);
else
hsv_to_rgb_v(hsv, rgb);
if (use_display_colorspace)
ui_block_to_scene_linear_v3(but->block, rgb);
@ -4501,11 +4517,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
/* reset only value */
len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
if (len >= 3) {
if (ELEM(len, 3, 4)) {
float rgb[3], def_hsv[3];
float *def;
float def[4];
float *hsv = ui_block_hsv_get(but->block);
def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
rgb_to_hsv_v(def, def_hsv);
@ -4519,9 +4534,34 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
hsv_to_rgb_v(def_hsv, rgb);
ui_set_but_vectorf(but, rgb);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
}
return WM_UI_HANDLER_BREAK;
}
else if (but->a1 == UI_GRAD_L_ALT) {
int len;
/* reset only value */
len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
if (ELEM(len, 3, 4)) {
float rgb[3], def_hsl[3];
float def[4];
float *hsl = ui_block_hsv_get(but->block);
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
rgb_to_hsl_v(def, def_hsl);
ui_get_but_vectorf(but, rgb);
rgb_to_hsl_compat_v(rgb, hsl);
def_hsl[0] = hsl[0];
def_hsl[1] = hsl[1];
hsl_to_rgb_v(def_hsl, rgb);
ui_set_but_vectorf(but, rgb);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
MEM_freeN(def);
}
return WM_UI_HANDLER_BREAK;
}
@ -4585,8 +4625,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
ui_get_but_vectorf(but, rgb);
copy_v3_v3(hsv, ui_block_hsv_get(but->block));
rgb_to_hsv_compat_v(rgb, hsv);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
/* exception, when using color wheel in 'locked' value state:
* allow choosing a hue for black values, by giving a tiny increment */
if (but->flag & UI_BUT_COLOR_LOCK) { // lock
@ -4599,10 +4640,12 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
/* calculate original hsv again */
copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
rgb_to_hsv_compat_v(data->origvec, hsvo);
ui_rgb_to_color_picker_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);
@ -4617,7 +4660,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
ui_color_snap_hue(snap, &hsv[0]);
}
hsv_to_rgb_v(hsv, rgb);
ui_color_picker_to_rgb_v(hsv, rgb);
if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (rgb[0] || rgb[1] || rgb[2])) {
normalize_v3(rgb);
@ -4642,7 +4685,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt;
ui_get_but_vectorf(but, rgb);
rgb_to_hsv_compat_v(rgb, hsv);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
/* Convert current color on hue/sat disc to circular coordinates phi, r */
phi = fmodf(hsv[0] + 0.25f, 1.0f) * -2.0f * (float)M_PI;
@ -4680,7 +4723,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
hsv_clamp_v(hsv, FLT_MAX);
hsv_to_rgb_v(hsv, data->vec);
ui_color_picker_to_rgb_v(hsv, data->vec);
if ((but->flag & UI_BUT_VEC_SIZE_LOCK) && (data->vec[0] || data->vec[1] || data->vec[2])) {
normalize_v3(data->vec);

View File

@ -473,6 +473,9 @@ void ui_popup_menu_memory_set(struct uiBlock *block, struct uiBut *but);
float *ui_block_hsv_get(struct uiBlock *block);
void ui_popup_block_scrolltest(struct uiBlock *block);
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]);
void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3]);
void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b);
/* searchbox for string button */
ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);

View File

@ -1646,7 +1646,8 @@ void ui_set_but_hsv(uiBut *but)
float col[3];
float *hsv = ui_block_hsv_get(but->block);
hsv_to_rgb_v(hsv, col);
ui_color_picker_to_rgb_v(hsv, col);
ui_set_but_vectorf(but, col);
}
@ -1660,7 +1661,7 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
/* this is to keep the H and S value when V is equal to zero
* and we are working in HSV mode, of course!
*/
rgb_to_hsv_compat_v(rgb, hsv);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
if (block->color_profile)
display = ui_block_display_get(block);
@ -1714,6 +1715,9 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
else if (bt->str[0] == 'V') {
ui_set_but_val(bt, hsv[2]);
}
else if (bt->str[0] == 'L') {
ui_set_but_val(bt, hsv[2]);
}
}
ui_check_but(bt);
@ -1737,15 +1741,15 @@ static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
popup->menuretval = UI_RETURN_UPDATE;
}
static void do_hsv_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
static void do_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
float rgb[3];
float *hsv = ui_block_hsv_get(but->block);
hsv_to_rgb_v(hsv, rgb);
ui_color_picker_to_rgb_v(hsv, rgb);
ui_update_block_buts_rgb(but->block, rgb);
if (popup)
@ -1788,12 +1792,12 @@ static void picker_new_hide_reveal(uiBlock *block, short colormode)
/* tag buttons */
for (bt = block->buttons.first; bt; bt = bt->next) {
if (bt->func == do_picker_rna_cb && bt->type == NUMSLI && bt->rnaindex != 3) {
if ((bt->func == do_picker_rna_cb) && bt->type == NUMSLI && bt->rnaindex != 3) {
/* RGB sliders (color circle and alpha are always shown) */
if (colormode == 0) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
}
else if (bt->func == do_hsv_rna_cb) {
else if (bt->func == do_color_wheel_rna_cb) {
/* HSV sliders */
if (colormode == 1) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
@ -1825,12 +1829,18 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
uiBut *bt;
/* HS circle */
bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0, 0, "Color");
bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
else {
bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
}
@ -1861,9 +1871,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
float softmin, softmax, hardmin, hardmax, step, precision;
float *hsv = ui_block_hsv_get(block);
int yco;
ui_block_hsv_get(block);
width = PICKER_TOTAL_W;
butwidth = width - 1.5f * UI_UNIT_X;
@ -1889,7 +1897,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
RNA_property_float_get_array(ptr, prop, rgba);
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
case USER_CP_CIRCLE_HSV:
case USER_CP_CIRCLE_HSL:
circle_picker(block, ptr, prop);
break;
case USER_CP_SQUARE_SV:
@ -1908,7 +1917,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
uiBlockBeginAlign(block);
bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
if (U.color_picker_type == USER_CP_CIRCLE_HSV)
bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
else if (U.color_picker_type == USER_CP_CIRCLE_HSL)
bt = uiDefButS(block, ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
@ -1936,12 +1948,17 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
yco = -3.0f * UI_UNIT_Y;
uiBlockBeginAlign(block);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
if (U.color_picker_type == USER_CP_CIRCLE_HSV)
bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
else if (U.color_picker_type == USER_CP_CIRCLE_HSL)
bt = uiDefButF(block, NUMSLI, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Lightness"));
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
uiBlockEndAlign(block);
if (rgba[3] != FLT_MAX) {
@ -2500,3 +2517,39 @@ float *ui_block_hsv_get(uiBlock *block)
{
return block->_hsv;
}
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3])
{
switch (U.color_picker_type) {
case USER_CP_CIRCLE_HSL:
rgb_to_hsl_compat_v(rgb, r_cp);
break;
default:
rgb_to_hsv_compat_v(rgb, r_cp);
break;
}
}
void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3])
{
switch (U.color_picker_type) {
case USER_CP_CIRCLE_HSL:
hsl_to_rgb_v(r_cp, rgb);
break;
default:
hsv_to_rgb_v(r_cp, rgb);
break;
}
}
void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b)
{
switch (U.color_picker_type) {
case USER_CP_CIRCLE_HSL:
hsl_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
break;
default:
hsv_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
break;
}
}

View File

@ -2240,7 +2240,8 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
row = uiLayoutRow(col, true);
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
case USER_CP_CIRCLE_HSV:
case USER_CP_CIRCLE_HSL:
but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, 0, 0, "");
break;
@ -2275,11 +2276,16 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
if (value_slider) {
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
case USER_CP_CIRCLE_HSV:
uiItemS(row);
uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
-1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
break;
case USER_CP_CIRCLE_HSL:
uiItemS(row);
uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
-1, softmin, softmax, UI_GRAD_L_ALT, 0, "");
break;
case USER_CP_SQUARE_SV:
uiItemS(col);
uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,

View File

@ -2063,12 +2063,12 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
hsvo[1] = hsv[1] = hsv_ptr[1];
hsvo[2] = hsv[2] = hsv_ptr[2];
rgb_to_hsv_compat_v(rgb, hsvo);
ui_rgb_to_color_picker_compat_v(rgb, hsvo);
if (color_profile)
ui_block_to_display_space_v3(but->block, rgb);
rgb_to_hsv_compat_v(rgb, hsv);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
/* exception: if 'lock' is set
* lock the value of the color wheel to 1.
@ -2076,8 +2076,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
if (but->flag & UI_BUT_COLOR_LOCK)
hsv[2] = 1.f;
hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent + 1, colcent + 2);
ui_color_picker_to_rgb(0.f, 0.f, hsv[2], colcent, colcent + 1, colcent + 2);
glShadeModel(GL_SMOOTH);
glBegin(GL_TRIANGLE_FAN);
@ -2091,7 +2091,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
ui_hsvcircle_vals_from_pos(hsv, hsv + 1, rect, centx + co * radius, centy + si * radius);
CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
hsv_to_rgb_v(hsv, col);
ui_color_picker_to_rgb_v(hsv, col);
glColor3fv(col);
glVertex2f(centx + co * radius, centy + si * radius);
}
@ -2291,6 +2292,7 @@ void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *x
case UI_GRAD_V:
x = hsv[2]; y = 0.5; break;
case UI_GRAD_V_ALT:
case UI_GRAD_L_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);
@ -2349,8 +2351,10 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
if (color_profile)
ui_block_to_display_space_v3(but->block, rgb);
rgb_to_hsv_v(rgb, hsv);
if(but->a1 == UI_GRAD_L_ALT)
rgb_to_hsl_v(rgb, hsv);
else
rgb_to_hsv_v(rgb, hsv);
v = hsv[2];
/* map v from property range to [0,1] */
@ -3483,7 +3487,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case HSVCUBE:
if (but->a1 == UI_GRAD_V_ALT) { /* vertical V slider, uses new widget draw now */
if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) { /* vertical V slider, uses new widget draw now */
ui_draw_but_HSV_v(but, rect);
}
else { /* other HSV pickers... */

View File

@ -733,10 +733,11 @@ typedef enum eGP_UserdefSettings {
/* color picker types */
typedef enum eColorPicker_Types {
USER_CP_CIRCLE = 0,
USER_CP_CIRCLE_HSV = 0,
USER_CP_SQUARE_SV = 1,
USER_CP_SQUARE_HS = 2,
USER_CP_SQUARE_HV = 3,
USER_CP_CIRCLE_HSL = 4,
} eColorPicker_Types;
/* timecode display styles */

View File

@ -3634,7 +3634,8 @@ static void rna_def_userdef_system(BlenderRNA *brna)
};
static EnumPropertyItem color_picker_types[] = {
{USER_CP_CIRCLE, "CIRCLE", 0, "Circle", "A circular Hue/Saturation color wheel, with Value slider"},
{USER_CP_CIRCLE_HSV, "CIRCLE_HSV", 0, "Circle (HSV)", "A circular Hue/Saturation color wheel, with Value slider"},
{USER_CP_CIRCLE_HSL, "CIRCLE_HSL", 0, "Circle (HSL)", "A circular Hue/Saturation color wheel, with Lightness slider"},
{USER_CP_SQUARE_SV, "SQUARE_SV", 0, "Square (SV + H)", "A square showing Saturation/Value, with Hue slider"},
{USER_CP_SQUARE_HS, "SQUARE_HS", 0, "Square (HS + V)", "A square showing Hue/Saturation, with Value slider"},
{USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"},