UI: Draw unsnapped HSV cursor guide #112116
|
@ -1858,6 +1858,8 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y);
|
||||||
* Draw panels, selected (panels currently being dragged) on top.
|
* Draw panels, selected (panels currently being dragged) on top.
|
||||||
*/
|
*/
|
||||||
void UI_panels_draw(const bContext *C, ARegion *region);
|
void UI_panels_draw(const bContext *C, ARegion *region);
|
||||||
|
void UI_draw_unsnaped_hsv_cursor(const uiBut *but);
|
||||||
|
void UI_draw_hsv_cursor(const float x, const float y, const float zoom, const float alpha = 1);
|
||||||
|
|
||||||
Panel *UI_panel_find_by_type(ListBase *lb, const PanelType *pt);
|
Panel *UI_panel_find_by_type(ListBase *lb, const PanelType *pt);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6791,44 +6791,65 @@ static int ui_do_but_HSVCUBE(
|
||||||
return WM_UI_HANDLER_CONTINUE;
|
return WM_UI_HANDLER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UI_draw_unsnaped_hsv_cursor(const uiBut *but)
|
||||||
|
{
|
||||||
|
uiHandleButtonData *data = but->active;
|
||||||
|
|
||||||
|
const bool use_continuous_grab = ui_but_is_cursor_warp(but);
|
||||||
|
|
||||||
|
if (!data || !use_continuous_grab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const float zoom = 1.0f / but->block->aspect;
|
||||||
|
UI_draw_hsv_cursor(data->ungrab_mval[0], data->ungrab_mval[1], zoom * 0.65f, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
static bool ui_numedit_but_HSVCIRCLE(uiBut *but,
|
static bool ui_numedit_but_HSVCIRCLE(uiBut *but,
|
||||||
uiHandleButtonData *data,
|
uiHandleButtonData *data,
|
||||||
float mx,
|
float mx,
|
||||||
float my,
|
float my,
|
||||||
const enum eSnapType snap,
|
const enum eSnapType snap,
|
||||||
const bool shift)
|
const bool shift,
|
||||||
|
const bool use_continuous_grab)
|
||||||
{
|
{
|
||||||
const bool changed = true;
|
const bool changed = true;
|
||||||
ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
|
ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
|
||||||
float *hsv = cpicker->hsv_perceptual;
|
float *hsv = cpicker->hsv_perceptual;
|
||||||
|
|
||||||
float mx_fl, my_fl;
|
/* If `use_continuous_grab = false` stores the absolute mouse position.
|
||||||
ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
|
* If `use_continuous_grab = true` stores relative mouse position within the `HSVCIRCLE`, this
|
||||||
|
* position will depend on mouse movement rather than the absolute mouse position.
|
||||||
#ifdef USE_CONT_MOUSE_CORRECT
|
*/
|
||||||
if (ui_but_is_cursor_warp(but)) {
|
static float mval[2];
|
||||||
/* OK but can go outside bounds */
|
|
||||||
data->ungrab_mval[0] = mx_fl;
|
|
||||||
data->ungrab_mval[1] = my_fl;
|
|
||||||
{ /* clamp */
|
|
||||||
const float radius = min_ff(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f;
|
|
||||||
const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)};
|
|
||||||
const float len = len_v2v2(cent, data->ungrab_mval);
|
|
||||||
if (len > radius) {
|
|
||||||
dist_ensure_v2_v2fl(data->ungrab_mval, cent, radius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rcti rect;
|
rcti rect;
|
||||||
BLI_rcti_rctf_copy(&rect, &but->rect);
|
BLI_rcti_rctf_copy(&rect, &but->rect);
|
||||||
|
|
||||||
float rgb[3];
|
if (use_continuous_grab) {
|
||||||
ui_but_v3_get(but, rgb);
|
const float fac = ui_mouse_scale_warp_factor(shift);
|
||||||
ui_scene_linear_to_perceptual_space(but, rgb);
|
mval[0] = (mx - float(data->draglastx)) * fac + mval[0];
|
||||||
ui_color_picker_rgb_to_hsv_compat(rgb, hsv);
|
mval[1] = (my - float(data->draglasty)) * fac + mval[1];
|
||||||
|
|
||||||
|
const float radius = min_ff(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f;
|
||||||
|
const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)};
|
||||||
|
const float len = len_v2v2(cent, mval);
|
||||||
|
|
||||||
|
if (len > radius) {
|
||||||
|
dist_ensure_v2_v2fl(mval, cent, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mval[0] = mx;
|
||||||
|
mval[1] = my;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_CONT_MOUSE_CORRECT
|
||||||
|
if (use_continuous_grab) {
|
||||||
|
/* OK but can go outside bounds */
|
||||||
|
data->ungrab_mval[0] = mval[0];
|
||||||
|
data->ungrab_mval[1] = mval[1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* exception, when using color wheel in 'locked' value state:
|
/* exception, when using color wheel in 'locked' value state:
|
||||||
* allow choosing a hue for black values, by giving a tiny increment */
|
* allow choosing a hue for black values, by giving a tiny increment */
|
||||||
if (cpicker->use_color_lock) {
|
if (cpicker->use_color_lock) {
|
||||||
|
@ -6847,24 +6868,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only apply the delta motion, not absolute */
|
ui_hsvcircle_vals_from_pos(&rect, mval[0], mval[1], hsv, hsv + 1);
|
||||||
if (shift) {
|
|
||||||
float xpos, ypos, hsvo[3], rgbo[3];
|
|
||||||
|
|
||||||
/* calculate original hsv again */
|
|
||||||
copy_v3_v3(hsvo, hsv);
|
|
||||||
copy_v3_v3(rgbo, data->origvec);
|
|
||||||
ui_scene_linear_to_perceptual_space(but, rgbo);
|
|
||||||
ui_color_picker_rgb_to_hsv_compat(rgbo, hsvo);
|
|
||||||
|
|
||||||
/* and original position */
|
|
||||||
ui_hsvcircle_pos_from_vals(cpicker, &rect, hsvo, &xpos, &ypos);
|
|
||||||
|
|
||||||
mx_fl = xpos - (data->dragstartx - mx_fl);
|
|
||||||
my_fl = ypos - (data->dragstarty - my_fl);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_hsvcircle_vals_from_pos(&rect, mx_fl, my_fl, hsv, hsv + 1);
|
|
||||||
|
|
||||||
if ((cpicker->use_color_cubic) && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
|
if ((cpicker->use_color_cubic) && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
|
||||||
hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
|
hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
|
||||||
|
@ -6874,6 +6878,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but,
|
||||||
ui_color_snap_hue(snap, &hsv[0]);
|
ui_color_snap_hue(snap, &hsv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float rgb[3];
|
||||||
ui_color_picker_hsv_to_rgb(hsv, rgb);
|
ui_color_picker_hsv_to_rgb(hsv, rgb);
|
||||||
|
|
||||||
if (cpicker->use_luminosity_lock) {
|
if (cpicker->use_luminosity_lock) {
|
||||||
|
@ -6976,6 +6981,8 @@ static int ui_do_but_HSVCIRCLE(
|
||||||
float *hsv = cpicker->hsv_perceptual;
|
float *hsv = cpicker->hsv_perceptual;
|
||||||
int mx = event->xy[0];
|
int mx = event->xy[0];
|
||||||
int my = event->xy[1];
|
int my = event->xy[1];
|
||||||
|
|
||||||
|
const bool shift = event->modifier & KM_SHIFT;
|
||||||
ui_window_to_block(data->region, block, &mx, &my);
|
ui_window_to_block(data->region, block, &mx, &my);
|
||||||
|
|
||||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||||
|
@ -6987,8 +6994,10 @@ static int ui_do_but_HSVCIRCLE(
|
||||||
data->draglasty = my;
|
data->draglasty = my;
|
||||||
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
|
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
|
||||||
|
|
||||||
|
/* On KM_PRESS the mouse is within the circle, use `use_continuous_grab = false` to pick
|
||||||
|
* color at mouse position. */
|
||||||
/* also do drag the first time */
|
/* also do drag the first time */
|
||||||
if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
|
if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, shift, false)) {
|
||||||
ui_numedit_apply(C, block, but, data);
|
ui_numedit_apply(C, block, but, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7059,8 +7068,9 @@ static int ui_do_but_HSVCIRCLE(
|
||||||
else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
|
else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
|
||||||
if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
|
if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
|
||||||
const enum eSnapType snap = ui_event_to_snap(event);
|
const enum eSnapType snap = ui_event_to_snap(event);
|
||||||
|
const bool use_continuous_grab = ui_but_is_cursor_warp(but) &&
|
||||||
if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->modifier & KM_SHIFT)) {
|
event->tablet.active == EVT_TABLET_NONE;
|
||||||
|
if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, shift, use_continuous_grab)) {
|
||||||
ui_numedit_apply(C, block, but, data);
|
ui_numedit_apply(C, block, but, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9115,6 +9125,11 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
|
||||||
|
|
||||||
void ui_but_activate_over(bContext *C, ARegion *region, uiBut *but)
|
void ui_but_activate_over(bContext *C, ARegion *region, uiBut *but)
|
||||||
{
|
{
|
||||||
|
/* If there is an active button then add UI_SELECT_DRAW to the to-be-activated one. */
|
||||||
|
if (ui_region_find_active_but(CTX_wm_region(C))) {
|
||||||
|
but->flag |= UI_SELECT_DRAW;
|
||||||
|
}
|
||||||
|
|
||||||
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
|
button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "UI_interface_icons.hh"
|
#include "UI_interface_icons.hh"
|
||||||
#include "UI_view2d.hh"
|
#include "UI_view2d.hh"
|
||||||
|
|
||||||
|
#include "DNA_windowmanager_types.h"
|
||||||
|
|
||||||
#include "interface_intern.hh"
|
#include "interface_intern.hh"
|
||||||
|
|
||||||
#include "GPU_batch.h"
|
#include "GPU_batch.h"
|
||||||
|
@ -2843,7 +2845,7 @@ static void widget_menu_back(
|
||||||
GPU_blend(GPU_BLEND_NONE);
|
GPU_blend(GPU_BLEND_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_hsv_cursor(const float x, const float y, const float zoom)
|
void UI_draw_hsv_cursor(const float x, const float y, const float zoom, const float alpha)
|
||||||
{
|
{
|
||||||
const float radius = zoom * 3.0f * U.pixelsize;
|
const float radius = zoom * 3.0f * U.pixelsize;
|
||||||
const uint pos = GPU_vertformat_attr_add(
|
const uint pos = GPU_vertformat_attr_add(
|
||||||
|
@ -2851,12 +2853,12 @@ static void ui_hsv_cursor(const float x, const float y, const float zoom)
|
||||||
|
|
||||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||||
|
|
||||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
GPU_blend(GPU_BLEND_ALPHA);
|
||||||
|
immUniformColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||||
imm_draw_circle_fill_2d(pos, x, y, radius, 8);
|
imm_draw_circle_fill_2d(pos, x, y, radius, 8);
|
||||||
|
|
||||||
GPU_blend(GPU_BLEND_ALPHA);
|
|
||||||
GPU_line_smooth(true);
|
GPU_line_smooth(true);
|
||||||
immUniformColor3f(0.0f, 0.0f, 0.0f);
|
immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
|
||||||
imm_draw_circle_wire_2d(pos, x, y, radius, 12);
|
imm_draw_circle_wire_2d(pos, x, y, radius, 12);
|
||||||
GPU_blend(GPU_BLEND_NONE);
|
GPU_blend(GPU_BLEND_NONE);
|
||||||
GPU_line_smooth(false);
|
GPU_line_smooth(false);
|
||||||
|
@ -2901,7 +2903,10 @@ void ui_hsvcircle_pos_from_vals(
|
||||||
*r_ypos = centy + sinf(-ang) * rad;
|
*r_ypos = centy + sinf(-ang) * rad;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
|
static void ui_draw_but_HSVCIRCLE(uiBut *but,
|
||||||
|
const uiWidgetColors *wcol,
|
||||||
|
const rcti *rect,
|
||||||
|
const bool tablet)
|
||||||
{
|
{
|
||||||
/* TODO(merwin): reimplement as shader for pixel-perfect colors */
|
/* TODO(merwin): reimplement as shader for pixel-perfect colors */
|
||||||
|
|
||||||
|
@ -3005,7 +3010,10 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const
|
||||||
float xpos, ypos;
|
float xpos, ypos;
|
||||||
ui_hsvcircle_pos_from_vals(cpicker, rect, hsv, &xpos, &ypos);
|
ui_hsvcircle_pos_from_vals(cpicker, rect, hsv, &xpos, &ypos);
|
||||||
const float zoom = 1.0f / but->block->aspect;
|
const float zoom = 1.0f / but->block->aspect;
|
||||||
ui_hsv_cursor(xpos, ypos, zoom);
|
if (!tablet) {
|
||||||
|
UI_draw_unsnaped_hsv_cursor(but);
|
||||||
|
}
|
||||||
|
UI_draw_hsv_cursor(xpos, ypos, zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@ -3239,8 +3247,7 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
|
||||||
CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
|
CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
|
||||||
|
|
||||||
const float zoom = 1.0f / but->block->aspect;
|
const float zoom = 1.0f / but->block->aspect;
|
||||||
|
UI_draw_hsv_cursor(x, y, zoom);
|
||||||
ui_hsv_cursor(x, y, zoom);
|
|
||||||
|
|
||||||
/* outline */
|
/* outline */
|
||||||
const uint pos = GPU_vertformat_attr_add(
|
const uint pos = GPU_vertformat_attr_add(
|
||||||
|
@ -3309,8 +3316,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
|
||||||
y = rect->ymin + v * BLI_rcti_size_y(rect);
|
y = rect->ymin + v * BLI_rcti_size_y(rect);
|
||||||
CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
|
CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
|
||||||
const float zoom = 1.0f / but->block->aspect;
|
const float zoom = 1.0f / but->block->aspect;
|
||||||
|
UI_draw_hsv_cursor(x, y, zoom);
|
||||||
ui_hsv_cursor(x, y, zoom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Separator for menus. */
|
/** Separator for menus. */
|
||||||
|
@ -4963,9 +4969,12 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UI_BTYPE_HSVCIRCLE:
|
case UI_BTYPE_HSVCIRCLE: {
|
||||||
ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
|
const wmWindow *win = CTX_wm_window(C);
|
||||||
|
const bool tablet = win->eventstate->tablet.active != EVT_TABLET_NONE;
|
||||||
|
ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect, tablet);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case UI_BTYPE_COLORBAND: {
|
case UI_BTYPE_COLORBAND: {
|
||||||
/* Horizontal padding to make room for handles at edges. */
|
/* Horizontal padding to make room for handles at edges. */
|
||||||
|
|
Loading…
Reference in New Issue