[gimp] app: new option "Use extents of layer contents" to Align tool.



commit c8547d0a503570fe44887bd2ef7fbdc56a73822c
Author: Jehan <jehan girinstud io>
Date:   Tue Oct 18 00:30:39 2022 +0200

    app: new option "Use extents of layer contents" to Align tool.
    
    Instead of using the layer borders, we use the bounding box for the contents.
    This is similar to first run "Crop to Content" on every selected layer except
    we don't actually need to crop. Therefore we can work on bigger layer than the
    actual content while still arranging them based on content bounds.
    
    So often the result of alignment/distribution feels wrong because it doesn't
    correspond to the content we are seeing. With this option, we'll have the option
    to choose the desired behavior.

 app/core/gimpimage-arrange.c | 51 ++++++++++++++++++++++++++++++++++----------
 app/core/gimpimage-arrange.h |  1 +
 app/tools/gimpalignoptions.c | 43 ++++++++++++++++++++++++++++++++-----
 app/tools/gimpalignoptions.h |  1 +
 app/tools/gimpaligntool.c    |  4 +---
 5 files changed, 81 insertions(+), 19 deletions(-)
---
diff --git a/app/core/gimpimage-arrange.c b/app/core/gimpimage-arrange.c
index e1174fb365..b5945a1034 100644
--- a/app/core/gimpimage-arrange.c
+++ b/app/core/gimpimage-arrange.c
@@ -30,15 +30,19 @@
 #include "gimpimage-undo.h"
 #include "gimpitem.h"
 #include "gimpguide.h"
+#include "gimppickable.h"
+#include "gimppickable-auto-shrink.h"
 
 #include "gimp-intl.h"
 
 
 static GList * sort_by_offset  (GList             *list);
 static void    compute_offsets (GList             *list,
-                                GimpAlignmentType  alignment);
+                                GimpAlignmentType  alignment,
+                                gboolean           align_contents);
 static void    compute_offset  (GObject           *object,
-                                GimpAlignmentType  alignment);
+                                GimpAlignmentType  alignment,
+                                gboolean           align_contents);
 static gint    offset_compare  (gconstpointer      a,
                                 gconstpointer      b);
 
@@ -50,6 +54,7 @@ static gint    offset_compare  (gconstpointer      a,
  * @alignment:            The point on each target object to bring into alignment.
  * @reference:            The #GObject to align the targets with, or %NULL.
  * @reference_alignment:  The point on the reference object to align the target item with..
+ * @align_contents:       Take into account non-empty contents rather than item borders.
  * @offset:               How much to shift the target from perfect alignment..
  *
  * This function shifts the positions of a set of target objects,
@@ -75,6 +80,7 @@ gimp_image_arrange_objects (GimpImage         *image,
                             GimpAlignmentType  alignment,
                             GObject           *reference,
                             GimpAlignmentType  reference_alignment,
+                            gboolean           align_contents,
                             gint               offset)
 {
   gboolean do_x = FALSE;
@@ -93,7 +99,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ALIGN_HCENTER:
     case GIMP_ALIGN_RIGHT:
       do_x = TRUE;
-      compute_offsets (list, GIMP_ALIGN_TOP);
+      compute_offsets (list, GIMP_ALIGN_TOP, align_contents);
       break;
 
       /* order horizontally for horizontal arrangement */
@@ -102,7 +108,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ARRANGE_RIGHT:
     case GIMP_ARRANGE_HFILL:
       do_x = TRUE;
-      compute_offsets (list, alignment);
+      compute_offsets (list, alignment, align_contents);
       break;
 
       /* order horizontally for vertical alignment */
@@ -110,7 +116,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ALIGN_VCENTER:
     case GIMP_ALIGN_BOTTOM:
       do_y = TRUE;
-      compute_offsets (list, GIMP_ALIGN_LEFT);
+      compute_offsets (list, GIMP_ALIGN_LEFT, align_contents);
       break;
 
       /* order vertically for vertical arrangement */
@@ -119,7 +125,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ARRANGE_BOTTOM:
     case GIMP_ARRANGE_VFILL:
       do_y = TRUE;
-      compute_offsets (list, alignment);
+      compute_offsets (list, alignment, align_contents);
       break;
 
     default:
@@ -129,7 +135,7 @@ gimp_image_arrange_objects (GimpImage         *image,
   object_list = sort_by_offset (list);
 
   /* now get offsets used for aligning */
-  compute_offsets (list, alignment);
+  compute_offsets (list, alignment, align_contents);
 
   if (reference == NULL)
     {
@@ -139,7 +145,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     }
   else
     {
-      compute_offset (reference, reference_alignment);
+      compute_offset (reference, reference_alignment, FALSE);
     }
 
   z0 = GPOINTER_TO_INT (g_object_get_data (reference, "align-offset"));
@@ -266,17 +272,19 @@ offset_compare (gconstpointer a,
  */
 static void
 compute_offsets (GList             *list,
-                 GimpAlignmentType  alignment)
+                 GimpAlignmentType  alignment,
+                 gboolean           align_contents)
 {
   GList *l;
 
   for (l = list; l; l = g_list_next (l))
-    compute_offset (l->data, alignment);
+    compute_offset (l->data, alignment, align_contents);
 }
 
 static void
 compute_offset (GObject           *object,
-                GimpAlignmentType  alignment)
+                GimpAlignmentType  alignment,
+                gboolean           align_contents)
 {
   gint object_offset_x = 0;
   gint object_offset_y = 0;
@@ -304,7 +312,28 @@ compute_offset (GObject           *object,
                         &object_width,
                         &object_height);
 
+      if (align_contents && GIMP_IS_PICKABLE (object))
+        {
+          gint x;
+          gint y;
+          gint width;
+          gint height;
+
+          if (gimp_pickable_auto_shrink (GIMP_PICKABLE (object),
+                                         0, 0,
+                                         gimp_item_get_width  (GIMP_ITEM (object)),
+                                         gimp_item_get_height (GIMP_ITEM (object)),
+                                         &x, &y, &width, &height) == GIMP_AUTO_SHRINK_SHRINK)
+            {
+              object_offset_x += x;
+              object_offset_y += y;
+              object_width     = width;
+              object_height    = height;
+            }
+        }
+
       gimp_item_get_offset (item, &off_x, &off_y);
+
       object_offset_x += off_x;
       object_offset_y += off_y;
     }
diff --git a/app/core/gimpimage-arrange.h b/app/core/gimpimage-arrange.h
index 1109a5deae..ab4722784f 100644
--- a/app/core/gimpimage-arrange.h
+++ b/app/core/gimpimage-arrange.h
@@ -24,6 +24,7 @@ void gimp_image_arrange_objects (GimpImage         *image,
                                  GimpAlignmentType  alignment,
                                  GObject           *reference,
                                  GimpAlignmentType  reference_alignment,
+                                 gboolean           align_contents,
                                  gint               offset);
 
 #endif  /*  __GIMP_IMAGE_ARRANGE_H__  */
diff --git a/app/tools/gimpalignoptions.c b/app/tools/gimpalignoptions.c
index 4d641c10b5..2aa4c3bbf9 100644
--- a/app/tools/gimpalignoptions.c
+++ b/app/tools/gimpalignoptions.c
@@ -34,6 +34,7 @@
 
 #include "vectors/gimpvectors.h"
 
+#include "widgets/gimppropwidgets.h"
 #include "widgets/gimpwidgets-utils.h"
 
 #include "gimpalignoptions.h"
@@ -56,12 +57,14 @@ enum
   PROP_OFFSET_Y,
   PROP_ALIGN_LAYERS,
   PROP_ALIGN_VECTORS,
+  PROP_ALIGN_CONTENTS,
 };
 
 struct _GimpAlignOptionsPrivate
 {
   gboolean   align_layers;
   gboolean   align_vectors;
+  gboolean   align_contents;
 
   GList     *selected_guides;
   GObject   *reference;
@@ -158,6 +161,12 @@ gimp_align_options_class_init (GimpAlignOptionsClass *klass)
                             _("Selected paths will be aligned or distributed by the tool"),
                             FALSE,
                             GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ALIGN_CONTENTS,
+                            "align-contents",
+                            _("Use extents of layer contents"),
+                            _("Instead of aligning or distributing on layer borders, use its content 
bounding box"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
 }
 
 static void
@@ -209,6 +218,10 @@ gimp_align_options_set_property (GObject      *object,
       gimp_align_options_update_area (options);
       break;
 
+    case PROP_ALIGN_CONTENTS:
+      options->priv->align_contents = g_value_get_boolean (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -243,6 +256,10 @@ gimp_align_options_get_property (GObject    *object,
       g_value_set_boolean (value, options->priv->align_vectors);
       break;
 
+    case PROP_ALIGN_CONTENTS:
+      g_value_set_boolean (value, options->priv->align_contents);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -360,14 +377,24 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
   gint              n = 0;
 
   /* Selected objects */
-  widget = gimp_prop_check_button_new (config, "align-layers", NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+  frame = gimp_frame_new (_("Objects to align or distribute"));
+  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
+
+  align_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+  gtk_container_add (GTK_CONTAINER (frame), align_vbox);
+  gtk_widget_show (align_vbox);
+
+  widget = gimp_prop_check_button_new (config, "align-contents", NULL);
+  widget = gimp_prop_expanding_frame_new (config, "align-layers",
+                                          NULL, widget, NULL);
+  gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
 
   widget = gimp_prop_check_button_new (config, "align-vectors", NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
 
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
   gtk_widget_show (hbox);
 
   widget = gtk_image_new_from_icon_name (GIMP_ICON_CURSOR, GTK_ICON_SIZE_BUTTON);
@@ -387,7 +414,7 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
   gtk_widget_show (widget);
 
   widget = gtk_label_new (NULL);
-  gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
   gtk_widget_show (widget);
   options->priv->selected_guides_label = widget;
 
@@ -643,6 +670,12 @@ gimp_align_options_get_reference (GimpAlignOptions *options,
   return reference;
 }
 
+gboolean
+gimp_align_options_align_contents (GimpAlignOptions *options)
+{
+  return options->priv->align_contents;
+}
+
 void
 gimp_align_options_pick_guide (GimpAlignOptions *options,
                                GimpGuide        *guide,
diff --git a/app/tools/gimpalignoptions.h b/app/tools/gimpalignoptions.h
index 45cac97ed0..0bdf27efa9 100644
--- a/app/tools/gimpalignoptions.h
+++ b/app/tools/gimpalignoptions.h
@@ -67,6 +67,7 @@ void        gimp_align_options_pick_reference    (GimpAlignOptions *options,
                                                   GObject          *object);
 GObject   * gimp_align_options_get_reference     (GimpAlignOptions *options,
                                                   gboolean          blink_if_none);
+gboolean    gimp_align_options_align_contents    (GimpAlignOptions *options);
 
 void        gimp_align_options_pick_guide        (GimpAlignOptions *options,
                                                   GimpGuide        *guide,
diff --git a/app/tools/gimpaligntool.c b/app/tools/gimpaligntool.c
index d096091fb4..19be598b0c 100644
--- a/app/tools/gimpaligntool.c
+++ b/app/tools/gimpaligntool.c
@@ -179,9 +179,6 @@ gimp_align_tool_constructed (GObject *object)
   g_signal_connect_object (options, "align-button-clicked",
                            G_CALLBACK (gimp_align_tool_align),
                            align_tool, G_CONNECT_SWAPPED);
-  g_signal_connect_object (align_tool, "undo",
-                           G_CALLBACK (gimp_align_tool_undo),
-                           align_tool, G_CONNECT_AFTER);
 }
 
 static void
@@ -765,6 +762,7 @@ gimp_align_tool_align (GimpAlignTool     *align_tool,
                               align_type,
                               reference_object,
                               align_type,
+                              gimp_align_options_align_contents (options),
                               offset);
 
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (align_tool));


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