diff options
-rw-r--r-- | source/blender/blenlib/BLI_math_color.h | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_color.c | 86 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 83 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 93 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 10 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 20 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 3 |
11 files changed, 255 insertions, 53 deletions
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 3892c98e140..8a6bc35141c 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -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); diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 51980ad36cb..43f6d4c29ae 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -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]) { diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index e486ccc814e..2177b066c1f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -283,6 +283,7 @@ typedef enum { #define UI_GRAD_V 5 #define UI_GRAD_V_ALT 9 +#define UI_GRAD_L_ALT 10 /* Drawing * diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index b8e00022a61..744d19dd6e1 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -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; } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 8ead084f756..f25e045f237 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index e0185d82925..9cdd85d8dc0 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -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); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 3d7492c9753..f92d87b2ed7 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -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; + } +} diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 8ce2a290446..d4d2bc4cebf 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -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, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 91ee357ea4f..263365b174d 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -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... */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 6faba7ccd2f..b9f1d604007 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index f14457d2290..ba42dd1370b 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -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"}, |