[gimp/gimp-2-10] app: add "show all" mode to GimpImage



commit 94cdbacca73c8a91a85567970c7f565884fab9e7
Author: Ell <ell_se yahoo com>
Date:   Wed Sep 4 14:31:52 2019 +0300

    app: add "show all" mode to GimpImage
    
    Add a "show all" mode to GimpImage, which, when active, causes the
    image projection's bounding box to be adjusted dynamically to the
    combined bounding box of all layers and the canvas.  This mode is
    controlled through the new gimp_image_{inc,dec}_show_all()
    functions, which should be called by the display; a corresponding
    display toggle will be added in the following commits.
    
    Note that from the user's perspective, "show all" is a display
    mode, rather than an image mode.  The GimpImage "show all" mode is
    therefore merely an implementation detail, and shouldn't have any
    effect on displays that don't use "show all" mode, or the PDB.
    The ability to use the image with or without taking its "show all"
    mode into account will be facilitated by the next commits.

 app/core/gimpimage-private.h |   6 ++
 app/core/gimpimage.c         | 134 +++++++++++++++++++++++++++++++++++++++++--
 app/core/gimpimage.h         |   3 +
 3 files changed, 139 insertions(+), 4 deletions(-)
---
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index 8ffda57b2c..a8fdc2fb61 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -49,6 +49,9 @@ struct _GimpImagePrivate
   GimpPrecision      precision;             /*  image's precision            */
   GimpLayerMode      new_layer_mode;        /*  default mode of new layers   */
 
+  gint               show_all;              /*  render full image content    */
+  GeglRectangle      bounding_box;          /*  image content bounding box   */
+
   guchar            *colormap;              /*  colormap (for indexed)       */
   gint               n_colors;              /*  # of colors (for indexed)    */
   GimpPalette       *palette;               /*  palette of colormap          */
@@ -103,6 +106,9 @@ struct _GimpImagePrivate
   GimpItemTree      *vectors;               /*  the tree of vectors          */
   GSList            *layer_stack;           /*  the layers in MRU order      */
 
+  GQuark             layer_offset_x_handler;
+  GQuark             layer_offset_y_handler;
+  GQuark             layer_bounding_box_handler;
   GQuark             layer_alpha_handler;
   GQuark             channel_name_changed_handler;
   GQuark             channel_color_changed_handler;
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 30875ef3f2..f4960197f5 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -228,6 +228,12 @@ static void     gimp_image_mask_update           (GimpDrawable      *drawable,
                                                   gint               width,
                                                   gint               height,
                                                   GimpImage         *image);
+static void     gimp_image_layer_offset_changed  (GimpDrawable      *drawable,
+                                                  const GParamSpec  *pspec,
+                                                  GimpImage         *image);
+static void     gimp_image_layer_bounding_box_changed
+                                                 (GimpDrawable      *drawable,
+                                                  GimpImage         *image);
 static void     gimp_image_layer_alpha_changed   (GimpDrawable      *drawable,
                                                   GimpImage         *image);
 static void     gimp_image_channel_add           (GimpContainer     *container,
@@ -250,6 +256,8 @@ static void     gimp_image_active_vectors_notify (GimpItemTree      *tree,
                                                   const GParamSpec  *pspec,
                                                   GimpImage         *image);
 
+static void     gimp_image_update_bounding_box   (GimpImage         *image);
+
 
 G_DEFINE_TYPE_WITH_CODE (GimpImage, gimp_image, GIMP_TYPE_VIEWABLE,
                          G_ADD_PRIVATE (GimpImage)
@@ -721,6 +729,12 @@ gimp_image_init (GimpImage *image)
   private->precision           = GIMP_PRECISION_U8_GAMMA;
   private->new_layer_mode      = -1;
 
+  private->show_all            = 0;
+  private->bounding_box.x      = 0;
+  private->bounding_box.y      = 0;
+  private->bounding_box.width  = 0;
+  private->bounding_box.height = 0;
+
   private->colormap            = NULL;
   private->n_colors            = 0;
   private->palette             = NULL;
@@ -774,6 +788,18 @@ gimp_image_init (GimpImage *image)
                             G_CALLBACK (gimp_image_invalidate),
                             image);
 
+  private->layer_offset_x_handler =
+    gimp_container_add_handler (private->layers->container, "notify::offset-x",
+                                G_CALLBACK (gimp_image_layer_offset_changed),
+                                image);
+  private->layer_offset_y_handler =
+    gimp_container_add_handler (private->layers->container, "notify::offset-y",
+                                G_CALLBACK (gimp_image_layer_offset_changed),
+                                image);
+  private->layer_bounding_box_handler =
+    gimp_container_add_handler (private->layers->container, "bounding-box-changed",
+                                G_CALLBACK (gimp_image_layer_bounding_box_changed),
+                                image);
   private->layer_alpha_handler =
     gimp_container_add_handler (private->layers->container, "alpha-changed",
                                 G_CALLBACK (gimp_image_layer_alpha_changed),
@@ -852,6 +878,8 @@ gimp_image_constructed (GObject *object)
 
   private->quick_mask_color = config->quick_mask_color;
 
+  gimp_image_update_bounding_box (image);
+
   if (private->base_type == GIMP_INDEXED)
     gimp_image_colormap_init (image);
 
@@ -1016,6 +1044,12 @@ gimp_image_dispose (GObject *object)
                                         gimp_image_invalidate,
                                         image);
 
+  gimp_container_remove_handler (private->layers->container,
+                                 private->layer_offset_x_handler);
+  gimp_container_remove_handler (private->layers->container,
+                                 private->layer_offset_y_handler);
+  gimp_container_remove_handler (private->layers->container,
+                                 private->layer_bounding_box_handler);
   gimp_container_remove_handler (private->layers->container,
                                  private->layer_alpha_handler);
 
@@ -1237,7 +1271,7 @@ gimp_image_size_changed (GimpViewable *viewable)
 
   gimp_image_metadata_update_pixel_size (image);
 
-  gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
+  gimp_image_update_bounding_box (image);
 }
 
 static gchar *
@@ -1499,9 +1533,7 @@ gimp_image_get_bounding_box (GimpProjectable *projectable)
 {
   GimpImage *image = GIMP_IMAGE (projectable);
 
-  return *GEGL_RECTANGLE (0, 0,
-                          gimp_image_get_width  (image),
-                          gimp_image_get_height (image));
+  return GIMP_IMAGE_GET_PRIVATE (image)->bounding_box;
 }
 
 static GeglNode *
@@ -1563,6 +1595,21 @@ gimp_image_mask_update (GimpDrawable *drawable,
   GIMP_IMAGE_GET_PRIVATE (image)->flush_accum.mask_changed = TRUE;
 }
 
+static void
+gimp_image_layer_offset_changed (GimpDrawable     *drawable,
+                                 const GParamSpec *pspec,
+                                 GimpImage        *image)
+{
+  gimp_image_update_bounding_box (image);
+}
+
+static void
+gimp_image_layer_bounding_box_changed (GimpDrawable *drawable,
+                                       GimpImage    *image)
+{
+  gimp_image_update_bounding_box (image);
+}
+
 static void
 gimp_image_layer_alpha_changed (GimpDrawable *drawable,
                                 GimpImage    *image)
@@ -1666,6 +1713,51 @@ gimp_image_active_vectors_notify (GimpItemTree     *tree,
   g_signal_emit (image, gimp_image_signals[ACTIVE_VECTORS_CHANGED], 0);
 }
 
+static void
+gimp_image_update_bounding_box (GimpImage *image)
+{
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+  GeglRectangle     bounding_box;
+
+  bounding_box.x      = 0;
+  bounding_box.y      = 0;
+  bounding_box.width  = gimp_image_get_width  (image);
+  bounding_box.height = gimp_image_get_height (image);
+
+  if (private->show_all)
+    {
+      GList *iter;
+
+      for (iter = gimp_image_get_layer_iter (image);
+           iter;
+           iter = g_list_next (iter))
+        {
+          GimpLayer     *layer = iter->data;
+          GeglRectangle  layer_bounding_box;
+          gint           offset_x;
+          gint           offset_y;
+
+          gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y);
+
+          layer_bounding_box = gimp_drawable_get_bounding_box (
+            GIMP_DRAWABLE (layer));
+
+          layer_bounding_box.x += offset_x;
+          layer_bounding_box.y += offset_y;
+
+          gegl_rectangle_bounding_box (&bounding_box,
+                                       &bounding_box, &layer_bounding_box);
+        }
+    }
+
+  if (! gegl_rectangle_equal (&bounding_box, &private->bounding_box))
+    {
+      private->bounding_box = bounding_box;
+
+      gimp_projectable_bounds_changed (GIMP_PROJECTABLE (image), 0, 0);
+    }
+}
+
 
 /*  public functions  */
 
@@ -3472,6 +3564,36 @@ gimp_image_inc_instance_count (GimpImage *image)
   GIMP_IMAGE_GET_PRIVATE (image)->instance_count++;
 }
 
+void
+gimp_image_inc_show_all_count (GimpImage *image)
+{
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+
+  GIMP_IMAGE_GET_PRIVATE (image)->show_all++;
+
+  if (GIMP_IMAGE_GET_PRIVATE (image)->show_all == 1)
+    {
+      g_clear_object (&GIMP_IMAGE_GET_PRIVATE (image)->pickable_buffer);
+
+      gimp_image_update_bounding_box (image);
+    }
+}
+
+void
+gimp_image_dec_show_all_count (GimpImage *image)
+{
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+
+  GIMP_IMAGE_GET_PRIVATE (image)->show_all--;
+
+  if (GIMP_IMAGE_GET_PRIVATE (image)->show_all == 0)
+    {
+      g_clear_object (&GIMP_IMAGE_GET_PRIVATE (image)->pickable_buffer);
+
+      gimp_image_update_bounding_box (image);
+    }
+}
+
 
 /*  parasites  */
 
@@ -4392,6 +4514,8 @@ gimp_image_add_layer (GimpImage *image,
   if (old_has_alpha != gimp_image_has_alpha (image))
     private->flush_accum.alpha_changed = TRUE;
 
+  gimp_image_update_bounding_box (image);
+
   return TRUE;
 }
 
@@ -4509,6 +4633,8 @@ gimp_image_remove_layer (GimpImage *image,
   if (old_has_alpha != gimp_image_has_alpha (image))
     private->flush_accum.alpha_changed = TRUE;
 
+  gimp_image_update_bounding_box (image);
+
   if (push_undo)
     gimp_image_undo_group_end (image);
 }
diff --git a/app/core/gimpimage.h b/app/core/gimpimage.h
index 35ffd87a41..caded196a4 100644
--- a/app/core/gimpimage.h
+++ b/app/core/gimpimage.h
@@ -304,6 +304,9 @@ void            gimp_image_dec_display_count     (GimpImage          *image);
 gint            gimp_image_get_instance_count    (GimpImage          *image);
 void            gimp_image_inc_instance_count    (GimpImage          *image);
 
+void            gimp_image_inc_show_all_count    (GimpImage          *image);
+void            gimp_image_dec_show_all_count    (GimpImage          *image);
+
 
 /*  parasites  */
 


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