gimp r26354 - in trunk: . app/core app/display



Author: martinn
Date: Sun Aug  3 11:35:53 2008
New Revision: 26354
URL: http://svn.gnome.org/viewvc/gimp?rev=26354&view=rev

Log:
2008-08-03  Martin Nordholts  <martinn svn gnome org>

	Further work for completing bug #362915 that makes changes to the
	image size (e.g when cropping) be much more nicely handled by
	display shell.

	* app/core/gimpimage.[ch]: Add new signal
	GimpImage::size-changed-detailed that is emited whenever
	GimpViewable::size-changed is. The new signal provides additional
	information, namely the previous origin relative to the current
	origin. Cliens choose what specific signal to listen to depending
	on how much info they need.

	* app/display/gimpdisplayshell-handlers.c: Connect to
	GimpImage::size-changed-detailed instead of
	GimpViewable::size-changed since the shell wants information about
	the previous image origin.
	(gimp_display_shell_resolution_changed_handler): Use
	gimp_display_shell_scale_resize() instead to avoid display
	garbage.

	* app/display/gimpdisplayshell-scale.[ch]: Add new utility
	function gimp_display_shell_center_image_on_next_size_allocate().

	* app/display/gimpdisplayshell-scroll.[ch]
	(gimp_display_shell_handle_size_changed_detailed): New function
	that replaces logic in gimp_display_shell_handle_size_changed and
	that takes previous-origin of the image into account and adjusts
	the offset so that the image content that remains doesn't move. If
	the window is resized on image resize, just center the image
	afterwards.

	* app/core/gimpimage-undo-push.[ch]
	(gimp_image_undo_push_image_size): Add previous-origin paremeters.

	* app/core/gimpimageundo.[ch]: Add and manage previous-origin
	properties so that the display shell offset can be appropriately
	adjusted also when undoing.

	* app/core/gimpundo.h
	* app/core/gimpimage-undo.c: Add previous_origin members to the
	undo accumulator and emit that information when the size of the
	image changes due to the undo.

	* app/core/gimpimage-crop.c (gimp_image_crop)
	* app/core/gimpimage-scale.c (gimp_image_scale)
	* app/core/gimpimage-rotate.c (gimp_image_rotate)
	* app/core/gimpimage-resize.c (gimp_image_resize_with_layers):
	Supply information about the previous-origin of the image to the
	size-changed signals and the undo system.


Modified:
   trunk/ChangeLog
   trunk/app/core/gimpimage-crop.c
   trunk/app/core/gimpimage-resize.c
   trunk/app/core/gimpimage-rotate.c
   trunk/app/core/gimpimage-scale.c
   trunk/app/core/gimpimage-undo-push.c
   trunk/app/core/gimpimage-undo-push.h
   trunk/app/core/gimpimage-undo.c
   trunk/app/core/gimpimage.c
   trunk/app/core/gimpimage.h
   trunk/app/core/gimpimageundo.c
   trunk/app/core/gimpimageundo.h
   trunk/app/core/gimpundo.h
   trunk/app/display/gimpdisplayshell-handlers.c
   trunk/app/display/gimpdisplayshell-scale.c
   trunk/app/display/gimpdisplayshell-scale.h
   trunk/app/display/gimpdisplayshell-scroll.c
   trunk/app/display/gimpdisplayshell-scroll.h

Modified: trunk/app/core/gimpimage-crop.c
==============================================================================
--- trunk/app/core/gimpimage-crop.c	(original)
+++ trunk/app/core/gimpimage-crop.c	Sun Aug  3 11:35:53 2008
@@ -129,7 +129,7 @@
                                      _("Resize Image"));
 
       /*  Push the image size to the stack  */
-      gimp_image_undo_push_image_size (image, NULL);
+      gimp_image_undo_push_image_size (image, NULL, x1, y1);
 
       /*  Set the new width and height  */
       g_object_set (image,
@@ -267,7 +267,8 @@
                          gimp_image_get_width  (image),
                          gimp_image_get_height (image));
 
-      gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+      gimp_image_emit_size_changed_signals (image, -x1, -y1);
+
       g_object_thaw_notify (G_OBJECT (image));
     }
 

Modified: trunk/app/core/gimpimage-resize.c
==============================================================================
--- trunk/app/core/gimpimage-resize.c	(original)
+++ trunk/app/core/gimpimage-resize.c	Sun Aug  3 11:35:53 2008
@@ -97,7 +97,7 @@
   old_height = gimp_image_get_height (image);
 
   /*  Push the image size to the stack  */
-  gimp_image_undo_push_image_size (image, NULL);
+  gimp_image_undo_push_image_size (image, NULL, -offset_x, -offset_y);
 
   /*  Set the new width and height  */
   g_object_set (image,
@@ -220,7 +220,8 @@
 
   gimp_image_undo_group_end (image);
 
-  gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+  gimp_image_emit_size_changed_signals (image, offset_x, offset_y);
+
   g_object_thaw_notify (G_OBJECT (image));
 
   gimp_unset_busy (image->gimp);

Modified: trunk/app/core/gimpimage-rotate.c
==============================================================================
--- trunk/app/core/gimpimage-rotate.c	(original)
+++ trunk/app/core/gimpimage-rotate.c	Sun Aug  3 11:35:53 2008
@@ -61,6 +61,8 @@
   gdouble   progress_current = 1.0;
   gint      new_image_width;
   gint      new_image_height;
+  gint      offset_x;
+  gint      offset_y;
   gboolean  size_changed;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
@@ -89,13 +91,17 @@
       new_image_width  = gimp_image_get_height (image);
       new_image_height = gimp_image_get_width  (image);
       size_changed     = TRUE;
+      offset_x         = (gimp_image_get_width  (image) - new_image_width)  / 2;
+      offset_y         = (gimp_image_get_height (image) - new_image_height) / 2;
       break;
 
     case GIMP_ROTATE_180:
       new_image_width  = gimp_image_get_width  (image);
       new_image_height = gimp_image_get_height (image);
       size_changed     = FALSE;
-     break;
+      offset_x         = 0;
+      offset_y         = 0;
+      break;
 
     default:
       g_assert_not_reached ();
@@ -186,7 +192,7 @@
       gdouble xres;
       gdouble yres;
 
-      gimp_image_undo_push_image_size (image, NULL);
+      gimp_image_undo_push_image_size (image, NULL, offset_x, offset_y);
 
       g_object_set (image,
                     "width",  new_image_width,
@@ -202,7 +208,7 @@
   gimp_image_undo_group_end (image);
 
   if (size_changed)
-    gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+    gimp_image_emit_size_changed_signals (image, -offset_x, -offset_y);
 
   g_object_thaw_notify (G_OBJECT (image));
 

Modified: trunk/app/core/gimpimage-scale.c
==============================================================================
--- trunk/app/core/gimpimage-scale.c	(original)
+++ trunk/app/core/gimpimage-scale.c	Sun Aug  3 11:35:53 2008
@@ -56,6 +56,8 @@
   GList        *remove           = NULL;
   gint          old_width;
   gint          old_height;
+  gint          offset_x;
+  gint          offset_y;
   gdouble       img_scale_w      = 1.0;
   gdouble       img_scale_h      = 1.0;
   gint          progress_steps;
@@ -79,14 +81,17 @@
   gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE,
                                _("Scale Image"));
 
-  /*  Push the image size to the stack  */
-  gimp_image_undo_push_image_size (image, NULL);
-
   old_width   = gimp_image_get_width  (image);
   old_height  = gimp_image_get_height (image);
   img_scale_w = (gdouble) new_width  / (gdouble) old_width;
   img_scale_h = (gdouble) new_height / (gdouble) old_height;
 
+  offset_x = (old_width  - new_width)  / 2;
+  offset_y = (old_height - new_height) / 2;
+
+  /*  Push the image size to the stack  */
+  gimp_image_undo_push_image_size (image, NULL, offset_x, offset_y);
+
   /*  Set the new width and height  */
   g_object_set (image,
                 "width",  new_width,
@@ -207,7 +212,8 @@
 
   g_object_unref (sub_progress);
 
-  gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+  gimp_image_emit_size_changed_signals (image, -offset_x, -offset_y);
+
   g_object_thaw_notify (G_OBJECT (image));
 
   gimp_unset_busy (image->gimp);

Modified: trunk/app/core/gimpimage-undo-push.c
==============================================================================
--- trunk/app/core/gimpimage-undo-push.c	(original)
+++ trunk/app/core/gimpimage-undo-push.c	Sun Aug  3 11:35:53 2008
@@ -80,13 +80,17 @@
 
 GimpUndo *
 gimp_image_undo_push_image_size (GimpImage   *image,
-                                 const gchar *undo_desc)
+                                 const gchar *undo_desc,
+                                 gdouble      previous_origin_x,
+                                 gdouble      previous_origin_y)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
   return gimp_image_undo_push (image, GIMP_TYPE_IMAGE_UNDO,
                                GIMP_UNDO_IMAGE_SIZE, undo_desc,
                                GIMP_DIRTY_IMAGE | GIMP_DIRTY_IMAGE_SIZE,
+                               "previous-origin-x", previous_origin_x,
+                               "previous-origin-y", previous_origin_y,
                                NULL);
 }
 

Modified: trunk/app/core/gimpimage-undo-push.h
==============================================================================
--- trunk/app/core/gimpimage-undo-push.h	(original)
+++ trunk/app/core/gimpimage-undo-push.h	Sun Aug  3 11:35:53 2008
@@ -25,7 +25,9 @@
 GimpUndo * gimp_image_undo_push_image_type          (GimpImage     *image,
                                                      const gchar   *undo_desc);
 GimpUndo * gimp_image_undo_push_image_size          (GimpImage     *image,
-                                                     const gchar   *undo_desc);
+                                                     const gchar   *undo_desc,
+                                                     gdouble        previous_origin_x,
+                                                     gdouble        previous_origin_y);
 GimpUndo * gimp_image_undo_push_image_resolution    (GimpImage     *image,
                                                      const gchar   *undo_desc);
 GimpUndo * gimp_image_undo_push_image_grid          (GimpImage     *image,

Modified: trunk/app/core/gimpimage-undo.c
==============================================================================
--- trunk/app/core/gimpimage-undo.c	(original)
+++ trunk/app/core/gimpimage-undo.c	Sun Aug  3 11:35:53 2008
@@ -381,8 +381,9 @@
         gimp_image_mode_changed (image);
 
       if (accum.size_changed)
-        gimp_viewable_size_changed (GIMP_VIEWABLE (image));
-
+        gimp_image_emit_size_changed_signals (image,
+                                              accum.previous_origin_x,
+                                              accum.previous_origin_y);
       if (accum.resolution_changed)
         gimp_image_resolution_changed (image);
 

Modified: trunk/app/core/gimpimage.c
==============================================================================
--- trunk/app/core/gimpimage.c	(original)
+++ trunk/app/core/gimpimage.c	Sun Aug  3 11:35:53 2008
@@ -88,6 +88,7 @@
   COMPONENT_ACTIVE_CHANGED,
   MASK_CHANGED,
   RESOLUTION_CHANGED,
+  SIZE_CHANGED_DETAILED,
   UNIT_CHANGED,
   QUICK_MASK_CHANGED,
   SELECTION_CONTROL,
@@ -314,6 +315,17 @@
                   gimp_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  gimp_image_signals[SIZE_CHANGED_DETAILED] =
+    g_signal_new ("size-changed-detailed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpImageClass, size_changed_detailed),
+                  NULL, NULL,
+                  gimp_marshal_VOID__DOUBLE_DOUBLE,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_DOUBLE,
+                  G_TYPE_DOUBLE);
+
   gimp_image_signals[UNIT_CHANGED] =
     g_signal_new ("unit-changed",
                   G_TYPE_FROM_CLASS (klass),
@@ -504,6 +516,7 @@
   klass->component_visibility_changed = NULL;
   klass->component_active_changed     = NULL;
   klass->mask_changed                 = NULL;
+  klass->size_changed_detailed        = NULL;
 
   klass->clean                        = NULL;
   klass->dirty                        = NULL;
@@ -1470,7 +1483,7 @@
       image->yresolution = yresolution;
 
       gimp_image_resolution_changed (image);
-      gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+      gimp_image_emit_size_changed_signals (image, 0.0, 0.0);
     }
 }
 
@@ -1793,6 +1806,29 @@
                  sample_point);
 }
 
+/**
+ * gimp_image_size_changed_detailed:
+ * @image:
+ * @previous_origin_x:
+ * @previous_origin_y:
+ *
+ * Emits the size-changed-detailed signal that is typically used to adjust the
+ * position of the image in the display shell on various operations,
+ * e.g. crop.
+ *
+ **/
+void
+gimp_image_size_changed_detailed (GimpImage *image,
+                                  gdouble    previous_origin_x,
+                                  gdouble    previous_origin_y)
+{
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+
+  g_signal_emit (image, gimp_image_signals[SIZE_CHANGED_DETAILED], 0,
+                 previous_origin_x,
+                 previous_origin_y);
+}
+
 void
 gimp_image_colormap_changed (GimpImage *image,
                              gint       color_index)
@@ -1821,6 +1857,21 @@
   g_signal_emit (image, gimp_image_signals[QUICK_MASK_CHANGED], 0);
 }
 
+void
+gimp_image_emit_size_changed_signals (GimpImage *image,
+                                      gdouble    previous_offset_x,
+                                      gdouble    previous_offset_y)
+{
+  /* Emit GimpViewable::size-changed */
+  gimp_viewable_size_changed (GIMP_VIEWABLE (image));
+
+  /* Then emit basically the same signal but with more
+   * details. Clients can choose what signal of these two to listen to
+   * depending on how much info they need.
+   */
+  gimp_image_size_changed_detailed (image, previous_offset_x, previous_offset_y);
+}
+
 
 /*  undo  */
 

Modified: trunk/app/core/gimpimage.h
==============================================================================
--- trunk/app/core/gimpimage.h	(original)
+++ trunk/app/core/gimpimage.h	Sun Aug  3 11:35:53 2008
@@ -216,6 +216,9 @@
                                          GimpSamplePoint      *sample_point);
   void (* sample_point_removed)         (GimpImage            *image,
                                          GimpSamplePoint      *sample_point);
+  void (* size_changed_detailed)        (GimpImage            *image,
+                                         gdouble               previous_origin_x,
+                                         gdouble               previous_origin_y);
   void (* parasite_attached)            (GimpImage            *image,
                                          const gchar          *name);
   void (* parasite_detached)            (GimpImage            *image,
@@ -319,11 +322,19 @@
                                                   GimpSamplePoint    *sample_point);
 void            gimp_image_sample_point_removed  (GimpImage          *image,
                                                   GimpSamplePoint    *sample_point);
+void            gimp_image_size_changed_detailed (GimpImage          *image,
+                                                  gdouble             previous_origin_x,
+                                                  gdouble             previous_origin_y);
 void            gimp_image_colormap_changed      (GimpImage          *image,
                                                   gint                col);
 void            gimp_image_selection_control     (GimpImage          *image,
                                                   GimpSelectionControl  control);
 void            gimp_image_quick_mask_changed    (GimpImage          *image);
+void            gimp_image_emit_size_changed_signals
+                                                 (GimpImage          *image,
+                                                  gdouble             previous_offset_x,
+                                                  gdouble             previous_offset_y);
+
 
 
 /*  undo  */

Modified: trunk/app/core/gimpimageundo.c
==============================================================================
--- trunk/app/core/gimpimageundo.c	(original)
+++ trunk/app/core/gimpimageundo.c	Sun Aug  3 11:35:53 2008
@@ -41,6 +41,8 @@
 enum
 {
   PROP_0,
+  PROP_PREVIOUS_ORIGIN_X,
+  PROP_PREVIOUS_ORIGIN_Y,
   PROP_GRID,
   PROP_PARASITE_NAME
 };
@@ -89,6 +91,20 @@
   undo_class->pop                = gimp_image_undo_pop;
   undo_class->free               = gimp_image_undo_free;
 
+  g_object_class_install_property (object_class, PROP_PREVIOUS_ORIGIN_X,
+                                   g_param_spec_double ("previous-origin-x", NULL, NULL,
+                                                        -G_MAXDOUBLE,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_PREVIOUS_ORIGIN_Y,
+                                   g_param_spec_double ("previous-origin-y", NULL, NULL,
+                                                        -G_MAXDOUBLE,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
   g_object_class_install_property (object_class, PROP_GRID,
                                    g_param_spec_object ("grid", NULL, NULL,
                                                         GIMP_TYPE_GRID,
@@ -176,6 +192,12 @@
 
   switch (property_id)
     {
+    case PROP_PREVIOUS_ORIGIN_X:
+      image_undo->previous_origin_x = g_value_get_double (value);
+      break;
+    case PROP_PREVIOUS_ORIGIN_Y:
+      image_undo->previous_origin_y = g_value_get_double (value);
+      break;
     case PROP_GRID:
       {
         GimpGrid *grid = g_value_get_object (value);
@@ -204,6 +226,12 @@
 
   switch (property_id)
     {
+    case PROP_PREVIOUS_ORIGIN_X:
+      g_value_set_double (value, image_undo->previous_origin_x);
+      break;
+    case PROP_PREVIOUS_ORIGIN_Y:
+      g_value_set_double (value, image_undo->previous_origin_y);
+      break;
     case PROP_GRID:
       g_value_set_object (value, image_undo->grid);
        break;
@@ -265,14 +293,21 @@
 
     case GIMP_UNDO_IMAGE_SIZE:
       {
-        gint width;
-        gint height;
-
-        width  = image_undo->width;
-        height = image_undo->height;
-
-        image_undo->width  = gimp_image_get_width  (image);
-        image_undo->height = gimp_image_get_height (image);
+        gint    width;
+        gint    height;
+        gdouble previous_origin_x;
+        gdouble previous_origin_y;
+
+        width             = image_undo->width;
+        height            = image_undo->height;
+        previous_origin_x = image_undo->previous_origin_x;
+        previous_origin_y = image_undo->previous_origin_y;
+
+        /* Transform to a redo */
+        image_undo->width             = gimp_image_get_width  (image);
+        image_undo->height            = gimp_image_get_height (image);
+        image_undo->previous_origin_x = -previous_origin_x;
+        image_undo->previous_origin_y = -previous_origin_y;
 
         g_object_set (image,
                       "width",  width,
@@ -284,7 +319,11 @@
 
         if (gimp_image_get_width  (image) != image_undo->width ||
             gimp_image_get_height (image) != image_undo->height)
-          accum->size_changed = TRUE;
+          {
+            accum->size_changed      = TRUE;
+            accum->previous_origin_x = previous_origin_x;
+            accum->previous_origin_y = previous_origin_y;
+          }
       }
       break;
 

Modified: trunk/app/core/gimpimageundo.h
==============================================================================
--- trunk/app/core/gimpimageundo.h	(original)
+++ trunk/app/core/gimpimageundo.h	Sun Aug  3 11:35:53 2008
@@ -40,6 +40,8 @@
   GimpImageBaseType  base_type;
   gint               width;
   gint               height;
+  gdouble            previous_origin_x;
+  gdouble            previous_origin_y;
   gdouble            xresolution;
   gdouble            yresolution;
   GimpUnit           resolution_unit;

Modified: trunk/app/core/gimpundo.h
==============================================================================
--- trunk/app/core/gimpundo.h	(original)
+++ trunk/app/core/gimpundo.h	Sun Aug  3 11:35:53 2008
@@ -27,6 +27,8 @@
 {
   gboolean mode_changed;
   gboolean size_changed;
+  gdouble  previous_origin_x;
+  gdouble  previous_origin_y;
   gboolean resolution_changed;
   gboolean unit_changed;
   gboolean quick_mask_changed;

Modified: trunk/app/display/gimpdisplayshell-handlers.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-handlers.c	(original)
+++ trunk/app/display/gimpdisplayshell-handlers.c	Sun Aug  3 11:35:53 2008
@@ -43,6 +43,7 @@
 #include "gimpdisplayshell-handlers.h"
 #include "gimpdisplayshell-icon.h"
 #include "gimpdisplayshell-scale.h"
+#include "gimpdisplayshell-scroll.h"
 #include "gimpdisplayshell-selection.h"
 #include "gimpdisplayshell-title.h"
 
@@ -64,7 +65,10 @@
 static void   gimp_display_shell_selection_control_handler  (GimpImage        *image,
                                                              GimpSelectionControl control,
                                                              GimpDisplayShell *shell);
-static void   gimp_display_shell_size_changed_handler       (GimpImage        *image,
+static void   gimp_display_shell_size_changed_detailed_handler
+                                                            (GimpImage        *image,
+                                                             gdouble           previous_origin_x,
+                                                             gdouble           previous_origin_y,
                                                              GimpDisplayShell *shell);
 static void   gimp_display_shell_resolution_changed_handler (GimpImage        *image,
                                                              GimpDisplayShell *shell);
@@ -148,8 +152,8 @@
   g_signal_connect (image, "selection-control",
                     G_CALLBACK (gimp_display_shell_selection_control_handler),
                     shell);
-  g_signal_connect (image, "size-changed",
-                    G_CALLBACK (gimp_display_shell_size_changed_handler),
+  g_signal_connect (image, "size-changed-detailed",
+                    G_CALLBACK (gimp_display_shell_size_changed_detailed_handler),
                     shell);
   g_signal_connect (image, "resolution-changed",
                     G_CALLBACK (gimp_display_shell_resolution_changed_handler),
@@ -338,7 +342,7 @@
                                         gimp_display_shell_resolution_changed_handler,
                                         shell);
   g_signal_handlers_disconnect_by_func (image,
-                                        gimp_display_shell_size_changed_handler,
+                                        gimp_display_shell_size_changed_detailed_handler,
                                         shell);
   g_signal_handlers_disconnect_by_func (image,
                                         gimp_display_shell_selection_control_handler,
@@ -410,15 +414,6 @@
 }
 
 static void
-gimp_display_shell_size_changed_handler (GimpImage        *image,
-                                         GimpDisplayShell *shell)
-{
-  gimp_display_shell_scale_resize (shell,
-                                   shell->display->config->resize_windows_on_resize,
-                                   FALSE);
-}
-
-static void
 gimp_display_shell_resolution_changed_handler (GimpImage        *image,
                                                GimpDisplayShell *shell)
 {
@@ -431,7 +426,13 @@
     }
   else
     {
-      gimp_display_shell_size_changed_handler (image, shell);
+      /* A resolution change has the same effect as a size change from
+       * a display shell point of view. Force a redraw of the display
+       * so that we don't get any display garbage.
+       */
+      gimp_display_shell_scale_resize (shell,
+                                       shell->display->config->resize_windows_on_resize,
+                                       FALSE);
     }
 }
 
@@ -479,6 +480,17 @@
 }
 
 static void
+gimp_display_shell_size_changed_detailed_handler (GimpImage        *image,
+                                                  gdouble           previous_origin_x,
+                                                  gdouble           previous_origin_y,
+                                                  GimpDisplayShell *shell)
+{
+  gimp_display_shell_handle_size_changed_detailed (shell,
+                                                   previous_origin_x,
+                                                   previous_origin_y);
+}
+
+static void
 gimp_display_shell_invalidate_preview_handler (GimpImage        *image,
                                                GimpDisplayShell *shell)
 {

Modified: trunk/app/display/gimpdisplayshell-scale.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-scale.c	(original)
+++ trunk/app/display/gimpdisplayshell-scale.c	Sun Aug  3 11:35:53 2008
@@ -541,6 +541,36 @@
                                       shell->display->config->resize_windows_on_zoom);
 }
 
+static void
+gimp_display_shell_size_allocate_center_image_callback (GimpDisplayShell *shell,
+                                                        GtkAllocation    *allocation,
+                                                        GtkWidget        *canvas)
+{
+  gimp_display_shell_center_image (shell, TRUE, TRUE);
+
+  g_signal_handlers_disconnect_by_func (canvas,
+                                        gimp_display_shell_size_allocate_center_image_callback,
+                                        shell);
+}
+
+/**
+ * gimp_display_shell_center_image_on_next_size_allocate:
+ * @shell:
+ *
+ * Centers the image in the display as soon as the canvas has got its
+ * new size
+ *
+ **/
+void
+gimp_display_shell_center_image_on_next_size_allocate (GimpDisplayShell *shell)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+  g_signal_connect_swapped (shell->canvas, "size-allocate",
+                            G_CALLBACK (gimp_display_shell_size_allocate_center_image_callback),
+                            shell);
+}
+
 /**
  * gimp_display_shell_scale_by_values:
  * @shell:         the #GimpDisplayShell

Modified: trunk/app/display/gimpdisplayshell-scale.h
==============================================================================
--- trunk/app/display/gimpdisplayshell-scale.h	(original)
+++ trunk/app/display/gimpdisplayshell-scale.h	Sun Aug  3 11:35:53 2008
@@ -41,6 +41,8 @@
 void   gimp_display_shell_center_image          (GimpDisplayShell *shell,
                                                  gboolean          horizontally,
                                                  gboolean          vertically);
+void   gimp_display_shell_center_image_on_next_size_allocate
+                                                (GimpDisplayShell *shell);
 void   gimp_display_shell_scale_by_values       (GimpDisplayShell *shell,
                                                  gdouble           scale,
                                                  gint              offset_x,

Modified: trunk/app/display/gimpdisplayshell-scroll.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-scroll.c	(original)
+++ trunk/app/display/gimpdisplayshell-scroll.c	Sun Aug  3 11:35:53 2008
@@ -26,6 +26,8 @@
 
 #include "display-types.h"
 
+#include "config/gimpdisplayconfig.h"
+
 #include "base/tile-manager.h"
 
 #include "core/gimpimage.h"
@@ -203,6 +205,47 @@
 }
 
 /**
+ * gimp_display_shell_handle_size_changed_detailed:
+ * @shell:
+ * @previous_origin_x:
+ * @previous_origin_y:
+ *
+ * On e.g. an image crop we want to avoid repositioning the image
+ * content in the display shell if possible.
+ *
+ **/
+void
+gimp_display_shell_handle_size_changed_detailed (GimpDisplayShell *shell,
+                                                 gdouble           previous_origin_x,
+                                                 gdouble           previous_origin_y)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+  if (shell->display->config->resize_windows_on_resize)
+    {
+      /* If the window is resized just center the image in it when it
+       * has change size
+       */
+      gimp_display_shell_shrink_wrap (shell, FALSE);
+      gimp_display_shell_center_image_on_next_size_allocate (shell);
+    }
+  else
+    {
+      gint scaled_previous_origin_x = SCALEX (shell, previous_origin_x);
+      gint scaled_previous_origin_y = SCALEY (shell, previous_origin_y);
+
+      /* Note that we can't use gimp_display_shell_scroll_private() here
+       * because that would expose the image twice, causing unwanted
+       * flicker.
+       */
+      gimp_display_shell_scale_by_values (shell, gimp_zoom_model_get_factor (shell->zoom),
+                                          shell->offset_x + scaled_previous_origin_x,
+                                          shell->offset_y + scaled_previous_origin_y,
+                                          FALSE);
+    }
+}
+
+/**
  * gimp_display_shell_get_scaled_viewport:
  * @shell:
  * @x:

Modified: trunk/app/display/gimpdisplayshell-scroll.h
==============================================================================
--- trunk/app/display/gimpdisplayshell-scroll.h	(original)
+++ trunk/app/display/gimpdisplayshell-scroll.h	Sun Aug  3 11:35:53 2008
@@ -26,6 +26,10 @@
 
 void       gimp_display_shell_scroll_clamp_offsets             (GimpDisplayShell       *shell);
 
+void       gimp_display_shell_handle_size_changed_detailed     (GimpDisplayShell       *shell,
+                                                                gdouble                 previous_origin_x,
+                                                                gdouble                 previous_origin_y);
+
 void       gimp_display_shell_get_scaled_viewport              (const GimpDisplayShell *shell,
                                                                 gint                   *x,
                                                                 gint                   *y,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]