Gizmo: use pivot center for UV gizmos
authorCampbell Barton <ideasman42@gmail.com>
Thu, 9 Jan 2020 02:56:45 +0000 (13:56 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 9 Jan 2020 05:42:24 +0000 (16:42 +1100)
source/blender/editors/include/ED_transform.h
source/blender/editors/include/ED_uvedit.h
source/blender/editors/space_image/space_image.c
source/blender/editors/transform/transform_gizmo_2d.c
source/blender/editors/uvedit/uvedit_ops.c

index 29bac9df93a22eab81bfa97094c34adb4437a645..d53ad7c42295fc8469a427b93bc7216e58a29854 100644 (file)
@@ -29,6 +29,7 @@
 struct Object;
 struct bContext;
 struct wmKeyConfig;
+struct wmMsgBus;
 struct wmOperatorType;
 
 void ED_keymap_transform(struct wmKeyConfig *keyconf);
@@ -165,28 +166,11 @@ void VIEW3D_GGT_xform_shear(struct wmGizmoGroupType *gzgt);
 /* *** transform_gizmo_extrude_3d.c *** */
 void VIEW3D_GGT_xform_extrude(struct wmGizmoGroupType *gzgt);
 
-/* Transform: Axis/Cage */
-bool ED_widgetgroup_gizmo2d_xform_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt);
-void ED_widgetgroup_gizmo2d_xform_setup(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_xform_setup_no_cage(const struct bContext *C,
-                                                struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_xform_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_xform_draw_prepare(const struct bContext *C,
-                                               struct wmGizmoGroup *gzgroup);
-
-/* Resize: Axis */
-bool ED_widgetgroup_gizmo2d_resize_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt);
-void ED_widgetgroup_gizmo2d_resize_setup(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_resize_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_resize_draw_prepare(const struct bContext *C,
-                                                struct wmGizmoGroup *gzgroup);
-
-/* Rotate: Axis */
-bool ED_widgetgroup_gizmo2d_rotate_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt);
-void ED_widgetgroup_gizmo2d_rotate_setup(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_rotate_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-void ED_widgetgroup_gizmo2d_rotate_draw_prepare(const struct bContext *C,
-                                                struct wmGizmoGroup *gzgroup);
+/* Generic 2D transform gizmo callback assignment. */
+void ED_widgetgroup_gizmo2d_xform_callbacks_set(struct wmGizmoGroupType *gzgt);
+void ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set(struct wmGizmoGroupType *gzgt);
+void ED_widgetgroup_gizmo2d_resize_callbacks_set(struct wmGizmoGroupType *gzgt);
+void ED_widgetgroup_gizmo2d_rotate_callbacks_set(struct wmGizmoGroupType *gzgt);
 
 #define SNAP_INCREMENTAL_ANGLE DEG2RAD(5.0)
 
index 1f50770eef62d03c853f5a361c3dfafe1085c876..1debdee53e9c199f9d960393742034fe5021646f 100644 (file)
@@ -50,8 +50,6 @@ bool ED_uvedit_minmax(const struct Scene *scene,
                       struct Object *obedit,
                       float min[2],
                       float max[2]);
-bool ED_uvedit_center(
-    const struct Scene *scene, Image *ima, struct Object *obedit, float cent[2], char mode);
 void ED_uvedit_select_all(struct BMesh *bm);
 
 bool ED_uvedit_minmax_multi(const struct Scene *scene,
@@ -67,6 +65,12 @@ bool ED_uvedit_center_multi(const struct Scene *scene,
                             float r_cent[2],
                             char mode);
 
+bool ED_uvedit_center_from_pivot(struct SpaceImage *sima,
+                                 struct Scene *scene,
+                                 struct ViewLayer *view_layer,
+                                 float r_center[2],
+                                 char mode);
+
 bool ED_object_get_active_image(struct Object *ob,
                                 int mat_nr,
                                 struct Image **r_ima,
index 2f93be8ae38212ac5854569f46ac551c3330e75c..57560c560d7958fe17009b02628901e0fbe54392 100644 (file)
@@ -470,11 +470,7 @@ static void IMAGE_GGT_gizmo2d(wmGizmoGroupType *gzgt)
   gzgt->gzmap_params.spaceid = SPACE_IMAGE;
   gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
 
-  gzgt->poll = ED_widgetgroup_gizmo2d_xform_poll;
-  gzgt->setup = ED_widgetgroup_gizmo2d_xform_setup;
-  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
-  gzgt->refresh = ED_widgetgroup_gizmo2d_xform_refresh;
-  gzgt->draw_prepare = ED_widgetgroup_gizmo2d_xform_draw_prepare;
+  ED_widgetgroup_gizmo2d_xform_callbacks_set(gzgt);
 }
 
 static void IMAGE_GGT_gizmo2d_translate(wmGizmoGroupType *gzgt)
@@ -488,11 +484,7 @@ static void IMAGE_GGT_gizmo2d_translate(wmGizmoGroupType *gzgt)
   gzgt->gzmap_params.spaceid = SPACE_IMAGE;
   gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
 
-  gzgt->poll = ED_widgetgroup_gizmo2d_xform_poll;
-  gzgt->setup = ED_widgetgroup_gizmo2d_xform_setup_no_cage;
-  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
-  gzgt->refresh = ED_widgetgroup_gizmo2d_xform_refresh;
-  gzgt->draw_prepare = ED_widgetgroup_gizmo2d_xform_draw_prepare;
+  ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set(gzgt);
 }
 
 static void IMAGE_GGT_gizmo2d_resize(wmGizmoGroupType *gzgt)
@@ -506,11 +498,7 @@ static void IMAGE_GGT_gizmo2d_resize(wmGizmoGroupType *gzgt)
   gzgt->gzmap_params.spaceid = SPACE_IMAGE;
   gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
 
-  gzgt->poll = ED_widgetgroup_gizmo2d_resize_poll;
-  gzgt->setup = ED_widgetgroup_gizmo2d_resize_setup;
-  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
-  gzgt->refresh = ED_widgetgroup_gizmo2d_resize_refresh;
-  gzgt->draw_prepare = ED_widgetgroup_gizmo2d_resize_draw_prepare;
+  ED_widgetgroup_gizmo2d_resize_callbacks_set(gzgt);
 }
 
 static void IMAGE_GGT_gizmo2d_rotate(wmGizmoGroupType *gzgt)
@@ -524,11 +512,7 @@ static void IMAGE_GGT_gizmo2d_rotate(wmGizmoGroupType *gzgt)
   gzgt->gzmap_params.spaceid = SPACE_IMAGE;
   gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
 
-  gzgt->poll = ED_widgetgroup_gizmo2d_rotate_poll;
-  gzgt->setup = ED_widgetgroup_gizmo2d_rotate_setup;
-  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
-  gzgt->refresh = ED_widgetgroup_gizmo2d_rotate_refresh;
-  gzgt->draw_prepare = ED_widgetgroup_gizmo2d_rotate_draw_prepare;
+  ED_widgetgroup_gizmo2d_rotate_callbacks_set(gzgt);
 }
 
 static void IMAGE_GGT_navigate(wmGizmoGroupType *gzgt)
index e76ece987df61c72c4c5ea1122352c595565d52c..dc8d820b0755630a5b9519b6842b7c326184cf26 100644 (file)
@@ -44,6 +44,7 @@
 #include "WM_api.h"
 #include "WM_types.h"
 #include "wm.h" /* XXX */
+#include "WM_message.h"
 
 #include "ED_image.h"
 #include "ED_screen.h"
 
 #include "transform.h" /* own include */
 
+/* -------------------------------------------------------------------- */
+/** \name Shared Callback's
+ */
+
+static void gizmo2d_pivot_point_message_subscribe(struct wmGizmoGroup *gzgroup,
+                                                  struct wmMsgBus *mbus,
+                                                  /* Additional args. */
+                                                  bScreen *screen,
+                                                  ScrArea *sa,
+                                                  ARegion *ar)
+{
+  wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = {
+      .owner = ar,
+      .user_data = gzgroup->parent_gzmap,
+      .notify = WM_gizmo_do_msg_notify_tag_refresh,
+  };
+
+  switch (sa->spacetype) {
+    case SPACE_IMAGE: {
+      SpaceImage *sima = sa->spacedata.first;
+      PointerRNA ptr;
+      RNA_pointer_create(&screen->id, &RNA_SpaceImageEditor, sima, &ptr);
+      {
+        extern PropertyRNA rna_SpaceImageEditor_pivot_point;
+        extern PropertyRNA rna_SpaceImageEditor_cursor_location;
+        const PropertyRNA *props[] = {
+            &rna_SpaceImageEditor_pivot_point,
+            (sima->around == V3D_AROUND_CURSOR) ? &rna_SpaceImageEditor_cursor_location : NULL,
+        };
+        for (int i = 0; i < ARRAY_SIZE(props); i++) {
+          if (props[i] == NULL) {
+            continue;
+          }
+          WM_msg_subscribe_rna(mbus, &ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__);
+        }
+      }
+      break;
+    }
+  }
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Arrow / Cage Gizmo Group
  *
  * Defines public functions, not the gizmo it's self:
  *
- * - #ED_widgetgroup_gizmo2d_xform_setup
- * - #ED_widgetgroup_gizmo2d_xform_refresh
- * - #ED_widgetgroup_gizmo2d_xform_draw_prepare
- * - #ED_widgetgroup_gizmo2d_xform_poll
+ * - #ED_widgetgroup_gizmo2d_xform_callbacks_set
+ * - #ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set
  *
  * \{ */
 
@@ -150,12 +192,13 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
   ScrArea *sa = CTX_wm_area(C);
   if (sa->spacetype == SPACE_IMAGE) {
     SpaceImage *sima = sa->spacedata.first;
+    Scene *scene = CTX_data_scene(C);
     ViewLayer *view_layer = CTX_data_view_layer(C);
     Image *ima = ED_space_image(sima);
     uint objects_len = 0;
     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(CTX_data_scene(C), ima, objects, objects_len, r_min, r_max)) {
+    if (!ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) {
       zero_v2(r_min);
       zero_v2(r_max);
     }
@@ -168,6 +211,18 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
   mid_v2_v2v2(r_center, r_min, r_max);
 }
 
+static void gizmo2d_calc_center(const bContext *C, float r_center[2])
+{
+  ScrArea *sa = CTX_wm_area(C);
+  zero_v2(r_center);
+  if (sa->spacetype == SPACE_IMAGE) {
+    SpaceImage *sima = sa->spacedata.first;
+    Scene *scene = CTX_data_scene(C);
+    ViewLayer *view_layer = CTX_data_view_layer(C);
+    ED_uvedit_center_from_pivot(sima, scene, view_layer, r_center, sima->around);
+  }
+}
+
 /**
  * Convert origin (or any other point) from view to region space.
  */
@@ -187,7 +242,7 @@ static int gizmo2d_modal(bContext *C,
   ARegion *ar = CTX_wm_region(C);
   float origin[3];
 
-  gizmo2d_calc_bounds(C, origin, NULL, NULL);
+  gizmo2d_calc_center(C, origin);
   gizmo2d_origin_to_region(ar, origin);
   WM_gizmo_set_matrix_location(widget, origin);
 
@@ -196,7 +251,7 @@ static int gizmo2d_modal(bContext *C,
   return OPERATOR_RUNNING_MODAL;
 }
 
-void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
 {
   wmOperatorType *ot_translate = WM_operatortype_find("TRANSFORM_OT_translate", true);
   GizmoGroup2D *ggd = gizmogroup2d_init(gzgroup);
@@ -299,18 +354,23 @@ void ED_widgetgroup_gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup
   }
 }
 
-void ED_widgetgroup_gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_xform_setup_no_cage(const bContext *C, wmGizmoGroup *gzgroup)
 {
-  ED_widgetgroup_gizmo2d_xform_setup(C, gzgroup);
+  gizmo2d_xform_setup(C, gzgroup);
   GizmoGroup2D *ggd = gzgroup->customdata;
   ggd->no_cage = true;
 }
 
-void ED_widgetgroup_gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
 {
   GizmoGroup2D *ggd = gzgroup->customdata;
   float origin[3];
-  gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max);
+  if (ggd->no_cage) {
+    gizmo2d_calc_center(C, origin);
+  }
+  else {
+    gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max);
+  }
   copy_v2_v2(ggd->origin, origin);
   bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max);
 
@@ -379,7 +439,7 @@ void ED_widgetgroup_gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgro
   }
 }
 
-void ED_widgetgroup_gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
 {
   ARegion *ar = CTX_wm_region(C);
   GizmoGroup2D *ggd = gzgroup->customdata;
@@ -403,7 +463,7 @@ void ED_widgetgroup_gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *
  * - Called on every redraw, better to do a more simple poll and check for selection in _refresh
  * - UV editing only, could be expanded for other things.
  */
-bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
 {
   if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) {
     return false;
@@ -439,6 +499,32 @@ bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUS
   return false;
 }
 
+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 *sa = CTX_wm_area(C);
+  ARegion *ar = CTX_wm_region(C);
+  gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar);
+}
+
+void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt)
+{
+  gzgt->poll = gizmo2d_xform_poll;
+  gzgt->setup = gizmo2d_xform_setup;
+  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
+  gzgt->refresh = gizmo2d_xform_refresh;
+  gzgt->draw_prepare = gizmo2d_xform_draw_prepare;
+}
+
+void ED_widgetgroup_gizmo2d_xform_no_cage_callbacks_set(wmGizmoGroupType *gzgt)
+{
+  ED_widgetgroup_gizmo2d_xform_callbacks_set(gzgt);
+  gzgt->setup = gizmo2d_xform_setup_no_cage;
+  gzgt->message_subscribe = gizmo2d_xform_no_cage_message_subscribe;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -446,10 +532,7 @@ bool ED_widgetgroup_gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *UNUS
  *
  * Defines public functions, not the gizmo it's self:
  *
- * - #ED_widgetgroup_gizmo2d_resize_setup
- * - #ED_widgetgroup_gizmo2d_resize_refresh
- * - #ED_widgetgroup_gizmo2d_resize_draw_prepare
- * - #ED_widgetgroup_gizmo2d_resize_poll
+ * - #ED_widgetgroup_gizmo2d_resize_callbacks_set
  *
  * \{ */
 
@@ -472,15 +555,15 @@ static GizmoGroup_Resize2D *gizmogroup2d_resize_init(wmGizmoGroup *gzgroup)
   return ggd;
 }
 
-void ED_widgetgroup_gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup)
 {
   GizmoGroup_Resize2D *ggd = gzgroup->customdata;
   float origin[3];
-  gizmo2d_calc_bounds(C, origin, NULL, NULL);
+  gizmo2d_calc_center(C, origin);
   copy_v2_v2(ggd->origin, origin);
 }
 
-void ED_widgetgroup_gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
 {
   ARegion *ar = CTX_wm_region(C);
   GizmoGroup_Resize2D *ggd = gzgroup->customdata;
@@ -504,12 +587,12 @@ void ED_widgetgroup_gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup
   }
 }
 
-bool ED_widgetgroup_gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
 {
-  return ED_widgetgroup_gizmo2d_xform_poll(C, NULL);
+  return gizmo2d_xform_poll(C, NULL);
 }
 
-void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
 {
 
   wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
@@ -566,6 +649,26 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup
   }
 }
 
+static void gizmo2d_resize_message_subscribe(const struct bContext *C,
+                                             struct wmGizmoGroup *gzgroup,
+                                             struct wmMsgBus *mbus)
+{
+  bScreen *screen = CTX_wm_screen(C);
+  ScrArea *sa = CTX_wm_area(C);
+  ARegion *ar = CTX_wm_region(C);
+  gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar);
+}
+
+void ED_widgetgroup_gizmo2d_resize_callbacks_set(wmGizmoGroupType *gzgt)
+{
+  gzgt->poll = gizmo2d_resize_poll;
+  gzgt->setup = gizmo2d_resize_setup;
+  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
+  gzgt->refresh = gizmo2d_resize_refresh;
+  gzgt->draw_prepare = gizmo2d_resize_draw_prepare;
+  gzgt->message_subscribe = gizmo2d_resize_message_subscribe;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -574,9 +677,6 @@ void ED_widgetgroup_gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup
  * Defines public functions, not the gizmo it's self:
  *
  * - #ED_widgetgroup_gizmo2d_rotate_setup
- * - #ED_widgetgroup_gizmo2d_rotate_refresh
- * - #ED_widgetgroup_gizmo2d_rotate_draw_prepare
- * - #ED_widgetgroup_gizmo2d_rotate_poll
  *
  * \{ */
 
@@ -596,15 +696,15 @@ static GizmoGroup_Rotate2D *gizmogroup2d_rotate_init(wmGizmoGroup *gzgroup)
   return ggd;
 }
 
-void ED_widgetgroup_gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup)
 {
   GizmoGroup_Rotate2D *ggd = gzgroup->customdata;
   float origin[3];
-  gizmo2d_calc_bounds(C, origin, NULL, NULL);
+  gizmo2d_calc_center(C, origin);
   copy_v2_v2(ggd->origin, origin);
 }
 
-void ED_widgetgroup_gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
+static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
 {
   ARegion *ar = CTX_wm_region(C);
   GizmoGroup_Rotate2D *ggd = gzgroup->customdata;
@@ -626,12 +726,12 @@ void ED_widgetgroup_gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup
   WM_gizmo_set_matrix_location(gz, origin);
 }
 
-bool ED_widgetgroup_gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
+static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
 {
-  return ED_widgetgroup_gizmo2d_xform_poll(C, NULL);
+  return gizmo2d_xform_poll(C, NULL);
 }
 
-void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
 {
 
   wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_rotate", true);
@@ -663,4 +763,24 @@ void ED_widgetgroup_gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup
   }
 }
 
+static void gizmo2d_rotate_message_subscribe(const struct bContext *C,
+                                             struct wmGizmoGroup *gzgroup,
+                                             struct wmMsgBus *mbus)
+{
+  bScreen *screen = CTX_wm_screen(C);
+  ScrArea *sa = CTX_wm_area(C);
+  ARegion *ar = CTX_wm_region(C);
+  gizmo2d_pivot_point_message_subscribe(gzgroup, mbus, screen, sa, ar);
+}
+
+void ED_widgetgroup_gizmo2d_rotate_callbacks_set(wmGizmoGroupType *gzgt)
+{
+  gzgt->poll = gizmo2d_rotate_poll;
+  gzgt->setup = gizmo2d_rotate_setup;
+  gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
+  gzgt->refresh = gizmo2d_rotate_refresh;
+  gzgt->draw_prepare = gizmo2d_rotate_draw_prepare;
+  gzgt->message_subscribe = gizmo2d_rotate_message_subscribe;
+}
+
 /** \} */
index d74bb048404197528bb0e1e48f18d8750f952d28..2b26151af8604c377ff3d68a9d1ac2709f47d008 100644 (file)
@@ -81,6 +81,7 @@
 
 #include "WM_api.h"
 #include "WM_types.h"
+#include "WM_message.h"
 
 #include "UI_interface.h"
 #include "UI_resources.h"
@@ -729,14 +730,6 @@ static bool ED_uvedit_median_multi(
   return (sel != 0);
 }
 
-static bool UNUSED_FUNCTION(ED_uvedit_median)(Scene *scene,
-                                              Image *ima,
-                                              Object *obedit,
-                                              float co[2])
-{
-  return ED_uvedit_median_multi(scene, ima, &obedit, 1, co);
-}
-
 bool ED_uvedit_center_multi(const Scene *scene,
                             Image *ima,
                             Object **objects_edit,
@@ -762,9 +755,26 @@ bool ED_uvedit_center_multi(const Scene *scene,
   return changed;
 }
 
-bool ED_uvedit_center(const Scene *scene, Image *ima, Object *obedit, float cent[2], char mode)
+bool ED_uvedit_center_from_pivot(
+    SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode)
 {
-  return ED_uvedit_center_multi(scene, ima, &obedit, 1, cent, mode);
+  bool changed = false;
+  switch (mode) {
+    case V3D_AROUND_CURSOR: {
+      copy_v2_v2(r_center, sima->cursor);
+      changed = true;
+      break;
+    }
+    default: {
+      uint objects_len = 0;
+      Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+          view_layer, ((View3D *)NULL), &objects_len);
+      changed = ED_uvedit_center_multi(scene, sima->image, objects, objects_len, r_center, mode);
+      MEM_freeN(objects);
+      break;
+    }
+  }
+  return changed;
 }
 
 /** \} */
@@ -4911,6 +4921,12 @@ static int uv_set_2d_cursor_exec(bContext *C, wmOperator *op)
 
   RNA_float_get_array(op->ptr, "location", sima->cursor);
 
+  {
+    struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+    bScreen *screen = CTX_wm_screen(C);
+    WM_msg_publish_rna_prop(mbus, &screen->id, sima, SpaceImageEditor, cursor_location);
+  }
+
   WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
 
   return OPERATOR_FINISHED;