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:
authorSebastian Parborg <darkdefende@gmail.com>2021-10-08 13:09:27 +0300
committerSebastian Parborg <darkdefende@gmail.com>2021-10-08 13:14:45 +0300
commit482806c81678e351ff171c68a757386a5b2d4676 (patch)
tree7f9b1dfccb0683584af937ec77b440cb6ccaa413 /source/blender/editors/transform/transform_gizmo_2d.c
parenta3e2cc0bb7fe47fa1122cd19c4fa8a5aa59f761c (diff)
VSE: Implement the bounding box (xform) tool in the seq preview window
Make the "xform" tool/gizmo available for strip transformations in the sequencer preview window. Because of the amount of hacks needed to make the gizmo work nicely with multiple strips at the same time, it was decided to only show the translate gizmo when multiple strips are selected. This is because the transforms with multiple strips would appear buggy because of our lack of shearing support in the transform system. There is also currently no way to properly sync the gizmo drawing with the transform when using multiple strips. Reviewed By: Richard Antalik, Campbell Barton Differential Revision: http://developer.blender.org/D12729
Diffstat (limited to 'source/blender/editors/transform/transform_gizmo_2d.c')
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c322
1 files changed, 242 insertions, 80 deletions
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index 61119c72ad6..7ba52ec823d 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -173,6 +173,7 @@ typedef struct GizmoGroup2D {
float origin[2];
float min[2];
float max[2];
+ float rotation;
bool no_cage;
@@ -241,7 +242,7 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
}
ScrArea *area = CTX_wm_area(C);
- bool changed = false;
+ bool has_select = false;
if (area->spacetype == SPACE_IMAGE) {
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -249,18 +250,75 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, NULL, &objects_len);
if (ED_uvedit_minmax_multi(scene, objects, objects_len, r_min, r_max)) {
- changed = true;
+ has_select = true;
}
MEM_freeN(objects);
}
+ else if (area->spacetype == SPACE_SEQ) {
+ Scene *scene = CTX_data_scene(C);
+ ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
+ SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
+ SEQ_filter_selected_strips(strips);
+ int selected_strips = SEQ_collection_len(strips);
+ if (selected_strips > 0) {
+ INIT_MINMAX2(r_min, r_max);
+ has_select = true;
- if (changed == false) {
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, strips) {
+ float quad[4][2];
+ SEQ_image_transform_quad_get(scene, seq, selected_strips != 1, quad);
+ for (int i = 0; i < 4; i++) {
+ minmax_v2v2_v2(r_min, r_max, quad[i]);
+ }
+ }
+ }
+ SEQ_collection_free(strips);
+ if (selected_strips > 1) {
+ /* Don't draw the cage as transforming multiple strips isn't currently very useful as it
+ * doesn't behave as one would expect.
+ *
+ * This is because our current transform system doesn't support shearing which would make the
+ * scaling transforms of the bounding box behave weirdly.
+ * In addition to this, the rotation of the bounding box can not currently be hooked up
+ * properly to read the result from the transform system (when transforming multiple strips).
+ */
+ mid_v2_v2v2(r_center, r_min, r_max);
+ zero_v2(r_min);
+ zero_v2(r_max);
+ return has_select;
+ }
+ }
+
+ if (has_select == false) {
zero_v2(r_min);
zero_v2(r_max);
}
mid_v2_v2v2(r_center, r_min, r_max);
- return changed;
+ return has_select;
+}
+
+static int gizmo2d_calc_transform_orientation(const bContext *C)
+{
+ ScrArea *area = CTX_wm_area(C);
+ if (area->spacetype != SPACE_SEQ) {
+ return V3D_ORIENT_GLOBAL;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+ Editing *ed = SEQ_editing_get(scene);
+ ListBase *seqbase = SEQ_active_seqbase_get(ed);
+ SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
+ SEQ_filter_selected_strips(strips);
+
+ bool use_local_orient = SEQ_collection_len(strips) == 1;
+ SEQ_collection_free(strips);
+
+ if (use_local_orient) {
+ return V3D_ORIENT_LOCAL;
+ }
+ return V3D_ORIENT_GLOBAL;
}
static float gizmo2d_calc_rotation(const bContext *C)
@@ -276,9 +334,10 @@ static float gizmo2d_calc_rotation(const bContext *C)
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
SEQ_filter_selected_strips(strips);
- Sequence *seq;
- SEQ_ITERATOR_FOREACH (seq, strips) {
- if (seq == ed->act_seq) {
+ if (SEQ_collection_len(strips) == 1) {
+ /* Only return the strip rotation if only one is selected. */
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, strips) {
StripTransform *transform = seq->strip->transform;
float mirror[2];
SEQ_image_transform_mirror_factor_get(seq, mirror);
@@ -436,17 +495,17 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup
ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X, ot_resize, NULL);
PropertyRNA *prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
PropertyRNA *prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
- RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_x);
RNA_property_boolean_set(ptr, prop_release_confirm, true);
- ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X, ot_resize, NULL);
RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_x);
+ ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X, ot_resize, NULL);
RNA_property_boolean_set(ptr, prop_release_confirm, true);
+ RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_x);
ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y, ot_resize, NULL);
- RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_y);
RNA_property_boolean_set(ptr, prop_release_confirm, true);
- ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y, ot_resize, NULL);
RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_y);
+ ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y, ot_resize, NULL);
RNA_property_boolean_set(ptr, prop_release_confirm, true);
+ RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint_y);
ptr = WM_gizmo_operator_set(
ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y, ot_resize, NULL);
@@ -465,87 +524,51 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup
}
}
-static void gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup)
+static void rotate_around_center_v2(float point[2], const float center[2], const float angle)
{
- gizmo2d_xform_setup(C, gzgroup);
- GizmoGroup2D *ggd = gzgroup->customdata;
- ggd->no_cage = true;
+ float tmp[2];
+
+ sub_v2_v2v2(tmp, point, center);
+ rotate_v2_v2fl(point, tmp, angle);
+ add_v2_v2(point, center);
}
static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
GizmoGroup2D *ggd = gzgroup->customdata;
- float origin[3];
bool has_select;
if (ggd->no_cage) {
- has_select = gizmo2d_calc_center(C, origin);
+ has_select = gizmo2d_calc_center(C, ggd->origin);
}
else {
- has_select = gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max);
+ has_select = gizmo2d_calc_bounds(C, ggd->origin, ggd->min, ggd->max);
+ ggd->rotation = gizmo2d_calc_rotation(C);
}
- copy_v2_v2(ggd->origin, origin);
+
bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max);
if (has_select == false) {
+ /* Nothing selected. Disable gizmo drawing and return. */
+ ggd->cage->flag |= WM_GIZMO_HIDDEN;
for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
ggd->translate_xy[i]->flag |= WM_GIZMO_HIDDEN;
}
- ggd->cage->flag |= WM_GIZMO_HIDDEN;
+ return;
}
- else {
- if (show_cage) {
- ggd->cage->flag &= ~WM_GIZMO_HIDDEN;
- for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
- wmGizmo *gz = ggd->translate_xy[i];
- gz->flag |= WM_GIZMO_HIDDEN;
- }
- }
- else {
- ggd->cage->flag |= WM_GIZMO_HIDDEN;
- for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
- wmGizmo *gz = ggd->translate_xy[i];
- gz->flag &= ~WM_GIZMO_HIDDEN;
- }
- }
- if (show_cage) {
- wmGizmoOpElem *gzop;
- float mid[2];
- const float *min = ggd->min;
- const float *max = ggd->max;
- mid_v2_v2v2(mid, min, max);
-
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X);
- PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f});
-
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f});
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f});
-
- gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE);
- RNA_property_float_set_array(
- &gzop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f});
+ if (!show_cage) {
+ /* Disable cage gizmo drawing and return. */
+ ggd->cage->flag |= WM_GIZMO_HIDDEN;
+ for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
+ ggd->translate_xy[i]->flag &= ~WM_GIZMO_HIDDEN;
}
+ return;
+ }
+
+ /* We will show the cage gizmo! Setup all necessary data. */
+ ggd->cage->flag &= ~WM_GIZMO_HIDDEN;
+ for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
+ ggd->translate_xy[i]->flag |= WM_GIZMO_HIDDEN;
}
}
@@ -554,7 +577,6 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
ARegion *region = CTX_wm_region(C);
GizmoGroup2D *ggd = gzgroup->customdata;
float origin[3] = {UNPACK2(ggd->origin), 0.0f};
- const float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f};
gizmo2d_origin_to_region(region, origin);
@@ -564,19 +586,128 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
}
UI_view2d_view_to_region_m4(&region->v2d, ggd->cage->matrix_space);
- WM_gizmo_set_matrix_offset_location(ggd->cage, origin_aa);
+ /* Define the bounding box of the gizmo in the offset transform matrix. */
+ unit_m4(ggd->cage->matrix_offset);
ggd->cage->matrix_offset[0][0] = (ggd->max[0] - ggd->min[0]);
ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]);
+
+ ScrArea *area = CTX_wm_area(C);
+
+ if (area->spacetype == SPACE_SEQ) {
+ gizmo2d_calc_center(C, origin);
+
+ float matrix_rotate[4][4];
+ unit_m4(matrix_rotate);
+ copy_v3_v3(matrix_rotate[3], origin);
+ rotate_m4(matrix_rotate, 'Z', ggd->rotation);
+ unit_m4(ggd->cage->matrix_basis);
+ mul_m4_m4m4(ggd->cage->matrix_basis, matrix_rotate, ggd->cage->matrix_basis);
+
+ float mid[2];
+ sub_v2_v2v2(mid, origin, ggd->origin);
+ mul_v2_fl(mid, -1.0f);
+ copy_v2_v2(ggd->cage->matrix_offset[3], mid);
+ }
+ else {
+ const float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f};
+ WM_gizmo_set_matrix_offset_location(ggd->cage, origin_aa);
+ }
}
-static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C,
- struct wmGizmoGroup *gzgroup,
- struct wmMsgBus *mbus)
+static void gizmo2d_xform_invoke_prepare(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ wmGizmo *UNUSED(gz),
+ const wmEvent *UNUSED(event))
{
- bScreen *screen = CTX_wm_screen(C);
+ GizmoGroup2D *ggd = gzgroup->customdata;
+ wmGizmoOpElem *gzop;
+ const float *mid = ggd->origin;
+ const float *min = ggd->min;
+ const float *max = ggd->max;
+
+ /* Define the different transform center points that will be used when grabbing the corners or
+ * rotating with the gizmo.
+ *
+ * The coordinates are referred to as their cardinal directions:
+ * N
+ * o
+ *NW | NE
+ * x-----------x
+ * | |
+ *W| C |E
+ * | |
+ * x-----------x
+ *SW S SE
+ */
+ float n[3] = {mid[0], max[1], 0.0f};
+ float w[3] = {min[0], mid[1], 0.0f};
+ float e[3] = {max[0], mid[1], 0.0f};
+ float s[3] = {mid[0], min[1], 0.0f};
+
+ float nw[3] = {min[0], max[1], 0.0f};
+ float ne[3] = {max[0], max[1], 0.0f};
+ float sw[3] = {min[0], min[1], 0.0f};
+ float se[3] = {max[0], min[1], 0.0f};
+
+ float c[3] = {mid[0], mid[1], 0.0f};
+
+ float orient_matrix[3][3];
+ unit_m3(orient_matrix);
+
ScrArea *area = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
- gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, area, region);
+
+ if (ggd->rotation != 0.0f && area->spacetype == SPACE_SEQ) {
+ float origin[3];
+ gizmo2d_calc_center(C, origin);
+ /* We need to rotate the cardinal points so they align with the rotated bounding box. */
+
+ rotate_around_center_v2(n, origin, ggd->rotation);
+ rotate_around_center_v2(w, origin, ggd->rotation);
+ rotate_around_center_v2(e, origin, ggd->rotation);
+ rotate_around_center_v2(s, origin, ggd->rotation);
+
+ rotate_around_center_v2(nw, origin, ggd->rotation);
+ rotate_around_center_v2(ne, origin, ggd->rotation);
+ rotate_around_center_v2(sw, origin, ggd->rotation);
+ rotate_around_center_v2(se, origin, ggd->rotation);
+
+ rotate_around_center_v2(c, origin, ggd->rotation);
+
+ rotate_m3(orient_matrix, ggd->rotation);
+ }
+
+ int orient_type = gizmo2d_calc_transform_orientation(C);
+
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X);
+ PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
+ PropertyRNA *prop_mouse_dir = RNA_struct_find_property(&gzop->ptr, "mouse_dir_constraint");
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, e);
+ RNA_property_float_set_array(&gzop->ptr, prop_mouse_dir, orient_matrix[0]);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_type);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, w);
+ RNA_property_float_set_array(&gzop->ptr, prop_mouse_dir, orient_matrix[0]);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_type);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, n);
+ RNA_property_float_set_array(&gzop->ptr, prop_mouse_dir, orient_matrix[1]);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_type);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, s);
+ RNA_property_float_set_array(&gzop->ptr, prop_mouse_dir, orient_matrix[1]);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_type);
+
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, ne);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, se);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, nw);
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, sw);
+
+ gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE);
+ RNA_property_float_set_array(&gzop->ptr, prop_center_override, c);
}
void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt)
@@ -586,6 +717,24 @@ void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt)
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo2d_xform_refresh;
gzgt->draw_prepare = gizmo2d_xform_draw_prepare;
+ gzgt->invoke_prepare = gizmo2d_xform_invoke_prepare;
+}
+
+static void gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup)
+{
+ gizmo2d_xform_setup(C, gzgroup);
+ GizmoGroup2D *ggd = gzgroup->customdata;
+ ggd->no_cage = true;
+}
+
+static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C,
+ struct wmGizmoGroup *gzgroup,
+ struct wmMsgBus *mbus)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+ gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, area, region);
}
void ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set(wmGizmoGroupType *gzgt)
@@ -726,6 +875,18 @@ static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgrou
}
}
+static void gizmo2d_resize_invoke_prepare(const bContext *C,
+ wmGizmoGroup *UNUSED(gzgroup),
+ wmGizmo *gz,
+ const wmEvent *UNUSED(event))
+{
+ wmGizmoOpElem *gzop;
+ int orient_type = gizmo2d_calc_transform_orientation(C);
+
+ gzop = WM_gizmo_operator_get(gz, 0);
+ RNA_enum_set(&gzop->ptr, "orient_type", orient_type);
+}
+
static void gizmo2d_resize_message_subscribe(const struct bContext *C,
struct wmGizmoGroup *gzgroup,
struct wmMsgBus *mbus)
@@ -743,6 +904,7 @@ void ED_widgetgroup_gizmo2d_resize_callbacks_set(wmGizmoGroupType *gzgt)
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo2d_resize_refresh;
gzgt->draw_prepare = gizmo2d_resize_draw_prepare;
+ gzgt->invoke_prepare = gizmo2d_resize_invoke_prepare;
gzgt->message_subscribe = gizmo2d_resize_message_subscribe;
}