Added a per image configurable grid.

This fixes bug #65198

* app/core/Makefile.am
* app/core/core-types.h:
* app/core/gimpgrid.[ch]: added new class GimpGrid.

* app/core/core-enums.[ch]: added new enum GimpGridType.

* app/core/gimpimage-guides.[ch]: removed the gimp_image_snap_*()
functions...

* app/core/gimpimage-snap.[ch]: ...and added them here since they
are no longer guide specific.

* app/core/gimpimage-undo-push.[ch]: added
gimp_image_undo_push_image_grid()

* app/display/gimpdisplayshell-handlers.c:
* app/core/gimpimage.[ch]: added grid member to _GimpImage. Added
new signal "grid_changed", added gimp_image_grid_changed(),
gimp_image_get_grid() and gimp_image_set_grid().

* app/display/gimpdisplayshell-appearance.[ch]: added
gimp_display_shell_set_show_grid(),
gimp_display_shell_get_show_grid(),
gimp_display_shell_set_snap_to_grid() and
gimp_display_shell_get_snap_to_grid().

* app/display/gimpdisplayshell-callbacks.c: added call to
gimp_display_shell_draw_grid()

* app/display/gimpdisplayshell.[ch]: added grid member to
_GimpDisplayShellVisibility, added snap_to_grid and grid_dialog
members to _GimpDisplayShell, added
gimp_display_shell_draw_grid(), modified
gimp_display_shell_snap_coords() to use the new
gimp_image_snap_*() functions.

* app/gui/image-menu.c: added grid entries to
image_menu_entries[].

* app/gui/view-commands.[ch]: added
view_configure_grid_cmd_callback(),
view_toggle_grid_cmd_callback() and
view_snap_to_grid_cmd_callback().

* app/gui/Makefile.am
* app/gui/grid-dialog.[ch]: added a grid dialog.
This commit is contained in:
Henrik Brix Andersen 2003-06-23 19:34:48 +00:00
parent ba91aeb86b
commit edd5c33923
34 changed files with 2450 additions and 231 deletions

View File

@ -1,3 +1,55 @@
2003-06-23 Henrik Brix Andersen <brix@gimp.org>
Added a per image configurable grid.
This fixes bug #65198
* app/core/Makefile.am
* app/core/core-types.h:
* app/core/gimpgrid.[ch]: added new class GimpGrid.
* app/core/core-enums.[ch]: added new enum GimpGridType.
* app/core/gimpimage-guides.[ch]: removed the gimp_image_snap_*()
functions...
* app/core/gimpimage-snap.[ch]: ...and added them here since they
are no longer guide specific.
* app/core/gimpimage-undo-push.[ch]: added
gimp_image_undo_push_image_grid()
* app/display/gimpdisplayshell-handlers.c:
* app/core/gimpimage.[ch]: added grid member to _GimpImage. Added
new signal "grid_changed", added gimp_image_grid_changed(),
gimp_image_get_grid() and gimp_image_set_grid().
* app/display/gimpdisplayshell-appearance.[ch]: added
gimp_display_shell_set_show_grid(),
gimp_display_shell_get_show_grid(),
gimp_display_shell_set_snap_to_grid() and
gimp_display_shell_get_snap_to_grid().
* app/display/gimpdisplayshell-callbacks.c: added call to
gimp_display_shell_draw_grid()
* app/display/gimpdisplayshell.[ch]: added grid member to
_GimpDisplayShellVisibility, added snap_to_grid and grid_dialog
members to _GimpDisplayShell, added
gimp_display_shell_draw_grid(), modified
gimp_display_shell_snap_coords() to use the new
gimp_image_snap_*() functions.
* app/gui/image-menu.c: added grid entries to
image_menu_entries[].
* app/gui/view-commands.[ch]: added
view_configure_grid_cmd_callback(),
view_toggle_grid_cmd_callback() and
view_snap_to_grid_cmd_callback().
* app/gui/Makefile.am
* app/gui/grid-dialog.[ch]: added a grid dialog.
2003-06-23 Michael Natterer <mitch@gimp.org>
* app/plug-in/plug-in.[ch]: added separate GMainLoops for waiting

View File

@ -42,6 +42,7 @@
#include "dialogs.h"
#include "info-dialog.h"
#include "info-window.h"
#include "grid-dialog.h"
#include "view-commands.h"
@ -350,6 +351,63 @@ view_snap_to_guides_cmd_callback (GtkWidget *widget,
}
}
void
view_configure_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GtkWidget *grid_dialog;
return_if_no_display (gdisp, data);
grid_dialog = grid_dialog_new (GIMP_DISPLAY (gdisp));
g_signal_connect_object (gdisp, "disconnect",
G_CALLBACK (gtk_widget_destroy),
grid_dialog,
G_CONNECT_SWAPPED);
gtk_widget_show (grid_dialog);
}
void
view_toggle_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
gimp_display_shell_set_show_grid (shell,
GTK_CHECK_MENU_ITEM (widget)->active);
}
void
view_snap_to_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
if (shell->snap_to_grid != GTK_CHECK_MENU_ITEM (widget)->active)
{
shell->snap_to_grid = GTK_CHECK_MENU_ITEM (widget)->active;
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->menubar_factory),
"/View/Snap to Grid",
shell->snap_to_grid);
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->popup_factory),
"/View/Snap to Grid",
shell->snap_to_grid);
}
}
void
view_new_view_cmd_callback (GtkWidget *widget,
gpointer data)

View File

@ -57,6 +57,12 @@ void view_toggle_guides_cmd_callback (GtkWidget *widget,
gpointer data);
void view_snap_to_guides_cmd_callback (GtkWidget *widget,
gpointer data);
void view_toggle_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_configure_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_snap_to_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_new_view_cmd_callback (GtkWidget *widget,
gpointer data);
void view_shrink_wrap_cmd_callback (GtkWidget *widget,

View File

@ -83,6 +83,8 @@ libappcore_a_sources = \
gimpenvirontable.c \
gimpgradient.c \
gimpgradient.h \
gimpgrid.c \
gimpgrid.h \
gimpimage.c \
gimpimage.h \
gimpimage-colorhash.c \
@ -125,6 +127,8 @@ libappcore_a_sources = \
gimpimage-rotate.h \
gimpimage-scale.c \
gimpimage-scale.h \
gimpimage-snap.c \
gimpimage-snap.h \
gimpimage-undo.c \
gimpimage-undo.h \
gimpimage-undo-push.c \

View File

@ -213,6 +213,27 @@ gimp_gradient_type_get_type (void)
}
static const GEnumValue gimp_grid_type_enum_values[] =
{
{ GIMP_GRID_TYPE_INTERSECTION, N_("Intersections Only"), "intersection" },
{ GIMP_GRID_TYPE_ON_OFF_DASH, N_("Dashed"), "on-off-dash" },
{ GIMP_GRID_TYPE_DOUBLE_DASH, N_("Double Dashed"), "double-dash" },
{ GIMP_GRID_TYPE_SOLID, N_("Solid"), "solid" },
{ 0, NULL, NULL }
};
GType
gimp_grid_type_get_type (void)
{
static GType enum_type = 0;
if (!enum_type)
enum_type = g_enum_register_static ("GimpGridType", gimp_grid_type_enum_values);
return enum_type;
}
static const GEnumValue gimp_image_base_type_enum_values[] =
{
{ GIMP_RGB, N_("RGB"), "rgb" },
@ -456,6 +477,7 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_GROUP_IMAGE_CROP, N_("Crop Image"), "group-image-crop" },
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, N_("Merge Layers"), "group-image-layers-merge" },
{ GIMP_UNDO_GROUP_IMAGE_QMASK, N_("QuickMask"), "group-image-qmask" },
{ GIMP_UNDO_GROUP_IMAGE_GRID, N_("Grid"), "group-image-grid" },
{ GIMP_UNDO_GROUP_IMAGE_GUIDE, N_("Guide"), "group-image-guide" },
{ GIMP_UNDO_GROUP_MASK, N_("Selection Mask"), "group-mask" },
{ GIMP_UNDO_GROUP_ITEM_PROPERTIES, N_("Item Properties"), "group-item-properties" },
@ -483,6 +505,7 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_IMAGE_SIZE, N_("Image Size"), "image-size" },
{ GIMP_UNDO_IMAGE_RESOLUTION, N_("Resolution Change"), "image-resolution" },
{ GIMP_UNDO_IMAGE_QMASK, N_("QuickMask"), "image-qmask" },
{ GIMP_UNDO_IMAGE_GRID, N_("Grid"), "image-grid" },
{ GIMP_UNDO_IMAGE_GUIDE, N_("Guide"), "image-guide" },
{ GIMP_UNDO_IMAGE_COLORMAP, N_("Change Indexed Palette"), "image-colormap" },
{ GIMP_UNDO_MASK, N_("Selection Mask"), "mask" },

View File

@ -170,6 +170,19 @@ typedef enum
} GimpGradientType;
#define GIMP_TYPE_GRID_TYPE (gimp_grid_type_get_type ())
GType gimp_grid_type_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_GRID_TYPE_INTERSECTION, /*< desc="Intersections Only" >*/
GIMP_GRID_TYPE_ON_OFF_DASH, /*< desc="Dashed" >*/
GIMP_GRID_TYPE_DOUBLE_DASH, /*< desc="Double Dashed" >*/
GIMP_GRID_TYPE_SOLID /*< desc="Solid" >*/
} GimpGridType;
#define GIMP_TYPE_IMAGE_BASE_TYPE (gimp_image_base_type_get_type ())
GType gimp_image_base_type_get_type (void) G_GNUC_CONST;
@ -335,6 +348,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_GROUP_IMAGE_CROP, /*< desc="Crop Image" >*/
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, /*< desc="Merge Layers" >*/
GIMP_UNDO_GROUP_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_GROUP_IMAGE_GRID, /*< desc="Grid" >*/
GIMP_UNDO_GROUP_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_GROUP_MASK, /*< desc="Selection Mask" >*/
GIMP_UNDO_GROUP_ITEM_PROPERTIES, /*< desc="Item Properties" >*/
@ -367,6 +381,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_IMAGE_SIZE, /*< desc="Image Size" >*/
GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Resolution Change" >*/
GIMP_UNDO_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/
GIMP_UNDO_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_IMAGE_COLORMAP, /*< desc="Change Indexed Palette" >*/
GIMP_UNDO_MASK, /*< desc="Selection Mask" >*/

View File

@ -73,6 +73,7 @@ typedef struct _GimpDocumentList GimpDocumentList;
typedef struct _GimpTemplate GimpTemplate;
typedef struct _GimpGrid GimpGrid;
/* drawable objects */

255
app/core/gimpgrid.c Normal file
View File

@ -0,0 +1,255 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "libgimpbase/gimplimits.h"
#include "libgimpcolor/gimpcolor.h"
#include "core-types.h"
#include "config/gimpconfig.h"
#include "config/gimpconfig-params.h"
#include "gimpgrid.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_XSPACING,
PROP_YSPACING,
PROP_SPACING_UNIT,
PROP_XOFFSET,
PROP_YOFFSET,
PROP_OFFSET_UNIT,
PROP_FGCOLOR,
PROP_BGCOLOR,
PROP_TYPE
};
static void gimp_grid_class_init (GimpGridClass *klass);
static void gimp_grid_finalize (GObject *object);
static void gimp_grid_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_grid_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static GObjectClass *parent_class = NULL;
GType
gimp_grid_get_type (void)
{
static GType grid_type = 0;
if (! grid_type)
{
static const GTypeInfo grid_info =
{
sizeof (GimpGridClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_grid_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpGrid),
0, /* n_preallocs */
NULL /* instance_init */
};
static const GInterfaceInfo grid_iface_info =
{
NULL, /* iface_init */
NULL, /* iface_finalize */
NULL /* iface_data */
};
grid_type = g_type_register_static (G_TYPE_OBJECT,
"GimpGrid", &grid_info, 0);
g_type_add_interface_static (grid_type,
GIMP_TYPE_CONFIG_INTERFACE,
&grid_iface_info);
}
return grid_type;
}
static void
gimp_grid_class_init (GimpGridClass *klass)
{
GObjectClass *object_class;
GimpRGB black;
GimpRGB white;
object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_grid_finalize;
object_class->get_property = gimp_grid_get_property;
object_class->set_property = gimp_grid_set_property;
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
gimp_rgba_set (&white, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_XSPACING,
"xspacing", NULL,
1.0, GIMP_MAX_IMAGE_SIZE, 10.0,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_YSPACING,
"yspacing", NULL,
1.0, GIMP_MAX_IMAGE_SIZE, 10.0,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_SPACING_UNIT,
"spacing-unit", NULL,
FALSE, GIMP_UNIT_INCH,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_XOFFSET,
"xoffset", NULL,
- GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE, 0.0,
0);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_YOFFSET,
"yoffset", NULL,
- GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE, 0.0,
0);
GIMP_CONFIG_INSTALL_PROP_UNIT (object_class, PROP_OFFSET_UNIT,
"offset-unit", NULL,
FALSE, GIMP_UNIT_INCH,
0);
GIMP_CONFIG_INSTALL_PROP_COLOR (object_class, PROP_FGCOLOR,
"fgcolor", NULL,
&black,
0);
GIMP_CONFIG_INSTALL_PROP_COLOR (object_class, PROP_BGCOLOR,
"bgcolor", NULL,
&white,
0);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_TYPE,
"type", NULL,
GIMP_TYPE_GRID_TYPE,
GIMP_GRID_TYPE_INTERSECTION,
0);
}
static void
gimp_grid_finalize (GObject *object)
{
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_grid_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpGrid *grid = GIMP_GRID (object);
switch (property_id)
{
case PROP_XSPACING:
g_value_set_double (value, grid->xspacing);
break;
case PROP_YSPACING:
g_value_set_double (value, grid->yspacing);
break;
case PROP_SPACING_UNIT:
g_value_set_int (value, grid->spacing_unit);
break;
case PROP_XOFFSET:
g_value_set_double (value, grid->xoffset);
break;
case PROP_YOFFSET:
g_value_set_double (value, grid->yoffset);
break;
case PROP_OFFSET_UNIT:
g_value_set_int (value, grid->offset_unit);
break;
case PROP_FGCOLOR:
g_value_set_boxed (value, &grid->fgcolor);
break;
case PROP_BGCOLOR:
g_value_set_boxed (value, &grid->bgcolor);
break;
case PROP_TYPE:
g_value_set_enum (value, grid->type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_grid_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpGrid *grid = GIMP_GRID (object);
GimpRGB *color;
switch (property_id)
{
case PROP_XSPACING:
grid->xspacing = g_value_get_double (value);
break;
case PROP_YSPACING:
grid->yspacing = g_value_get_double (value);
break;
case PROP_SPACING_UNIT:
grid->spacing_unit = g_value_get_int (value);
break;
case PROP_XOFFSET:
grid->xoffset = g_value_get_double (value);
break;
case PROP_YOFFSET:
grid->yoffset = g_value_get_double (value);
break;
case PROP_OFFSET_UNIT:
grid->offset_unit = g_value_get_int (value);
break;
case PROP_FGCOLOR:
color = g_value_get_boxed (value);
grid->fgcolor = *color;
break;
case PROP_BGCOLOR:
color = g_value_get_boxed (value);
grid->bgcolor = *color;
break;
case PROP_TYPE:
grid->type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}

58
app/core/gimpgrid.h Normal file
View File

@ -0,0 +1,58 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_GRID_H__
#define __GIMP_GRID_H__
#define GIMP_TYPE_GRID (gimp_grid_get_type ())
#define GIMP_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_GRID, GimpGrid))
#define GIMP_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_GRID, GimpGridClass))
#define GIMP_IS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_GRID))
#define GIMP_IS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_GRID))
#define GIMP_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_GRID, GimpGridClass))
typedef struct _GimpGridClass GimpGridClass;
struct _GimpGrid
{
GObject parent_instance;
gdouble xspacing;
gdouble yspacing;
GimpUnit spacing_unit;
gdouble xoffset;
gdouble yoffset;
GimpUnit offset_unit;
GimpRGB fgcolor;
GimpRGB bgcolor;
GimpGridType type;
};
struct _GimpGridClass
{
GObjectClass parent_class;
};
GType gimp_grid_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_GRID_H__ */

View File

@ -216,209 +216,3 @@ gimp_image_find_guide (GimpImage *gimage,
return NULL;
}
gboolean
gimp_image_snap_x (GimpImage *gimage,
gdouble x,
gint *tx)
{
GList *list;
GimpGuide *guide;
gint mindist = G_MAXINT;
gint dist;
gboolean snapped = FALSE;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx != NULL, FALSE);
*tx = ROUND (x);
if (x < 0 || x >= gimage->width)
return FALSE;
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
if (guide->orientation == GIMP_ORIENTATION_VERTICAL)
{
dist = ABS (guide->position - x);
if (dist < MIN (GUIDE_EPSILON, mindist))
{
mindist = dist;
*tx = guide->position;
snapped = TRUE;
}
}
}
return snapped;
}
gboolean
gimp_image_snap_y (GimpImage *gimage,
gdouble y,
gint *ty)
{
GList *list;
GimpGuide *guide;
gint mindist = G_MAXINT;
gint dist;
gboolean snapped = FALSE;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (ty != NULL, FALSE);
*ty = ROUND (y);
if (y < 0 || y >= gimage->height)
return FALSE;
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
{
dist = ABS (guide->position - y);
if (dist < MIN (GUIDE_EPSILON, mindist))
{
mindist = dist;
*ty = guide->position;
snapped = TRUE;
}
}
}
return snapped;
}
gboolean
gimp_image_snap_point (GimpImage *gimage,
gdouble x,
gdouble y,
gint *tx,
gint *ty)
{
GList *list;
GimpGuide *guide;
gint minxdist, minydist;
gint dist;
gboolean snapped = FALSE;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx != NULL, FALSE);
g_return_val_if_fail (ty != NULL, FALSE);
*tx = ROUND (x);
*ty = ROUND (y);
if (x < 0 || x >= gimage->width ||
y < 0 || y >= gimage->height)
{
return FALSE;
}
minxdist = G_MAXINT;
minydist = G_MAXINT;
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
dist = ABS (guide->position - y);
if (dist < MIN (GUIDE_EPSILON, minydist))
{
minydist = dist;
*ty = guide->position;
snapped = TRUE;
}
break;
case GIMP_ORIENTATION_VERTICAL:
dist = ABS (guide->position - x);
if (dist < MIN (GUIDE_EPSILON, minxdist))
{
minxdist = dist;
*tx = guide->position;
snapped = TRUE;
}
break;
default:
break;
}
}
return snapped;
}
gboolean
gimp_image_snap_rectangle (GimpImage *gimage,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gint *tx1,
gint *ty1)
{
gint nx1, ny1;
gint nx2, ny2;
gboolean snap1, snap2, snap3, snap4;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx1 != NULL, FALSE);
g_return_val_if_fail (ty1 != NULL, FALSE);
*tx1 = ROUND (x1);
*ty1 = ROUND (y1);
snap1 = gimp_image_snap_x (gimage, x1, &nx1);
snap2 = gimp_image_snap_x (gimage, x2, &nx2);
snap3 = gimp_image_snap_y (gimage, y1, &ny1);
snap4 = gimp_image_snap_y (gimage, y2, &ny2);
if (snap1 && snap2)
{
if (ABS (x1 - nx1) > ABS (x2 - nx2))
snap1 = FALSE;
else
snap2 = FALSE;
}
if (snap1)
*tx1 = nx1;
else if (snap2)
*tx1 = ROUND (x1 + (nx2 - x2));
if (snap3 && snap4)
{
if (ABS (y1 - ny1) > ABS (y2 - ny2))
snap3 = FALSE;
else
snap4 = FALSE;
}
if (snap3)
*ty1 = ny1;
else if (snap4)
*ty1 = ROUND (y1 + (ny2 - y2));
return (snap1 || snap2 || snap3 || snap4);
}

View File

@ -45,24 +45,5 @@ GimpGuide * gimp_image_find_guide (GimpImage *gimage,
gdouble x,
gdouble y);
gboolean gimp_image_snap_x (GimpImage *gimage,
gdouble x,
gint *tx);
gboolean gimp_image_snap_y (GimpImage *gimage,
gdouble y,
gint *ty);
gboolean gimp_image_snap_point (GimpImage *gimage,
gdouble x,
gdouble y,
gint *tx,
gint *ty);
gboolean gimp_image_snap_rectangle (GimpImage *gimage,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gint *tx1,
gint *ty1);
#endif /* __GIMP_IMAGE_GUIDES_H__ */

383
app/core/gimpimage-snap.c Normal file
View File

@ -0,0 +1,383 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "core-types.h"
#include "gimp.h"
#include "gimpimage.h"
#include "gimpimage-snap.h"
#include "gimp-intl.h"
#define EPSILON 5
/* public functions */
gboolean
gimp_image_snap_x (GimpImage *gimage,
gdouble x,
gint *tx,
gboolean snap_to_guides,
gboolean snap_to_grid)
{
GList *list;
GimpGuide *guide;
GimpGrid *grid;
gdouble xspacing;
gdouble xoffset;
gint mindist = G_MAXINT;
gint dist;
gint i;
gboolean snapped = FALSE;
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)
return FALSE;
*tx = ROUND (x);
if (x < 0 || x >= gimage->width)
return FALSE;
if (snap_to_guides && gimage->guides != NULL)
{
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
if (guide->orientation == GIMP_ORIENTATION_VERTICAL)
{
dist = ABS (guide->position - x);
if (dist < MIN (EPSILON, mindist))
{
mindist = dist;
*tx = guide->position;
snapped = TRUE;
}
}
}
}
if (snap_to_grid && gimage->grid != NULL)
{
grid = gimp_image_get_grid (gimage);
g_object_get (G_OBJECT (grid),
"xspacing", &xspacing,
"xoffset", &xoffset,
NULL);
for (i = xoffset; i <= gimage->width; i += xspacing)
{
if (i < 0)
continue;
dist = ABS (i - x);
if (dist < MIN (EPSILON, mindist))
{
mindist = dist;
*tx = i;
snapped = TRUE;
}
}
}
return snapped;
}
gboolean
gimp_image_snap_y (GimpImage *gimage,
gdouble y,
gint *ty,
gboolean snap_to_guides,
gboolean snap_to_grid)
{
GList *list;
GimpGuide *guide;
GimpGrid *grid;
gdouble yspacing;
gdouble yoffset;
gint mindist = G_MAXINT;
gint dist;
gint i;
gboolean snapped = FALSE;
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)
return FALSE;
*ty = ROUND (y);
if (y < 0 || y >= gimage->height)
return FALSE;
if (snap_to_guides && gimage->guides != NULL)
{
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
{
dist = ABS (guide->position - y);
if (dist < MIN (EPSILON, mindist))
{
mindist = dist;
*ty = guide->position;
snapped = TRUE;
}
}
}
}
if (snap_to_grid && gimage->grid != NULL)
{
grid = gimp_image_get_grid (gimage);
g_object_get (G_OBJECT (grid),
"yspacing", &yspacing,
"yoffset", &yoffset,
NULL);
for (i = yoffset; i <= gimage->height; i += yspacing)
{
if (i < 0)
continue;
dist = ABS (i - y);
if (dist < MIN (EPSILON, mindist))
{
mindist = dist;
*ty = i;
snapped = TRUE;
}
}
}
return snapped;
}
gboolean
gimp_image_snap_point (GimpImage *gimage,
gdouble x,
gdouble y,
gint *tx,
gint *ty,
gboolean snap_to_guides,
gboolean snap_to_grid)
{
GList *list;
GimpGuide *guide;
GimpGrid *grid;
gdouble xspacing, yspacing;
gdouble xoffset, yoffset;
gint minxdist, minydist;
gint dist;
gint i;
gboolean snapped = FALSE;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx != NULL, FALSE);
g_return_val_if_fail (ty != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
return FALSE;
*tx = ROUND (x);
*ty = ROUND (y);
if (x < 0 || x >= gimage->width ||
y < 0 || y >= gimage->height)
{
return FALSE;
}
minxdist = G_MAXINT;
minydist = G_MAXINT;
if (snap_to_guides && gimage->guides != NULL)
{
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
if (guide->position < 0)
continue;
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
dist = ABS (guide->position - y);
if (dist < MIN (EPSILON, minydist))
{
minydist = dist;
*ty = guide->position;
snapped = TRUE;
}
break;
case GIMP_ORIENTATION_VERTICAL:
dist = ABS (guide->position - x);
if (dist < MIN (EPSILON, minxdist))
{
minxdist = dist;
*tx = guide->position;
snapped = TRUE;
}
break;
default:
break;
}
}
}
if (snap_to_grid && gimage->grid != NULL)
{
grid = gimp_image_get_grid (gimage);
g_object_get (G_OBJECT (grid),
"xspacing", &xspacing,
"yspacing", &yspacing,
"xoffset", &xoffset,
"yoffset", &yoffset,
NULL);
for (i = xoffset; i <= gimage->width; i += xspacing)
{
if (i < 0)
continue;
dist = ABS (i - x);
if (dist < MIN (EPSILON, minxdist))
{
minxdist = dist;
*tx = i;
snapped = TRUE;
}
}
for (i = yoffset; i <= gimage->height; i += yspacing)
{
if (i < 0)
continue;
dist = ABS (i - y);
if (dist < MIN (EPSILON, minydist))
{
minydist = dist;
*ty = i;
snapped = TRUE;
}
}
}
return snapped;
}
gboolean
gimp_image_snap_rectangle (GimpImage *gimage,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gint *tx1,
gint *ty1,
gboolean snap_to_guides,
gboolean snap_to_grid)
{
gint nx1, ny1;
gint nx2, ny2;
gboolean snap1, snap2, snap3, snap4;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (tx1 != NULL, FALSE);
g_return_val_if_fail (ty1 != NULL, FALSE);
if (! snap_to_guides && ! snap_to_grid)
return FALSE;
*tx1 = ROUND (x1);
*ty1 = ROUND (y1);
snap1 = gimp_image_snap_x (gimage, x1, &nx1,
snap_to_guides,
snap_to_grid);
snap2 = gimp_image_snap_x (gimage, x2, &nx2,
snap_to_guides,
snap_to_grid);
snap3 = gimp_image_snap_y (gimage, y1, &ny1,
snap_to_guides,
snap_to_grid);
snap4 = gimp_image_snap_y (gimage, y2, &ny2,
snap_to_guides,
snap_to_grid);
if (snap1 && snap2)
{
if (ABS (x1 - nx1) > ABS (x2 - nx2))
snap1 = FALSE;
else
snap2 = FALSE;
}
if (snap1)
*tx1 = nx1;
else if (snap2)
*tx1 = ROUND (x1 + (nx2 - x2));
if (snap3 && snap4)
{
if (ABS (y1 - ny1) > ABS (y2 - ny2))
snap3 = FALSE;
else
snap4 = FALSE;
}
if (snap3)
*ty1 = ny1;
else if (snap4)
*ty1 = ROUND (y1 + (ny2 - y2));
return (snap1 || snap2 || snap3 || snap4);
}

51
app/core/gimpimage-snap.h Normal file
View File

@ -0,0 +1,51 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattisbvf
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_IMAGE_SNAP_H__
#define __GIMP_IMAGE_SNAP_H__
gboolean gimp_image_snap_x (GimpImage *gimage,
gdouble x,
gint *tx,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean gimp_image_snap_y (GimpImage *gimage,
gdouble y,
gint *ty,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean gimp_image_snap_point (GimpImage *gimage,
gdouble x,
gdouble y,
gint *tx,
gint *ty,
gboolean snap_to_guides,
gboolean snap_to_grid);
gboolean gimp_image_snap_rectangle (GimpImage *gimage,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
gint *tx1,
gint *ty1,
gboolean snap_to_guides,
gboolean snap_to_grid);
#endif /* __GIMP_IMAGE_SNAP_H__ */

View File

@ -39,6 +39,7 @@
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpgrid.h"
#include "gimpimage-colormap.h"
#include "gimpimage-guides.h"
#include "gimpimage-mask.h"
@ -624,6 +625,93 @@ undo_free_image_qmask (GimpUndo *undo,
}
/****************/
/* Grid Undo */
/****************/
typedef struct _GridUndo GridUndo;
struct _GridUndo
{
GimpGrid *grid;
};
static gboolean undo_pop_image_grid (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_image_grid (GimpUndo *undo,
GimpUndoMode undo_mode);
gboolean
gimp_image_undo_push_image_grid (GimpImage *gimage,
const gchar *undo_desc,
GimpGrid *grid)
{
GimpUndo *new;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (grid == NULL || GIMP_IS_GRID (grid), FALSE);
#ifdef __GNUC__
#warning FIXME: mark image as dirty when grid save functionality is added
#endif
if ((new = gimp_image_undo_push (gimage,
sizeof (GridUndo),
sizeof (GridUndo),
GIMP_UNDO_IMAGE_GRID, undo_desc,
FALSE,
undo_pop_image_grid,
undo_free_image_grid)))
{
GridUndo *gu;
gu = new->data;
if (grid)
gu->grid = g_object_ref (grid);
else
gu->grid = NULL;
return TRUE;
}
return FALSE;
}
static gboolean
undo_pop_image_grid (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GridUndo *gu;
GimpGrid *tmp;
gu = (GridUndo *) undo->data;
tmp = gimp_image_get_grid (undo->gimage);
gimp_image_set_grid (undo->gimage, gu->grid, FALSE);
gu->grid = tmp;
gimp_image_grid_changed (undo->gimage);
return TRUE;
}
static void
undo_free_image_grid (GimpUndo *undo,
GimpUndoMode undo_mode)
{
GridUndo *gu;
gu = (GridUndo *) undo->data;
if (gu->grid)
g_object_unref (gu->grid);
g_free (gu);
}
/****************/
/* Guide Undo */
/****************/

View File

@ -46,6 +46,9 @@ gboolean gimp_image_undo_push_image_resolution (GimpImage *gimage,
const gchar *undo_desc);
gboolean gimp_image_undo_push_image_qmask (GimpImage *gimage,
const gchar *undo_desc);
gboolean gimp_image_undo_push_image_grid (GimpImage *gimage,
const gchar *undo_desc,
GimpGrid *grid);
gboolean gimp_image_undo_push_image_guide (GimpImage *gimage,
const gchar *undo_desc,
GimpGuide *guide);

View File

@ -39,6 +39,7 @@
#include "gimp.h"
#include "gimp-parasites.h"
#include "gimpcontext.h"
#include "gimpgrid.h"
#include "gimpimage.h"
#include "gimpimage-colorhash.h"
#include "gimpimage-colormap.h"
@ -80,6 +81,7 @@ enum
ACTIVE_VECTORS_CHANGED,
COMPONENT_VISIBILITY_CHANGED,
COMPONENT_ACTIVE_CHANGED,
GRID_CHANGED,
MASK_CHANGED,
RESOLUTION_CHANGED,
UNIT_CHANGED,
@ -259,6 +261,15 @@ gimp_image_class_init (GimpImageClass *klass)
G_TYPE_NONE, 1,
GIMP_TYPE_CHANNEL_TYPE);
gimp_image_signals[GRID_CHANGED] =
g_signal_new ("grid_changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpImageClass, grid_changed),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_image_signals[MASK_CHANGED] =
g_signal_new ("mask_changed",
G_TYPE_FROM_CLASS (klass),
@ -400,6 +411,7 @@ gimp_image_class_init (GimpImageClass *klass)
viewable_class->get_new_preview = gimp_image_get_new_preview;
viewable_class->get_description = gimp_image_get_description;
klass->grid_changed = NULL;
klass->mode_changed = NULL;
klass->alpha_changed = NULL;
klass->floating_selection_changed = NULL;
@ -455,6 +467,8 @@ gimp_image_init (GimpImage *gimage)
gimage->guides = NULL;
gimage->grid = NULL;
gimage->layers = gimp_list_new (GIMP_TYPE_LAYER,
GIMP_CONTAINER_POLICY_STRONG);
gimage->channels = gimp_list_new (GIMP_TYPE_CHANNEL,
@ -573,6 +587,12 @@ gimp_image_finalize (GObject *object)
gimage->guides = NULL;
}
if (gimage->grid)
{
g_object_unref (gimage->grid);
gimage->grid = NULL;
}
if (gimage->undo_stack)
{
g_object_unref (gimage->undo_stack);
@ -626,6 +646,8 @@ gimp_image_get_memsize (GimpObject *object)
memsize += (g_list_length (gimage->guides) * (sizeof (GList) +
sizeof (GimpGuide)));
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->grid));
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->layers));
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->channels));
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->vectors));
@ -3220,3 +3242,37 @@ gimp_image_invalidate_channel_previews (GimpImage *gimage)
(GFunc) gimp_viewable_invalidate_preview,
NULL);
}
/* grid */
void
gimp_image_grid_changed (GimpImage *gimage)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_signal_emit (gimage, gimp_image_signals[GRID_CHANGED], 0);
}
GimpGrid *
gimp_image_get_grid (GimpImage *gimage)
{
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
return gimage->grid;
}
void
gimp_image_set_grid (GimpImage *gimage,
GimpGrid *grid,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (grid == NULL || GIMP_IS_GRID (grid));
if (push_undo)
gimp_image_undo_push_image_grid (gimage, _("Grid"), gimage->grid);
gimage->grid = grid;
gimp_image_grid_changed (gimage);
}

View File

@ -124,6 +124,7 @@ struct _GimpImage
/* channels */
GList *guides; /* guides */
GimpGrid *grid; /* grid */
/* Layer/Channel attributes */
GimpContainer *layers; /* the list of layers */
@ -174,6 +175,7 @@ struct _GimpImageClass
GimpChannelType channel);
void (* component_active_changed) (GimpImage *gimage,
GimpChannelType channel);
void (* grid_changed) (GimpImage *gimage);
void (* mask_changed) (GimpImage *gimage);
void (* resolution_changed) (GimpImage *gimage);
void (* unit_changed) (GimpImage *gimage);
@ -269,6 +271,7 @@ void gimp_image_set_component_visible (GimpImage *gimage,
gboolean gimp_image_get_component_visible (const GimpImage *gimage,
GimpChannelType type);
void gimp_image_grid_changed (GimpImage *gimage);
void gimp_image_mode_changed (GimpImage *gimage);
void gimp_image_alpha_changed (GimpImage *gimage);
void gimp_image_update (GimpImage *gimage,
@ -483,5 +486,10 @@ GimpLayer * gimp_image_pick_correlate_layer (const GimpImage *gimage,
void gimp_image_invalidate_layer_previews (GimpImage *gimage);
void gimp_image_invalidate_channel_previews (GimpImage *gimage);
GimpGrid * gimp_image_get_grid (GimpImage *gimage);
void gimp_image_set_grid (GimpImage *gimage,
GimpGrid *grid,
gboolean push_undo);
#endif /* __GIMP_IMAGE_H__ */

411
app/dialogs/grid-dialog.c Normal file
View File

@ -0,0 +1,411 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpbase/gimplimits.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "gui-types.h"
#include "config/gimpconfig-types.h"
#include "config/gimpconfig-utils.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpgrid.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-appearance.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimppropwidgets.h"
#include "grid-dialog.h"
#include "gimp-intl.h"
#define GRID_COLOR_SIZE 20
/* local functions */
static void reset_callback (GtkWidget *widget,
GtkWidget *dialog);
static void remove_callback (GtkWidget *widget,
GtkWidget *dialog);
static void cancel_callback (GtkWidget *widget,
GtkWidget *dialog);
static void ok_callback (GtkWidget *widget,
GtkWidget *dialog);
/* public function */
GtkWidget *
grid_dialog_new (GimpDisplay *gdisp)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid_orig;
GimpGrid *grid;
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *type;
GtkWidget *color_button;
GtkWidget *sizeentry;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
g_return_val_if_fail (GIMP_IS_DISPLAY (gdisp), NULL);
gimage = GIMP_IMAGE (gdisp->gimage);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
grid = g_object_new (GIMP_TYPE_GRID, NULL);
g_object_ref (G_OBJECT (grid));
/* the dialog */
dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gimage),
_("Configure Grid"), "configure_grid",
GIMP_STOCK_GRID, _("Configure Image Grid"),
gimp_standard_help_func,
"dialogs/configure_grid.html",
GIMP_STOCK_RESET, reset_callback,
NULL, NULL, NULL, FALSE, FALSE,
GTK_STOCK_REMOVE, remove_callback,
NULL, NULL, NULL, FALSE, FALSE,
GTK_STOCK_CANCEL, cancel_callback,
NULL, NULL, NULL, FALSE, TRUE,
GTK_STOCK_OK, ok_callback,
NULL, NULL, NULL, TRUE, FALSE,
NULL);
/* the main vbox */
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
main_vbox);
/* misc options */
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
show_button = gtk_check_button_new_with_label (_("Show Grid"));
gtk_box_pack_start (GTK_BOX (vbox), show_button, FALSE, FALSE, 0);
show_grid = gimp_display_shell_get_show_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
show_grid);
gtk_widget_show (show_button);
snap_button = gtk_check_button_new_with_label (_("Snap to Grid"));
gtk_box_pack_start (GTK_BOX (vbox), snap_button, FALSE, FALSE, 0);
snap_to_grid = gimp_display_shell_get_snap_to_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (snap_button),
snap_to_grid);
gtk_widget_show (snap_button);
gtk_widget_show (vbox);
/* the appearence frame */
frame = gtk_frame_new (_("Appearence"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
table = gtk_table_new (3, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_container_add (GTK_CONTAINER (frame), table);
type = gimp_prop_enum_option_menu_new (G_OBJECT (grid), "type",
GIMP_GRID_TYPE_INTERSECTION,
GIMP_GRID_TYPE_SOLID);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Line Style:"), 1.0, 0.5,
type, 1, TRUE);
color_button = gimp_prop_color_button_new (G_OBJECT (grid), "fgcolor",
_("Grid Foreground Color"),
GRID_COLOR_SIZE, GRID_COLOR_SIZE,
GIMP_COLOR_AREA_FLAT);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Foreground Color:"), 1.0, 0.5,
color_button, 1, TRUE);
color_button = gimp_prop_color_button_new (G_OBJECT (grid), "bgcolor",
_("Grid Background Color"),
GRID_COLOR_SIZE, GRID_COLOR_SIZE,
GIMP_COLOR_AREA_FLAT);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
_("Background Color:"), 1.0, 0.5,
color_button, 1, TRUE);
gtk_widget_show (table);
/* the spacing frame */
frame = gtk_frame_new (_("Spacing"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
hbox = gtk_hbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
gtk_container_add (GTK_CONTAINER (frame), hbox);
sizeentry = gimp_prop_coordinates_new (G_OBJECT (grid),
"xspacing",
"yspacing",
"spacing-unit",
"%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE,
gimage->xresolution,
gimage->yresolution,
TRUE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
0, 1.0, GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
1, 1.0, GIMP_MAX_IMAGE_SIZE);
gtk_table_set_col_spacings (GTK_TABLE (sizeentry), 2);
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Width"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Height"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
gtk_widget_show (hbox);
/* the offset frame */
frame = gtk_frame_new (_("Offset"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
hbox = gtk_hbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
gtk_container_add (GTK_CONTAINER (frame), hbox);
sizeentry = gimp_prop_coordinates_new (G_OBJECT (grid),
"xoffset",
"yoffset",
"offset-unit",
"%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE,
gimage->xresolution,
gimage->yresolution,
TRUE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
0, - GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
1, - GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gtk_table_set_col_spacings (GTK_TABLE (sizeentry), 2);
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Width"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Height"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
gtk_widget_show (hbox);
if (grid_orig)
{
gimp_config_copy_properties (G_OBJECT (grid_orig), G_OBJECT (grid));
}
else
{
gimp_config_reset_properties (G_OBJECT (grid));
g_object_set (G_OBJECT (grid),
"spacing-unit", gimage->unit,
NULL);
g_object_set (G_OBJECT (grid),
"offset-unit", gimage->unit,
NULL);
}
gtk_widget_show (main_vbox);
g_object_set_data (G_OBJECT (dialog), "gimage", gimage);
g_object_set_data (G_OBJECT (dialog), "shell", shell);
g_object_set_data (G_OBJECT (dialog), "grid", grid);
g_object_set_data (G_OBJECT (dialog), "show-button", show_button);
g_object_set_data (G_OBJECT (dialog), "snap-button", snap_button);
return dialog;
}
/* local functions */
static void
reset_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid_orig;
GimpGrid *grid;
GimpUnit unit_orig;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
shell = g_object_get_data (G_OBJECT (dialog), "shell");
show_button = g_object_get_data (G_OBJECT (dialog), "show-button");
snap_button = g_object_get_data (G_OBJECT (dialog), "snap-button");
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
unit_orig = gimp_image_get_unit (GIMP_IMAGE (gimage));
if (grid_orig)
{
gimp_config_copy_properties (G_OBJECT (grid_orig),
G_OBJECT (grid));
}
else
{
g_object_freeze_notify (G_OBJECT (grid));
gimp_config_reset_properties (G_OBJECT (grid));
g_object_set (G_OBJECT (grid),
"spacing-unit", unit_orig,
NULL);
g_object_set (G_OBJECT (grid),
"offset-unit", unit_orig,
NULL);
g_object_thaw_notify (G_OBJECT (grid));
}
show_grid = gimp_display_shell_get_show_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
show_grid);
snap_to_grid = gimp_display_shell_get_snap_to_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (snap_button),
snap_to_grid);
}
static void
remove_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpGrid *grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
gimp_image_set_grid (gimage, NULL, TRUE);
g_object_unref (G_OBJECT (grid));
gtk_widget_destroy (dialog);
}
static void
cancel_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpGrid *grid;
grid = g_object_get_data (G_OBJECT (dialog), "grid");
g_object_unref (G_OBJECT (grid));
gtk_widget_destroy (dialog);
}
static void
ok_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid;
GimpGrid *grid_orig;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
shell = g_object_get_data (G_OBJECT (dialog), "shell");
show_button = g_object_get_data (G_OBJECT (dialog), "show-button");
snap_button = g_object_get_data (G_OBJECT (dialog), "snap-button");
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
if (grid_orig == NULL || gimp_config_diff (G_OBJECT (grid_orig), G_OBJECT (grid), 0))
gimp_image_set_grid (GIMP_IMAGE (gimage), grid, TRUE);
else
g_object_unref (G_OBJECT (grid));
show_grid = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_button));
gimp_display_shell_set_show_grid (GIMP_DISPLAY_SHELL (shell), show_grid);
snap_to_grid = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (snap_button));
gimp_display_shell_set_snap_to_grid (GIMP_DISPLAY_SHELL (shell), snap_to_grid);
gtk_widget_destroy (dialog);
}

24
app/dialogs/grid-dialog.h Normal file
View File

@ -0,0 +1,24 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GRID_DIALOG_H__
#define __GRID_DIALOG_H__
GtkWidget * grid_dialog_new (GimpDisplay *gdisp);
#endif /* __GRID_DIALOG_H__ */

View File

@ -207,6 +207,63 @@ gimp_display_shell_get_show_layer (GimpDisplayShell *shell)
return GET_VISIBILITY (shell)->active_layer;
}
void
gimp_display_shell_set_show_grid (GimpDisplayShell *shell,
gboolean show)
{
GimpDisplayShellVisibility *visibility;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
visibility = GET_VISIBILITY (shell);
if (show != visibility->grid)
{
visibility->grid = show ? TRUE : FALSE;
if (shell->gdisp->gimage->grid)
gimp_display_shell_expose_full (shell);
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->menubar_factory),
"/View/Show Grid", show);
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->popup_factory),
"/View/Show Grid", show);
}
}
gboolean
gimp_display_shell_get_show_grid (GimpDisplayShell *shell)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
return GET_VISIBILITY (shell)->grid;
}
void
gimp_display_shell_set_snap_to_grid (GimpDisplayShell *shell,
gboolean snap)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
if (snap != shell->snap_to_grid)
{
shell->snap_to_grid = snap ? TRUE : FALSE;
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->menubar_factory),
"/View/Snap to Grid", snap);
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->popup_factory),
"/View/Snap to Grid", snap);
}
}
gboolean
gimp_display_shell_get_snap_to_grid (GimpDisplayShell *shell)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
return shell->snap_to_grid;
}
void
gimp_display_shell_set_show_guides (GimpDisplayShell *shell,
gboolean show)

View File

@ -36,6 +36,14 @@ void gimp_display_shell_set_show_layer (GimpDisplayShell *shell,
gboolean show);
gboolean gimp_display_shell_get_show_layer (GimpDisplayShell *shell);
void gimp_display_shell_set_show_grid (GimpDisplayShell *shell,
gboolean show);
gboolean gimp_display_shell_get_show_grid (GimpDisplayShell *shell);
void gimp_display_shell_set_snap_to_grid (GimpDisplayShell *shell,
gboolean snap);
gboolean gimp_display_shell_get_snap_to_grid (GimpDisplayShell *shell);
void gimp_display_shell_set_show_guides (GimpDisplayShell *shell,
gboolean show);
gboolean gimp_display_shell_get_show_guides (GimpDisplayShell *shell);

View File

@ -211,6 +211,7 @@ gimp_display_shell_events (GtkWidget *widget,
gimp_display_shell_set_show_selection (shell, visibility.selection);
gimp_display_shell_set_show_layer (shell, visibility.active_layer);
gimp_display_shell_set_show_guides (shell, visibility.guides);
gimp_display_shell_set_show_grid (shell, visibility.grid);
gimp_display_shell_set_show_menubar (shell, visibility.menubar);
gimp_display_shell_set_show_rulers (shell, visibility.rulers);
gimp_display_shell_set_show_scrollbars (shell, visibility.scrollbars);
@ -335,6 +336,9 @@ gimp_display_shell_canvas_expose (GtkWidget *widget,
/* draw the guides */
gimp_display_shell_draw_guides (shell);
/* draw the grid */
gimp_display_shell_draw_grid (shell);
/* and the cursor (if we have a software cursor) */
if (shell->have_cursor)
gimp_display_shell_draw_cursor (shell);

View File

@ -36,9 +36,10 @@
#include "core/gimp.h"
#include "core/gimpbuffer.h"
#include "core/gimpcontext.h"
#include "core/gimpgrid.h"
#include "core/gimpimage.h"
#include "core/gimpimage-guides.h"
#include "core/gimpimage-mask.h"
#include "core/gimpimage-snap.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimpmarshal.h"
@ -208,6 +209,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->proximity = FALSE;
shell->snap_to_guides = TRUE;
shell->snap_to_grid = TRUE;
shell->select = NULL;
@ -254,6 +256,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->info_dialog = NULL;
shell->scale_dialog = NULL;
shell->nav_popup = NULL;
shell->grid_dialog = NULL;
shell->filters = NULL;
shell->filters_dialog = NULL;
@ -266,6 +269,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->visibility.selection = TRUE;
shell->visibility.active_layer = TRUE;
shell->visibility.guides = TRUE;
shell->visibility.grid = TRUE;
shell->visibility.menubar = FALSE;
shell->visibility.rulers = TRUE;
shell->visibility.scrollbars = TRUE;
@ -274,6 +278,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->fullscreen_visibility.selection = TRUE;
shell->fullscreen_visibility.active_layer = TRUE;
shell->fullscreen_visibility.guides = TRUE;
shell->fullscreen_visibility.grid = TRUE;
shell->fullscreen_visibility.menubar = FALSE;
shell->fullscreen_visibility.rulers = FALSE;
shell->fullscreen_visibility.scrollbars = FALSE;
@ -396,6 +401,12 @@ gimp_display_shell_destroy (GtkObject *object)
shell->nav_popup = NULL;
}
if (shell->grid_dialog)
{
gtk_widget_destroy (shell->grid_dialog);
shell->grid_dialog = NULL;
}
shell->gdisp = NULL;
GTK_OBJECT_CLASS (parent_class)->destroy (object);
@ -967,6 +978,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
gint snap_width,
gint snap_height)
{
gboolean snap_to_guides = FALSE;
gboolean snap_to_grid = FALSE;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (coords != NULL);
g_return_if_fail (snapped_coords != NULL);
@ -976,6 +990,18 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
if (gimp_display_shell_get_show_guides (shell) &&
shell->snap_to_guides &&
shell->gdisp->gimage->guides)
{
snap_to_guides = TRUE;
}
if (gimp_display_shell_get_show_grid (shell) &&
gimp_display_shell_get_snap_to_grid (shell) &&
shell->gdisp->gimage->grid)
{
snap_to_grid = TRUE;
}
if (snap_to_guides || snap_to_grid)
{
gboolean snapped;
gint tx, ty;
@ -990,7 +1016,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
coords->y + snap_offset_y +
snap_height,
&tx,
&ty);
&ty,
snap_to_guides,
snap_to_grid);
}
else
{
@ -998,7 +1026,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
coords->x + snap_offset_x,
coords->y + snap_offset_y,
&tx,
&ty);
&ty,
snap_to_guides,
snap_to_grid);
}
if (snapped)
@ -1328,6 +1358,131 @@ gimp_display_shell_draw_guides (GimpDisplayShell *shell)
}
}
void
gimp_display_shell_draw_grid (GimpDisplayShell *shell)
{
GdkGC *gc;
GdkGCValues values;
GdkColor fg, bg;
GimpGrid *grid;
gdouble xspacing, yspacing;
gdouble xoffset, yoffset;
GimpRGB *fgcolor, *bgcolor;
GimpGridType type;
gint x1, x2;
gint y1, y2;
gint x, y;
gint x_real, y_real;
const gint length = 2;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
grid = GIMP_GRID (shell->gdisp->gimage->grid);
if (grid == NULL)
return;
if (gimp_display_shell_get_show_grid (shell))
{
g_object_get (G_OBJECT (grid),
"xspacing", &xspacing,
"yspacing", &yspacing,
"xoffset", &xoffset,
"yoffset", &yoffset,
"fgcolor", &fgcolor,
"bgcolor", &bgcolor,
"type", &type,
NULL);
switch (type)
{
case GIMP_GRID_TYPE_INTERSECTION:
values.line_style = GDK_LINE_SOLID;
break;
case GIMP_GRID_TYPE_ON_OFF_DASH:
values.line_style = GDK_LINE_ON_OFF_DASH;
break;
case GIMP_GRID_TYPE_DOUBLE_DASH:
values.line_style = GDK_LINE_DOUBLE_DASH;
break;
case GIMP_GRID_TYPE_SOLID:
values.line_style = GDK_LINE_SOLID;
break;
default:
g_assert_not_reached ();
}
values.join_style = GDK_JOIN_MITER;
gc = gdk_gc_new_with_values (shell->canvas->window, &values,
GDK_GC_LINE_STYLE | GDK_GC_JOIN_STYLE);
gimp_rgb_get_gdk_color (fgcolor, &fg);
gimp_rgb_get_gdk_color (bgcolor, &bg);
gdk_gc_set_rgb_fg_color (gc, &fg);
gdk_gc_set_rgb_bg_color (gc, &bg);
gimp_display_shell_transform_xy (shell, 0, 0, &x1, &y1, FALSE);
gimp_display_shell_transform_xy (shell,
shell->gdisp->gimage->width,
shell->gdisp->gimage->height,
&x2, &y2, FALSE);
switch (type)
{
case GIMP_GRID_TYPE_INTERSECTION:
for (x = xoffset; x <= shell->gdisp->gimage->width; x += xspacing)
{
for (y = yoffset; y <= shell->gdisp->gimage->height; y += yspacing)
{
gimp_display_shell_transform_xy (shell, x, y, &x_real, &y_real, FALSE);
if (x_real >= x1 && x_real < x2)
{
gdk_draw_line (shell->canvas->window, gc,
x_real, CLAMP (y_real - length, y1, y2 - 1),
x_real, CLAMP (y_real + length, y1, y2 - 1));
}
if (y_real >= y1 && y_real < y2)
{
gdk_draw_line (shell->canvas->window, gc,
CLAMP (x_real - length, x1, x2 - 1), y_real,
CLAMP (x_real + length, x1, x2 - 1), y_real);
}
}
}
break;
case GIMP_GRID_TYPE_ON_OFF_DASH:
case GIMP_GRID_TYPE_DOUBLE_DASH:
case GIMP_GRID_TYPE_SOLID:
for (x = xoffset; x < shell->gdisp->gimage->width; x += xspacing)
{
gimp_display_shell_transform_xy (shell, x, 0, &x_real, &y_real, FALSE);
if (x_real > x1)
gdk_draw_line (shell->canvas->window, gc, x_real, y1, x_real, y2 - 1);
}
for (y = yoffset; y < shell->gdisp->gimage->height; y += yspacing)
{
gimp_display_shell_transform_xy (shell, 0, y, &x_real, &y_real, FALSE);
if (y_real > y1)
gdk_draw_line (shell->canvas->window, gc, x1, y_real, x2 - 1, y_real);
}
break;
default:
g_assert_not_reached ();
}
}
}
void
gimp_display_shell_draw_area (GimpDisplayShell *shell,
gint x,

View File

@ -34,6 +34,7 @@ struct _GimpDisplayShellVisibility
gboolean selection;
gboolean active_layer;
gboolean guides;
gboolean grid;
gboolean menubar;
gboolean rulers;
@ -107,6 +108,7 @@ 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? */
Selection *select; /* Selection object */
@ -155,6 +157,7 @@ struct _GimpDisplayShell
InfoDialog *info_dialog; /* image information dialog */
GtkWidget *scale_dialog; /* scale (zoom) dialog */
GtkWidget *nav_popup; /* navigation popup */
GtkWidget *grid_dialog; /* grid configuration dialog */
GList *filters; /* color display conversion stuff */
GtkWidget *filters_dialog; /* color display filter dialog */
@ -233,6 +236,8 @@ void gimp_display_shell_draw_guide (GimpDisplayShell *shell,
gboolean active);
void gimp_display_shell_draw_guides (GimpDisplayShell *shell);
void gimp_display_shell_draw_grid (GimpDisplayShell *shell);
void gimp_display_shell_update_icon (GimpDisplayShell *shell);
void gimp_display_shell_shrink_wrap (GimpDisplayShell *shell);

View File

@ -53,6 +53,8 @@ static void gimp_display_shell_undo_event_handler (GimpImage *g
GimpUndoEvent event,
GimpUndo *undo,
GimpDisplayShell *shell);
static void gimp_display_shell_grid_changed_handler (GimpImage *gimage,
GimpDisplayShell *shell);
static void gimp_display_shell_name_changed_handler (GimpImage *gimage,
GimpDisplayShell *shell);
static void gimp_display_shell_selection_control_handler (GimpImage *gimage,
@ -122,6 +124,9 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
g_signal_connect (gimage, "undo_event",
G_CALLBACK (gimp_display_shell_undo_event_handler),
shell);
g_signal_connect (gimage, "grid_changed",
G_CALLBACK (gimp_display_shell_grid_changed_handler),
shell);
g_signal_connect (gimage, "name_changed",
G_CALLBACK (gimp_display_shell_name_changed_handler),
shell);
@ -256,6 +261,9 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
g_signal_handlers_disconnect_by_func (gimage,
gimp_display_shell_name_changed_handler,
shell);
g_signal_handlers_disconnect_by_func (gimage,
gimp_display_shell_grid_changed_handler,
shell);
g_signal_handlers_disconnect_by_func (gimage,
gimp_display_shell_undo_event_handler,
shell);
@ -283,6 +291,16 @@ gimp_display_shell_undo_event_handler (GimpImage *gimage,
gimp_display_shell_update_title (shell);
}
static void
gimp_display_shell_grid_changed_handler (GimpImage *gimage,
GimpDisplayShell *shell)
{
gimp_display_shell_expose_full (shell);
/* update item factory */
gimp_display_flush (shell->gdisp);
}
static void
gimp_display_shell_name_changed_handler (GimpImage *gimage,
GimpDisplayShell *shell)

View File

@ -36,9 +36,10 @@
#include "core/gimp.h"
#include "core/gimpbuffer.h"
#include "core/gimpcontext.h"
#include "core/gimpgrid.h"
#include "core/gimpimage.h"
#include "core/gimpimage-guides.h"
#include "core/gimpimage-mask.h"
#include "core/gimpimage-snap.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimpmarshal.h"
@ -208,6 +209,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->proximity = FALSE;
shell->snap_to_guides = TRUE;
shell->snap_to_grid = TRUE;
shell->select = NULL;
@ -254,6 +256,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->info_dialog = NULL;
shell->scale_dialog = NULL;
shell->nav_popup = NULL;
shell->grid_dialog = NULL;
shell->filters = NULL;
shell->filters_dialog = NULL;
@ -266,6 +269,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->visibility.selection = TRUE;
shell->visibility.active_layer = TRUE;
shell->visibility.guides = TRUE;
shell->visibility.grid = TRUE;
shell->visibility.menubar = FALSE;
shell->visibility.rulers = TRUE;
shell->visibility.scrollbars = TRUE;
@ -274,6 +278,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->fullscreen_visibility.selection = TRUE;
shell->fullscreen_visibility.active_layer = TRUE;
shell->fullscreen_visibility.guides = TRUE;
shell->fullscreen_visibility.grid = TRUE;
shell->fullscreen_visibility.menubar = FALSE;
shell->fullscreen_visibility.rulers = FALSE;
shell->fullscreen_visibility.scrollbars = FALSE;
@ -396,6 +401,12 @@ gimp_display_shell_destroy (GtkObject *object)
shell->nav_popup = NULL;
}
if (shell->grid_dialog)
{
gtk_widget_destroy (shell->grid_dialog);
shell->grid_dialog = NULL;
}
shell->gdisp = NULL;
GTK_OBJECT_CLASS (parent_class)->destroy (object);
@ -967,6 +978,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
gint snap_width,
gint snap_height)
{
gboolean snap_to_guides = FALSE;
gboolean snap_to_grid = FALSE;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (coords != NULL);
g_return_if_fail (snapped_coords != NULL);
@ -976,6 +990,18 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
if (gimp_display_shell_get_show_guides (shell) &&
shell->snap_to_guides &&
shell->gdisp->gimage->guides)
{
snap_to_guides = TRUE;
}
if (gimp_display_shell_get_show_grid (shell) &&
gimp_display_shell_get_snap_to_grid (shell) &&
shell->gdisp->gimage->grid)
{
snap_to_grid = TRUE;
}
if (snap_to_guides || snap_to_grid)
{
gboolean snapped;
gint tx, ty;
@ -990,7 +1016,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
coords->y + snap_offset_y +
snap_height,
&tx,
&ty);
&ty,
snap_to_guides,
snap_to_grid);
}
else
{
@ -998,7 +1026,9 @@ gimp_display_shell_snap_coords (GimpDisplayShell *shell,
coords->x + snap_offset_x,
coords->y + snap_offset_y,
&tx,
&ty);
&ty,
snap_to_guides,
snap_to_grid);
}
if (snapped)
@ -1328,6 +1358,131 @@ gimp_display_shell_draw_guides (GimpDisplayShell *shell)
}
}
void
gimp_display_shell_draw_grid (GimpDisplayShell *shell)
{
GdkGC *gc;
GdkGCValues values;
GdkColor fg, bg;
GimpGrid *grid;
gdouble xspacing, yspacing;
gdouble xoffset, yoffset;
GimpRGB *fgcolor, *bgcolor;
GimpGridType type;
gint x1, x2;
gint y1, y2;
gint x, y;
gint x_real, y_real;
const gint length = 2;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
grid = GIMP_GRID (shell->gdisp->gimage->grid);
if (grid == NULL)
return;
if (gimp_display_shell_get_show_grid (shell))
{
g_object_get (G_OBJECT (grid),
"xspacing", &xspacing,
"yspacing", &yspacing,
"xoffset", &xoffset,
"yoffset", &yoffset,
"fgcolor", &fgcolor,
"bgcolor", &bgcolor,
"type", &type,
NULL);
switch (type)
{
case GIMP_GRID_TYPE_INTERSECTION:
values.line_style = GDK_LINE_SOLID;
break;
case GIMP_GRID_TYPE_ON_OFF_DASH:
values.line_style = GDK_LINE_ON_OFF_DASH;
break;
case GIMP_GRID_TYPE_DOUBLE_DASH:
values.line_style = GDK_LINE_DOUBLE_DASH;
break;
case GIMP_GRID_TYPE_SOLID:
values.line_style = GDK_LINE_SOLID;
break;
default:
g_assert_not_reached ();
}
values.join_style = GDK_JOIN_MITER;
gc = gdk_gc_new_with_values (shell->canvas->window, &values,
GDK_GC_LINE_STYLE | GDK_GC_JOIN_STYLE);
gimp_rgb_get_gdk_color (fgcolor, &fg);
gimp_rgb_get_gdk_color (bgcolor, &bg);
gdk_gc_set_rgb_fg_color (gc, &fg);
gdk_gc_set_rgb_bg_color (gc, &bg);
gimp_display_shell_transform_xy (shell, 0, 0, &x1, &y1, FALSE);
gimp_display_shell_transform_xy (shell,
shell->gdisp->gimage->width,
shell->gdisp->gimage->height,
&x2, &y2, FALSE);
switch (type)
{
case GIMP_GRID_TYPE_INTERSECTION:
for (x = xoffset; x <= shell->gdisp->gimage->width; x += xspacing)
{
for (y = yoffset; y <= shell->gdisp->gimage->height; y += yspacing)
{
gimp_display_shell_transform_xy (shell, x, y, &x_real, &y_real, FALSE);
if (x_real >= x1 && x_real < x2)
{
gdk_draw_line (shell->canvas->window, gc,
x_real, CLAMP (y_real - length, y1, y2 - 1),
x_real, CLAMP (y_real + length, y1, y2 - 1));
}
if (y_real >= y1 && y_real < y2)
{
gdk_draw_line (shell->canvas->window, gc,
CLAMP (x_real - length, x1, x2 - 1), y_real,
CLAMP (x_real + length, x1, x2 - 1), y_real);
}
}
}
break;
case GIMP_GRID_TYPE_ON_OFF_DASH:
case GIMP_GRID_TYPE_DOUBLE_DASH:
case GIMP_GRID_TYPE_SOLID:
for (x = xoffset; x < shell->gdisp->gimage->width; x += xspacing)
{
gimp_display_shell_transform_xy (shell, x, 0, &x_real, &y_real, FALSE);
if (x_real > x1)
gdk_draw_line (shell->canvas->window, gc, x_real, y1, x_real, y2 - 1);
}
for (y = yoffset; y < shell->gdisp->gimage->height; y += yspacing)
{
gimp_display_shell_transform_xy (shell, 0, y, &x_real, &y_real, FALSE);
if (y_real > y1)
gdk_draw_line (shell->canvas->window, gc, x1, y_real, x2 - 1, y_real);
}
break;
default:
g_assert_not_reached ();
}
}
}
void
gimp_display_shell_draw_area (GimpDisplayShell *shell,
gint x,

View File

@ -34,6 +34,7 @@ struct _GimpDisplayShellVisibility
gboolean selection;
gboolean active_layer;
gboolean guides;
gboolean grid;
gboolean menubar;
gboolean rulers;
@ -107,6 +108,7 @@ 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? */
Selection *select; /* Selection object */
@ -155,6 +157,7 @@ struct _GimpDisplayShell
InfoDialog *info_dialog; /* image information dialog */
GtkWidget *scale_dialog; /* scale (zoom) dialog */
GtkWidget *nav_popup; /* navigation popup */
GtkWidget *grid_dialog; /* grid configuration dialog */
GList *filters; /* color display conversion stuff */
GtkWidget *filters_dialog; /* color display filter dialog */
@ -233,6 +236,8 @@ void gimp_display_shell_draw_guide (GimpDisplayShell *shell,
gboolean active);
void gimp_display_shell_draw_guides (GimpDisplayShell *shell);
void gimp_display_shell_draw_grid (GimpDisplayShell *shell);
void gimp_display_shell_update_icon (GimpDisplayShell *shell);
void gimp_display_shell_shrink_wrap (GimpDisplayShell *shell);

View File

@ -29,6 +29,8 @@ dialogs_sources = \
font-select.h \
gradient-select.c \
gradient-select.h \
grid-dialog.h \
grid-dialog.c \
info-dialog.c \
info-dialog.h \
info-window.c \

411
app/gui/grid-dialog.c Normal file
View File

@ -0,0 +1,411 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpbase/gimplimits.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "gui-types.h"
#include "config/gimpconfig-types.h"
#include "config/gimpconfig-utils.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpgrid.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-appearance.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimppropwidgets.h"
#include "grid-dialog.h"
#include "gimp-intl.h"
#define GRID_COLOR_SIZE 20
/* local functions */
static void reset_callback (GtkWidget *widget,
GtkWidget *dialog);
static void remove_callback (GtkWidget *widget,
GtkWidget *dialog);
static void cancel_callback (GtkWidget *widget,
GtkWidget *dialog);
static void ok_callback (GtkWidget *widget,
GtkWidget *dialog);
/* public function */
GtkWidget *
grid_dialog_new (GimpDisplay *gdisp)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid_orig;
GimpGrid *grid;
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
GtkWidget *type;
GtkWidget *color_button;
GtkWidget *sizeentry;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
g_return_val_if_fail (GIMP_IS_DISPLAY (gdisp), NULL);
gimage = GIMP_IMAGE (gdisp->gimage);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
grid = g_object_new (GIMP_TYPE_GRID, NULL);
g_object_ref (G_OBJECT (grid));
/* the dialog */
dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gimage),
_("Configure Grid"), "configure_grid",
GIMP_STOCK_GRID, _("Configure Image Grid"),
gimp_standard_help_func,
"dialogs/configure_grid.html",
GIMP_STOCK_RESET, reset_callback,
NULL, NULL, NULL, FALSE, FALSE,
GTK_STOCK_REMOVE, remove_callback,
NULL, NULL, NULL, FALSE, FALSE,
GTK_STOCK_CANCEL, cancel_callback,
NULL, NULL, NULL, FALSE, TRUE,
GTK_STOCK_OK, ok_callback,
NULL, NULL, NULL, TRUE, FALSE,
NULL);
/* the main vbox */
main_vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
main_vbox);
/* misc options */
vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
show_button = gtk_check_button_new_with_label (_("Show Grid"));
gtk_box_pack_start (GTK_BOX (vbox), show_button, FALSE, FALSE, 0);
show_grid = gimp_display_shell_get_show_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
show_grid);
gtk_widget_show (show_button);
snap_button = gtk_check_button_new_with_label (_("Snap to Grid"));
gtk_box_pack_start (GTK_BOX (vbox), snap_button, FALSE, FALSE, 0);
snap_to_grid = gimp_display_shell_get_snap_to_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (snap_button),
snap_to_grid);
gtk_widget_show (snap_button);
gtk_widget_show (vbox);
/* the appearence frame */
frame = gtk_frame_new (_("Appearence"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
table = gtk_table_new (3, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_container_add (GTK_CONTAINER (frame), table);
type = gimp_prop_enum_option_menu_new (G_OBJECT (grid), "type",
GIMP_GRID_TYPE_INTERSECTION,
GIMP_GRID_TYPE_SOLID);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Line Style:"), 1.0, 0.5,
type, 1, TRUE);
color_button = gimp_prop_color_button_new (G_OBJECT (grid), "fgcolor",
_("Grid Foreground Color"),
GRID_COLOR_SIZE, GRID_COLOR_SIZE,
GIMP_COLOR_AREA_FLAT);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Foreground Color:"), 1.0, 0.5,
color_button, 1, TRUE);
color_button = gimp_prop_color_button_new (G_OBJECT (grid), "bgcolor",
_("Grid Background Color"),
GRID_COLOR_SIZE, GRID_COLOR_SIZE,
GIMP_COLOR_AREA_FLAT);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
_("Background Color:"), 1.0, 0.5,
color_button, 1, TRUE);
gtk_widget_show (table);
/* the spacing frame */
frame = gtk_frame_new (_("Spacing"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
hbox = gtk_hbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
gtk_container_add (GTK_CONTAINER (frame), hbox);
sizeentry = gimp_prop_coordinates_new (G_OBJECT (grid),
"xspacing",
"yspacing",
"spacing-unit",
"%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE,
gimage->xresolution,
gimage->yresolution,
TRUE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
0, 1.0, GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
1, 1.0, GIMP_MAX_IMAGE_SIZE);
gtk_table_set_col_spacings (GTK_TABLE (sizeentry), 2);
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Width"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Height"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
gtk_widget_show (hbox);
/* the offset frame */
frame = gtk_frame_new (_("Offset"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
hbox = gtk_hbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
gtk_container_add (GTK_CONTAINER (frame), hbox);
sizeentry = gimp_prop_coordinates_new (G_OBJECT (grid),
"xoffset",
"yoffset",
"offset-unit",
"%a",
GIMP_SIZE_ENTRY_UPDATE_SIZE,
gimage->xresolution,
gimage->yresolution,
TRUE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
0, - GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry),
1, - GIMP_MAX_IMAGE_SIZE,
GIMP_MAX_IMAGE_SIZE);
gtk_table_set_col_spacings (GTK_TABLE (sizeentry), 2);
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Width"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Height"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
gtk_widget_show (hbox);
if (grid_orig)
{
gimp_config_copy_properties (G_OBJECT (grid_orig), G_OBJECT (grid));
}
else
{
gimp_config_reset_properties (G_OBJECT (grid));
g_object_set (G_OBJECT (grid),
"spacing-unit", gimage->unit,
NULL);
g_object_set (G_OBJECT (grid),
"offset-unit", gimage->unit,
NULL);
}
gtk_widget_show (main_vbox);
g_object_set_data (G_OBJECT (dialog), "gimage", gimage);
g_object_set_data (G_OBJECT (dialog), "shell", shell);
g_object_set_data (G_OBJECT (dialog), "grid", grid);
g_object_set_data (G_OBJECT (dialog), "show-button", show_button);
g_object_set_data (G_OBJECT (dialog), "snap-button", snap_button);
return dialog;
}
/* local functions */
static void
reset_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid_orig;
GimpGrid *grid;
GimpUnit unit_orig;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
shell = g_object_get_data (G_OBJECT (dialog), "shell");
show_button = g_object_get_data (G_OBJECT (dialog), "show-button");
snap_button = g_object_get_data (G_OBJECT (dialog), "snap-button");
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
unit_orig = gimp_image_get_unit (GIMP_IMAGE (gimage));
if (grid_orig)
{
gimp_config_copy_properties (G_OBJECT (grid_orig),
G_OBJECT (grid));
}
else
{
g_object_freeze_notify (G_OBJECT (grid));
gimp_config_reset_properties (G_OBJECT (grid));
g_object_set (G_OBJECT (grid),
"spacing-unit", unit_orig,
NULL);
g_object_set (G_OBJECT (grid),
"offset-unit", unit_orig,
NULL);
g_object_thaw_notify (G_OBJECT (grid));
}
show_grid = gimp_display_shell_get_show_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
show_grid);
snap_to_grid = gimp_display_shell_get_snap_to_grid (GIMP_DISPLAY_SHELL (shell));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (snap_button),
snap_to_grid);
}
static void
remove_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpGrid *grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
gimp_image_set_grid (gimage, NULL, TRUE);
g_object_unref (G_OBJECT (grid));
gtk_widget_destroy (dialog);
}
static void
cancel_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpGrid *grid;
grid = g_object_get_data (G_OBJECT (dialog), "grid");
g_object_unref (G_OBJECT (grid));
gtk_widget_destroy (dialog);
}
static void
ok_callback (GtkWidget *widget,
GtkWidget *dialog)
{
GimpImage *gimage;
GimpDisplayShell *shell;
GimpGrid *grid;
GimpGrid *grid_orig;
GtkWidget *show_button;
GtkWidget *snap_button;
gboolean show_grid;
gboolean snap_to_grid;
gimage = g_object_get_data (G_OBJECT (dialog), "gimage");
grid = g_object_get_data (G_OBJECT (dialog), "grid");
shell = g_object_get_data (G_OBJECT (dialog), "shell");
show_button = g_object_get_data (G_OBJECT (dialog), "show-button");
snap_button = g_object_get_data (G_OBJECT (dialog), "snap-button");
grid_orig = gimp_image_get_grid (GIMP_IMAGE (gimage));
if (grid_orig == NULL || gimp_config_diff (G_OBJECT (grid_orig), G_OBJECT (grid), 0))
gimp_image_set_grid (GIMP_IMAGE (gimage), grid, TRUE);
else
g_object_unref (G_OBJECT (grid));
show_grid = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_button));
gimp_display_shell_set_show_grid (GIMP_DISPLAY_SHELL (shell), show_grid);
snap_to_grid = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (snap_button));
gimp_display_shell_set_snap_to_grid (GIMP_DISPLAY_SHELL (shell), snap_to_grid);
gtk_widget_destroy (dialog);
}

24
app/gui/grid-dialog.h Normal file
View File

@ -0,0 +1,24 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GRID_DIALOG_H__
#define __GRID_DIALOG_H__
GtkWidget * grid_dialog_new (GimpDisplay *gdisp);
#endif /* __GRID_DIALOG_H__ */

View File

@ -422,6 +422,21 @@ GimpItemFactoryEntry image_menu_entries[] =
MENU_SEPARATOR ("/View/---"),
{ { N_("/View/Configure Grid..."), NULL,
view_configure_grid_cmd_callback, 0, NULL },
NULL,
"view/configure_grid.html", NULL },
{ { N_("/View/Show Grid"), NULL,
view_toggle_grid_cmd_callback, 0, "<ToggleItem>" },
NULL,
"view/toggle_grid.html", NULL },
{ { N_("/View/Snap to Grid"), NULL,
view_snap_to_grid_cmd_callback, 0, "<ToggleItem>" },
NULL,
"view/snap_to_grid.html", NULL },
MENU_SEPARATOR ("/View/---"),
{ { N_("/View/Show Menubar"), NULL,
view_toggle_menubar_cmd_callback, 0, "<ToggleItem>" },
NULL,
@ -1414,6 +1429,11 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/View/Snap to Guides", gdisp);
SET_ACTIVE ("/View/Snap to Guides", gdisp && shell->snap_to_guides);
SET_SENSITIVE ("/View/Show Grid", gdisp);
SET_ACTIVE ("/View/Show Grid", gdisp && visibility->grid);
SET_SENSITIVE ("/View/Snap to Grid", gdisp);
SET_ACTIVE ("/View/Snap to Grid", gdisp && shell->snap_to_grid);
SET_SENSITIVE ("/View/Show Menubar", gdisp);
SET_ACTIVE ("/View/Show Menubar", gdisp && visibility->menubar);
SET_SENSITIVE ("/View/Show Rulers", gdisp);

View File

@ -42,6 +42,7 @@
#include "dialogs.h"
#include "info-dialog.h"
#include "info-window.h"
#include "grid-dialog.h"
#include "view-commands.h"
@ -350,6 +351,63 @@ view_snap_to_guides_cmd_callback (GtkWidget *widget,
}
}
void
view_configure_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GtkWidget *grid_dialog;
return_if_no_display (gdisp, data);
grid_dialog = grid_dialog_new (GIMP_DISPLAY (gdisp));
g_signal_connect_object (gdisp, "disconnect",
G_CALLBACK (gtk_widget_destroy),
grid_dialog,
G_CONNECT_SWAPPED);
gtk_widget_show (grid_dialog);
}
void
view_toggle_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
gimp_display_shell_set_show_grid (shell,
GTK_CHECK_MENU_ITEM (widget)->active);
}
void
view_snap_to_grid_cmd_callback (GtkWidget *widget,
gpointer data)
{
GimpDisplay *gdisp;
GimpDisplayShell *shell;
return_if_no_display (gdisp, data);
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
if (shell->snap_to_grid != GTK_CHECK_MENU_ITEM (widget)->active)
{
shell->snap_to_grid = GTK_CHECK_MENU_ITEM (widget)->active;
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->menubar_factory),
"/View/Snap to Grid",
shell->snap_to_grid);
gimp_item_factory_set_active (GTK_ITEM_FACTORY (shell->popup_factory),
"/View/Snap to Grid",
shell->snap_to_grid);
}
}
void
view_new_view_cmd_callback (GtkWidget *widget,
gpointer data)

View File

@ -57,6 +57,12 @@ void view_toggle_guides_cmd_callback (GtkWidget *widget,
gpointer data);
void view_snap_to_guides_cmd_callback (GtkWidget *widget,
gpointer data);
void view_toggle_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_configure_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_snap_to_grid_cmd_callback (GtkWidget *widget,
gpointer data);
void view_new_view_cmd_callback (GtkWidget *widget,
gpointer data);
void view_shrink_wrap_cmd_callback (GtkWidget *widget,

View File

@ -422,6 +422,21 @@ GimpItemFactoryEntry image_menu_entries[] =
MENU_SEPARATOR ("/View/---"),
{ { N_("/View/Configure Grid..."), NULL,
view_configure_grid_cmd_callback, 0, NULL },
NULL,
"view/configure_grid.html", NULL },
{ { N_("/View/Show Grid"), NULL,
view_toggle_grid_cmd_callback, 0, "<ToggleItem>" },
NULL,
"view/toggle_grid.html", NULL },
{ { N_("/View/Snap to Grid"), NULL,
view_snap_to_grid_cmd_callback, 0, "<ToggleItem>" },
NULL,
"view/snap_to_grid.html", NULL },
MENU_SEPARATOR ("/View/---"),
{ { N_("/View/Show Menubar"), NULL,
view_toggle_menubar_cmd_callback, 0, "<ToggleItem>" },
NULL,
@ -1414,6 +1429,11 @@ image_menu_update (GtkItemFactory *item_factory,
SET_SENSITIVE ("/View/Snap to Guides", gdisp);
SET_ACTIVE ("/View/Snap to Guides", gdisp && shell->snap_to_guides);
SET_SENSITIVE ("/View/Show Grid", gdisp);
SET_ACTIVE ("/View/Show Grid", gdisp && visibility->grid);
SET_SENSITIVE ("/View/Snap to Grid", gdisp);
SET_ACTIVE ("/View/Snap to Grid", gdisp && shell->snap_to_grid);
SET_SENSITIVE ("/View/Show Menubar", gdisp);
SET_ACTIVE ("/View/Show Menubar", gdisp && visibility->menubar);
SET_SENSITIVE ("/View/Show Rulers", gdisp);