Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface_region_color_picker.c')
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.c134
1 files changed, 73 insertions, 61 deletions
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c
index a99bcb2b73c..7c2afaf1a92 100644
--- a/source/blender/editors/interface/interface_region_color_picker.c
+++ b/source/blender/editors/interface/interface_region_color_picker.c
@@ -111,6 +111,36 @@ void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, flo
}
}
+/* Returns true if the button is for a color with gamma baked in,
+ * or if it's a color picker for such a button. */
+bool ui_but_is_color_gamma(uiBut *but)
+{
+ if (but->rnaprop) {
+ if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ return true;
+ }
+ }
+
+ return but->block->is_color_gamma_picker;
+}
+
+void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3])
+{
+ /* Map to color picking space for HSV values and HSV cube/circle,
+ * assuming it is more perceptually linear then the scene linear
+ * space for intuitive color picking. */
+ if (!ui_but_is_color_gamma(but)) {
+ IMB_colormanagement_scene_linear_to_color_picking_v3(rgb);
+ }
+}
+
+void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3])
+{
+ if (!ui_but_is_color_gamma(but)) {
+ IMB_colormanagement_color_picking_to_scene_linear_v3(rgb);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -132,28 +162,18 @@ void ui_but_hsv_set(uiBut *but)
/* Updates all buttons who share the same color picker as the one passed
* also used by small picker, be careful with name checks below... */
static void ui_update_color_picker_buts_rgb(
- uiBlock *block, ColorPicker *cpicker, const float rgb[3], bool is_display_space)
+ uiBut *from_but, uiBlock *block, ColorPicker *cpicker, const float rgb[3])
{
uiBut *bt;
float *hsv = cpicker->color_data;
- struct ColorManagedDisplay *display = NULL;
- /* this is to keep the H and S value when V is equal to zero
- * and we are working in HSV mode, of course!
- */
- if (is_display_space) {
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
- }
- else {
- /* we need to convert to display space to use hsv, because hsv is stored in display space */
- float rgb_display[3];
- copy_v3_v3(rgb_display, rgb);
- ui_block_cm_to_display_space_v3(block, rgb_display);
- ui_rgb_to_color_picker_compat_v(rgb_display, hsv);
+ /* Convert from RGB to HSV in perceptually linear space. */
+ float tmp[3];
+ copy_v3_v3(tmp, rgb);
+ if (from_but) {
+ ui_scene_linear_to_color_picker_space(from_but, tmp);
}
-
- if (block->color_profile)
- display = ui_block_cm_display_get(block);
+ ui_rgb_to_color_picker_compat_v(tmp, hsv);
/* this updates button strings, is hackish... but button pointers are on stack of caller function */
for (bt = block->buttons.first; bt; bt = bt->next) {
@@ -177,9 +197,9 @@ static void ui_update_color_picker_buts_rgb(
copy_v3_v3(rgb_gamma, rgb);
- if (display) {
+ if (!block->is_color_gamma_picker) {
/* make a display version, for Hex code */
- IMB_colormanagement_scene_linear_to_display_v3(rgb_gamma, display);
+ ui_block_cm_to_display_space_v3(block, rgb_gamma);
}
if (rgb_gamma[0] > 1.0f) rgb_gamma[0] = modf(rgb_gamma[0], &intpart);
@@ -230,7 +250,7 @@ static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
if (prop) {
RNA_property_float_get_array(&ptr, prop, rgb);
ui_update_color_picker_buts_rgb(
- but->block, but->custom_data, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA));
+ but, but->block, but->custom_data, rgb);
}
if (popup)
@@ -244,16 +264,13 @@ static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
float rgb[3];
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
- bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
ui_color_picker_to_rgb_v(hsv, rgb);
- /* hsv is saved in display space so convert back */
- if (use_display_colorspace) {
- ui_block_cm_to_scene_linear_v3(but->block, rgb);
- }
+ /* hsv is saved in perceptually linear space so convert back */
+ ui_color_picker_to_scene_linear_space(but, rgb);
- ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, !use_display_colorspace);
+ ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -270,12 +287,12 @@ static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexc
hex_to_rgb(hexcol, rgb, rgb + 1, rgb + 2);
/* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
- if (but->block->color_profile) {
+ if (!but->block->is_color_gamma_picker) {
/* so we need to linearise it for Blender */
ui_block_cm_to_scene_linear_v3(but->block, rgb);
}
- ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, false);
+ ui_update_color_picker_buts_rgb(NULL, but->block, cpicker, rgb);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -378,37 +395,22 @@ static void ui_colorpicker_square(uiBlock *block, PointerRNA *ptr, PropertyRNA *
/* a HS circle, V slider, rgb/hsv/hex sliders */
static void ui_block_colorpicker(
- uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker)
+ uiBlock *block, uiBut *from_but, float rgba[4], bool show_picker)
{
static short colormode = 0; /* temp? 0=rgb, 1=hsv, 2=hex */
uiBut *bt;
int width, butwidth;
- static char tip[50];
static char hexcol[128];
- float rgb_gamma[3];
- unsigned char rgb_gamma_uchar[3];
float softmin, softmax, hardmin, hardmax, step, precision;
int yco;
ColorPicker *cpicker = ui_block_colorpicker_create(block);
float *hsv = cpicker->color_data;
+ PointerRNA *ptr = &from_but->rnapoin;
+ PropertyRNA *prop = from_but->rnaprop;
width = PICKER_TOTAL_W;
butwidth = width - 1.5f * UI_UNIT_X;
- /* existence of profile means storage is in linear color space, with display correction */
- /* XXX That tip message is not use anywhere! */
- if (!block->color_profile) {
- BLI_strncpy(tip, N_("Value in Display Color Space"), sizeof(tip));
- copy_v3_v3(rgb_gamma, rgba);
- }
- else {
- BLI_strncpy(tip, N_("Value in Linear RGB Color Space"), sizeof(tip));
-
- /* make a display version, for Hex code */
- copy_v3_v3(rgb_gamma, rgba);
- ui_block_cm_to_display_space_v3(block, rgb_gamma);
- }
-
/* sneaky way to check for alpha */
rgba[3] = FLT_MAX;
@@ -416,6 +418,11 @@ static void ui_block_colorpicker(
RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
RNA_property_float_get_array(ptr, prop, rgba);
+ float rgb_perceptual[3];
+ copy_v3_v3(rgb_perceptual, rgba);
+ ui_scene_linear_to_color_picker_space(from_but, rgb_perceptual);
+ ui_rgb_to_color_picker_v(rgb_perceptual, hsv);
+
/* when the softmax isn't defined in the RNA,
* using very large numbers causes sRGB/linear round trip to fail. */
if (softmax == FLT_MAX) {
@@ -539,6 +546,19 @@ static void ui_block_colorpicker(
rgba[3] = 1.0f;
}
+ /* Hex color is in display space. This should actually be sRGB without any view
+ * transform, as most other applications would expect this. */
+ float rgb_gamma[3];
+ unsigned char rgb_gamma_uchar[3];
+
+ if (block->is_color_gamma_picker) {
+ copy_v3_v3(rgb_gamma, rgba);
+ }
+ else {
+ copy_v3_v3(rgb_gamma, rgba);
+ ui_block_cm_to_display_space_v3(block, rgb_gamma);
+ }
+
rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma);
BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((uint), rgb_gamma_uchar, ));
@@ -552,8 +572,6 @@ static void ui_block_colorpicker(
block, UI_BTYPE_LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y,
butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- ui_rgb_to_color_picker_v(rgb_gamma, hsv);
-
ui_colorpicker_hide_reveal(block, colormode);
}
@@ -576,24 +594,18 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *blo
float rgb[3];
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
- bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
ui_but_v3_get(but, rgb);
-
- if (use_display_colorspace)
- ui_block_cm_to_display_space_v3(block, rgb);
-
+ ui_scene_linear_to_color_picker_space(but, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
hsv[2] = clamp_f(hsv[2] + add, 0.0f, 1.0f);
- ui_color_picker_to_rgb_v(hsv, rgb);
-
- if (use_display_colorspace)
- ui_block_cm_to_scene_linear_v3(block, rgb);
+ ui_color_picker_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_scene_linear_space(but, rgb);
ui_but_v3_set(but, rgb);
- ui_update_color_picker_buts_rgb(block, cpicker, rgb, !use_display_colorspace);
+ ui_update_color_picker_buts_rgb(but, block, cpicker, rgb);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -612,8 +624,8 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS);
- if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- block->color_profile = false;
+ if (ui_but_is_color_gamma(but)) {
+ block->is_color_gamma_picker = true;
}
if (but->block) {
@@ -626,7 +638,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
copy_v3_v3(handle->retvec, but->editvec);
- ui_block_colorpicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker);
+ ui_block_colorpicker(block, but, handle->retvec, show_picker);
block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);