Commit edd5c339 authored by Henrik Brix Andersen's avatar Henrik Brix Andersen

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.
parent ba91aeb8
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
......@@ -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)
......
......@@ -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,
......
......@@ -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 \
......
......@@ -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" },
......
......@@ -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" >*/
......
......@@ -73,6 +73,7 @@ typedef struct _GimpDocumentList GimpDocumentList;
typedef struct _GimpTemplate GimpTemplate;
typedef struct _GimpGrid GimpGrid;
/* drawable objects */
......
/* 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;
}
}
/* 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__ */
......@@ -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);