app: big UI rework of the align/distribute tool.

- Adding a separate pivot widget to allow choosing which point of the items we
  align or distribute. E.g. until now, we could only align the right side of
  objects to the right side of the reference object, left to left and center to
  center. Now these are independent. Therefore I can align the left side of
  objects to the right border of a selection or a layer, and so on.
- Only keep 2 "distribute" buttons (for now). Most of the distribution actions
  were basically broken or extremely hard to understand. Also they were
  apparently mixing concepts of alignments with distributions. Now let's
  basically only keep the bases: horizontal or vertical distributions.
  Everything is still possible using a mix of alignment and distribution
  buttons, and it's much clearer.
- Since the GimpAlignmentType was used nearly only there (except for some usage
  like to store dock side or filter preview split direction, but these
  GIMP_ARRANGE_* values were unused there), I removed the various enum values
  which we don't use anymore.
- The Reference settings gets its own subsection in the Align tool options.
  Until now, it looked like it only applied to alignment, whereas it applies to
  distribution too.

Note: this is still work-in-progress, mostly some initial dev work to put some
algorithmic bases. We had some UI and specification discussions with Aryeom
already and some things might still change a lot.
This commit is contained in:
Jehan 2022-11-08 17:38:57 +01:00
parent 63dc7dee8a
commit 2b0928d895
8 changed files with 183 additions and 182 deletions

View File

@ -51,12 +51,6 @@ gimp_alignment_type_get_type (void)
{ GIMP_ALIGN_TOP, "GIMP_ALIGN_TOP", "align-top" },
{ GIMP_ALIGN_VCENTER, "GIMP_ALIGN_VCENTER", "align-vcenter" },
{ GIMP_ALIGN_BOTTOM, "GIMP_ALIGN_BOTTOM", "align-bottom" },
{ GIMP_ARRANGE_LEFT, "GIMP_ARRANGE_LEFT", "arrange-left" },
{ GIMP_ARRANGE_HCENTER, "GIMP_ARRANGE_HCENTER", "arrange-hcenter" },
{ GIMP_ARRANGE_RIGHT, "GIMP_ARRANGE_RIGHT", "arrange-right" },
{ 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 }
@ -70,12 +64,6 @@ gimp_alignment_type_get_type (void)
{ GIMP_ALIGN_TOP, "GIMP_ALIGN_TOP", NULL },
{ GIMP_ALIGN_VCENTER, "GIMP_ALIGN_VCENTER", NULL },
{ GIMP_ALIGN_BOTTOM, "GIMP_ALIGN_BOTTOM", NULL },
{ GIMP_ARRANGE_LEFT, "GIMP_ARRANGE_LEFT", NULL },
{ GIMP_ARRANGE_HCENTER, "GIMP_ARRANGE_HCENTER", NULL },
{ GIMP_ARRANGE_RIGHT, "GIMP_ARRANGE_RIGHT", NULL },
{ 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 }

View File

@ -60,12 +60,6 @@ typedef enum /*< pdb-skip >*/
GIMP_ALIGN_TOP,
GIMP_ALIGN_VCENTER,
GIMP_ALIGN_BOTTOM,
GIMP_ARRANGE_LEFT,
GIMP_ARRANGE_HCENTER,
GIMP_ARRANGE_RIGHT,
GIMP_ARRANGE_TOP,
GIMP_ARRANGE_VCENTER,
GIMP_ARRANGE_BOTTOM,
GIMP_ARRANGE_HFILL,
GIMP_ARRANGE_VFILL
} GimpAlignmentType;

View File

@ -38,10 +38,14 @@
static GList * sort_by_offset (GList *list);
static void compute_offsets (GList *list,
GimpAlignmentType alignment,
gboolean use_x_offset,
gdouble align_x,
gdouble align_y,
gboolean align_contents);
static void compute_offset (GObject *object,
GimpAlignmentType alignment,
gboolean use_x_offset,
gdouble align_x,
gdouble align_y,
gboolean align_contents);
static gint offset_compare (gconstpointer a,
gconstpointer b);
@ -51,7 +55,8 @@ static gint offset_compare (gconstpointer a,
* gimp_image_arrange_objects:
* @image: The #GimpImage to which the objects belong.
* @list: A #GList of objects to be aligned.
* @alignment: The point on each target object to bring into alignment.
* @align_x: Relative X coordinate of point on each target object to bring into alignment.
* @align_y: Relative Y coordinate of 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.
@ -77,22 +82,27 @@ static gint offset_compare (gconstpointer a,
void
gimp_image_arrange_objects (GimpImage *image,
GList *list,
GimpAlignmentType alignment,
gdouble align_x,
gdouble align_y,
GObject *reference,
GimpAlignmentType reference_alignment,
gboolean align_contents,
gint offset)
{
gboolean do_x = FALSE;
gboolean do_y = FALSE;
gint z0 = 0;
gdouble reference_x = 0.0;
gdouble reference_y = 0.0;
gboolean use_ref_x_offset = FALSE;
gboolean use_obj_x_offset = FALSE;
gboolean do_x = FALSE;
gboolean do_y = FALSE;
gint z0 = 0;
GList *object_list;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (G_IS_OBJECT (reference) || reference == NULL);
/* get offsets used for sorting */
switch (alignment)
switch (reference_alignment)
{
/* order vertically for horizontal alignment */
case GIMP_ALIGN_LEFT:
@ -101,19 +111,25 @@ gimp_image_arrange_objects (GimpImage *image,
if (GIMP_IS_GUIDE (reference) &&
gimp_guide_get_orientation (GIMP_GUIDE (reference)) == GIMP_ORIENTATION_HORIZONTAL)
return;
use_obj_x_offset = TRUE;
use_ref_x_offset = TRUE;
if (reference_alignment == GIMP_ALIGN_HCENTER)
reference_x = 0.5;
else if (reference_alignment == GIMP_ALIGN_RIGHT)
reference_x = 1.0;
do_x = TRUE;
compute_offsets (list, GIMP_ALIGN_TOP, align_contents);
break;
/* order horizontally for horizontal arrangement */
case GIMP_ARRANGE_LEFT:
case GIMP_ARRANGE_HCENTER:
case GIMP_ARRANGE_RIGHT:
case GIMP_ARRANGE_HFILL:
if (GIMP_IS_GUIDE (reference))
return;
use_obj_x_offset = TRUE;
use_ref_x_offset = TRUE;
do_x = TRUE;
compute_offsets (list, alignment, align_contents);
break;
/* order horizontally for vertical alignment */
@ -123,41 +139,43 @@ gimp_image_arrange_objects (GimpImage *image,
if (GIMP_IS_GUIDE (reference) &&
gimp_guide_get_orientation (GIMP_GUIDE (reference)) == GIMP_ORIENTATION_VERTICAL)
return;
if (reference_alignment == GIMP_ALIGN_VCENTER)
reference_y = 0.5;
else if (reference_alignment == GIMP_ALIGN_BOTTOM)
reference_y = 1.0;
do_y = TRUE;
compute_offsets (list, GIMP_ALIGN_LEFT, align_contents);
break;
/* order vertically for vertical arrangement */
case GIMP_ARRANGE_TOP:
case GIMP_ARRANGE_VCENTER:
case GIMP_ARRANGE_BOTTOM:
case GIMP_ARRANGE_VFILL:
if (GIMP_IS_GUIDE (reference))
return;
do_y = TRUE;
compute_offsets (list, alignment, align_contents);
break;
default:
g_return_if_reached ();
}
/* get offsets used for sorting */
compute_offsets (list, use_obj_x_offset, align_x, align_y, align_contents);
/* Sort. */
object_list = sort_by_offset (list);
/* now get offsets used for aligning */
compute_offsets (list, alignment, align_contents);
compute_offsets (list, use_obj_x_offset, align_x, align_y, align_contents);
if (reference == NULL)
{
reference = G_OBJECT (object_list->data);
object_list = g_list_next (object_list);
reference_alignment = alignment;
}
else
{
compute_offset (reference, reference_alignment, FALSE);
object_list = g_list_delete_link (object_list, object_list);
}
/* Compute the offset for the reference (esp. for alignment. */
compute_offset (reference, use_ref_x_offset, reference_x, reference_y, FALSE);
z0 = GPOINTER_TO_INT (g_object_get_data (reference, "align-offset"));
if (object_list)
@ -174,14 +192,14 @@ gimp_image_arrange_objects (GimpImage *image,
(reference, "align-width"));
/* The offset parameter works as an internal margin */
fill_offset = (distr_width - 2 * offset) /
(gint) g_list_length (object_list);
(gdouble) (g_list_length (object_list) + 1);
}
if (reference_alignment == GIMP_ARRANGE_VFILL)
else if (reference_alignment == GIMP_ARRANGE_VFILL)
{
distr_height = GPOINTER_TO_INT (g_object_get_data
(reference, "align-height"));
fill_offset = (distr_height - 2 * offset) /
(gint) g_list_length (object_list);
(gdouble) (g_list_length (object_list) + 1);
}
/* FIXME: undo group type is wrong */
@ -201,17 +219,11 @@ gimp_image_arrange_objects (GimpImage *image,
if (reference_alignment == GIMP_ARRANGE_HFILL)
{
gint width = GPOINTER_TO_INT (g_object_get_data (target,
"align-width"));
xtranslate = ROUND (z0 - z1 + (n - 0.5) * fill_offset -
width / 2.0 + offset);
xtranslate = ROUND (z0 - z1 + n * fill_offset);
}
else if (reference_alignment == GIMP_ARRANGE_VFILL)
{
gint height = GPOINTER_TO_INT (g_object_get_data (target,
"align-height"));
ytranslate = ROUND (z0 - z1 + (n - 0.5) * fill_offset -
height / 2.0 + offset);
ytranslate = ROUND (z0 - z1 + n * fill_offset);
}
else /* the normal computing, when we don't depend on the
* width or height of the reference object
@ -281,20 +293,24 @@ offset_compare (gconstpointer a,
* object as object data.
*/
static void
compute_offsets (GList *list,
GimpAlignmentType alignment,
gboolean align_contents)
compute_offsets (GList *list,
gboolean use_x_offset,
gdouble align_x,
gdouble align_y,
gboolean align_contents)
{
GList *l;
for (l = list; l; l = g_list_next (l))
compute_offset (l->data, alignment, align_contents);
compute_offset (l->data, use_x_offset, align_x, align_y, align_contents);
}
static void
compute_offset (GObject *object,
GimpAlignmentType alignment,
gboolean align_contents)
compute_offset (GObject *object,
gboolean use_x_offset,
gdouble align_x,
gdouble align_y,
gboolean align_contents)
{
gint object_offset_x = 0;
gint object_offset_y = 0;
@ -372,43 +388,10 @@ compute_offset (GObject *object,
g_printerr ("Alignment object is not an image, item or guide.\n");
}
switch (alignment)
{
case GIMP_ALIGN_LEFT:
case GIMP_ARRANGE_LEFT:
case GIMP_ARRANGE_HFILL:
offset = object_offset_x;
break;
case GIMP_ALIGN_HCENTER:
case GIMP_ARRANGE_HCENTER:
offset = object_offset_x + object_width / 2;
break;
case GIMP_ALIGN_RIGHT:
case GIMP_ARRANGE_RIGHT:
offset = object_offset_x + object_width;
break;
case GIMP_ALIGN_TOP:
case GIMP_ARRANGE_TOP:
case GIMP_ARRANGE_VFILL:
offset = object_offset_y;
break;
case GIMP_ALIGN_VCENTER:
case GIMP_ARRANGE_VCENTER:
offset = object_offset_y + object_height / 2;
break;
case GIMP_ALIGN_BOTTOM:
case GIMP_ARRANGE_BOTTOM:
offset = object_offset_y + object_height;
break;
default:
g_return_if_reached ();
}
if (use_x_offset)
offset = object_offset_x + object_width * align_x;
else
offset = object_offset_y + object_height * align_y;
g_object_set_data (object, "align-offset",
GINT_TO_POINTER (offset));

View File

@ -21,7 +21,8 @@
void gimp_image_arrange_objects (GimpImage *image,
GList *list,
GimpAlignmentType alignment,
gdouble align_x,
gdouble align_y,
GObject *reference,
GimpAlignmentType reference_alignment,
gboolean align_contents,

View File

@ -34,6 +34,7 @@
#include "vectors/gimpvectors.h"
#include "widgets/gimppivotselector.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpwidgets-utils.h"
@ -45,8 +46,8 @@
#define ALIGN_VER_N_BUTTONS 3
#define ALIGN_HOR_N_BUTTONS 3
#define DISTR_VER_N_BUTTONS 4
#define DISTR_HOR_N_BUTTONS 4
#define DISTR_VER_N_BUTTONS 1
#define DISTR_HOR_N_BUTTONS 1
enum
@ -64,6 +65,8 @@ enum
PROP_ALIGN_LAYERS,
PROP_ALIGN_VECTORS,
PROP_ALIGN_CONTENTS,
PROP_PIVOT_X,
PROP_PIVOT_Y,
};
struct _GimpAlignOptionsPrivate
@ -71,6 +74,8 @@ struct _GimpAlignOptionsPrivate
gboolean align_layers;
gboolean align_vectors;
gboolean align_contents;
gdouble pivot_x;
gdouble pivot_y;
GList *selected_guides;
GObject *reference;
@ -79,6 +84,7 @@ struct _GimpAlignOptionsPrivate
GtkWidget *reference_combo;
GtkWidget *reference_box;
GtkWidget *reference_label;
GtkWidget *pivot_selector;
GtkWidget *align_ver_button[ALIGN_VER_N_BUTTONS];
GtkWidget *align_hor_button[ALIGN_HOR_N_BUTTONS];
@ -107,6 +113,8 @@ static void gimp_align_options_guide_removed (GimpImage *image
GimpAlignOptions *options);
static void gimp_align_options_reference_removed (GObject *object,
GimpAlignOptions *options);
static void gimp_align_options_pivot_changed (GimpPivotSelector *selector,
GimpAlignOptions *options);
G_DEFINE_TYPE_WITH_PRIVATE (GimpAlignOptions, gimp_align_options, GIMP_TYPE_TOOL_OPTIONS)
@ -161,13 +169,13 @@ gimp_align_options_class_init (GimpAlignOptionsClass *klass)
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ALIGN_LAYERS,
"align-layers",
_("Align or distribute selected layers"),
_("Selected layers"),
_("Selected layers will be aligned or distributed by the tool"),
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ALIGN_VECTORS,
"align-vectors",
_("Align or distribute selected paths"),
_("Selected paths"),
_("Selected paths will be aligned or distributed by the tool"),
FALSE,
GIMP_PARAM_STATIC_STRINGS);
@ -177,6 +185,20 @@ gimp_align_options_class_init (GimpAlignOptionsClass *klass)
_("Instead of aligning or distributing on layer borders, use its content bounding box"),
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PIVOT_X,
"pivot-x",
"X position of the point to align in objects",
NULL,
0.0, 1.0, 0.5,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PIVOT_Y,
"pivot-y",
"Y position of the point to align in objects",
NULL,
0.0, 1.0, 0.5,
GIMP_PARAM_STATIC_STRINGS);
}
static void
@ -232,6 +254,13 @@ gimp_align_options_set_property (GObject *object,
options->priv->align_contents = g_value_get_boolean (value);
break;
case PROP_PIVOT_X:
options->priv->pivot_x = g_value_get_double (value);
break;
case PROP_PIVOT_Y:
options->priv->pivot_y = g_value_get_double (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -270,6 +299,13 @@ gimp_align_options_get_property (GObject *object,
g_value_set_boolean (value, options->priv->align_contents);
break;
case PROP_PIVOT_X:
g_value_set_double (value, options->priv->pivot_x);
break;
case PROP_PIVOT_Y:
g_value_set_double (value, options->priv->pivot_y);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -319,24 +355,6 @@ gimp_align_options_button_new (GimpAlignOptions *options,
case GIMP_ALIGN_BOTTOM:
icon_name = GIMP_ICON_GRAVITY_SOUTH;
break;
case GIMP_ARRANGE_LEFT:
icon_name = GIMP_ICON_GRAVITY_WEST;
break;
case GIMP_ARRANGE_HCENTER:
icon_name = GIMP_ICON_CENTER_HORIZONTAL;
break;
case GIMP_ARRANGE_RIGHT:
icon_name = GIMP_ICON_GRAVITY_EAST;
break;
case GIMP_ARRANGE_TOP:
icon_name = GIMP_ICON_GRAVITY_NORTH;
break;
case GIMP_ARRANGE_VCENTER:
icon_name = GIMP_ICON_CENTER_VERTICAL;
break;
case GIMP_ARRANGE_BOTTOM:
icon_name = GIMP_ICON_GRAVITY_SOUTH;
break;
case GIMP_ARRANGE_HFILL:
icon_name = GIMP_ICON_FILL_HORIZONTAL;
break;
@ -377,7 +395,8 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
GimpAlignOptions *options = GIMP_ALIGN_OPTIONS (tool_options);
GtkWidget *vbox = gimp_tool_options_gui (tool_options);
GtkWidget *widget;
GtkWidget *align_vbox;
GtkWidget *section_vbox;
GtkWidget *items_grid;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *label;
@ -391,20 +410,34 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
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);
section_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), section_vbox);
gtk_widget_show (section_vbox);
items_grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (section_vbox), items_grid);
gtk_widget_show (items_grid);
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);
gtk_grid_attach (GTK_GRID (items_grid), widget, 0, 0, 1, 1);
widget = gimp_prop_check_button_new (config, "align-vectors", NULL);
gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
gtk_grid_attach (GTK_GRID (items_grid), widget, 0, 1, 1, 1);
options->priv->pivot_selector = gimp_pivot_selector_new (0.0, 0.0, 1.0, 1.0);
gimp_pivot_selector_set_position (GIMP_PIVOT_SELECTOR (options->priv->pivot_selector),
options->priv->pivot_x, options->priv->pivot_y);
gtk_grid_attach (GTK_GRID (items_grid), options->priv->pivot_selector, 1, 0, 1, 2);
gtk_widget_show (options->priv->pivot_selector);
g_signal_connect (options->priv->pivot_selector, "changed",
G_CALLBACK (gimp_align_options_pivot_changed),
options);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
widget = gtk_image_new_from_icon_name (GIMP_ICON_CURSOR, GTK_ICON_SIZE_BUTTON);
@ -424,28 +457,27 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gtk_widget_show (widget);
widget = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
options->priv->selected_guides_label = widget;
/* Align frame */
frame = gimp_frame_new (_("Align"));
/* Reference frame */
frame = gimp_frame_new (_("Reference"));
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);
section_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), section_vbox);
gtk_widget_show (section_vbox);
combo = gimp_prop_enum_combo_box_new (config, "align-reference", 0, 0);
gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Relative to"));
g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_box_pack_start (GTK_BOX (align_vbox), combo, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), combo, FALSE, FALSE, 0);
options->priv->reference_combo = combo;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
options->priv->reference_box = hbox;
@ -458,13 +490,21 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gtk_widget_show (widget);
widget = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (align_vbox), widget, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
options->priv->reference_label = widget;
/* Align frame */
frame = gimp_frame_new (_("Align"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
section_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), section_vbox);
gtk_widget_show (section_vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
n = 0;
@ -481,7 +521,7 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
_("Align right edge of target"));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
n = 0;
@ -502,54 +542,26 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
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);
section_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), section_vbox);
gtk_widget_show (section_vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
n = 0;
options->priv->distr_ver_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_LEFT, hbox,
_("Distribute left edges of targets"));
options->priv->distr_ver_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_HCENTER, hbox,
_("Distribute horizontal centers of targets"));
options->priv->distr_ver_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_RIGHT, hbox,
_("Distribute right edges of targets"));
options->priv->distr_ver_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);
n = 0;
options->priv->distr_hor_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_TOP, hbox,
_("Distribute top edges of targets"));
options->priv->distr_hor_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_VCENTER, hbox,
_("Distribute vertical centers of targets"));
options->priv->distr_hor_button[n++] =
gimp_align_options_button_new (options, GIMP_ARRANGE_BOTTOM, hbox,
_("Distribute bottoms of targets"));
options->priv->distr_hor_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_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Offset X:"));
@ -561,7 +573,7 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (align_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Offset Y:"));
@ -622,6 +634,15 @@ gimp_align_options_get_objects (GimpAlignOptions *options)
return objects;
}
void
gimp_align_options_get_pivot (GimpAlignOptions *options,
gdouble *x,
gdouble *y)
{
gimp_pivot_selector_get_position (GIMP_PIVOT_SELECTOR (options->priv->pivot_selector),
x, y);
}
void
gimp_align_options_pick_reference (GimpAlignOptions *options,
GObject *object)
@ -891,3 +912,17 @@ gimp_align_options_reference_removed (GObject *object,
if (G_OBJECT (object) == options->priv->reference)
gimp_align_options_pick_reference (options, NULL);
}
static void
gimp_align_options_pivot_changed (GimpPivotSelector *selector,
GimpAlignOptions *options)
{
gdouble x;
gdouble y;
gimp_pivot_selector_get_position (selector, &x, &y);
g_object_set (options,
"pivot-x", x,
"pivot-y", y,
NULL);
}

View File

@ -59,6 +59,9 @@ GType gimp_align_options_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_align_options_gui (GimpToolOptions *tool_options);
GList * gimp_align_options_get_objects (GimpAlignOptions *options);
void gimp_align_options_get_pivot (GimpAlignOptions *options,
gdouble *x,
gdouble *y);
void gimp_align_options_pick_reference (GimpAlignOptions *options,
GObject *object);

View File

@ -765,6 +765,8 @@ gimp_align_tool_align (GimpAlignTool *align_tool,
GList *objects;
GList *list;
gint offset = 0;
gdouble align_x = 0.0;
gdouble align_y = 0.0;
/* if nothing is selected, just return */
objects = gimp_align_options_get_objects (options);
@ -784,16 +786,10 @@ gimp_align_tool_align (GimpAlignTool *align_tool,
offset = 0;
break;
case GIMP_ARRANGE_LEFT:
case GIMP_ARRANGE_HCENTER:
case GIMP_ARRANGE_RIGHT:
case GIMP_ARRANGE_HFILL:
offset = options->offset_x;
break;
case GIMP_ARRANGE_TOP:
case GIMP_ARRANGE_VCENTER:
case GIMP_ARRANGE_BOTTOM:
case GIMP_ARRANGE_VFILL:
offset = options->offset_y;
break;
@ -812,8 +808,9 @@ gimp_align_tool_align (GimpAlignTool *align_tool,
gimp_draw_tool_pause (GIMP_DRAW_TOOL (align_tool));
gimp_align_options_get_pivot (options, &align_x, &align_y);
gimp_image_arrange_objects (image, list,
align_type,
align_x, align_y,
reference_object,
align_type,
gimp_align_options_align_contents (options),

View File

@ -35,7 +35,7 @@ struct _GimpSessionInfoDock
gchar *dock_type;
/* What side this dock is in in single-window mode. Either
* GIMP_ARRANGE_LEFT, GIMP_ARRANGE_RIGHT or -1.
* GIMP_ALIGN_LEFT, GIMP_ALIGN_RIGHT or -1.
*/
GimpAlignmentType side;