UI: Transform Arrow Cursor Refactor
Mouse cursors used during transforms made to work better with changes of user scale and line width. Differential Revision: https://developer.blender.org/D9668 Reviewed by Campbell Barton
This commit is contained in:
parent
425e706921
commit
b4b02eb4ff
|
@ -45,103 +45,49 @@ enum eArrowDirection {
|
|||
RIGHT,
|
||||
};
|
||||
|
||||
struct ArrowDims {
|
||||
int offset;
|
||||
int length;
|
||||
int size;
|
||||
};
|
||||
#define ARROW_WIDTH (2.0f * U.pixelsize)
|
||||
#define DASH_WIDTH (1.0f)
|
||||
#define DASH_LENGTH (8.0f * DASH_WIDTH * U.pixelsize)
|
||||
|
||||
#define POS_INDEX 0
|
||||
/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
|
||||
* private to this file - merwin
|
||||
*/
|
||||
|
||||
static void drawArrow(enum eArrowDirection dir, const struct ArrowDims *arrow_dims)
|
||||
static void drawArrow(const uint pos_id, const enum eArrowDirection dir)
|
||||
{
|
||||
int offset = arrow_dims->offset;
|
||||
int length = arrow_dims->length;
|
||||
int size = arrow_dims->size;
|
||||
int offset = 5.0f * UI_DPI_FAC;
|
||||
int length = (6.0f * UI_DPI_FAC) + (4.0f * U.pixelsize);
|
||||
int size = (3.0f * UI_DPI_FAC) + (2.0f * U.pixelsize);
|
||||
|
||||
/* To line up the arrow point nicely, one end has to be extended by half its width. But
|
||||
* being on a 45 degree angle, Pythagoras says a movement of sqrt(2)/2 * (line width /2) */
|
||||
float adjust = (M_SQRT2 * ARROW_WIDTH / 4.0f);
|
||||
|
||||
if (ELEM(dir, LEFT, DOWN)) {
|
||||
offset = -offset;
|
||||
length = -length;
|
||||
size = -size;
|
||||
adjust = -adjust;
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 6);
|
||||
|
||||
switch (dir) {
|
||||
case LEFT:
|
||||
offset = -offset;
|
||||
length = -length;
|
||||
size = -size;
|
||||
ATTR_FALLTHROUGH;
|
||||
case RIGHT:
|
||||
immVertex2f(POS_INDEX, offset, 0);
|
||||
immVertex2f(POS_INDEX, offset + length, 0);
|
||||
immVertex2f(POS_INDEX, offset + length, 0);
|
||||
immVertex2f(POS_INDEX, offset + length - size, -size);
|
||||
immVertex2f(POS_INDEX, offset + length, 0);
|
||||
immVertex2f(POS_INDEX, offset + length - size, size);
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
offset = -offset;
|
||||
length = -length;
|
||||
size = -size;
|
||||
ATTR_FALLTHROUGH;
|
||||
case UP:
|
||||
immVertex2f(POS_INDEX, 0, offset);
|
||||
immVertex2f(POS_INDEX, 0, offset + length);
|
||||
immVertex2f(POS_INDEX, 0, offset + length);
|
||||
immVertex2f(POS_INDEX, -size, offset + length - size);
|
||||
immVertex2f(POS_INDEX, 0, offset + length);
|
||||
immVertex2f(POS_INDEX, size, offset + length - size);
|
||||
break;
|
||||
if (ELEM(dir, LEFT, RIGHT)) {
|
||||
immVertex2f(pos_id, offset, 0);
|
||||
immVertex2f(pos_id, offset + length, 0);
|
||||
immVertex2f(pos_id, offset + length + adjust, adjust);
|
||||
immVertex2f(pos_id, offset + length - size, -size);
|
||||
immVertex2f(pos_id, offset + length, 0);
|
||||
immVertex2f(pos_id, offset + length - size, size);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
}
|
||||
|
||||
static void drawArrowHead(enum eArrowDirection dir, int size)
|
||||
{
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
|
||||
switch (dir) {
|
||||
case LEFT:
|
||||
size = -size;
|
||||
ATTR_FALLTHROUGH;
|
||||
case RIGHT:
|
||||
immVertex2f(POS_INDEX, 0, 0);
|
||||
immVertex2f(POS_INDEX, -size, -size);
|
||||
immVertex2f(POS_INDEX, 0, 0);
|
||||
immVertex2f(POS_INDEX, -size, size);
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
size = -size;
|
||||
ATTR_FALLTHROUGH;
|
||||
case UP:
|
||||
immVertex2f(POS_INDEX, 0, 0);
|
||||
immVertex2f(POS_INDEX, -size, -size);
|
||||
immVertex2f(POS_INDEX, 0, 0);
|
||||
immVertex2f(POS_INDEX, size, -size);
|
||||
break;
|
||||
else {
|
||||
immVertex2f(pos_id, 0, offset);
|
||||
immVertex2f(pos_id, 0, offset + length);
|
||||
immVertex2f(pos_id, adjust, offset + length + adjust);
|
||||
immVertex2f(pos_id, -size, offset + length - size);
|
||||
immVertex2f(pos_id, 0, offset + length);
|
||||
immVertex2f(pos_id, size, offset + length - size);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
}
|
||||
|
||||
static void drawArc(float angle_start, float angle_end, int segments, float size)
|
||||
{
|
||||
float delta = (angle_end - angle_start) / segments;
|
||||
float angle;
|
||||
int a;
|
||||
|
||||
immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
|
||||
|
||||
for (angle = angle_start, a = 0; a < segments; angle += delta, a++) {
|
||||
immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size);
|
||||
}
|
||||
immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size);
|
||||
|
||||
immEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll callback for cursor drawing:
|
||||
* #WM_paint_cursor_activate
|
||||
|
@ -149,11 +95,7 @@ static void drawArc(float angle_start, float angle_end, int segments, float size
|
|||
bool transform_draw_cursor_poll(bContext *C)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
|
||||
if (region && region->regiontype == RGN_TYPE_WINDOW) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return (region && region->regiontype == RGN_TYPE_WINDOW) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,181 +106,115 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd
|
|||
{
|
||||
TransInfo *t = (TransInfo *)customdata;
|
||||
|
||||
if (t->helpline != HLP_NONE) {
|
||||
struct ArrowDims arrow_dims = {
|
||||
.offset = 5 * UI_DPI_FAC,
|
||||
.length = 10 * UI_DPI_FAC,
|
||||
.size = 5 * UI_DPI_FAC,
|
||||
};
|
||||
|
||||
float cent[2];
|
||||
const float mval[3] = {x, y, 0.0f};
|
||||
float tmval[2] = {
|
||||
(float)t->mval[0],
|
||||
(float)t->mval[1],
|
||||
};
|
||||
|
||||
projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
|
||||
/* Offset the values for the area region. */
|
||||
const float offset[2] = {
|
||||
t->region->winrct.xmin,
|
||||
t->region->winrct.ymin,
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cent[i] += offset[i];
|
||||
tmval[i] += offset[i];
|
||||
}
|
||||
|
||||
GPU_line_smooth(true);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
GPU_matrix_push();
|
||||
|
||||
/* Dashed lines first. */
|
||||
if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
|
||||
const uint shdr_pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */
|
||||
BLI_assert(shdr_pos == POS_INDEX);
|
||||
|
||||
GPU_line_width(1.0f);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
|
||||
|
||||
float viewport_size[4];
|
||||
GPU_viewport_size_get_f(viewport_size);
|
||||
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
|
||||
|
||||
immUniform1i("colors_len", 0); /* "simple" mode */
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
immUniform1f("dash_width", 6.0f * UI_DPI_FAC);
|
||||
immUniform1f("dash_factor", 0.5f);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immVertex2fv(POS_INDEX, cent);
|
||||
immVertex2f(POS_INDEX, tmval[0], tmval[1]);
|
||||
immEnd();
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
/* And now, solid lines. */
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
UNUSED_VARS_NDEBUG(pos); /* silence warning */
|
||||
BLI_assert(pos == POS_INDEX);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
switch (t->helpline) {
|
||||
case HLP_SPRING:
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
drawArrow(UP, &arrow_dims);
|
||||
drawArrow(DOWN, &arrow_dims);
|
||||
break;
|
||||
case HLP_HARROW:
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
drawArrow(RIGHT, &arrow_dims);
|
||||
drawArrow(LEFT, &arrow_dims);
|
||||
break;
|
||||
case HLP_VARROW:
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
drawArrow(UP, &arrow_dims);
|
||||
drawArrow(DOWN, &arrow_dims);
|
||||
break;
|
||||
case HLP_CARROW: {
|
||||
/* Draw arrow based on direction defined by custom-points. */
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
|
||||
const int *data = t->mouse.data;
|
||||
const float dx = data[2] - data[0], dy = data[3] - data[1];
|
||||
const float angle = -atan2f(dx, dy);
|
||||
|
||||
GPU_matrix_push();
|
||||
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
||||
|
||||
drawArrow(UP, &arrow_dims);
|
||||
drawArrow(DOWN, &arrow_dims);
|
||||
|
||||
GPU_matrix_pop();
|
||||
break;
|
||||
}
|
||||
case HLP_ANGLE: {
|
||||
float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1];
|
||||
float angle = atan2f(dy, dx);
|
||||
float dist = hypotf(dx, dy);
|
||||
float delta_angle = min_ff(15.0f / (dist / UI_DPI_FAC), (float)M_PI / 4.0f);
|
||||
float spacing_angle = min_ff(5.0f / (dist / UI_DPI_FAC), (float)M_PI / 12.0f);
|
||||
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
|
||||
GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0);
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
drawArc(angle - delta_angle, angle - spacing_angle, 10, dist);
|
||||
drawArc(angle + spacing_angle, angle + delta_angle, 10, dist);
|
||||
|
||||
GPU_matrix_push();
|
||||
|
||||
GPU_matrix_translate_3f(
|
||||
cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z');
|
||||
|
||||
drawArrowHead(DOWN, arrow_dims.size);
|
||||
|
||||
GPU_matrix_pop();
|
||||
|
||||
GPU_matrix_translate_3f(
|
||||
cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z');
|
||||
|
||||
drawArrowHead(UP, arrow_dims.size);
|
||||
break;
|
||||
}
|
||||
case HLP_TRACKBALL: {
|
||||
uchar col[3], col2[3];
|
||||
UI_GetThemeColor3ubv(TH_GRID, col);
|
||||
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
|
||||
GPU_line_width(3.0f);
|
||||
|
||||
UI_make_axis_color(col, col2, 'X');
|
||||
immUniformColor3ubv(col2);
|
||||
|
||||
drawArrow(RIGHT, &arrow_dims);
|
||||
drawArrow(LEFT, &arrow_dims);
|
||||
|
||||
UI_make_axis_color(col, col2, 'Y');
|
||||
immUniformColor3ubv(col2);
|
||||
|
||||
drawArrow(UP, &arrow_dims);
|
||||
drawArrow(DOWN, &arrow_dims);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
GPU_matrix_pop();
|
||||
|
||||
GPU_line_smooth(false);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
if (t->helpline == HLP_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
float cent[2];
|
||||
const float mval[3] = {x, y, 0.0f};
|
||||
float tmval[2] = {
|
||||
(float)t->mval[0],
|
||||
(float)t->mval[1],
|
||||
};
|
||||
|
||||
projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO);
|
||||
/* Offset the values for the area region. */
|
||||
const float offset[2] = {
|
||||
t->region->winrct.xmin,
|
||||
t->region->winrct.ymin,
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cent[i] += offset[i];
|
||||
tmval[i] += offset[i];
|
||||
}
|
||||
|
||||
float viewport_size[4];
|
||||
GPU_viewport_size_get_f(viewport_size);
|
||||
|
||||
GPU_line_smooth(true);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
const uint pos_id = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
/* Dashed lines first. */
|
||||
if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
|
||||
GPU_line_width(DASH_WIDTH);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
|
||||
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
|
||||
immUniform1i("colors_len", 0); /* "simple" mode */
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
immUniform1f("dash_width", DASH_LENGTH);
|
||||
immUniform1f("dash_factor", 0.5f);
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immVertex2fv(pos_id, cent);
|
||||
immVertex2f(pos_id, tmval[0], tmval[1]);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
/* And now, solid lines. */
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
||||
immUniform2fv("viewportSize", &viewport_size[2]);
|
||||
immUniform1f("lineWidth", ARROW_WIDTH);
|
||||
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_translate_3fv(mval);
|
||||
|
||||
switch (t->helpline) {
|
||||
case HLP_SPRING:
|
||||
GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
|
||||
drawArrow(pos_id, UP);
|
||||
drawArrow(pos_id, DOWN);
|
||||
break;
|
||||
case HLP_HARROW:
|
||||
drawArrow(pos_id, RIGHT);
|
||||
drawArrow(pos_id, LEFT);
|
||||
break;
|
||||
case HLP_VARROW:
|
||||
drawArrow(pos_id, UP);
|
||||
drawArrow(pos_id, DOWN);
|
||||
break;
|
||||
case HLP_CARROW: {
|
||||
/* Draw arrow based on direction defined by custom-points. */
|
||||
const int *data = t->mouse.data;
|
||||
const float angle = -atan2f(data[2] - data[0], data[3] - data[1]);
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
||||
drawArrow(pos_id, UP);
|
||||
drawArrow(pos_id, DOWN);
|
||||
break;
|
||||
}
|
||||
case HLP_ANGLE: {
|
||||
GPU_matrix_push();
|
||||
float angle = atan2f(tmval[1] - cent[1], tmval[0] - cent[0]);
|
||||
GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
||||
drawArrow(pos_id, DOWN);
|
||||
GPU_matrix_pop();
|
||||
GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
|
||||
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
||||
drawArrow(pos_id, UP);
|
||||
break;
|
||||
}
|
||||
case HLP_TRACKBALL: {
|
||||
uchar col[3], col2[3];
|
||||
UI_GetThemeColor3ubv(TH_GRID, col);
|
||||
UI_make_axis_color(col, col2, 'X');
|
||||
immUniformColor3ubv(col2);
|
||||
drawArrow(pos_id, RIGHT);
|
||||
drawArrow(pos_id, LEFT);
|
||||
UI_make_axis_color(col, col2, 'Y');
|
||||
immUniformColor3ubv(col2);
|
||||
drawArrow(pos_id, UP);
|
||||
drawArrow(pos_id, DOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GPU_matrix_pop();
|
||||
immUnbindProgram();
|
||||
GPU_line_smooth(false);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue