diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-11-03 12:26:35 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-11-03 12:57:09 +0300 |
commit | 2a87bd89951204a5dd15b60ba86cbba72fc3b088 (patch) | |
tree | d4eaa0a5bab4f6ca0da0b3d1c0fa8fa8272c0f6a /source/blender/editors/interface/interface_region_color_picker.c | |
parent | d19d094ca9bb4f05b0f95c9f168340050864f103 (diff) |
Cleanup: split interface_regions.c
Each region type is quite separate and file was getting too big.
Diffstat (limited to 'source/blender/editors/interface/interface_region_color_picker.c')
-rw-r--r-- | source/blender/editors/interface/interface_region_color_picker.c | 650 |
1 files changed, 650 insertions, 0 deletions
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c new file mode 100644 index 00000000000..4309e913d9e --- /dev/null +++ b/source/blender/editors/interface/interface_region_color_picker.c @@ -0,0 +1,650 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/interface/interface_region_color_picker.c + * \ingroup edinterface + * + * Color Picker Region & Color Utils + */ + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_userdef_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_string.h" + +#include "BKE_context.h" + +#include "WM_types.h" + +#include "RNA_access.h" + +#include "UI_interface.h" + +#include "BLT_translation.h" + +#include "ED_screen.h" + +#include "IMB_colormanagement.h" + +#include "interface_intern.h" + +/* -------------------------------------------------------------------- */ +/** \name Color Conversion + * \{ */ + +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_rgb_to_color_picker_v(const float rgb[3], float r_cp[3]) +{ + switch (U.color_picker_type) { + case USER_CP_CIRCLE_HSL: + rgb_to_hsl_v(rgb, r_cp); + break; + default: + rgb_to_hsv_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; + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Color Picker + * \{ */ + +/* for picker, while editing hsv */ +void ui_but_hsv_set(uiBut *but) +{ + float col[3]; + ColorPicker *cpicker = but->custom_data; + float *hsv = cpicker->color_data; + + ui_color_picker_to_rgb_v(hsv, col); + + ui_but_v3_set(but, col); +} + +/* 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 *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); + } + + if (block->color_profile) + display = ui_block_cm_display_get(block); + + /* this updates button strings, is hackish... but button pointers are on stack of caller function */ + for (bt = block->buttons.first; bt; bt = bt->next) { + if (bt->custom_data != cpicker) + continue; + + if (bt->rnaprop) { + ui_but_v3_set(bt, rgb); + + /* original button that created the color picker already does undo + * push, so disable it on RNA buttons in the color picker block */ + UI_but_flag_disable(bt, UI_BUT_UNDO); + } + else if (STREQ(bt->str, "Hex: ")) { + float rgb_gamma[3]; + unsigned char rgb_gamma_uchar[3]; + double intpart; + char col[16]; + + /* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */ + + copy_v3_v3(rgb_gamma, rgb); + + if (display) { + /* make a display version, for Hex code */ + IMB_colormanagement_scene_linear_to_display_v3(rgb_gamma, display); + } + + if (rgb_gamma[0] > 1.0f) rgb_gamma[0] = modf(rgb_gamma[0], &intpart); + if (rgb_gamma[1] > 1.0f) rgb_gamma[1] = modf(rgb_gamma[1], &intpart); + if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart); + + rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma); + BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3_EX((uint), rgb_gamma_uchar, )); + + strcpy(bt->poin, col); + } + else if (bt->str[1] == ' ') { + if (bt->str[0] == 'R') { + ui_but_value_set(bt, rgb[0]); + } + else if (bt->str[0] == 'G') { + ui_but_value_set(bt, rgb[1]); + } + else if (bt->str[0] == 'B') { + ui_but_value_set(bt, rgb[2]); + } + else if (bt->str[0] == 'H') { + ui_but_value_set(bt, hsv[0]); + } + else if (bt->str[0] == 'S') { + ui_but_value_set(bt, hsv[1]); + } + else if (bt->str[0] == 'V') { + ui_but_value_set(bt, hsv[2]); + } + else if (bt->str[0] == 'L') { + ui_but_value_set(bt, hsv[2]); + } + } + + ui_but_update(bt); + } +} + +static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +{ + uiBut *but = (uiBut *)bt1; + uiPopupBlockHandle *popup = but->block->handle; + PropertyRNA *prop = but->rnaprop; + PointerRNA ptr = but->rnapoin; + float rgb[4]; + + 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)); + } + + if (popup) + popup->menuretval = UI_RETURN_UPDATE; +} + +static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +{ + uiBut *but = (uiBut *)bt1; + uiPopupBlockHandle *popup = but->block->handle; + 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); + } + + ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, !use_display_colorspace); + + if (popup) + popup->menuretval = UI_RETURN_UPDATE; +} + +static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl) +{ + uiBut *but = (uiBut *)bt1; + uiPopupBlockHandle *popup = but->block->handle; + ColorPicker *cpicker = but->custom_data; + char *hexcol = (char *)hexcl; + float rgb[3]; + + 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) { + /* 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); + + if (popup) + popup->menuretval = UI_RETURN_UPDATE; +} + +static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +{ + uiBut *but = (uiBut *)bt1; + uiPopupBlockHandle *popup = but->block->handle; + + if (popup) + popup->menuretval = UI_RETURN_OK; +} + +static void ui_colorpicker_hide_reveal(uiBlock *block, short colormode) +{ + uiBut *bt; + + /* tag buttons */ + for (bt = block->buttons.first; bt; bt = bt->next) { + if ((bt->func == ui_colorpicker_rna_cb) && bt->type == UI_BTYPE_NUM_SLIDER && 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 == ui_color_wheel_rna_cb) { + /* HSV sliders */ + if (colormode == 1) bt->flag &= ~UI_HIDDEN; + else bt->flag |= UI_HIDDEN; + } + else if (bt->func == ui_colorpicker_hex_rna_cb || bt->type == UI_BTYPE_LABEL) { + /* hex input or gamma correction status label */ + if (colormode == 2) bt->flag &= ~UI_HIDDEN; + else bt->flag |= UI_HIDDEN; + } + } +} + +static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +{ + uiBut *bt = bt1; + short colormode = ui_but_value_get(bt); + ui_colorpicker_hide_reveal(bt->block, colormode); +} + +#define PICKER_H (7.5f * U.widget_unit) +#define PICKER_W (7.5f * U.widget_unit) +#define PICKER_SPACE (0.3f * U.widget_unit) +#define PICKER_BAR (0.7f * U.widget_unit) + +#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR) + +static void ui_colorpicker_circle(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, ColorPicker *cpicker) +{ + uiBut *bt; + + /* HS circle */ + bt = uiDefButR_prop( + block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, + ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + + /* value */ + if (U.color_picker_type == USER_CP_CIRCLE_HSL) { + bt = uiDefButR_prop( + block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, + ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness"); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + } + else { + bt = uiDefButR_prop( + block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, + ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + } + bt->custom_data = cpicker; +} + + +static void ui_colorpicker_square(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type, ColorPicker *cpicker) +{ + uiBut *bt; + int bartype = type + 3; + + /* HS square */ + bt = uiDefButR_prop( + block, UI_BTYPE_HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, + ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + + /* value */ + bt = uiDefButR_prop( + block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, + ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; +} + +/* 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) +{ + 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; + + 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; + + RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); + RNA_property_float_range(ptr, prop, &hardmin, &hardmax); + RNA_property_float_get_array(ptr, prop, rgba); + + /* when the softmax isn't defined in the RNA, + * using very large numbers causes sRGB/linear round trip to fail. */ + if (softmax == FLT_MAX) { + softmax = 1.0f; + } + + switch (U.color_picker_type) { + case USER_CP_SQUARE_SV: + ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker); + break; + case USER_CP_SQUARE_HS: + ui_colorpicker_square(block, ptr, prop, UI_GRAD_HS, cpicker); + break; + case USER_CP_SQUARE_HV: + ui_colorpicker_square(block, ptr, prop, UI_GRAD_HV, cpicker); + break; + + /* user default */ + case USER_CP_CIRCLE_HSV: + case USER_CP_CIRCLE_HSL: + default: + ui_colorpicker_circle(block, ptr, prop, cpicker); + break; + } + + /* mode */ + yco = -1.5f * UI_UNIT_Y; + UI_block_align_begin(block); + bt = uiDefButS( + block, UI_BTYPE_ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, + &colormode, 0.0, 0.0, 0, 0, ""); + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; + if (U.color_picker_type == USER_CP_CIRCLE_HSL) { + bt = uiDefButS( + block, UI_BTYPE_ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, + &colormode, 0.0, 1.0, 0, 0, ""); + } + else { + bt = uiDefButS( + block, UI_BTYPE_ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, + &colormode, 0.0, 1.0, 0, 0, ""); + } + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButS( + block, UI_BTYPE_ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, + &colormode, 0.0, 2.0, 0, 0, ""); + UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL); + bt->custom_data = cpicker; + UI_block_align_end(block); + + yco = -3.0f * UI_UNIT_Y; + if (show_picker) { + bt = uiDefIconButO( + block, UI_BTYPE_BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, + butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); + UI_but_func_set(bt, ui_popup_close_cb, bt, NULL); + bt->custom_data = cpicker; + } + + /* RGB values */ + UI_block_align_begin(block); + bt = uiDefButR_prop( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, + ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButR_prop( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, + ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + bt = uiDefButR_prop( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, + ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + + /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); + * but need to use UI_but_func_set for updating other fake buttons */ + + /* HSV values */ + yco = -3.0f * UI_UNIT_Y; + UI_block_align_begin(block); + bt = uiDefButF( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("H:"), 0, yco, butwidth, + UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; + bt = uiDefButF( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, + butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; + if (U.color_picker_type == USER_CP_CIRCLE_HSL) { + bt = uiDefButF( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, + butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness")); + } + else { + bt = uiDefButF( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, + hsv + 2, 0.0, softmax, 10, 3, TIP_("Value")); + } + + bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */ + UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + bt->custom_data = cpicker; + + UI_block_align_end(block); + + if (rgba[3] != FLT_MAX) { + bt = uiDefButR_prop( + block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, + ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha")); + UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + bt->custom_data = cpicker; + } + else { + rgba[3] = 1.0f; + } + + rgb_float_to_uchar(rgb_gamma_uchar, rgb_gamma); + BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((uint), rgb_gamma_uchar, )); + + yco = -3.0f * UI_UNIT_Y; + bt = uiDefBut( + block, UI_BTYPE_TEXT, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, + hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); + UI_but_func_set(bt, ui_colorpicker_hex_rna_cb, bt, hexcol); + bt->custom_data = cpicker; + uiDefBut( + 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); +} + + +static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event) +{ + float add = 0.0f; + + if (event->type == WHEELUPMOUSE) + add = 0.05f; + else if (event->type == WHEELDOWNMOUSE) + add = -0.05f; + + if (add != 0.0f) { + uiBut *but; + + for (but = block->buttons.first; but; but = but->next) { + if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) { + uiPopupBlockHandle *popup = block->handle; + 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_rgb_to_color_picker_compat_v(rgb, hsv); + + hsv[2] = CLAMPIS(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_but_v3_set(but, rgb); + + ui_update_color_picker_buts_rgb(block, cpicker, rgb, !use_display_colorspace); + if (popup) + popup->menuretval = UI_RETURN_UPDATE; + + return 1; + } + } + } + return 0; +} + +uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_but) +{ + uiBut *but = arg_but; + uiBlock *block; + bool show_picker = true; + + block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS); + + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + block->color_profile = false; + } + + if (but->block) { + /* if color block is invoked from a popup we wouldn't be able to set color properly + * this is because color picker will close popups first and then will try to figure + * out active button RNA, and of course it'll fail + */ + show_picker = (but->block->flag & UI_BLOCK_POPUP) == 0; + } + + copy_v3_v3(handle->retvec, but->editvec); + + ui_block_colorpicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker); + + block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT; + UI_block_bounds_set_normal(block, 0.5 * UI_UNIT_X); + + block->block_event_func = ui_colorpicker_small_wheel_cb; + + /* and lets go */ + block->direction = UI_DIR_UP; + + return block; +} + +ColorPicker *ui_block_colorpicker_create(struct uiBlock *block) +{ + ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker"); + BLI_addhead(&block->color_pickers.list, cpicker); + + return cpicker; +} + +/** \} */ |