1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-05 21:02:42 +02:00

Merge branch 'wip/Jehan/alt-mr-2287' into 'master'

app: reorganize the Align/Distribute tool options.

See merge request GNOME/gimp!2489
This commit is contained in:
Jehan
2025-10-05 18:45:09 +00:00
7 changed files with 316 additions and 74 deletions

View File

@@ -55,6 +55,10 @@ gimp_alignment_type_get_type (void)
{ GIMP_ARRANGE_VFILL, "GIMP_ARRANGE_VFILL", "arrange-vfill" },
{ GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP, "GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP", "distribute-even-horizontal-gap" },
{ GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP, "GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP", "distribute-even-vertical-gap" },
{ GIMP_SHIFT_FROM_TOP, "GIMP_SHIFT_FROM_TOP", "shift-from-top" },
{ GIMP_SHIFT_FROM_BOTTOM, "GIMP_SHIFT_FROM_BOTTOM", "shift-from-bottom" },
{ GIMP_SHIFT_FROM_LEFT, "GIMP_SHIFT_FROM_LEFT", "shift-from-left" },
{ GIMP_SHIFT_FROM_RIGHT, "GIMP_SHIFT_FROM_RIGHT", "shift-from-right" },
{ 0, NULL, NULL }
};
@@ -70,6 +74,10 @@ gimp_alignment_type_get_type (void)
{ GIMP_ARRANGE_VFILL, NC_("alignment-type", "Distribute anchor points vertically evenly"), NULL },
{ GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP, NC_("alignment-type", "Distribute horizontally with even horizontal gaps"), NULL },
{ GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP, NC_("alignment-type", "Distribute vertically with even vertical gaps"), NULL },
{ GIMP_SHIFT_FROM_TOP, NC_("alignment-type", "Align to the top and distribute vertically with offset"), NULL },
{ GIMP_SHIFT_FROM_BOTTOM, NC_("alignment-type", "Align to the bottom and distribute vertically with offset"), NULL },
{ GIMP_SHIFT_FROM_LEFT, NC_("alignment-type", "Align to the left and distribute horizontally with offset"), NULL },
{ GIMP_SHIFT_FROM_RIGHT, NC_("alignment-type", "Align to the right and distribute horizontally with offset"), NULL },
{ 0, NULL, NULL }
};

View File

@@ -52,16 +52,20 @@ GType gimp_alignment_type_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_ALIGN_LEFT, /*< desc="Align to the left" >*/
GIMP_ALIGN_HCENTER, /*< desc="Center horizontally" >*/
GIMP_ALIGN_RIGHT, /*< desc="Align to the right" >*/
GIMP_ALIGN_TOP, /*< desc="Align to the top" >*/
GIMP_ALIGN_VCENTER, /*< desc="Center vertically" >*/
GIMP_ALIGN_BOTTOM, /*< desc="Align to the bottom" >*/
GIMP_ARRANGE_HFILL, /*< desc="Distribute anchor points horizontally evenly" >*/
GIMP_ARRANGE_VFILL, /*< desc="Distribute anchor points vertically evenly" >*/
GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP, /*< desc="Distribute horizontally with even horizontal gaps" >*/
GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP, /*< desc="Distribute vertically with even vertical gaps" >*/
GIMP_ALIGN_LEFT, /*< desc="Align to the left" >*/
GIMP_ALIGN_HCENTER, /*< desc="Center horizontally" >*/
GIMP_ALIGN_RIGHT, /*< desc="Align to the right" >*/
GIMP_ALIGN_TOP, /*< desc="Align to the top" >*/
GIMP_ALIGN_VCENTER, /*< desc="Center vertically" >*/
GIMP_ALIGN_BOTTOM, /*< desc="Align to the bottom" >*/
GIMP_ARRANGE_HFILL, /*< desc="Distribute anchor points horizontally evenly" >*/
GIMP_ARRANGE_VFILL, /*< desc="Distribute anchor points vertically evenly" >*/
GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP, /*< desc="Distribute horizontally with even horizontal gaps" >*/
GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP, /*< desc="Distribute vertically with even vertical gaps" >*/
GIMP_SHIFT_FROM_TOP, /*< desc="Align to the top and distribute vertically with offset" >*/
GIMP_SHIFT_FROM_BOTTOM, /*< desc="Align to the bottom and distribute vertically with offset" >*/
GIMP_SHIFT_FROM_LEFT, /*< desc="Align to the left and distribute horizontally with offset" >*/
GIMP_SHIFT_FROM_RIGHT, /*< desc="Align to the right and distribute horizontally with offset" >*/
} GimpAlignmentType;

View File

@@ -52,24 +52,24 @@ 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.
* @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.
* @image: The #GimpImage to which the objects belong.
* @list: A #GList of objects to be aligned.
* @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.
* @align_type: The type of alignment or distribution.
* @align_contents: Take into account non-empty contents rather than item borders.
*
* This function shifts the positions of a set of target objects,
* which can be "items" or guides, to bring them into a specified type
* of alignment with a reference object, which can be an item, guide,
* or image. If the requested alignment does not make sense (i.e.,
* or image. If the requested alignment does not make sense (e.g.
* trying to align a vertical guide vertically), nothing happens and
* no error message is generated.
*
* The objects in the list are sorted into increasing order before
* being arranged, where the order is defined by the type of alignment
* being requested. If the @reference argument is %NULL, then the
* being requested. If the @reference argument is %NULL, then the
* first object in the sorted list is used as reference.
*/
void
@@ -78,8 +78,9 @@ gimp_image_arrange_objects (GimpImage *image,
gdouble align_x,
gdouble align_y,
GObject *reference,
GimpAlignmentType reference_alignment,
gboolean align_contents)
GimpAlignmentType align_type,
gboolean align_contents,
gint offset)
{
gdouble reference_x = 0.0;
gdouble reference_y = 0.0;
@@ -115,7 +116,7 @@ gimp_image_arrange_objects (GimpImage *image,
}
/* get offsets used for sorting */
switch (reference_alignment)
switch (align_type)
{
/* order vertically for horizontal alignment */
case GIMP_ALIGN_LEFT:
@@ -124,13 +125,15 @@ gimp_image_arrange_objects (GimpImage *image,
if (GIMP_IS_GUIDE (reference) &&
gimp_guide_get_orientation (GIMP_GUIDE (reference)) == GIMP_ORIENTATION_HORIZONTAL)
return;
case GIMP_SHIFT_FROM_LEFT:
case GIMP_SHIFT_FROM_RIGHT:
use_obj_x_offset = TRUE;
use_ref_x_offset = TRUE;
if (reference_alignment == GIMP_ALIGN_HCENTER)
if (align_type == GIMP_ALIGN_HCENTER)
reference_x = 0.5;
else if (reference_alignment == GIMP_ALIGN_RIGHT)
else if (align_type == GIMP_ALIGN_RIGHT)
reference_x = 1.0;
do_x = TRUE;
@@ -152,10 +155,12 @@ gimp_image_arrange_objects (GimpImage *image,
if (GIMP_IS_GUIDE (reference) &&
gimp_guide_get_orientation (GIMP_GUIDE (reference)) == GIMP_ORIENTATION_VERTICAL)
return;
case GIMP_SHIFT_FROM_TOP:
case GIMP_SHIFT_FROM_BOTTOM:
if (reference_alignment == GIMP_ALIGN_VCENTER)
if (align_type == GIMP_ALIGN_VCENTER)
reference_y = 0.5;
else if (reference_alignment == GIMP_ALIGN_BOTTOM)
else if (align_type == GIMP_ALIGN_BOTTOM)
reference_y = 1.0;
do_y = TRUE;
@@ -200,10 +205,10 @@ gimp_image_arrange_objects (GimpImage *image,
gint n;
gdouble fill_offset = 0;
if (reference_alignment == GIMP_ARRANGE_HFILL ||
reference_alignment == GIMP_ARRANGE_VFILL ||
reference_alignment == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP ||
reference_alignment == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
if (align_type == GIMP_ARRANGE_HFILL ||
align_type == GIMP_ARRANGE_VFILL ||
align_type == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP ||
align_type == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
{
/* Distribution does not use the reference. Extreme coordinate items
* are used instead.
@@ -214,14 +219,14 @@ gimp_image_arrange_objects (GimpImage *image,
z0 = GPOINTER_TO_INT (g_object_get_data (object_list->data, "align-offset"));
distr_length = GPOINTER_TO_INT (g_object_get_data (last_object->data, "align-offset")) - z0;
if (reference_alignment == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP ||
reference_alignment == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
if (align_type == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP ||
align_type == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
{
for (list = object_list; list && list->next; list = g_list_next (list))
{
gint obj_len;
if (reference_alignment == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP)
if (align_type == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP)
obj_len = GPOINTER_TO_INT (g_object_get_data (list->data, "align-width"));
else
obj_len = GPOINTER_TO_INT (g_object_get_data (list->data, "align-height"));
@@ -242,6 +247,29 @@ gimp_image_arrange_objects (GimpImage *image,
object_list = g_list_delete_link (object_list, last_object);
object_list = g_list_delete_link (object_list, object_list);
}
else if (align_type == GIMP_SHIFT_FROM_TOP ||
align_type == GIMP_SHIFT_FROM_LEFT)
{
z0 = GPOINTER_TO_INT (g_object_get_data (object_list->data, "align-offset"));
fill_offset = offset;
/* First object won't move. */
object_list = g_list_delete_link (object_list, object_list);
}
else if (align_type == GIMP_SHIFT_FROM_BOTTOM ||
align_type == GIMP_SHIFT_FROM_RIGHT)
{
GList *last_object = g_list_last (object_list);
z0 = GPOINTER_TO_INT (g_object_get_data (last_object->data, "align-offset"));
fill_offset = -offset;
/* Last object won't move. */
object_list = g_list_delete_link (object_list, last_object);
/* Start from the end. */
object_list = g_list_reverse (object_list);
}
else
{
if (reference == NULL)
@@ -270,15 +298,15 @@ gimp_image_arrange_objects (GimpImage *image,
z1 = GPOINTER_TO_INT (g_object_get_data (target, "align-offset"));
if (reference_alignment == GIMP_ARRANGE_HFILL)
if (align_type == GIMP_ARRANGE_HFILL)
{
xtranslate = ROUND (z0 - z1 + n * fill_offset);
}
else if (reference_alignment == GIMP_ARRANGE_VFILL)
else if (align_type == GIMP_ARRANGE_VFILL)
{
ytranslate = ROUND (z0 - z1 + n * fill_offset);
}
else if (reference_alignment == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP)
else if (align_type == GIMP_DISTRIBUTE_EVEN_HORIZONTAL_GAP)
{
gint obj_len;
@@ -287,7 +315,7 @@ gimp_image_arrange_objects (GimpImage *image,
obj_len = GPOINTER_TO_INT (g_object_get_data (target, "align-width"));
z0 = z0 + fill_offset + obj_len;
}
else if (reference_alignment == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
else if (align_type == GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP)
{
gint obj_len;
@@ -296,6 +324,16 @@ gimp_image_arrange_objects (GimpImage *image,
obj_len = GPOINTER_TO_INT (g_object_get_data (target, "align-height"));
z0 = z0 + fill_offset + obj_len;
}
else if (align_type == GIMP_SHIFT_FROM_TOP ||
align_type == GIMP_SHIFT_FROM_BOTTOM)
{
ytranslate = ROUND (z0 - z1 + n * fill_offset);
}
else if (align_type == GIMP_SHIFT_FROM_LEFT ||
align_type == GIMP_SHIFT_FROM_RIGHT)
{
xtranslate = ROUND (z0 - z1 + n * fill_offset);
}
else /* the normal computing, when we don't depend on the
* width or height of the reference object
*/

View File

@@ -24,4 +24,5 @@ void gimp_image_arrange_objects (GimpImage *image,
gdouble align_y,
GObject *reference,
GimpAlignmentType reference_alignment,
gboolean align_contents);
gboolean align_contents,
gint offset);

View File

@@ -44,10 +44,12 @@
#include "gimp-intl.h"
#define ALIGN_VER_N_BUTTONS 3
#define ALIGN_HOR_N_BUTTONS 3
#define DISTR_VER_N_BUTTONS 2
#define DISTR_HOR_N_BUTTONS 2
#define ALIGN_VER_N_BUTTONS 3
#define ALIGN_HOR_N_BUTTONS 3
#define DISTR_VER_N_BUTTONS 2
#define DISTR_HOR_N_BUTTONS 2
#define ALIGN_DISTR_VER_N_BUTTONS 2
#define ALIGN_DISTR_HOR_N_BUTTONS 2
enum
@@ -62,9 +64,11 @@ enum
PROP_ALIGN_REFERENCE,
PROP_ALIGN_LAYERS,
PROP_ALIGN_PATHS,
PROP_ALIGN_GUIDES,
PROP_ALIGN_CONTENTS,
PROP_PIVOT_X,
PROP_PIVOT_Y,
PROP_SHIFT_OFFSET,
};
struct _GimpAlignOptionsPrivate
@@ -73,9 +77,11 @@ struct _GimpAlignOptionsPrivate
gboolean align_layers;
gboolean align_paths;
gboolean align_guides;
gboolean align_contents;
gdouble pivot_x;
gdouble pivot_y;
gint shift_offset;
GList *selected_guides;
GObject *reference;
@@ -85,11 +91,14 @@ struct _GimpAlignOptionsPrivate
GtkWidget *reference_box;
GtkWidget *reference_label;
GtkWidget *pivot_selector;
GtkWidget *anchor_label;
GtkWidget *align_ver_button[ALIGN_VER_N_BUTTONS];
GtkWidget *align_hor_button[ALIGN_HOR_N_BUTTONS];
GtkWidget *distr_ver_button[DISTR_VER_N_BUTTONS];
GtkWidget *distr_hor_button[DISTR_HOR_N_BUTTONS];
GtkWidget *offset_ver_button[ALIGN_DISTR_VER_N_BUTTONS];
GtkWidget *offset_hor_button[ALIGN_DISTR_HOR_N_BUTTONS];
};
@@ -116,6 +125,8 @@ static void gimp_align_options_reference_removed (GObject *objec
static void gimp_align_options_pivot_changed (GimpPivotSelector *selector,
GimpAlignOptions *options);
static const gchar * gimp_align_options_get_anchor_text (GimpAlignOptions *options);
G_DEFINE_TYPE_WITH_PRIVATE (GimpAlignOptions, gimp_align_options, GIMP_TYPE_TOOL_OPTIONS)
@@ -165,6 +176,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_GUIDES,
"align-guides",
_("Pick guides"),
_("Picked guides 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"),
@@ -185,6 +202,13 @@ gimp_align_options_class_init (GimpAlignOptionsClass *klass)
NULL,
0.0, 1.0, 0.5,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_INT (object_class, PROP_SHIFT_OFFSET,
"shift-offset",
"Offset in pixels when shifting",
NULL,
-G_MAXINT, G_MAXINT, 10,
GIMP_PARAM_STATIC_STRINGS);
}
static void
@@ -230,6 +254,12 @@ gimp_align_options_set_property (GObject *object,
options->priv->align_paths = g_value_get_boolean (value);
gimp_align_options_update_area (options);
break;
case PROP_ALIGN_GUIDES:
options->priv->align_guides = g_value_get_boolean (value);
if (! options->priv->align_guides)
g_clear_pointer (&options->priv->selected_guides, g_list_free);
gimp_align_options_update_area (options);
break;
case PROP_ALIGN_CONTENTS:
options->priv->align_contents = g_value_get_boolean (value);
@@ -242,6 +272,10 @@ gimp_align_options_set_property (GObject *object,
options->priv->pivot_y = g_value_get_double (value);
break;
case PROP_SHIFT_OFFSET:
options->priv->shift_offset = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -268,6 +302,9 @@ gimp_align_options_get_property (GObject *object,
case PROP_ALIGN_PATHS:
g_value_set_boolean (value, options->priv->align_paths);
break;
case PROP_ALIGN_GUIDES:
g_value_set_boolean (value, options->priv->align_guides);
break;
case PROP_ALIGN_CONTENTS:
g_value_set_boolean (value, options->priv->align_contents);
@@ -280,6 +317,10 @@ gimp_align_options_get_property (GObject *object,
g_value_set_double (value, options->priv->pivot_y);
break;
case PROP_SHIFT_OFFSET:
g_value_set_int (value, options->priv->shift_offset);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -312,21 +353,25 @@ gimp_align_options_button_new (GimpAlignOptions *options,
switch (action)
{
case GIMP_ALIGN_LEFT:
case GIMP_SHIFT_FROM_LEFT:
icon_name = GIMP_ICON_GRAVITY_WEST;
break;
case GIMP_ALIGN_HCENTER:
icon_name = GIMP_ICON_CENTER_HORIZONTAL;
break;
case GIMP_ALIGN_RIGHT:
case GIMP_SHIFT_FROM_RIGHT:
icon_name = GIMP_ICON_GRAVITY_EAST;
break;
case GIMP_ALIGN_TOP:
case GIMP_SHIFT_FROM_TOP:
icon_name = GIMP_ICON_GRAVITY_NORTH;
break;
case GIMP_ALIGN_VCENTER:
icon_name = GIMP_ICON_CENTER_VERTICAL;
break;
case GIMP_ALIGN_BOTTOM:
case GIMP_SHIFT_FROM_BOTTOM:
icon_name = GIMP_ICON_GRAVITY_SOUTH;
break;
case GIMP_ARRANGE_HFILL:
@@ -375,21 +420,19 @@ 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 *popover;
GtkWidget *section_vbox;
GtkWidget *items_grid;
GtkWidget *guide_box;
GtkWidget *hbox;
GtkWidget *frame;
GtkWidget *combo;
gchar *text;
gint n = 0;
/* Selected objects */
frame = gimp_frame_new (_("Targets"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* SECTION: Objects */
section_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), section_vbox);
gtk_container_add (GTK_CONTAINER (vbox), section_vbox);
gtk_widget_show (section_vbox);
items_grid = gtk_grid_new ();
@@ -404,20 +447,14 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
widget = gimp_prop_check_button_new (config, "align-paths", NULL);
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);
gtk_widget_set_tooltip_text (options->priv->pivot_selector,
_("Set anchor point of targets"));
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);
guide_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
widget = gimp_prop_expanding_frame_new (config, "align-guides",
NULL, guide_box, NULL);
gtk_grid_attach (GTK_GRID (items_grid), widget, 0, 2, 1, 1);
gtk_widget_show (widget);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (guide_box), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
widget = gtk_image_new_from_icon_name (GIMP_ICON_CURSOR, GTK_ICON_SIZE_BUTTON);
@@ -437,11 +474,49 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gtk_widget_show (widget);
widget = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (section_vbox), widget, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (guide_box), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
options->priv->selected_guides_label = widget;
/* Align frame */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
widget = gtk_button_new_from_icon_name (GIMP_ICON_LAYER_ANCHOR, GTK_ICON_SIZE_BUTTON);
gtk_widget_set_tooltip_text (widget, _("Set which point in each item will be aligned or distributed"));
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
/* The popup for the anchor point selection */
popover = gtk_popover_new (widget);
options->priv->pivot_selector = gimp_pivot_selector_new (0.0, 0.0, 1.0, 1.0);
gtk_widget_set_tooltip_text (options->priv->pivot_selector,
_("Set anchor point of targets"));
gimp_pivot_selector_set_position (GIMP_PIVOT_SELECTOR (options->priv->pivot_selector),
options->priv->pivot_x, options->priv->pivot_y);
gtk_container_add (GTK_CONTAINER (popover), options->priv->pivot_selector);
gtk_widget_show (options->priv->pivot_selector);
g_signal_connect_swapped (widget, "clicked",
G_CALLBACK (gtk_popover_popup),
popover);
/* The anchor point label */
text = g_strdup_printf (_("Anchor point: %s"),
gimp_align_options_get_anchor_text (options));
widget = gtk_label_new (text);
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD);
g_free (text);
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
options->priv->anchor_label = widget;
g_signal_connect (options->priv->pivot_selector, "changed",
G_CALLBACK (gimp_align_options_pivot_changed),
options);
/* SECTION: Align */
frame = gimp_frame_new (_("Align"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
@@ -511,7 +586,7 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gimp_align_options_button_new (options, GIMP_ALIGN_BOTTOM, hbox,
_("Align anchor points of targets on bottom of reference"));
/* Distribute frame */
/* SECTION: Distribute */
frame = gimp_frame_new (_("Distribute"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
@@ -544,6 +619,39 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gimp_align_options_button_new (options, GIMP_DISTRIBUTE_EVEN_VERTICAL_GAP, hbox,
_("Distribute vertically with even vertical gaps"));
/* SECTION: Shift by Offset */
frame = gimp_frame_new (_("Shift"));
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 (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
n = 0;
options->priv->offset_hor_button[n++] =
gimp_align_options_button_new (options, GIMP_SHIFT_FROM_LEFT, hbox,
_("Align to the left and distribute horizontally with offset"));
options->priv->offset_hor_button[n++] =
gimp_align_options_button_new (options, GIMP_SHIFT_FROM_RIGHT, hbox,
_("Align to the right and distribute horizontally with offset"));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
n = 0;
options->priv->offset_ver_button[n++] =
gimp_align_options_button_new (options, GIMP_SHIFT_FROM_TOP, hbox,
_("Align to the top and distribute vertically with offset"));
options->priv->offset_ver_button[n++] =
gimp_align_options_button_new (options, GIMP_SHIFT_FROM_BOTTOM, hbox,
_("Align to the bottom and distribute vertically with offset"));
g_signal_connect_object (gimp_get_user_context (GIMP_CONTEXT (options)->gimp),
"image-changed",
G_CALLBACK (gimp_align_options_image_changed),
@@ -552,6 +660,18 @@ gimp_align_options_gui (GimpToolOptions *tool_options)
gimp_context_get_image (gimp_get_user_context (GIMP_CONTEXT (options)->gimp)),
options);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (section_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
widget = gtk_label_new (_("Offset:"));
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
widget = gimp_prop_spin_button_new (config, "shift-offset", 1, 20, 0);
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
return vbox;
}
@@ -582,7 +702,7 @@ gimp_align_options_get_objects (GimpAlignOptions *options)
objects = g_list_concat (objects, paths);
}
if (options->priv->selected_guides)
if (options->priv->align_guides && options->priv->selected_guides)
{
GList *guides;
@@ -671,11 +791,26 @@ gimp_align_options_align_contents (GimpAlignOptions *options)
return options->priv->align_contents;
}
gboolean
gimp_align_options_align_guides (GimpAlignOptions *options)
{
return options->priv->align_guides;
}
gint
gimp_align_options_get_shift_offset (GimpAlignOptions *options)
{
return options->priv->shift_offset;
}
void
gimp_align_options_pick_guide (GimpAlignOptions *options,
GimpGuide *guide,
gboolean extend)
{
if (! options->priv->align_guides)
return;
if (! extend)
g_clear_pointer (&options->priv->selected_guides, g_list_free);
@@ -761,8 +896,8 @@ gimp_align_options_update_area (GimpAlignOptions *options)
n_items += g_list_length (layers);
if (options->priv->align_paths)
n_items += g_list_length (paths);
n_items += g_list_length (options->priv->selected_guides);
if (options->priv->align_guides)
n_items += g_list_length (options->priv->selected_guides);
}
if (n_items > 0)
@@ -787,9 +922,13 @@ gimp_align_options_update_area (GimpAlignOptions *options)
gtk_widget_set_sensitive (options->priv->distr_ver_button[i], enable_ver_distr);
for (gint i = 0; i < DISTR_HOR_N_BUTTONS; i++)
gtk_widget_set_sensitive (options->priv->distr_hor_button[i], enable_hor_distr);
for (gint i = 0; i < ALIGN_DISTR_HOR_N_BUTTONS; i++)
gtk_widget_set_sensitive (options->priv->offset_hor_button[i], enable_hor_distr);
for (gint i = 0; i < ALIGN_DISTR_VER_N_BUTTONS; i++)
gtk_widget_set_sensitive (options->priv->offset_ver_button[i], enable_ver_distr);
/* Update the guide picking widgets. */
if (options->priv->selected_guides)
if (options->priv->align_guides && options->priv->selected_guides)
{
gchar *tmp_txt;
@@ -881,4 +1020,46 @@ gimp_align_options_pivot_changed (GimpPivotSelector *selector,
"pivot-x", x,
"pivot-y", y,
NULL);
if (options->priv->anchor_label)
{
gchar *text;
text = g_strdup_printf (_("Anchor point: %s"),
gimp_align_options_get_anchor_text (options));
gtk_label_set_text (GTK_LABEL (options->priv->anchor_label), text);
g_free (text);
}
}
static const gchar *
gimp_align_options_get_anchor_text (GimpAlignOptions *options)
{
if (options->priv->pivot_x == 0.0)
{
if (options->priv->pivot_y == 0.0)
return _("top-left");
else if (options->priv->pivot_y == 0.5)
return _("left");
else
return _("bottom-left");
}
else if (options->priv->pivot_x == 0.5)
{
if (options->priv->pivot_y == 0.0)
return _("top");
else if (options->priv->pivot_y == 0.5)
return _("center");
else
return _("bottom");
}
else
{
if (options->priv->pivot_y == 0.0)
return _("top-right");
else if (options->priv->pivot_y == 0.5)
return _("right");
else
return _("bottom-right");
}
}

View File

@@ -64,6 +64,8 @@ void gimp_align_options_pick_reference (GimpAlignOptions *options,
GObject * gimp_align_options_get_reference (GimpAlignOptions *options,
gboolean blink_if_none);
gboolean gimp_align_options_align_contents (GimpAlignOptions *options);
gboolean gimp_align_options_align_guides (GimpAlignOptions *options);
gint gimp_align_options_get_shift_offset (GimpAlignOptions *options);
void gimp_align_options_pick_guide (GimpAlignOptions *options,
GimpGuide *guide,

View File

@@ -191,6 +191,9 @@ gimp_align_tool_constructed (GObject *object)
g_signal_connect_object (options, "notify::align-contents",
G_CALLBACK (gimp_align_tool_redraw),
align_tool, G_CONNECT_SWAPPED);
g_signal_connect_object (options, "notify::align-guides",
G_CALLBACK (gimp_align_tool_redraw),
align_tool, G_CONNECT_SWAPPED);
g_signal_connect_object (gimp_get_user_context (GIMP_CONTEXT (options)->gimp),
"display-changed",
G_CALLBACK (gimp_align_tool_display_changed),
@@ -545,6 +548,7 @@ gimp_align_tool_status_update (GimpTool *tool,
gboolean proximity)
{
GimpAlignTool *align_tool = GIMP_ALIGN_TOOL (tool);
GimpAlignOptions *options = GIMP_ALIGN_TOOL_GET_OPTIONS (align_tool);
gchar *status = NULL;
GdkModifierType extend_mask;
@@ -576,16 +580,19 @@ gimp_align_tool_status_update (GimpTool *tool,
break;
case ALIGN_TOOL_ALIGN_IDLE:
status = g_strdup (_("Click on a guide to add it to objects to align, "
"click anywhere else to unselect all guides"));
if (gimp_align_options_align_guides (options))
status = g_strdup (_("Click on a guide to add it to objects to align, "
"click anywhere else to unselect all guides"));
break;
case ALIGN_TOOL_ALIGN_PICK_GUIDE:
status = gimp_suggest_modifiers (_("Click to select this guide for alignment"),
extend_mask & ~state,
NULL, NULL, NULL);
if (gimp_align_options_align_guides (options))
status = gimp_suggest_modifiers (_("Click to select this guide for alignment"),
extend_mask & ~state,
NULL, NULL, NULL);
break;
case ALIGN_TOOL_ALIGN_ADD_GUIDE:
status = g_strdup (_("Click to add this guide to the list of objects to align"));
if (gimp_align_options_align_guides (options))
status = g_strdup (_("Click to add this guide to the list of objects to align"));
break;
case ALIGN_TOOL_NO_ACTION:
@@ -811,7 +818,8 @@ gimp_align_tool_align (GimpAlignTool *align_tool,
align_x, align_y,
reference_object,
align_type,
gimp_align_options_align_contents (options));
gimp_align_options_align_contents (options),
gimp_align_options_get_shift_offset (options));
gimp_draw_tool_resume (GIMP_DRAW_TOOL (align_tool));