[gimp] Adds "fill" arrange modes to the Align Tool



commit 72ac53705f03fca5f8cd74e597bf679c687fe6df
Author: João S. O. Bueno <gwidion gmail com>
Date:   Thu Mar 13 03:38:53 2014 -0300

    Adds "fill" arrange modes to the Align Tool
    
    The Align Tool had to be used in a very hacky way if one
    intended to evenly distribute items across an image,
    or other reference object (it would actually require one to
    calculate the item spacing out of GIMP). This adds vertical
    and horizontal fill modes: the reference object is divided
    in N equal segments, where N is the number of items,
    and each item is placed in the center of one of
    these segments. The existing "offset" parameter
    is used as an extra margin for the distribution,
    and can be set to negative values, so that the items can
    even get moved outside the boundaries of the reference object.

 app/core/core-enums.c                    |    4 +
 app/core/core-enums.h                    |    4 +-
 app/core/gimpimage-arrange.c             |   89 +++++++++++++++++++++++++----
 app/tools/gimpalignoptions.c             |   14 +++++
 app/tools/gimpalignoptions.h             |    2 +-
 app/tools/gimpaligntool.c                |    2 +
 libgimpwidgets/gimpstock.c               |    6 ++
 libgimpwidgets/gimpstock.h               |    3 +
 themes/Default/images/Makefile.am        |    2 +
 themes/Default/images/stock-hfill-24.png |  Bin 0 -> 7270 bytes
 themes/Default/images/stock-vfill-24.png |  Bin 0 -> 7037 bytes
 11 files changed, 111 insertions(+), 15 deletions(-)
---
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 7ec1164..9ad2755 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -450,6 +450,8 @@ gimp_alignment_type_get_type (void)
     { GIMP_ARRANGE_TOP, "GIMP_ARRANGE_TOP", "arrange-top" },
     { GIMP_ARRANGE_VCENTER, "GIMP_ARRANGE_VCENTER", "arrange-vcenter" },
     { GIMP_ARRANGE_BOTTOM, "GIMP_ARRANGE_BOTTOM", "arrange-bottom" },
+    { GIMP_ARRANGE_HFILL, "GIMP_ARRANGE_HFILL", "arrange-hfill" },
+    { GIMP_ARRANGE_VFILL, "GIMP_ARRANGE_VFILL", "arrange-vfill" },
     { 0, NULL, NULL }
   };
 
@@ -467,6 +469,8 @@ gimp_alignment_type_get_type (void)
     { GIMP_ARRANGE_TOP, "GIMP_ARRANGE_TOP", NULL },
     { GIMP_ARRANGE_VCENTER, "GIMP_ARRANGE_VCENTER", NULL },
     { GIMP_ARRANGE_BOTTOM, "GIMP_ARRANGE_BOTTOM", NULL },
+    { GIMP_ARRANGE_HFILL, "GIMP_ARRANGE_HFILL", NULL },
+    { GIMP_ARRANGE_VFILL, "GIMP_ARRANGE_VFILL", NULL },
     { 0, NULL, NULL }
   };
 
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index beb09b2..4af5bc0 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -233,7 +233,9 @@ typedef enum  /*< pdb-skip >*/
   GIMP_ARRANGE_RIGHT,
   GIMP_ARRANGE_TOP,
   GIMP_ARRANGE_VCENTER,
-  GIMP_ARRANGE_BOTTOM
+  GIMP_ARRANGE_BOTTOM,
+  GIMP_ARRANGE_HFILL,
+  GIMP_ARRANGE_VFILL
 } GimpAlignmentType;
 
 
diff --git a/app/core/gimpimage-arrange.c b/app/core/gimpimage-arrange.c
index 523585e..668b65c 100644
--- a/app/core/gimpimage-arrange.c
+++ b/app/core/gimpimage-arrange.c
@@ -67,7 +67,9 @@ static gint    offset_compare  (gconstpointer      a,
  * object in the sorted list is used as reference.
  *
  * When there are multiple target objects, they are arranged so that the spacing
- * between consecutive ones is given by the argument @offset.
+ * between consecutive ones is given by the argument @offset but for HFILL and VFILL -
+ * in this case, @offset works as an internal margin for the distribution
+ * (and it can be negative).
  */
 void
 gimp_image_arrange_objects (GimpImage         *image,
@@ -99,6 +101,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ARRANGE_LEFT:
     case GIMP_ARRANGE_HCENTER:
     case GIMP_ARRANGE_RIGHT:
+    case GIMP_ARRANGE_HFILL:
       do_x = TRUE;
       compute_offsets (list, alignment);
       break;
@@ -113,6 +116,7 @@ gimp_image_arrange_objects (GimpImage         *image,
     case GIMP_ARRANGE_TOP:
     case GIMP_ARRANGE_VCENTER:
     case GIMP_ARRANGE_BOTTOM:
+    case GIMP_ARRANGE_VFILL:
       do_y = TRUE;
       compute_offsets (list, alignment);
       break;
@@ -127,36 +131,79 @@ gimp_image_arrange_objects (GimpImage         *image,
     {
       reference = G_OBJECT (object_list->data);
       object_list = g_list_next (object_list);
+      reference_alignment = alignment;
     }
   else
-    compute_offset (reference, reference_alignment);
+    {
+      compute_offset (reference, reference_alignment);
+    }
 
   z0 = GPOINTER_TO_INT (g_object_get_data (reference, "align-offset"));
 
   if (object_list)
     {
-      GList *l;
-      gint   n;
+      GList    *lst;
+      gint     n;
+      gint     distr_width  = 0;
+      gint     distr_height = 0;
+      gdouble  fill_offset  = 0;
 
+      if (reference_alignment == GIMP_ARRANGE_HFILL)
+        {
+          distr_width = GPOINTER_TO_INT (g_object_get_data
+                                         (reference, "align-width"));
+          /* The offset parameter works as an internal margin */
+          fill_offset = (distr_width - 2 * offset) /
+                         g_list_length (object_list);
+        }
+      if (reference_alignment == GIMP_ARRANGE_VFILL)
+        {
+          distr_height = GPOINTER_TO_INT (g_object_get_data
+                                          (reference, "align-height"));
+          fill_offset = (distr_height - 2 * offset) /
+                         g_list_length (object_list);
+        }
       /* FIXME: undo group type is wrong */
       gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE,
                                    C_("undo-type", "Arrange Objects"));
 
-      for (l = object_list, n = 1; l; l = g_list_next (l), n++)
+      for (lst = object_list, n = 1; lst; lst = g_list_next (lst), n++)
         {
-          GObject *target          = G_OBJECT (l->data);
+          GObject *target          = G_OBJECT (lst->data);
           gint     xtranslate      = 0;
           gint     ytranslate      = 0;
+          gint     width;
+          gint     height;
           gint     z1;
 
           z1 = GPOINTER_TO_INT (g_object_get_data (target,
                                                     "align-offset"));
 
-          if (do_x)
-            xtranslate = z0 - z1 + n * offset;
+          if (reference_alignment == GIMP_ARRANGE_HFILL)
+            {
+
+              width = GPOINTER_TO_INT (g_object_get_data (target,
+                                                    "align-width"));
+              xtranslate = ROUND (z0 - z1 + (n - 0.5) * fill_offset -
+                                  width/2.0 + offset);
+            }
+          else if (reference_alignment == GIMP_ARRANGE_VFILL)
+            {
+              height = GPOINTER_TO_INT (g_object_get_data (target,
+                                                    "align-height"));
+              ytranslate =  ROUND (z0 - z1 + (n - 0.5) * fill_offset -
+                                   height/2.0 + offset);
+            }
+          else /* the normal computing, when we don't depend on the
+                * width or height of the reference object
+                */
+            {
+              if (do_x)
+                xtranslate = z0 - z1 + n * offset;
 
-          if (do_y)
-            ytranslate = z0 - z1 + n * offset;
+              if (do_y)
+                ytranslate = z0 - z1 + n * offset;
+            }
 
           /* now actually align the target object */
           if (GIMP_IS_ITEM (target))
@@ -220,10 +267,10 @@ static void
 compute_offsets (GList             *list,
                  GimpAlignmentType  alignment)
 {
-  GList *l;
+  GList *lst;
 
-  for (l = list; l; l = g_list_next (l))
-    compute_offset (G_OBJECT (l->data), alignment);
+  for (lst = list; lst; lst = g_list_next (lst))
+    compute_offset (G_OBJECT (lst->data), alignment);
 }
 
 static void
@@ -325,6 +372,7 @@ compute_offset (GObject *object,
     {
     case GIMP_ALIGN_LEFT:
     case GIMP_ARRANGE_LEFT:
+    case GIMP_ARRANGE_HFILL:
       offset = object_offset_x;
       break;
     case GIMP_ALIGN_HCENTER:
@@ -337,6 +385,7 @@ compute_offset (GObject *object,
       break;
     case GIMP_ALIGN_TOP:
     case GIMP_ARRANGE_TOP:
+    case GIMP_ARRANGE_VFILL:
       offset = object_offset_y;
       break;
     case GIMP_ALIGN_VCENTER:
@@ -353,4 +402,18 @@ compute_offset (GObject *object,
 
   g_object_set_data (object, "align-offset",
                      GINT_TO_POINTER (offset));
+
+  /* These are only used for HFILL and VFILL,  but
+   * since the call to gimp_image_arrange_objects
+   * allows for two different alignments (object and reference_alignment)
+   * we better be on the safe side in case they differ.
+   * (the current implementation of the align tool always
+   * pass the same value to both parameters)
+   */
+  g_object_set_data (object, "align-width",
+                     GINT_TO_POINTER (object_width));
+
+  g_object_set_data (object, "align-height",
+                     GINT_TO_POINTER (object_height));
+
 }
diff --git a/app/tools/gimpalignoptions.c b/app/tools/gimpalignoptions.c
index 1a80f76..26e7092 100644
--- a/app/tools/gimpalignoptions.c
+++ b/app/tools/gimpalignoptions.c
@@ -229,6 +229,12 @@ gimp_align_options_button_new (GimpAlignOptions  *options,
     case GIMP_ARRANGE_BOTTOM:
       stock_id = GIMP_STOCK_GRAVITY_SOUTH;
       break;
+    case GIMP_ARRANGE_HFILL:
+        stock_id = GIMP_STOCK_HFILL;
+        break;
+    case GIMP_ARRANGE_VFILL:
+        stock_id = GIMP_STOCK_VFILL;
+        break;
     default:
       g_return_val_if_reached (NULL);
       break;
@@ -340,6 +346,10 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
     gimp_align_options_button_new (options, GIMP_ARRANGE_RIGHT, hbox,
                                    _("Distribute right edges of targets"));
 
+  options->button[n++] =
+    gimp_align_options_button_new (options, GIMP_ARRANGE_HFILL, hbox,
+                                   _("Distribute targets evenly in the horizontal"));
+
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
   gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
   gtk_widget_show (hbox);
@@ -356,6 +366,10 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
     gimp_align_options_button_new (options, GIMP_ARRANGE_BOTTOM, hbox,
                                    _("Distribute bottoms of targets"));
 
+  options->button[n++] =
+    gimp_align_options_button_new (options, GIMP_ARRANGE_VFILL, hbox,
+                                   _("Distribute targets evenly in the vertical"));
+
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
   gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
   gtk_widget_show (hbox);
diff --git a/app/tools/gimpalignoptions.h b/app/tools/gimpalignoptions.h
index c357288..c31a621 100644
--- a/app/tools/gimpalignoptions.h
+++ b/app/tools/gimpalignoptions.h
@@ -22,7 +22,7 @@
 #include "core/gimptooloptions.h"
 
 
-#define ALIGN_OPTIONS_N_BUTTONS 12
+#define ALIGN_OPTIONS_N_BUTTONS 14
 
 
 #define GIMP_TYPE_ALIGN_OPTIONS            (gimp_align_options_get_type ())
diff --git a/app/tools/gimpaligntool.c b/app/tools/gimpaligntool.c
index 6d32cf6..2066076 100644
--- a/app/tools/gimpaligntool.c
+++ b/app/tools/gimpaligntool.c
@@ -740,6 +740,8 @@ gimp_align_tool_align (GimpAlignTool     *align_tool,
     case GIMP_ARRANGE_TOP:
     case GIMP_ARRANGE_VCENTER:
     case GIMP_ARRANGE_BOTTOM:
+    case GIMP_ARRANGE_HFILL:
+    case GIMP_ARRANGE_VFILL:
       offset = options->offset_x;
       break;
     }
diff --git a/libgimpwidgets/gimpstock.c b/libgimpwidgets/gimpstock.c
index 53b335e..16bd90b 100644
--- a/libgimpwidgets/gimpstock.c
+++ b/libgimpwidgets/gimpstock.c
@@ -158,6 +158,9 @@ static const GtkStockItem gimp_stock_items[] =
   { GIMP_STOCK_HCENTER,                  NULL,        0, 0, LIBGIMP_DOMAIN },
   { GIMP_STOCK_VCENTER,                  NULL,        0, 0, LIBGIMP_DOMAIN },
 
+  { GIMP_STOCK_HFILL,                    NULL,        0, 0, LIBGIMP_DOMAIN },
+  { GIMP_STOCK_VFILL,                    NULL,        0, 0, LIBGIMP_DOMAIN },
+
   { GIMP_STOCK_HCHAIN,                   NULL,        0, 0, LIBGIMP_DOMAIN },
   { GIMP_STOCK_HCHAIN_BROKEN,            NULL,        0, 0, LIBGIMP_DOMAIN },
   { GIMP_STOCK_VCHAIN,                   NULL,        0, 0, LIBGIMP_DOMAIN },
@@ -375,6 +378,9 @@ gimp_stock_button_pixbufs[] =
   { GIMP_STOCK_HCENTER,                  stock_hcenter_24                  },
   { GIMP_STOCK_VCENTER,                  stock_vcenter_24                  },
 
+  { GIMP_STOCK_HFILL,                    stock_hfill_24                    },
+  { GIMP_STOCK_VFILL,                    stock_vfill_24                    },
+
   { GIMP_STOCK_HCHAIN,                   stock_hchain_24                   },
   { GIMP_STOCK_HCHAIN_BROKEN,            stock_hchain_broken_24            },
   { GIMP_STOCK_VCHAIN,                   stock_vchain_24                   },
diff --git a/libgimpwidgets/gimpstock.h b/libgimpwidgets/gimpstock.h
index 2f0d6d1..ec9eec7 100644
--- a/libgimpwidgets/gimpstock.h
+++ b/libgimpwidgets/gimpstock.h
@@ -67,6 +67,9 @@ G_BEGIN_DECLS
 #define GIMP_STOCK_HCENTER                  "gimp-hcenter"
 #define GIMP_STOCK_VCENTER                  "gimp-vcenter"
 
+#define GIMP_STOCK_HFILL                    "gimp-hfill"
+#define GIMP_STOCK_VFILL                    "gimp-vfill"
+
 #define GIMP_STOCK_HCHAIN                   "gimp-hchain"
 #define GIMP_STOCK_HCHAIN_BROKEN            "gimp-hchain-broken"
 #define GIMP_STOCK_VCHAIN                   "gimp-vchain"
diff --git a/themes/Default/images/Makefile.am b/themes/Default/images/Makefile.am
index e6a06b1..75d41e6 100644
--- a/themes/Default/images/Makefile.am
+++ b/themes/Default/images/Makefile.am
@@ -178,6 +178,7 @@ STOCK_BUTTON_IMAGES = \
        stock-hcenter-24.png                    \
        stock-hchain-24.png                     \
        stock-hchain-broken-24.png              \
+       stock-hfill-24.png                      \
        stock-histogram-22.png                  \
        stock-image-24.png                      \
        stock-images-24.png                     \
@@ -219,6 +220,7 @@ STOCK_BUTTON_IMAGES = \
        stock-vcenter-24.png                    \
        stock-vchain-24.png                     \
        stock-vchain-broken-24.png              \
+       stock-vfill-24.png                      \
        stock-video-24.png                      \
        stock-warning-24.png                    \
        stock-web-24.png                        \
diff --git a/themes/Default/images/stock-hfill-24.png b/themes/Default/images/stock-hfill-24.png
new file mode 100644
index 0000000..8f718d9
Binary files /dev/null and b/themes/Default/images/stock-hfill-24.png differ
diff --git a/themes/Default/images/stock-vfill-24.png b/themes/Default/images/stock-vfill-24.png
new file mode 100644
index 0000000..86969b7
Binary files /dev/null and b/themes/Default/images/stock-vfill-24.png differ


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