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:
authorCampbell Barton <ideasman42@gmail.com>2019-12-20 10:16:44 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-12-20 10:19:56 +0300
commit50a56f566f675b9d298060f368f4a345a7ccd741 (patch)
treeda38ac511b8fdf5e6a452eb0862309c4d149dfa5 /source/blender
parentc5a76447171e263bba6388ff2292cc7f3880bd56 (diff)
Cleanup: split transform cursor drawing into their own files
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/transform/CMakeLists.txt2
-rw-r--r--source/blender/editors/transform/transform.c342
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_draw.c114
-rw-r--r--source/blender/editors/transform/transform_draw.h0
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.c340
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.h31
7 files changed, 525 insertions, 306 deletions
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index 5853574dced..6f39a8c3b9c 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -59,6 +59,7 @@ set(SRC
transform_convert_sculpt.c
transform_convert_sequencer.c
transform_convert_tracking.c
+ transform_draw_cursors.c
transform_generics.c
transform_gizmo_2d.c
transform_gizmo_3d.c
@@ -71,6 +72,7 @@ set(SRC
transform.h
transform_convert.h
+ transform_draw_cursors.h
transform_snap.h
)
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 719064ba1d6..7112444655b 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -95,6 +95,7 @@
#include "transform.h"
#include "transform_convert.h"
+#include "transform_draw_cursors.h"
#include "transform_snap.h"
/* Disabling, since when you type you know what you are doing,
@@ -1684,299 +1685,6 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa
return success;
}
-typedef enum {
- UP,
- DOWN,
- LEFT,
- RIGHT,
-} ArrowDirection;
-
-#define POS_INDEX 0
-/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
- * private to this file - merwin
- */
-
-static void drawArrow(ArrowDirection d, short offset, short length, short size)
-{
- immBegin(GPU_PRIM_LINES, 6);
-
- offset = round_fl_to_short(UI_DPI_FAC * offset);
- length = round_fl_to_short(UI_DPI_FAC * length);
- size = round_fl_to_short(UI_DPI_FAC * size);
-
- switch (d) {
- 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;
- }
-
- immEnd();
-}
-
-static void drawArrowHead(ArrowDirection d, short size)
-{
- size = round_fl_to_short(UI_DPI_FAC * size);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- switch (d) {
- 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;
- }
-
- immEnd();
-}
-
-static void drawArc(float angle_start, float angle_end, int segments, float size)
-{
- segments = round_fl_to_int(segments * UI_DPI_FAC);
-
- 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();
-}
-
-static bool helpline_poll(bContext *C)
-{
- ARegion *ar = CTX_wm_region(C);
-
- if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
- return 1;
- }
- return 0;
-}
-
-static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
-{
- TransInfo *t = (TransInfo *)customdata;
-
- if (t->helpline != HLP_NONE) {
- 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->ar->winrct.xmin,
- t->ar->winrct.ymin,
- };
-
- for (int i = 0; i < 2; i++) {
- cent[i] += offset[i];
- tmval[i] += offset[i];
- }
-
- GPU_line_smooth(true);
- GPU_blend(true);
-
- 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, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- break;
- case HLP_HARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(RIGHT, 5, 10, 5);
- drawArrow(LEFT, 5, 10, 5);
- break;
- case HLP_VARROW:
- immUniformThemeColor3(TH_VIEW_OVERLAY);
-
- GPU_matrix_translate_3fv(mval);
-
- GPU_line_width(3.0f);
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- 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, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
-
- 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, 5);
-
- 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, 5);
- break;
- }
- case HLP_TRACKBALL: {
- unsigned char 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, 5, 10, 5);
- drawArrow(LEFT, 5, 10, 5);
-
- UI_make_axis_color(col, col2, 'Y');
- immUniformColor3ubv(col2);
-
- drawArrow(UP, 5, 10, 5);
- drawArrow(DOWN, 5, 10, 5);
- break;
- }
- }
-
- immUnbindProgram();
- GPU_matrix_pop();
-
- GPU_line_smooth(false);
- GPU_blend(false);
- }
-}
-
static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *ar)
{
/* Don't show overlays when not the active view and when overlay is disabled: T57139 */
@@ -2394,38 +2102,62 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
t->draw_handle_pixel = ED_region_draw_cb_activate(
t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
else if (t->spacetype == SPACE_IMAGE) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
else if (t->spacetype == SPACE_CLIP) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
else if (t->spacetype == SPACE_NODE) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
else if (t->spacetype == SPACE_GRAPH) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
else if (t->spacetype == SPACE_ACTION) {
t->draw_handle_view = ED_region_draw_cb_activate(
t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
- t->draw_handle_cursor = WM_paint_cursor_activate(
- CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t);
+ t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ SPACE_TYPE_ANY,
+ RGN_TYPE_ANY,
+ transform_draw_cursor_poll,
+ transform_draw_cursor_draw,
+ t);
}
createTransData(C, t); // make TransData structs from selection
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 4b529765ab0..95506918d98 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -649,7 +649,7 @@ typedef struct TransInfo {
short index;
short *types[2];
/* this gets used when custom_orientation is V3D_ORIENT_CUSTOM */
- TransformOrientation *custom;
+ struct TransformOrientation *custom;
} orientation;
/** backup from view3d, to restore on end. */
short gizmo_flag;
diff --git a/source/blender/editors/transform/transform_draw.c b/source/blender/editors/transform/transform_draw.c
new file mode 100644
index 00000000000..e44442b7e49
--- /dev/null
+++ b/source/blender/editors/transform/transform_draw.c
@@ -0,0 +1,114 @@
+
+/* -------------------------------------------------------------------- */
+/** \name Auto-Key (Pixel Space)
+ * \{ */
+
+/* just draw a little warning message in the top-right corner of the viewport
+ * to warn that autokeying is enabled */
+static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
+{
+ const char *printable = IFACE_("Auto Keying On");
+ float printable_size[2];
+ int xco, yco;
+
+ const rcti *rect = ED_region_visible_rect(ar);
+
+ const int font_id = BLF_default();
+ BLF_width_and_height(
+ font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
+
+ xco = (rect->xmax - U.widget_unit) - (int)printable_size[0];
+ yco = (rect->ymax - U.widget_unit);
+
+ /* warning text (to clarify meaning of overlays)
+ * - original color was red to match the icon, but that clashes badly with a less nasty border
+ */
+ unsigned char color[3];
+ UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color);
+ BLF_color3ubv(font_id, color);
+#ifdef WITH_INTERNATIONAL
+ BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+#else
+ BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX);
+#endif
+
+ /* autokey recording icon... */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ xco -= U.widget_unit;
+ yco -= (int)printable_size[1] / 2;
+
+ UI_icon_draw(xco, yco, ICON_REC);
+
+ GPU_blend(false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Constraints (View Space)
+ * \{ */
+
+/* called from drawview.c, as an extra per-window draw option */
+void drawPropCircle(const struct bContext *C, TransInfo *t)
+{
+ if (t->flag & T_PROP_EDIT) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ float tmat[4][4], imat[4][4];
+ int depth_test_enabled;
+
+ if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
+ copy_m4_m4(tmat, rv3d->viewmat);
+ invert_m4_m4(imat, tmat);
+ }
+ else {
+ unit_m4(tmat);
+ unit_m4(imat);
+ }
+
+ GPU_matrix_push();
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* pass */
+ }
+ else if (t->spacetype == SPACE_IMAGE) {
+ GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
+ }
+ else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) {
+ /* only scale y */
+ rcti *mask = &t->ar->v2d.mask;
+ rctf *datamask = &t->ar->v2d.cur;
+ float xsize = BLI_rctf_size_x(datamask);
+ float ysize = BLI_rctf_size_y(datamask);
+ float xmask = BLI_rcti_size_x(mask);
+ float ymask = BLI_rcti_size_y(mask);
+ GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask));
+ }
+
+ depth_test_enabled = GPU_depth_test_enabled();
+ if (depth_test_enabled) {
+ GPU_depth_test(false);
+ }
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_GRID);
+
+ GPU_logic_op_invert_set(true);
+ imm_drawcircball(t->center_global, t->prop_size, imat, pos);
+ GPU_logic_op_invert_set(false);
+
+ immUnbindProgram();
+
+ if (depth_test_enabled) {
+ GPU_depth_test(true);
+ }
+
+ GPU_matrix_pop();
+ }
+}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_draw.h b/source/blender/editors/transform/transform_draw.h
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/source/blender/editors/transform/transform_draw.h
diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c
new file mode 100644
index 00000000000..b5df1e4e98b
--- /dev/null
+++ b/source/blender/editors/transform/transform_draw_cursors.c
@@ -0,0 +1,340 @@
+/*
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#include "BLI_math.h"
+
+#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_state.h"
+
+#include "BKE_context.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "transform.h"
+#include "transform_draw_cursors.h" /* Own include. */
+
+typedef enum {
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT,
+} ArrowDirection;
+
+#define POS_INDEX 0
+/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions
+ * private to this file - merwin
+ */
+
+static void drawArrow(ArrowDirection d, short offset, short length, short size)
+{
+ immBegin(GPU_PRIM_LINES, 6);
+
+ offset = round_fl_to_short(UI_DPI_FAC * offset);
+ length = round_fl_to_short(UI_DPI_FAC * length);
+ size = round_fl_to_short(UI_DPI_FAC * size);
+
+ switch (d) {
+ 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;
+ }
+
+ immEnd();
+}
+
+static void drawArrowHead(ArrowDirection d, short size)
+{
+ size = round_fl_to_short(UI_DPI_FAC * size);
+
+ immBegin(GPU_PRIM_LINES, 4);
+
+ switch (d) {
+ 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;
+ }
+
+ immEnd();
+}
+
+static void drawArc(float angle_start, float angle_end, int segments, float size)
+{
+ segments = round_fl_to_int(segments * UI_DPI_FAC);
+
+ 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
+ */
+bool transform_draw_cursor_poll(bContext *C)
+{
+ ARegion *ar = CTX_wm_region(C);
+
+ if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Cursor and help-line drawing, callback for:
+ * #WM_paint_cursor_activate
+ */
+void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customdata)
+{
+ TransInfo *t = (TransInfo *)customdata;
+
+ if (t->helpline != HLP_NONE) {
+ 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->ar->winrct.xmin,
+ t->ar->winrct.ymin,
+ };
+
+ for (int i = 0; i < 2; i++) {
+ cent[i] += offset[i];
+ tmval[i] += offset[i];
+ }
+
+ GPU_line_smooth(true);
+ GPU_blend(true);
+
+ 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, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ break;
+ case HLP_HARROW:
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+ GPU_matrix_translate_3fv(mval);
+
+ GPU_line_width(3.0f);
+ drawArrow(RIGHT, 5, 10, 5);
+ drawArrow(LEFT, 5, 10, 5);
+ break;
+ case HLP_VARROW:
+ immUniformThemeColor3(TH_VIEW_OVERLAY);
+
+ GPU_matrix_translate_3fv(mval);
+
+ GPU_line_width(3.0f);
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ 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, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+
+ 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, 5);
+
+ 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, 5);
+ break;
+ }
+ case HLP_TRACKBALL: {
+ unsigned char 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, 5, 10, 5);
+ drawArrow(LEFT, 5, 10, 5);
+
+ UI_make_axis_color(col, col2, 'Y');
+ immUniformColor3ubv(col2);
+
+ drawArrow(UP, 5, 10, 5);
+ drawArrow(DOWN, 5, 10, 5);
+ break;
+ }
+ }
+
+ immUnbindProgram();
+ GPU_matrix_pop();
+
+ GPU_line_smooth(false);
+ GPU_blend(false);
+ }
+}
diff --git a/source/blender/editors/transform/transform_draw_cursors.h b/source/blender/editors/transform/transform_draw_cursors.h
new file mode 100644
index 00000000000..e7696bad5a7
--- /dev/null
+++ b/source/blender/editors/transform/transform_draw_cursors.h
@@ -0,0 +1,31 @@
+/*
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edtransform
+ */
+
+#ifndef __TRANSFORM_DRAW_CURSORS_H__
+#define __TRANSFORM_DRAW_CURSORS_H__
+
+/* Callbacks for #WM_paint_cursor_activate */
+bool transform_draw_cursor_poll(struct bContext *C);
+void transform_draw_cursor_draw(struct bContext *C, int x, int y, void *customdata);
+
+#endif /* __TRANSFORM_DRAW_CURSORS_H__ */