Remove the GimpSymmetry::get_operation() virtual function, and
instead implement gimp_symmetry_get_operation() by returning an
appropriate gegl:transform node based on the matrix returned by
gimp_symmetry_get_matrix(). The returned node is owned by the
caller; since we no longer use the node's identity for caching
trnasformed brushes, we no longer cache the transformation nodes.
Remove the function's paint_width and paint_height parameters, and
instead return a transformation that should be applied at the
center of the brush. This simplifies the application of the
transformation in the Clone and Heal tools, as per the next commit.
Remove the implementation of GimpSymmetry::get_operation() from all
its subclasses, which should now only implement
GimpSymmetry::get_transform().
(cherry picked from commit 60a3965020)
731 lines
24 KiB
C
731 lines
24 KiB
C
/* GIMP - The GNU Image Manipulation Program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* gimpsymmetry-mirror.c
|
|
* Copyright (C) 2015 Jehan <jehan@gimp.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <cairo.h>
|
|
#include <gegl.h>
|
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
|
|
|
#include "libgimpconfig/gimpconfig.h"
|
|
|
|
#include "core-types.h"
|
|
|
|
#include "gimp.h"
|
|
#include "gimp-cairo.h"
|
|
#include "gimpbrush.h"
|
|
#include "gimpguide.h"
|
|
#include "gimpimage.h"
|
|
#include "gimpimage-guides.h"
|
|
#include "gimpimage-symmetry.h"
|
|
#include "gimpitem.h"
|
|
#include "gimpsymmetry-mirror.h"
|
|
|
|
#include "gimp-intl.h"
|
|
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_HORIZONTAL_SYMMETRY,
|
|
PROP_VERTICAL_SYMMETRY,
|
|
PROP_POINT_SYMMETRY,
|
|
PROP_DISABLE_TRANSFORMATION,
|
|
PROP_MIRROR_POSITION_X,
|
|
PROP_MIRROR_POSITION_Y
|
|
};
|
|
|
|
|
|
/* Local function prototypes */
|
|
|
|
static void gimp_mirror_constructed (GObject *object);
|
|
static void gimp_mirror_finalize (GObject *object);
|
|
static void gimp_mirror_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec);
|
|
static void gimp_mirror_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec);
|
|
|
|
static void gimp_mirror_update_strokes (GimpSymmetry *mirror,
|
|
GimpDrawable *drawable,
|
|
GimpCoords *origin);
|
|
static void gimp_mirror_get_transform (GimpSymmetry *mirror,
|
|
gint stroke,
|
|
gdouble *angle,
|
|
gboolean *reflect);
|
|
static void gimp_mirror_reset (GimpMirror *mirror);
|
|
static void gimp_mirror_add_guide (GimpMirror *mirror,
|
|
GimpOrientationType orientation);
|
|
static void gimp_mirror_remove_guide (GimpMirror *mirror,
|
|
GimpOrientationType orientation);
|
|
static void gimp_mirror_guide_removed_cb (GObject *object,
|
|
GimpMirror *mirror);
|
|
static void gimp_mirror_guide_position_cb (GObject *object,
|
|
GParamSpec *pspec,
|
|
GimpMirror *mirror);
|
|
static void gimp_mirror_active_changed (GimpSymmetry *sym);
|
|
static void gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
|
|
gboolean active);
|
|
static void gimp_mirror_set_vertical_symmetry (GimpMirror *mirror,
|
|
gboolean active);
|
|
static void gimp_mirror_set_point_symmetry (GimpMirror *mirror,
|
|
gboolean active);
|
|
|
|
static void gimp_mirror_image_size_changed_cb (GimpImage *image,
|
|
gint previous_origin_x,
|
|
gint previous_origin_y,
|
|
gint previous_width,
|
|
gint previous_height,
|
|
GimpSymmetry *sym);
|
|
|
|
G_DEFINE_TYPE (GimpMirror, gimp_mirror, GIMP_TYPE_SYMMETRY)
|
|
|
|
#define parent_class gimp_mirror_parent_class
|
|
|
|
|
|
static void
|
|
gimp_mirror_class_init (GimpMirrorClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GimpSymmetryClass *symmetry_class = GIMP_SYMMETRY_CLASS (klass);
|
|
GParamSpec *pspec;
|
|
|
|
object_class->constructed = gimp_mirror_constructed;
|
|
object_class->finalize = gimp_mirror_finalize;
|
|
object_class->set_property = gimp_mirror_set_property;
|
|
object_class->get_property = gimp_mirror_get_property;
|
|
|
|
symmetry_class->label = _("Mirror");
|
|
symmetry_class->update_strokes = gimp_mirror_update_strokes;
|
|
symmetry_class->get_transform = gimp_mirror_get_transform;
|
|
symmetry_class->active_changed = gimp_mirror_active_changed;
|
|
|
|
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_HORIZONTAL_SYMMETRY,
|
|
"horizontal-symmetry",
|
|
_("Horizontal Symmetry"),
|
|
_("Reflect the initial stroke across a horizontal axis"),
|
|
FALSE,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VERTICAL_SYMMETRY,
|
|
"vertical-symmetry",
|
|
_("Vertical Symmetry"),
|
|
_("Reflect the initial stroke across a vertical axis"),
|
|
FALSE,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_POINT_SYMMETRY,
|
|
"point-symmetry",
|
|
_("Central Symmetry"),
|
|
_("Invert the initial stroke through a point"),
|
|
FALSE,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DISABLE_TRANSFORMATION,
|
|
"disable-transformation",
|
|
_("Disable brush transform"),
|
|
_("Disable brush reflection"),
|
|
FALSE,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_MIRROR_POSITION_X,
|
|
"mirror-position-x",
|
|
_("Vertical axis position"),
|
|
NULL,
|
|
0.0, G_MAXDOUBLE, 0.0,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
pspec = g_object_class_find_property (object_class, "mirror-position-x");
|
|
gegl_param_spec_set_property_key (pspec, "unit", "pixel-coordinate");
|
|
gegl_param_spec_set_property_key (pspec, "axis", "x");
|
|
|
|
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_MIRROR_POSITION_Y,
|
|
"mirror-position-y",
|
|
_("Horizontal axis position"),
|
|
NULL,
|
|
0.0, G_MAXDOUBLE, 0.0,
|
|
GIMP_PARAM_STATIC_STRINGS |
|
|
GIMP_SYMMETRY_PARAM_GUI);
|
|
|
|
pspec = g_object_class_find_property (object_class, "mirror-position-y");
|
|
gegl_param_spec_set_property_key (pspec, "unit", "pixel-coordinate");
|
|
gegl_param_spec_set_property_key (pspec, "axis", "y");
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_init (GimpMirror *mirror)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_constructed (GObject *object)
|
|
{
|
|
GimpSymmetry *sym = GIMP_SYMMETRY (object);
|
|
|
|
g_signal_connect_object (sym->image, "size-changed-detailed",
|
|
G_CALLBACK (gimp_mirror_image_size_changed_cb),
|
|
sym, 0);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_finalize (GObject *object)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (object);
|
|
|
|
g_clear_object (&mirror->horizontal_guide);
|
|
g_clear_object (&mirror->vertical_guide);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (object);
|
|
GimpImage *image = GIMP_SYMMETRY (mirror)->image;
|
|
|
|
switch (property_id)
|
|
{
|
|
case PROP_HORIZONTAL_SYMMETRY:
|
|
gimp_mirror_set_horizontal_symmetry (mirror,
|
|
g_value_get_boolean (value));
|
|
break;
|
|
|
|
case PROP_VERTICAL_SYMMETRY:
|
|
gimp_mirror_set_vertical_symmetry (mirror,
|
|
g_value_get_boolean (value));
|
|
break;
|
|
|
|
case PROP_POINT_SYMMETRY:
|
|
gimp_mirror_set_point_symmetry (mirror,
|
|
g_value_get_boolean (value));
|
|
break;
|
|
|
|
case PROP_DISABLE_TRANSFORMATION:
|
|
mirror->disable_transformation = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_MIRROR_POSITION_X:
|
|
if (g_value_get_double (value) >= 0.0 &&
|
|
g_value_get_double (value) < (gdouble) gimp_image_get_width (image))
|
|
{
|
|
mirror->mirror_position_x = g_value_get_double (value);
|
|
|
|
if (mirror->vertical_guide)
|
|
{
|
|
g_signal_handlers_block_by_func (mirror->vertical_guide,
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
gimp_image_move_guide (image, mirror->vertical_guide,
|
|
mirror->mirror_position_x,
|
|
FALSE);
|
|
g_signal_handlers_unblock_by_func (mirror->vertical_guide,
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PROP_MIRROR_POSITION_Y:
|
|
if (g_value_get_double (value) >= 0.0 &&
|
|
g_value_get_double (value) < (gdouble) gimp_image_get_height (image))
|
|
{
|
|
mirror->mirror_position_y = g_value_get_double (value);
|
|
|
|
if (mirror->horizontal_guide)
|
|
{
|
|
g_signal_handlers_block_by_func (mirror->horizontal_guide,
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
gimp_image_move_guide (image, mirror->horizontal_guide,
|
|
mirror->mirror_position_y,
|
|
FALSE);
|
|
g_signal_handlers_unblock_by_func (mirror->horizontal_guide,
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (object);
|
|
|
|
switch (property_id)
|
|
{
|
|
case PROP_HORIZONTAL_SYMMETRY:
|
|
g_value_set_boolean (value, mirror->horizontal_mirror);
|
|
break;
|
|
case PROP_VERTICAL_SYMMETRY:
|
|
g_value_set_boolean (value, mirror->vertical_mirror);
|
|
break;
|
|
case PROP_POINT_SYMMETRY:
|
|
g_value_set_boolean (value, mirror->point_symmetry);
|
|
break;
|
|
case PROP_DISABLE_TRANSFORMATION:
|
|
g_value_set_boolean (value, mirror->disable_transformation);
|
|
break;
|
|
case PROP_MIRROR_POSITION_X:
|
|
g_value_set_double (value, mirror->mirror_position_x);
|
|
break;
|
|
case PROP_MIRROR_POSITION_Y:
|
|
g_value_set_double (value, mirror->mirror_position_y);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_update_strokes (GimpSymmetry *sym,
|
|
GimpDrawable *drawable,
|
|
GimpCoords *origin)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (sym);
|
|
GList *strokes = NULL;
|
|
GimpCoords *coords;
|
|
|
|
g_list_free_full (sym->strokes, g_free);
|
|
strokes = g_list_prepend (strokes,
|
|
g_memdup (origin, sizeof (GimpCoords)));
|
|
|
|
if (mirror->horizontal_mirror)
|
|
{
|
|
coords = g_memdup (origin, sizeof (GimpCoords));
|
|
coords->y = 2.0 * mirror->mirror_position_y - origin->y;
|
|
strokes = g_list_prepend (strokes, coords);
|
|
}
|
|
|
|
if (mirror->vertical_mirror)
|
|
{
|
|
coords = g_memdup (origin, sizeof (GimpCoords));
|
|
coords->x = 2.0 * mirror->mirror_position_x - origin->x;
|
|
strokes = g_list_prepend (strokes, coords);
|
|
}
|
|
|
|
if (mirror->point_symmetry)
|
|
{
|
|
coords = g_memdup (origin, sizeof (GimpCoords));
|
|
coords->x = 2.0 * mirror->mirror_position_x - origin->x;
|
|
coords->y = 2.0 * mirror->mirror_position_y - origin->y;
|
|
strokes = g_list_prepend (strokes, coords);
|
|
}
|
|
|
|
sym->strokes = g_list_reverse (strokes);
|
|
|
|
g_signal_emit_by_name (sym, "strokes-updated", sym->image);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_get_transform (GimpSymmetry *sym,
|
|
gint stroke,
|
|
gdouble *angle,
|
|
gboolean *reflect)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (sym);
|
|
|
|
if (mirror->disable_transformation)
|
|
return;
|
|
|
|
if (! mirror->horizontal_mirror && stroke >= 1)
|
|
stroke++;
|
|
|
|
if (! mirror->vertical_mirror && stroke >= 2)
|
|
stroke++;
|
|
|
|
switch (stroke)
|
|
{
|
|
/* original */
|
|
case 0:
|
|
break;
|
|
|
|
/* horizontal */
|
|
case 1:
|
|
*angle = 180.0;
|
|
*reflect = TRUE;
|
|
break;
|
|
|
|
/* vertical */
|
|
case 2:
|
|
*reflect = TRUE;
|
|
break;
|
|
|
|
/* central */
|
|
case 3:
|
|
*angle = 180.0;
|
|
break;
|
|
|
|
default:
|
|
g_return_if_reached ();
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_reset (GimpMirror *mirror)
|
|
{
|
|
GimpSymmetry *sym = GIMP_SYMMETRY (mirror);
|
|
|
|
if (sym->origin)
|
|
{
|
|
gimp_symmetry_set_origin (sym, sym->drawable,
|
|
sym->origin);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_add_guide (GimpMirror *mirror,
|
|
GimpOrientationType orientation)
|
|
{
|
|
GimpSymmetry *sym = GIMP_SYMMETRY (mirror);
|
|
GimpImage *image;
|
|
Gimp *gimp;
|
|
GimpGuide *guide;
|
|
gdouble position;
|
|
|
|
image = sym->image;
|
|
gimp = image->gimp;
|
|
|
|
guide = gimp_guide_custom_new (orientation,
|
|
gimp->next_guide_ID++,
|
|
GIMP_GUIDE_STYLE_MIRROR);
|
|
|
|
if (orientation == GIMP_ORIENTATION_HORIZONTAL)
|
|
{
|
|
/* Mirror guide position at first activation is at canvas middle. */
|
|
if (mirror->mirror_position_y < 1.0)
|
|
position = gimp_image_get_height (image) / 2.0;
|
|
else
|
|
position = mirror->mirror_position_y;
|
|
|
|
g_object_set (mirror,
|
|
"mirror-position-y", position,
|
|
NULL);
|
|
|
|
mirror->horizontal_guide = guide;
|
|
}
|
|
else
|
|
{
|
|
/* Mirror guide position at first activation is at canvas middle. */
|
|
if (mirror->mirror_position_x < 1.0)
|
|
position = gimp_image_get_width (image) / 2.0;
|
|
else
|
|
position = mirror->mirror_position_x;
|
|
|
|
g_object_set (mirror,
|
|
"mirror-position-x", position,
|
|
NULL);
|
|
|
|
mirror->vertical_guide = guide;
|
|
}
|
|
|
|
g_signal_connect (guide, "removed",
|
|
G_CALLBACK (gimp_mirror_guide_removed_cb),
|
|
mirror);
|
|
|
|
gimp_image_add_guide (image, guide, (gint) position);
|
|
|
|
g_signal_connect (guide, "notify::position",
|
|
G_CALLBACK (gimp_mirror_guide_position_cb),
|
|
mirror);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_remove_guide (GimpMirror *mirror,
|
|
GimpOrientationType orientation)
|
|
{
|
|
GimpSymmetry *sym = GIMP_SYMMETRY (mirror);
|
|
GimpImage *image;
|
|
GimpGuide *guide;
|
|
|
|
image = sym->image;
|
|
guide = (orientation == GIMP_ORIENTATION_HORIZONTAL) ?
|
|
mirror->horizontal_guide : mirror->vertical_guide;
|
|
|
|
/* The guide may have already been removed, for instance from GUI. */
|
|
if (guide)
|
|
{
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (guide),
|
|
gimp_mirror_guide_removed_cb,
|
|
mirror);
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (guide),
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
|
|
gimp_image_remove_guide (image, guide, FALSE);
|
|
g_object_unref (guide);
|
|
|
|
if (orientation == GIMP_ORIENTATION_HORIZONTAL)
|
|
mirror->horizontal_guide = NULL;
|
|
else
|
|
mirror->vertical_guide = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_guide_removed_cb (GObject *object,
|
|
GimpMirror *mirror)
|
|
{
|
|
GimpSymmetry *symmetry = GIMP_SYMMETRY (mirror);
|
|
|
|
g_signal_handlers_disconnect_by_func (object,
|
|
gimp_mirror_guide_removed_cb,
|
|
mirror);
|
|
g_signal_handlers_disconnect_by_func (object,
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
|
|
if (GIMP_GUIDE (object) == mirror->horizontal_guide)
|
|
{
|
|
g_object_unref (mirror->horizontal_guide);
|
|
mirror->horizontal_guide = NULL;
|
|
|
|
g_object_set (mirror,
|
|
"horizontal-symmetry", FALSE,
|
|
NULL);
|
|
g_object_set (mirror,
|
|
"point-symmetry", FALSE,
|
|
NULL);
|
|
g_object_set (mirror,
|
|
"mirror-position-y", 0.0,
|
|
NULL);
|
|
|
|
if (mirror->vertical_guide &&
|
|
! mirror->vertical_mirror)
|
|
{
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (mirror->vertical_guide),
|
|
gimp_mirror_guide_removed_cb,
|
|
mirror);
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (mirror->vertical_guide),
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
|
|
gimp_image_remove_guide (symmetry->image,
|
|
mirror->vertical_guide,
|
|
FALSE);
|
|
g_clear_object (&mirror->vertical_guide);
|
|
}
|
|
}
|
|
else if (GIMP_GUIDE (object) == mirror->vertical_guide)
|
|
{
|
|
g_object_unref (mirror->vertical_guide);
|
|
mirror->vertical_guide = NULL;
|
|
|
|
g_object_set (mirror,
|
|
"vertical-symmetry", FALSE,
|
|
NULL);
|
|
g_object_set (mirror,
|
|
"point-symmetry", FALSE,
|
|
NULL);
|
|
g_object_set (mirror,
|
|
"mirror-position-x", 0.0,
|
|
NULL);
|
|
|
|
if (mirror->horizontal_guide &&
|
|
! mirror->horizontal_mirror)
|
|
{
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (mirror->horizontal_guide),
|
|
gimp_mirror_guide_removed_cb,
|
|
mirror);
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (mirror->horizontal_guide),
|
|
gimp_mirror_guide_position_cb,
|
|
mirror);
|
|
|
|
gimp_image_remove_guide (symmetry->image,
|
|
mirror->horizontal_guide,
|
|
FALSE);
|
|
g_clear_object (&mirror->horizontal_guide);
|
|
}
|
|
}
|
|
|
|
if (mirror->horizontal_guide == NULL &&
|
|
mirror->vertical_guide == NULL)
|
|
{
|
|
gimp_image_symmetry_remove (symmetry->image,
|
|
GIMP_SYMMETRY (mirror));
|
|
}
|
|
else
|
|
{
|
|
gimp_mirror_reset (mirror);
|
|
g_signal_emit_by_name (mirror, "gui-param-changed",
|
|
GIMP_SYMMETRY (mirror)->image);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_guide_position_cb (GObject *object,
|
|
GParamSpec *pspec,
|
|
GimpMirror *mirror)
|
|
{
|
|
GimpGuide *guide = GIMP_GUIDE (object);
|
|
|
|
if (guide == mirror->horizontal_guide)
|
|
{
|
|
g_object_set (mirror,
|
|
"mirror-position-y", (gdouble) gimp_guide_get_position (guide),
|
|
NULL);
|
|
}
|
|
else if (guide == mirror->vertical_guide)
|
|
{
|
|
g_object_set (mirror,
|
|
"mirror-position-x", (gdouble) gimp_guide_get_position (guide),
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_active_changed (GimpSymmetry *sym)
|
|
{
|
|
GimpMirror *mirror = GIMP_MIRROR (sym);
|
|
|
|
if (sym->active)
|
|
{
|
|
if ((mirror->horizontal_mirror || mirror->point_symmetry) &&
|
|
! mirror->horizontal_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
|
|
if ((mirror->vertical_mirror || mirror->point_symmetry) &&
|
|
! mirror->vertical_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
else
|
|
{
|
|
if (mirror->horizontal_guide)
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
|
|
if (mirror->vertical_guide)
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
|
|
gboolean active)
|
|
{
|
|
if (active == mirror->horizontal_mirror)
|
|
return;
|
|
|
|
mirror->horizontal_mirror = active;
|
|
|
|
if (active)
|
|
{
|
|
if (! mirror->horizontal_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
}
|
|
else if (! mirror->point_symmetry)
|
|
{
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
}
|
|
|
|
gimp_mirror_reset (mirror);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_set_vertical_symmetry (GimpMirror *mirror,
|
|
gboolean active)
|
|
{
|
|
if (active == mirror->vertical_mirror)
|
|
return;
|
|
|
|
mirror->vertical_mirror = active;
|
|
|
|
if (active)
|
|
{
|
|
if (! mirror->vertical_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
else if (! mirror->point_symmetry)
|
|
{
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
|
|
gimp_mirror_reset (mirror);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_set_point_symmetry (GimpMirror *mirror,
|
|
gboolean active)
|
|
{
|
|
if (active == mirror->point_symmetry)
|
|
return;
|
|
|
|
mirror->point_symmetry = active;
|
|
|
|
if (active)
|
|
{
|
|
/* Show the horizontal guide unless already shown */
|
|
if (! mirror->horizontal_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
|
|
/* Show the vertical guide unless already shown */
|
|
if (! mirror->vertical_guide)
|
|
gimp_mirror_add_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
else
|
|
{
|
|
/* Remove the horizontal guide unless needed by horizontal mirror */
|
|
if (! mirror->horizontal_mirror)
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_HORIZONTAL);
|
|
|
|
/* Remove the vertical guide unless needed by vertical mirror */
|
|
if (! mirror->vertical_mirror)
|
|
gimp_mirror_remove_guide (mirror, GIMP_ORIENTATION_VERTICAL);
|
|
}
|
|
|
|
gimp_mirror_reset (mirror);
|
|
}
|
|
|
|
static void
|
|
gimp_mirror_image_size_changed_cb (GimpImage *image,
|
|
gint previous_origin_x,
|
|
gint previous_origin_y,
|
|
gint previous_width,
|
|
gint previous_height,
|
|
GimpSymmetry *sym)
|
|
{
|
|
if (previous_width != gimp_image_get_width (image) ||
|
|
previous_height != gimp_image_get_height (image))
|
|
{
|
|
g_signal_emit_by_name (sym, "gui-param-changed", sym->image);
|
|
}
|
|
}
|