Commit 150bea1e authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Implemented "Snap to Canvas Edges" (fixes bug #152971) and "Snap to Active

2005-01-03  Michael Natterer  <mitch@gimp.org>

	Implemented "Snap to Canvas Edges" (fixes bug #152971) and
	"Snap to Active Path" (half way done):

	* app/core/gimpimage-snap.[ch]: added boolean snap_to_canvas and
	snap_to_vectors parameters (snap_to_vectors works fine when
	snapping to a point, but is unimplemented for snapping to a
	rectangle).

	* app/display/gimpdisplayshell.[ch] (struct GimpDisplayShell):
	added snap_to_canvas and snap_to_vectors booleans.

	* app/display/gimpdisplayshell-appearance.[ch]: added API to
	get/set them.

	* app/actions/view-actions.c
	* app/actions/view-commands.[ch]
	* app/widgets/gimphelp-ids.h: added actions, callbacks and help IDs.

	* menus/image-menu.xml.in: added them to Image->View.
parent 28251be0
2005-01-03 Michael Natterer <mitch@gimp.org>
Implemented "Snap to Canvas Edges" (fixes bug #152971) and
"Snap to Active Path" (half way done):
* app/core/gimpimage-snap.[ch]: added boolean snap_to_canvas and
snap_to_vectors parameters (snap_to_vectors works fine when
snapping to a point, but is unimplemented for snapping to a
rectangle).
* app/display/gimpdisplayshell.[ch] (struct GimpDisplayShell):
added snap_to_canvas and snap_to_vectors booleans.
* app/display/gimpdisplayshell-appearance.[ch]: added API to
get/set them.
* app/actions/view-actions.c
* app/actions/view-commands.[ch]
* app/widgets/gimphelp-ids.h: added actions, callbacks and help IDs.
* menus/image-menu.xml.in: added them to Image->View.
2005-01-03 Sven Neumann <neumann@jpk.com>
* plug-ins/ifscompose/ifscompose.c: use g_free() to release memory
......
......@@ -157,6 +157,18 @@ static GimpToggleActionEntry view_toggle_actions[] =
FALSE,
GIMP_HELP_VIEW_SNAP_TO_GRID },
{ "view-snap-to-canvas", NULL,
N_("S_nap to Canvas Edges"), NULL, NULL,
G_CALLBACK (view_snap_to_canvas_cmd_callback),
FALSE,
GIMP_HELP_VIEW_SNAP_TO_CANVAS },
{ "view-snap-to-vectors", NULL,
N_("Snap to Active Pat_h"), NULL, NULL,
G_CALLBACK (view_snap_to_vectors_cmd_callback),
FALSE,
GIMP_HELP_VIEW_SNAP_TO_VECTORS },
{ "view-show-menubar", NULL,
N_("Show _Menubar"), NULL, NULL,
G_CALLBACK (view_toggle_menubar_cmd_callback),
......@@ -514,6 +526,8 @@ view_actions_update (GimpActionGroup *group,
SET_ACTIVE ("view-snap-to-guides", gdisp && shell->snap_to_guides);
SET_ACTIVE ("view-show-grid", gdisp && options->show_grid);
SET_ACTIVE ("view-snap-to-grid", gdisp && shell->snap_to_grid);
SET_ACTIVE ("view-snap-to-canvas", gdisp && shell->snap_to_canvas);
SET_ACTIVE ("view-snap-to-vectors", gdisp && shell->snap_to_vectors);
if (gdisp)
{
......
......@@ -526,6 +526,38 @@ view_snap_to_grid_cmd_callback (GtkAction *action,
gimp_display_shell_set_snap_to_grid (shell, active);
}
void
view_snap_to_canvas_cmd_callback (GtkAction *action,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
gboolean active;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
gimp_display_shell_set_snap_to_canvas (shell, active);
}
void
view_snap_to_vectors_cmd_callback (GtkAction *action,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
gboolean active;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
gimp_display_shell_set_snap_to_vectors (shell, active);
}
void
view_padding_color_cmd_callback (GtkAction *action,
gint value,
......
......@@ -73,6 +73,10 @@ void view_toggle_grid_cmd_callback (GtkAction *action,
gpointer data);
void view_snap_to_grid_cmd_callback (GtkAction *action,
gpointer data);
void view_snap_to_canvas_cmd_callback (GtkAction *action,
gpointer data);
void view_snap_to_vectors_cmd_callback (GtkAction *action,
gpointer data);
void view_padding_color_cmd_callback (GtkAction *action,
gint value,
gpointer data);
......
......@@ -28,6 +28,9 @@
#include "gimpimage-guides.h"
#include "gimpimage-snap.h"
#include "vectors/gimpstroke.h"
#include "vectors/gimpvectors.h"
#include "gimp-intl.h"
......@@ -40,7 +43,8 @@ gimp_image_snap_x (GimpImage *gimage,
gdouble *tx,
gdouble epsilon_x,
gboolean snap_to_guides,
gboolean snap_to_grid)
gboolean snap_to_grid,
gboolean snap_to_canvas)
{
GList *list;
GimpGuide *guide;
......@@ -55,7 +59,7 @@ gimp_image_snap_x (GimpImage *gimage,
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
if (! (snap_to_guides || snap_to_grid || snap_to_canvas))
return FALSE;
*tx = x;
......@@ -111,6 +115,27 @@ gimp_image_snap_x (GimpImage *gimage,
}
}
if (snap_to_canvas)
{
dist = ABS (x);
if (dist < MIN (epsilon_x, mindist))
{
mindist = dist;
*tx = 0;
snapped = TRUE;
}
dist = ABS (gimage->width - x);
if (dist < MIN (epsilon_x, mindist))
{
mindist = dist;
*tx = gimage->width;
snapped = TRUE;
}
}
return snapped;
}
......@@ -120,7 +145,8 @@ gimp_image_snap_y (GimpImage *gimage,
gdouble *ty,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid)
gboolean snap_to_grid,
gboolean snap_to_canvas)
{
GList *list;
GimpGuide *guide;
......@@ -135,7 +161,7 @@ gimp_image_snap_y (GimpImage *gimage,
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (ty != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
if (! (snap_to_guides || snap_to_grid || snap_to_canvas))
return FALSE;
*ty = y;
......@@ -191,6 +217,27 @@ gimp_image_snap_y (GimpImage *gimage,
}
}
if (snap_to_canvas)
{
dist = ABS (y);
if (dist < MIN (epsilon_y, mindist))
{
mindist = dist;
*ty = 0;
snapped = TRUE;
}
dist = ABS (gimage->height - y);
if (dist < MIN (epsilon_y, mindist))
{
mindist = dist;
*ty = gimage->height;
snapped = TRUE;
}
}
return snapped;
}
......@@ -203,7 +250,9 @@ gimp_image_snap_point (GimpImage *gimage,
gdouble epsilon_x,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid)
gboolean snap_to_grid,
gboolean snap_to_canvas,
gboolean snap_to_vectors)
{
GList *list;
GimpGuide *guide;
......@@ -219,7 +268,7 @@ gimp_image_snap_point (GimpImage *gimage,
g_return_val_if_fail (tx != NULL, FALSE);
g_return_val_if_fail (ty != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
if (! (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors))
return FALSE;
*tx = x;
......@@ -315,6 +364,80 @@ gimp_image_snap_point (GimpImage *gimage,
}
}
if (snap_to_canvas)
{
dist = ABS (x);
if (dist < MIN (epsilon_x, minxdist))
{
minxdist = dist;
*tx = 0;
snapped = TRUE;
}
dist = ABS (gimage->width - x);
if (dist < MIN (epsilon_x, minxdist))
{
minxdist = dist;
*tx = gimage->width;
snapped = TRUE;
}
dist = ABS (y);
if (dist < MIN (epsilon_y, minydist))
{
minydist = dist;
*ty = 0;
snapped = TRUE;
}
dist = ABS (gimage->height - y);
if (dist < MIN (epsilon_y, minydist))
{
minydist = dist;
*ty = gimage->height;
snapped = TRUE;
}
}
if (snap_to_vectors && gimage->active_vectors != NULL)
{
GimpVectors *vectors = gimp_image_get_active_vectors (gimage);
GimpStroke *stroke = NULL;
GimpCoords coords = { x, y, 0, 0, 0 };
while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke)))
{
GimpCoords nearest;
if (gimp_stroke_nearest_point_get (stroke, &coords, 1.0,
&nearest,
NULL, NULL, NULL) >= 0)
{
dist = ABS (nearest.x - x);
if (dist < MIN (epsilon_x, minxdist))
{
minxdist = dist;
*tx = nearest.x;
snapped = TRUE;
}
dist = ABS (nearest.y - y);
if (dist < MIN (epsilon_y, minydist))
{
minydist = dist;
*ty = nearest.y;
snapped = TRUE;
}
}
}
}
return snapped;
}
......@@ -329,7 +452,9 @@ gimp_image_snap_rectangle (GimpImage *gimage,
gdouble epsilon_x,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid)
gboolean snap_to_grid,
gboolean snap_to_canvas,
gboolean snap_to_vectors)
{
gdouble nx1, ny1;
gdouble nx2, ny2;
......@@ -339,28 +464,36 @@ gimp_image_snap_rectangle (GimpImage *gimage,
g_return_val_if_fail (tx1 != NULL, FALSE);
g_return_val_if_fail (ty1 != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
if (! (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors))
return FALSE;
#ifdef __GNUC__
#warning FIXME: implement rectangle snapping to vectors
#endif
*tx1 = x1;
*ty1 = y1;
snap1 = gimp_image_snap_x (gimage, x1, &nx1,
epsilon_x,
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas);
snap2 = gimp_image_snap_x (gimage, x2, &nx2,
epsilon_x,
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas);
snap3 = gimp_image_snap_y (gimage, y1, &ny1,
epsilon_y,
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas);
snap4 = gimp_image_snap_y (gimage, y2, &ny2,
epsilon_y,
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas);
if (snap1 && snap2)
{
......
......@@ -25,13 +25,15 @@ gboolean gimp_image_snap_x (GimpImage *gimage,
gdouble *tx,
gdouble epsilon_x,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean snap_to_grid,
gboolean snap_to_canvas);
gboolean gimp_image_snap_y (GimpImage *gimage,
gdouble y,
gdouble *ty,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean snap_to_grid,
gboolean snap_to_canvas);
gboolean gimp_image_snap_point (GimpImage *gimage,
gdouble x,
gdouble y,
......@@ -40,7 +42,9 @@ gboolean gimp_image_snap_point (GimpImage *gimage,
gdouble epsilon_x,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean snap_to_grid,
gboolean snap_to_canvas,
gboolean snap_to_vectors);
gboolean gimp_image_snap_rectangle (GimpImage *gimage,
gdouble x1,
gdouble y1,
......@@ -51,7 +55,9 @@ gboolean gimp_image_snap_rectangle (GimpImage *gimage,
gdouble epsilon_x,
gdouble epsilon_y,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean snap_to_grid,
gboolean snap_to_canvas,
gboolean snap_to_vectors);
#endif /* __GIMP_IMAGE_SNAP_H__ */
......@@ -452,6 +452,56 @@ gimp_display_shell_get_snap_to_guides (GimpDisplayShell *shell)
return shell->snap_to_guides;
}
void
gimp_display_shell_set_snap_to_canvas (GimpDisplayShell *shell,
gboolean snap)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
if (snap != shell->snap_to_canvas)
{
shell->snap_to_canvas = snap ? TRUE : FALSE;
SET_ACTIVE (shell->menubar_manager, "view-snap-to-canvas", snap);
if (IS_ACTIVE_DISPLAY (shell))
SET_ACTIVE (shell->popup_manager, "view-snap-to-canvas", snap);
}
}
gboolean
gimp_display_shell_get_snap_to_canvas (GimpDisplayShell *shell)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
return shell->snap_to_canvas;
}
void
gimp_display_shell_set_snap_to_vectors (GimpDisplayShell *shell,
gboolean snap)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
if (snap != shell->snap_to_vectors)
{
shell->snap_to_vectors = snap ? TRUE : FALSE;
SET_ACTIVE (shell->menubar_manager, "view-snap-to-vectors", snap);
if (IS_ACTIVE_DISPLAY (shell))
SET_ACTIVE (shell->popup_manager, "view-snap-to-vectors", snap);
}
}
gboolean
gimp_display_shell_get_snap_to_vectors (GimpDisplayShell *shell)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
return shell->snap_to_vectors;
}
void
gimp_display_shell_set_padding (GimpDisplayShell *shell,
GimpCanvasPaddingMode padding_mode,
......
......@@ -68,6 +68,14 @@ void gimp_display_shell_set_snap_to_guides (GimpDisplayShell *shell,
gboolean snap);
gboolean gimp_display_shell_get_snap_to_guides (GimpDisplayShell *shell);
void gimp_display_shell_set_snap_to_canvas (GimpDisplayShell *shell,
gboolean snap);
gboolean gimp_display_shell_get_snap_to_canvas (GimpDisplayShell *shell);
void gimp_display_shell_set_snap_to_vectors (GimpDisplayShell *shell,
gboolean snap);
gboolean gimp_display_shell_get_snap_to_vectors (GimpDisplayShell *shell);
void gimp_display_shell_set_padding (GimpDisplayShell *shell,
GimpCanvasPaddingMode mode,
const GimpRGB *color);
......
......@@ -249,6 +249,8 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->proximity = FALSE;
shell->snap_to_guides = TRUE;
shell->snap_to_grid = FALSE;
shell->snap_to_canvas = FALSE;
shell->snap_to_vectors = FALSE;
shell->select = NULL;
......@@ -1107,6 +1109,8 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
{
gboolean snap_to_guides = FALSE;
gboolean snap_to_grid = FALSE;
gboolean snap_to_canvas = FALSE;
gboolean snap_to_vectors = FALSE;
gboolean snapped = FALSE;
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
......@@ -1115,7 +1119,7 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
*snapped_coords = *coords;
if (shell->snap_to_guides &&
if (gimp_display_shell_get_snap_to_guides (shell) &&
shell->gdisp->gimage->guides)
{
snap_to_guides = TRUE;
......@@ -1127,7 +1131,15 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
snap_to_grid = TRUE;
}
if (snap_to_guides || snap_to_grid)
snap_to_canvas = gimp_display_shell_get_snap_to_canvas (shell);
if (gimp_display_shell_get_snap_to_vectors (shell) &&
gimp_image_get_active_vectors (shell->gdisp->gimage))
{
snap_to_vectors = TRUE;
}
if (snap_to_guides || snap_to_grid || snap_to_canvas || snap_to_vectors)
{
gdouble tx, ty;
gint snap_distance;
......@@ -1149,7 +1161,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
FUNSCALEX (shell, snap_distance),
FUNSCALEY (shell, snap_distance),
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas,
snap_to_vectors);
}
else
{
......@@ -1161,7 +1175,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
FUNSCALEX (shell, snap_distance),
FUNSCALEY (shell, snap_distance),
snap_to_guides,
snap_to_grid);
snap_to_grid,
snap_to_canvas,
snap_to_vectors);
}
if (snapped)
......
......@@ -93,6 +93,8 @@ struct _GimpDisplayShell
gboolean proximity; /* is a device in proximity */
gboolean snap_to_guides; /* should the guides be snapped to? */
gboolean snap_to_grid; /* should the grid be snapped to? */
gboolean snap_to_canvas; /* should the canvas be snapped to? */
gboolean snap_to_vectors; /* should the active path be snapped */
Selection *select; /* Selection object */
......
......@@ -82,6 +82,8 @@
#define GIMP_HELP_VIEW_SNAP_TO_GUIDES "gimp-view-snap-to-guides"
#define GIMP_HELP_VIEW_SHOW_GRID "gimp-view-show-grid"
#define GIMP_HELP_VIEW_SNAP_TO_GRID "gimp-view-snap-to-grid"
#define GIMP_HELP_VIEW_SNAP_TO_CANVAS "gimp-view-snap-to-canvas"
#define GIMP_HELP_VIEW_SNAP_TO_VECTORS "gimp-view-snap-to-vectors"
#define GIMP_HELP_VIEW_SHOW_MENUBAR "gimp-view-show-menubar"
#define GIMP_HELP_VIEW_SHOW_RULERS "gimp-view-show-rulers"
#define GIMP_HELP_VIEW_SHOW_SCROLLBARS "gimp-view-show-scrollbars"
......
......@@ -241,6 +241,8 @@
<menuitem action="view-snap-to-guides" />
<menuitem action="view-show-grid" />
<menuitem action="view-snap-to-grid" />
<menuitem action="view-snap-to-canvas" />
<menuitem action="view-snap-to-vectors" />
<menu action="view-padding-color-menu" name="Padding color">
<menuitem action="view-padding-color-theme" />
<menuitem action="view-padding-color-light-check" />
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment