mirror of https://github.com/GNOME/gimp.git
parent
9a4edab746
commit
4dca1d5640
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Thu Apr 8 07:12:10 MEST 1999 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
|
* app/crop.[ch]: Ok, this is a little bit more than what we
|
||||||
|
discussed on the list: Basically, it allows to use the crop
|
||||||
|
tool as usual or as a resize-tool for layers and the image.
|
||||||
|
|
||||||
|
The defaults are the new behaviour. Holding the <Alt>-Key
|
||||||
|
when creating the selection toggles the "Allow-expand" mode,
|
||||||
|
holding the <Shift>-key when cropping, gives you the opposite
|
||||||
|
of your default setting for "Crop layers".
|
||||||
|
|
||||||
|
The button for "Selection" is gone, but will reappear somewhere
|
||||||
|
else soon. But first, I need some sleep...
|
||||||
|
|
||||||
Wed Apr 7 23:53:22 BST 1999 Andy Thomas <alt@gimp.org>
|
Wed Apr 7 23:53:22 BST 1999 Andy Thomas <alt@gimp.org>
|
||||||
|
|
||||||
Changed:-
|
Changed:-
|
||||||
|
|
253
app/crop.c
253
app/crop.c
|
@ -63,6 +63,7 @@ struct _crop
|
||||||
#define RESIZING_LEFT 2
|
#define RESIZING_LEFT 2
|
||||||
#define RESIZING_RIGHT 3
|
#define RESIZING_RIGHT 3
|
||||||
#define CROPPING 4
|
#define CROPPING 4
|
||||||
|
#define REFRAMING 5
|
||||||
|
|
||||||
/* speed of key movement */
|
/* speed of key movement */
|
||||||
#define ARROW_VELOCITY 25
|
#define ARROW_VELOCITY 25
|
||||||
|
@ -84,7 +85,7 @@ static void crop_arrow_keys_func (Tool *, GdkEventKey *, gpointer);
|
||||||
|
|
||||||
|
|
||||||
/* Crop helper functions */
|
/* Crop helper functions */
|
||||||
static void crop_image (GImage *gimage, int, int, int, int);
|
static void crop_image (GImage *gimage, int, int, int, int, int, int);
|
||||||
static void crop_recalc (Tool *, Crop *);
|
static void crop_recalc (Tool *, Crop *);
|
||||||
static void crop_start (Tool *, Crop *);
|
static void crop_start (Tool *, Crop *);
|
||||||
static void crop_adjust_guides (GImage *, int, int, int, int);
|
static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
|
@ -93,6 +94,7 @@ static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
static void crop_info_update (Tool *);
|
static void crop_info_update (Tool *);
|
||||||
static void crop_info_create (Tool *);
|
static void crop_info_create (Tool *);
|
||||||
static void crop_ok_callback (GtkWidget *, gpointer);
|
static void crop_ok_callback (GtkWidget *, gpointer);
|
||||||
|
static void crop_resize_callback (GtkWidget *, gpointer);
|
||||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||||
static void crop_close_callback (GtkWidget *, gpointer);
|
static void crop_close_callback (GtkWidget *, gpointer);
|
||||||
|
|
||||||
|
@ -117,6 +119,12 @@ init_crop_options()
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *checkbutton;
|
GtkWidget *checkbutton;
|
||||||
|
GtkWidget *defaults_frame;
|
||||||
|
GtkWidget *defaults_box;
|
||||||
|
|
||||||
|
options.layer_only = FALSE;
|
||||||
|
options.default_to_enlarge = TRUE;
|
||||||
|
options.default_to_crop = FALSE;
|
||||||
|
|
||||||
/* the main vbox */
|
/* the main vbox */
|
||||||
vbox = gtk_vbox_new (FALSE, 2);
|
vbox = gtk_vbox_new (FALSE, 2);
|
||||||
|
@ -137,6 +145,38 @@ init_crop_options()
|
||||||
options.layer_only);
|
options.layer_only);
|
||||||
gtk_widget_show(checkbutton);
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* defaults */
|
||||||
|
defaults_frame = gtk_frame_new (_("Defaults"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), defaults_frame, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
defaults_box = gtk_vbox_new (FALSE, 1);
|
||||||
|
gtk_container_add (GTK_CONTAINER (defaults_frame), defaults_box);
|
||||||
|
|
||||||
|
/* enlarge toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Allow Enlarging"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_enlarge);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_enlarge);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* crop toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Crop Layers"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_crop);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_crop);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
gtk_widget_show (defaults_box);
|
||||||
|
gtk_widget_show (defaults_frame);
|
||||||
|
|
||||||
/* Register this selection options widget with the main tools
|
/* Register this selection options widget with the main tools
|
||||||
* options dialog */
|
* options dialog */
|
||||||
|
|
||||||
|
@ -157,7 +197,6 @@ crop_checkbutton_update (GtkWidget *w,
|
||||||
*toggle_val = FALSE;
|
*toggle_val = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crop_button_press (Tool *tool,
|
crop_button_press (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
|
@ -192,11 +231,25 @@ crop_button_press (Tool *tool,
|
||||||
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
||||||
crop->function = MOVING;
|
crop->function = MOVING;
|
||||||
|
|
||||||
/* If the pointer is in the rectangular region, crop it! */
|
/* If the pointer is in the rectangular region, crop or resize it! */
|
||||||
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
||||||
bevent->y > crop->y1 && bevent->y < crop->y2)
|
bevent->y > crop->y1 && bevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
else
|
||||||
crop->function = CROPPING;
|
crop->function = CROPPING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = CROPPING;
|
||||||
|
else
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* otherwise, the new function will be creating, since we want to start anew */
|
/* otherwise, the new function will be creating, since we want to start anew */
|
||||||
else
|
else
|
||||||
crop->function = CREATING;
|
crop->function = CREATING;
|
||||||
|
@ -247,10 +300,17 @@ crop_button_release (Tool *tool,
|
||||||
|
|
||||||
if (! (bevent->state & GDK_BUTTON3_MASK))
|
if (! (bevent->state & GDK_BUTTON3_MASK))
|
||||||
{
|
{
|
||||||
if (crop->function == CROPPING)
|
switch (crop->function)
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case CROPPING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
break;
|
||||||
|
case REFRAMING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
crop_info_update (tool);
|
crop_info_update (tool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -316,17 +376,19 @@ crop_motion (Tool *tool,
|
||||||
{
|
{
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int curx, cury;
|
int curx, cury;
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
gchar size[STATUSBAR_SIZE];
|
gchar size[STATUSBAR_SIZE];
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
/* This is the only case when the motion events should be ignored--
|
/* This is the only case when the motion events should be ignored--
|
||||||
we're just waiting for the button release event to crop the image */
|
we're just waiting for the button release event to crop the image */
|
||||||
if (crop->function == CROPPING)
|
if (crop->function == CROPPING || crop->function == REFRAMING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
||||||
|
@ -344,18 +406,56 @@ crop_motion (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
switch (crop->function)
|
switch (crop->function)
|
||||||
{
|
{
|
||||||
case CREATING :
|
case CREATING :
|
||||||
x1 = BOUNDS (x1, 0, gdisp->gimage->width);
|
if (clamp)
|
||||||
y1 = BOUNDS (y1, 0, gdisp->gimage->height);
|
{
|
||||||
x2 = BOUNDS (x2, 0, gdisp->gimage->width);
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
y2 = BOUNDS (y2, 0, gdisp->gimage->height);
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_LEFT :
|
case RESIZING_LEFT :
|
||||||
x1 = BOUNDS (crop->tx1 + inc_x, 0, gdisp->gimage->width);
|
x1 = crop->tx1 + inc_x;
|
||||||
y1 = BOUNDS (crop->ty1 + inc_y, 0, gdisp->gimage->height);
|
y1 = crop->ty1 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
}
|
||||||
x2 = MAXIMUM (x1, crop->tx2);
|
x2 = MAXIMUM (x1, crop->tx2);
|
||||||
y2 = MAXIMUM (y1, crop->ty2);
|
y2 = MAXIMUM (y1, crop->ty2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -363,8 +463,13 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_RIGHT :
|
case RESIZING_RIGHT :
|
||||||
x2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
x2 = crop->tx2 + inc_x;
|
||||||
y2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
y2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
x1 = MINIMUM (crop->tx1, x2);
|
x1 = MINIMUM (crop->tx1, x2);
|
||||||
y1 = MINIMUM (crop->ty1, y2);
|
y1 = MINIMUM (crop->ty1, y2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -372,8 +477,11 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOVING :
|
case MOVING :
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
if (clamp)
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
{
|
||||||
|
inc_x = BOUNDS (inc_x, min_x - crop->tx1, max_x - crop->tx2);
|
||||||
|
inc_y = BOUNDS (inc_y, min_y - crop->ty1, max_y - crop->ty2);
|
||||||
|
}
|
||||||
x1 = crop->tx1 + inc_x;
|
x1 = crop->tx1 + inc_x;
|
||||||
x2 = crop->tx2 + inc_x;
|
x2 = crop->tx2 + inc_x;
|
||||||
y1 = crop->ty1 + inc_y;
|
y1 = crop->ty1 + inc_y;
|
||||||
|
@ -456,7 +564,22 @@ crop_cursor_update (Tool *tool,
|
||||||
ctype = GDK_FLEUR;
|
ctype = GDK_FLEUR;
|
||||||
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
||||||
mevent->y > crop->y1 && mevent->y < crop->y2)
|
mevent->y > crop->y1 && mevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
else
|
||||||
ctype = GDK_ICON;
|
ctype = GDK_ICON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_ICON;
|
||||||
|
else
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ctype = GDK_CROSS;
|
ctype = GDK_CROSS;
|
||||||
|
|
||||||
|
@ -470,7 +593,10 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
{
|
{
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
|
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
|
@ -496,17 +622,55 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
||||||
{
|
{
|
||||||
crop->tx2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
crop->tx2 = crop->tx2 + inc_x;
|
||||||
crop->ty2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
crop->ty2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
crop->tx2 = BOUNDS (crop->tx2, min_x, max_x);
|
||||||
|
crop->ty2 = BOUNDS (crop->ty2, min_y, max_y);
|
||||||
|
}
|
||||||
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
||||||
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (clamp)
|
||||||
{
|
{
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
||||||
|
}
|
||||||
crop->tx1 += inc_x;
|
crop->tx1 += inc_x;
|
||||||
crop->tx2 += inc_x;
|
crop->tx2 += inc_x;
|
||||||
crop->ty1 += inc_y;
|
crop->ty1 += inc_y;
|
||||||
|
@ -638,7 +802,9 @@ crop_image (GImage *gimage,
|
||||||
int x1,
|
int x1,
|
||||||
int y1,
|
int y1,
|
||||||
int x2,
|
int x2,
|
||||||
int y2)
|
int y2,
|
||||||
|
int layer_only,
|
||||||
|
int crop_layers)
|
||||||
{
|
{
|
||||||
Layer *layer;
|
Layer *layer;
|
||||||
Layer *floating_layer;
|
Layer *floating_layer;
|
||||||
|
@ -659,7 +825,7 @@ crop_image (GImage *gimage,
|
||||||
{
|
{
|
||||||
gimp_add_busy_cursors();
|
gimp_add_busy_cursors();
|
||||||
|
|
||||||
if (options.layer_only)
|
if (layer_only)
|
||||||
{
|
{
|
||||||
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
||||||
|
|
||||||
|
@ -718,6 +884,8 @@ crop_image (GImage *gimage,
|
||||||
|
|
||||||
layer_translate (layer, -x1, -y1);
|
layer_translate (layer, -x1, -y1);
|
||||||
|
|
||||||
|
if (crop_layers)
|
||||||
|
{
|
||||||
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
||||||
|
|
||||||
lx1 = BOUNDS (off_x, 0, gimage->width);
|
lx1 = BOUNDS (off_x, 0, gimage->width);
|
||||||
|
@ -727,8 +895,6 @@ crop_image (GImage *gimage,
|
||||||
width = lx2 - lx1;
|
width = lx2 - lx1;
|
||||||
height = ly2 - ly1;
|
height = ly2 - ly1;
|
||||||
|
|
||||||
list = g_slist_next (list);
|
|
||||||
|
|
||||||
if (width && height)
|
if (width && height)
|
||||||
layer_resize (layer, width, height,
|
layer_resize (layer, width, height,
|
||||||
-(lx1 - off_x),
|
-(lx1 - off_x),
|
||||||
|
@ -737,6 +903,9 @@ crop_image (GImage *gimage,
|
||||||
gimage_remove_layer (gimage, layer);
|
gimage_remove_layer (gimage, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list = g_slist_next (list);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the projection matches the gimage size */
|
/* Make sure the projection matches the gimage size */
|
||||||
gimage_projection_realloc (gimage);
|
gimage_projection_realloc (gimage);
|
||||||
|
|
||||||
|
@ -839,10 +1008,11 @@ crop_start (Tool *tool,
|
||||||
/* Crop dialog functions */
|
/* Crop dialog functions */
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
static ActionAreaItem action_items[3] =
|
static ActionAreaItem action_items[4] =
|
||||||
{
|
{
|
||||||
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
||||||
{ N_("Selection"), crop_selection_callback, NULL, NULL },
|
{ N_("Resize"), crop_resize_callback, NULL, NULL },
|
||||||
|
/* { N_("Selection"), crop_selection_callback, NULL, NULL }, */
|
||||||
{ N_("Close"), crop_close_callback, NULL, NULL },
|
{ N_("Close"), crop_close_callback, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -949,7 +1119,28 @@ crop_ok_callback (GtkWidget *w,
|
||||||
tool = active_tool;
|
tool = active_tool;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) tool->gdisp_ptr;
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
|
||||||
|
/* Finish the tool */
|
||||||
|
draw_core_stop (crop->core, tool);
|
||||||
|
info_dialog_popdown (crop_info);
|
||||||
|
tool->state = INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crop_resize_callback (GtkWidget *w,
|
||||||
|
gpointer client_data)
|
||||||
|
{
|
||||||
|
Tool * tool;
|
||||||
|
Crop * crop;
|
||||||
|
GDisplay * gdisp;
|
||||||
|
|
||||||
|
tool = active_tool;
|
||||||
|
crop = (Crop *) tool->private;
|
||||||
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
|
||||||
/* Finish the tool */
|
/* Finish the tool */
|
||||||
draw_core_stop (crop->core, tool);
|
draw_core_stop (crop->core, tool);
|
||||||
|
@ -1113,11 +1304,14 @@ crop_invoker (Argument *args)
|
||||||
int int_value;
|
int int_value;
|
||||||
int new_width, new_height;
|
int new_width, new_height;
|
||||||
int offx, offy;
|
int offx, offy;
|
||||||
|
int layer_only, crop_layers ;
|
||||||
|
|
||||||
new_width = 1;
|
new_width = 1;
|
||||||
new_height = 1;
|
new_height = 1;
|
||||||
offx = 0;
|
offx = 0;
|
||||||
offy = 0;
|
offy = 0;
|
||||||
|
layer_only = FALSE;
|
||||||
|
crop_layers = TRUE;
|
||||||
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
if (success)
|
if (success)
|
||||||
|
@ -1147,7 +1341,8 @@ crop_invoker (Argument *args)
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
crop_image (gimage, offx, offy, offx + new_width, offy + new_height,
|
||||||
|
layer_only, crop_layers);
|
||||||
|
|
||||||
return procedural_db_return_args (&crop_proc, success);
|
return procedural_db_return_args (&crop_proc, success);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ void tools_free_crop (Tool *);
|
||||||
/* tool options */
|
/* tool options */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int layer_only;
|
int layer_only;
|
||||||
|
int default_to_enlarge;
|
||||||
|
int default_to_crop;
|
||||||
} CropToolOptions;
|
} CropToolOptions;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,3 +38,5 @@ typedef struct {
|
||||||
extern ProcRecord crop_proc;
|
extern ProcRecord crop_proc;
|
||||||
|
|
||||||
#endif /* __CROP_H__ */
|
#endif /* __CROP_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
253
app/tools/crop.c
253
app/tools/crop.c
|
@ -63,6 +63,7 @@ struct _crop
|
||||||
#define RESIZING_LEFT 2
|
#define RESIZING_LEFT 2
|
||||||
#define RESIZING_RIGHT 3
|
#define RESIZING_RIGHT 3
|
||||||
#define CROPPING 4
|
#define CROPPING 4
|
||||||
|
#define REFRAMING 5
|
||||||
|
|
||||||
/* speed of key movement */
|
/* speed of key movement */
|
||||||
#define ARROW_VELOCITY 25
|
#define ARROW_VELOCITY 25
|
||||||
|
@ -84,7 +85,7 @@ static void crop_arrow_keys_func (Tool *, GdkEventKey *, gpointer);
|
||||||
|
|
||||||
|
|
||||||
/* Crop helper functions */
|
/* Crop helper functions */
|
||||||
static void crop_image (GImage *gimage, int, int, int, int);
|
static void crop_image (GImage *gimage, int, int, int, int, int, int);
|
||||||
static void crop_recalc (Tool *, Crop *);
|
static void crop_recalc (Tool *, Crop *);
|
||||||
static void crop_start (Tool *, Crop *);
|
static void crop_start (Tool *, Crop *);
|
||||||
static void crop_adjust_guides (GImage *, int, int, int, int);
|
static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
|
@ -93,6 +94,7 @@ static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
static void crop_info_update (Tool *);
|
static void crop_info_update (Tool *);
|
||||||
static void crop_info_create (Tool *);
|
static void crop_info_create (Tool *);
|
||||||
static void crop_ok_callback (GtkWidget *, gpointer);
|
static void crop_ok_callback (GtkWidget *, gpointer);
|
||||||
|
static void crop_resize_callback (GtkWidget *, gpointer);
|
||||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||||
static void crop_close_callback (GtkWidget *, gpointer);
|
static void crop_close_callback (GtkWidget *, gpointer);
|
||||||
|
|
||||||
|
@ -117,6 +119,12 @@ init_crop_options()
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *checkbutton;
|
GtkWidget *checkbutton;
|
||||||
|
GtkWidget *defaults_frame;
|
||||||
|
GtkWidget *defaults_box;
|
||||||
|
|
||||||
|
options.layer_only = FALSE;
|
||||||
|
options.default_to_enlarge = TRUE;
|
||||||
|
options.default_to_crop = FALSE;
|
||||||
|
|
||||||
/* the main vbox */
|
/* the main vbox */
|
||||||
vbox = gtk_vbox_new (FALSE, 2);
|
vbox = gtk_vbox_new (FALSE, 2);
|
||||||
|
@ -137,6 +145,38 @@ init_crop_options()
|
||||||
options.layer_only);
|
options.layer_only);
|
||||||
gtk_widget_show(checkbutton);
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* defaults */
|
||||||
|
defaults_frame = gtk_frame_new (_("Defaults"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), defaults_frame, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
defaults_box = gtk_vbox_new (FALSE, 1);
|
||||||
|
gtk_container_add (GTK_CONTAINER (defaults_frame), defaults_box);
|
||||||
|
|
||||||
|
/* enlarge toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Allow Enlarging"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_enlarge);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_enlarge);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* crop toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Crop Layers"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_crop);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_crop);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
gtk_widget_show (defaults_box);
|
||||||
|
gtk_widget_show (defaults_frame);
|
||||||
|
|
||||||
/* Register this selection options widget with the main tools
|
/* Register this selection options widget with the main tools
|
||||||
* options dialog */
|
* options dialog */
|
||||||
|
|
||||||
|
@ -157,7 +197,6 @@ crop_checkbutton_update (GtkWidget *w,
|
||||||
*toggle_val = FALSE;
|
*toggle_val = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crop_button_press (Tool *tool,
|
crop_button_press (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
|
@ -192,11 +231,25 @@ crop_button_press (Tool *tool,
|
||||||
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
||||||
crop->function = MOVING;
|
crop->function = MOVING;
|
||||||
|
|
||||||
/* If the pointer is in the rectangular region, crop it! */
|
/* If the pointer is in the rectangular region, crop or resize it! */
|
||||||
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
||||||
bevent->y > crop->y1 && bevent->y < crop->y2)
|
bevent->y > crop->y1 && bevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
else
|
||||||
crop->function = CROPPING;
|
crop->function = CROPPING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = CROPPING;
|
||||||
|
else
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* otherwise, the new function will be creating, since we want to start anew */
|
/* otherwise, the new function will be creating, since we want to start anew */
|
||||||
else
|
else
|
||||||
crop->function = CREATING;
|
crop->function = CREATING;
|
||||||
|
@ -247,10 +300,17 @@ crop_button_release (Tool *tool,
|
||||||
|
|
||||||
if (! (bevent->state & GDK_BUTTON3_MASK))
|
if (! (bevent->state & GDK_BUTTON3_MASK))
|
||||||
{
|
{
|
||||||
if (crop->function == CROPPING)
|
switch (crop->function)
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case CROPPING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
break;
|
||||||
|
case REFRAMING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
crop_info_update (tool);
|
crop_info_update (tool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -316,17 +376,19 @@ crop_motion (Tool *tool,
|
||||||
{
|
{
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int curx, cury;
|
int curx, cury;
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
gchar size[STATUSBAR_SIZE];
|
gchar size[STATUSBAR_SIZE];
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
/* This is the only case when the motion events should be ignored--
|
/* This is the only case when the motion events should be ignored--
|
||||||
we're just waiting for the button release event to crop the image */
|
we're just waiting for the button release event to crop the image */
|
||||||
if (crop->function == CROPPING)
|
if (crop->function == CROPPING || crop->function == REFRAMING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
||||||
|
@ -344,18 +406,56 @@ crop_motion (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
switch (crop->function)
|
switch (crop->function)
|
||||||
{
|
{
|
||||||
case CREATING :
|
case CREATING :
|
||||||
x1 = BOUNDS (x1, 0, gdisp->gimage->width);
|
if (clamp)
|
||||||
y1 = BOUNDS (y1, 0, gdisp->gimage->height);
|
{
|
||||||
x2 = BOUNDS (x2, 0, gdisp->gimage->width);
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
y2 = BOUNDS (y2, 0, gdisp->gimage->height);
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_LEFT :
|
case RESIZING_LEFT :
|
||||||
x1 = BOUNDS (crop->tx1 + inc_x, 0, gdisp->gimage->width);
|
x1 = crop->tx1 + inc_x;
|
||||||
y1 = BOUNDS (crop->ty1 + inc_y, 0, gdisp->gimage->height);
|
y1 = crop->ty1 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
}
|
||||||
x2 = MAXIMUM (x1, crop->tx2);
|
x2 = MAXIMUM (x1, crop->tx2);
|
||||||
y2 = MAXIMUM (y1, crop->ty2);
|
y2 = MAXIMUM (y1, crop->ty2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -363,8 +463,13 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_RIGHT :
|
case RESIZING_RIGHT :
|
||||||
x2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
x2 = crop->tx2 + inc_x;
|
||||||
y2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
y2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
x1 = MINIMUM (crop->tx1, x2);
|
x1 = MINIMUM (crop->tx1, x2);
|
||||||
y1 = MINIMUM (crop->ty1, y2);
|
y1 = MINIMUM (crop->ty1, y2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -372,8 +477,11 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOVING :
|
case MOVING :
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
if (clamp)
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
{
|
||||||
|
inc_x = BOUNDS (inc_x, min_x - crop->tx1, max_x - crop->tx2);
|
||||||
|
inc_y = BOUNDS (inc_y, min_y - crop->ty1, max_y - crop->ty2);
|
||||||
|
}
|
||||||
x1 = crop->tx1 + inc_x;
|
x1 = crop->tx1 + inc_x;
|
||||||
x2 = crop->tx2 + inc_x;
|
x2 = crop->tx2 + inc_x;
|
||||||
y1 = crop->ty1 + inc_y;
|
y1 = crop->ty1 + inc_y;
|
||||||
|
@ -456,7 +564,22 @@ crop_cursor_update (Tool *tool,
|
||||||
ctype = GDK_FLEUR;
|
ctype = GDK_FLEUR;
|
||||||
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
||||||
mevent->y > crop->y1 && mevent->y < crop->y2)
|
mevent->y > crop->y1 && mevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
else
|
||||||
ctype = GDK_ICON;
|
ctype = GDK_ICON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_ICON;
|
||||||
|
else
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ctype = GDK_CROSS;
|
ctype = GDK_CROSS;
|
||||||
|
|
||||||
|
@ -470,7 +593,10 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
{
|
{
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
|
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
|
@ -496,17 +622,55 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
||||||
{
|
{
|
||||||
crop->tx2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
crop->tx2 = crop->tx2 + inc_x;
|
||||||
crop->ty2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
crop->ty2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
crop->tx2 = BOUNDS (crop->tx2, min_x, max_x);
|
||||||
|
crop->ty2 = BOUNDS (crop->ty2, min_y, max_y);
|
||||||
|
}
|
||||||
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
||||||
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (clamp)
|
||||||
{
|
{
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
||||||
|
}
|
||||||
crop->tx1 += inc_x;
|
crop->tx1 += inc_x;
|
||||||
crop->tx2 += inc_x;
|
crop->tx2 += inc_x;
|
||||||
crop->ty1 += inc_y;
|
crop->ty1 += inc_y;
|
||||||
|
@ -638,7 +802,9 @@ crop_image (GImage *gimage,
|
||||||
int x1,
|
int x1,
|
||||||
int y1,
|
int y1,
|
||||||
int x2,
|
int x2,
|
||||||
int y2)
|
int y2,
|
||||||
|
int layer_only,
|
||||||
|
int crop_layers)
|
||||||
{
|
{
|
||||||
Layer *layer;
|
Layer *layer;
|
||||||
Layer *floating_layer;
|
Layer *floating_layer;
|
||||||
|
@ -659,7 +825,7 @@ crop_image (GImage *gimage,
|
||||||
{
|
{
|
||||||
gimp_add_busy_cursors();
|
gimp_add_busy_cursors();
|
||||||
|
|
||||||
if (options.layer_only)
|
if (layer_only)
|
||||||
{
|
{
|
||||||
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
||||||
|
|
||||||
|
@ -718,6 +884,8 @@ crop_image (GImage *gimage,
|
||||||
|
|
||||||
layer_translate (layer, -x1, -y1);
|
layer_translate (layer, -x1, -y1);
|
||||||
|
|
||||||
|
if (crop_layers)
|
||||||
|
{
|
||||||
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
||||||
|
|
||||||
lx1 = BOUNDS (off_x, 0, gimage->width);
|
lx1 = BOUNDS (off_x, 0, gimage->width);
|
||||||
|
@ -727,8 +895,6 @@ crop_image (GImage *gimage,
|
||||||
width = lx2 - lx1;
|
width = lx2 - lx1;
|
||||||
height = ly2 - ly1;
|
height = ly2 - ly1;
|
||||||
|
|
||||||
list = g_slist_next (list);
|
|
||||||
|
|
||||||
if (width && height)
|
if (width && height)
|
||||||
layer_resize (layer, width, height,
|
layer_resize (layer, width, height,
|
||||||
-(lx1 - off_x),
|
-(lx1 - off_x),
|
||||||
|
@ -737,6 +903,9 @@ crop_image (GImage *gimage,
|
||||||
gimage_remove_layer (gimage, layer);
|
gimage_remove_layer (gimage, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list = g_slist_next (list);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the projection matches the gimage size */
|
/* Make sure the projection matches the gimage size */
|
||||||
gimage_projection_realloc (gimage);
|
gimage_projection_realloc (gimage);
|
||||||
|
|
||||||
|
@ -839,10 +1008,11 @@ crop_start (Tool *tool,
|
||||||
/* Crop dialog functions */
|
/* Crop dialog functions */
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
static ActionAreaItem action_items[3] =
|
static ActionAreaItem action_items[4] =
|
||||||
{
|
{
|
||||||
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
||||||
{ N_("Selection"), crop_selection_callback, NULL, NULL },
|
{ N_("Resize"), crop_resize_callback, NULL, NULL },
|
||||||
|
/* { N_("Selection"), crop_selection_callback, NULL, NULL }, */
|
||||||
{ N_("Close"), crop_close_callback, NULL, NULL },
|
{ N_("Close"), crop_close_callback, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -949,7 +1119,28 @@ crop_ok_callback (GtkWidget *w,
|
||||||
tool = active_tool;
|
tool = active_tool;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) tool->gdisp_ptr;
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
|
||||||
|
/* Finish the tool */
|
||||||
|
draw_core_stop (crop->core, tool);
|
||||||
|
info_dialog_popdown (crop_info);
|
||||||
|
tool->state = INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crop_resize_callback (GtkWidget *w,
|
||||||
|
gpointer client_data)
|
||||||
|
{
|
||||||
|
Tool * tool;
|
||||||
|
Crop * crop;
|
||||||
|
GDisplay * gdisp;
|
||||||
|
|
||||||
|
tool = active_tool;
|
||||||
|
crop = (Crop *) tool->private;
|
||||||
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
|
||||||
/* Finish the tool */
|
/* Finish the tool */
|
||||||
draw_core_stop (crop->core, tool);
|
draw_core_stop (crop->core, tool);
|
||||||
|
@ -1113,11 +1304,14 @@ crop_invoker (Argument *args)
|
||||||
int int_value;
|
int int_value;
|
||||||
int new_width, new_height;
|
int new_width, new_height;
|
||||||
int offx, offy;
|
int offx, offy;
|
||||||
|
int layer_only, crop_layers ;
|
||||||
|
|
||||||
new_width = 1;
|
new_width = 1;
|
||||||
new_height = 1;
|
new_height = 1;
|
||||||
offx = 0;
|
offx = 0;
|
||||||
offy = 0;
|
offy = 0;
|
||||||
|
layer_only = FALSE;
|
||||||
|
crop_layers = TRUE;
|
||||||
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
if (success)
|
if (success)
|
||||||
|
@ -1147,7 +1341,8 @@ crop_invoker (Argument *args)
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
crop_image (gimage, offx, offy, offx + new_width, offy + new_height,
|
||||||
|
layer_only, crop_layers);
|
||||||
|
|
||||||
return procedural_db_return_args (&crop_proc, success);
|
return procedural_db_return_args (&crop_proc, success);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ void tools_free_crop (Tool *);
|
||||||
/* tool options */
|
/* tool options */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int layer_only;
|
int layer_only;
|
||||||
|
int default_to_enlarge;
|
||||||
|
int default_to_crop;
|
||||||
} CropToolOptions;
|
} CropToolOptions;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,3 +38,5 @@ typedef struct {
|
||||||
extern ProcRecord crop_proc;
|
extern ProcRecord crop_proc;
|
||||||
|
|
||||||
#endif /* __CROP_H__ */
|
#endif /* __CROP_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct _crop
|
||||||
#define RESIZING_LEFT 2
|
#define RESIZING_LEFT 2
|
||||||
#define RESIZING_RIGHT 3
|
#define RESIZING_RIGHT 3
|
||||||
#define CROPPING 4
|
#define CROPPING 4
|
||||||
|
#define REFRAMING 5
|
||||||
|
|
||||||
/* speed of key movement */
|
/* speed of key movement */
|
||||||
#define ARROW_VELOCITY 25
|
#define ARROW_VELOCITY 25
|
||||||
|
@ -84,7 +85,7 @@ static void crop_arrow_keys_func (Tool *, GdkEventKey *, gpointer);
|
||||||
|
|
||||||
|
|
||||||
/* Crop helper functions */
|
/* Crop helper functions */
|
||||||
static void crop_image (GImage *gimage, int, int, int, int);
|
static void crop_image (GImage *gimage, int, int, int, int, int, int);
|
||||||
static void crop_recalc (Tool *, Crop *);
|
static void crop_recalc (Tool *, Crop *);
|
||||||
static void crop_start (Tool *, Crop *);
|
static void crop_start (Tool *, Crop *);
|
||||||
static void crop_adjust_guides (GImage *, int, int, int, int);
|
static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
|
@ -93,6 +94,7 @@ static void crop_adjust_guides (GImage *, int, int, int, int);
|
||||||
static void crop_info_update (Tool *);
|
static void crop_info_update (Tool *);
|
||||||
static void crop_info_create (Tool *);
|
static void crop_info_create (Tool *);
|
||||||
static void crop_ok_callback (GtkWidget *, gpointer);
|
static void crop_ok_callback (GtkWidget *, gpointer);
|
||||||
|
static void crop_resize_callback (GtkWidget *, gpointer);
|
||||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||||
static void crop_close_callback (GtkWidget *, gpointer);
|
static void crop_close_callback (GtkWidget *, gpointer);
|
||||||
|
|
||||||
|
@ -117,6 +119,12 @@ init_crop_options()
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *checkbutton;
|
GtkWidget *checkbutton;
|
||||||
|
GtkWidget *defaults_frame;
|
||||||
|
GtkWidget *defaults_box;
|
||||||
|
|
||||||
|
options.layer_only = FALSE;
|
||||||
|
options.default_to_enlarge = TRUE;
|
||||||
|
options.default_to_crop = FALSE;
|
||||||
|
|
||||||
/* the main vbox */
|
/* the main vbox */
|
||||||
vbox = gtk_vbox_new (FALSE, 2);
|
vbox = gtk_vbox_new (FALSE, 2);
|
||||||
|
@ -137,6 +145,38 @@ init_crop_options()
|
||||||
options.layer_only);
|
options.layer_only);
|
||||||
gtk_widget_show(checkbutton);
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* defaults */
|
||||||
|
defaults_frame = gtk_frame_new (_("Defaults"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), defaults_frame, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
defaults_box = gtk_vbox_new (FALSE, 1);
|
||||||
|
gtk_container_add (GTK_CONTAINER (defaults_frame), defaults_box);
|
||||||
|
|
||||||
|
/* enlarge toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Allow Enlarging"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_enlarge);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_enlarge);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
/* crop toggle */
|
||||||
|
checkbutton = gtk_check_button_new_with_label(_("Crop Layers"));
|
||||||
|
gtk_box_pack_start(GTK_BOX(defaults_box), checkbutton,
|
||||||
|
FALSE, FALSE, 0);
|
||||||
|
gtk_signal_connect(GTK_OBJECT(checkbutton), "toggled",
|
||||||
|
(GtkSignalFunc) crop_checkbutton_update,
|
||||||
|
&options.default_to_crop);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),
|
||||||
|
options.default_to_crop);
|
||||||
|
gtk_widget_show(checkbutton);
|
||||||
|
|
||||||
|
gtk_widget_show (defaults_box);
|
||||||
|
gtk_widget_show (defaults_frame);
|
||||||
|
|
||||||
/* Register this selection options widget with the main tools
|
/* Register this selection options widget with the main tools
|
||||||
* options dialog */
|
* options dialog */
|
||||||
|
|
||||||
|
@ -157,7 +197,6 @@ crop_checkbutton_update (GtkWidget *w,
|
||||||
*toggle_val = FALSE;
|
*toggle_val = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crop_button_press (Tool *tool,
|
crop_button_press (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
|
@ -192,11 +231,25 @@ crop_button_press (Tool *tool,
|
||||||
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
bevent->y == BOUNDS (bevent->y, crop->y1, crop->y1 + crop->srh)))
|
||||||
crop->function = MOVING;
|
crop->function = MOVING;
|
||||||
|
|
||||||
/* If the pointer is in the rectangular region, crop it! */
|
/* If the pointer is in the rectangular region, crop or resize it! */
|
||||||
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
else if (bevent->x > crop->x1 && bevent->x < crop->x2 &&
|
||||||
bevent->y > crop->y1 && bevent->y < crop->y2)
|
bevent->y > crop->y1 && bevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
else
|
||||||
crop->function = CROPPING;
|
crop->function = CROPPING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( bevent->state & GDK_SHIFT_MASK )
|
||||||
|
crop->function = CROPPING;
|
||||||
|
else
|
||||||
|
crop->function = REFRAMING;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* otherwise, the new function will be creating, since we want to start anew */
|
/* otherwise, the new function will be creating, since we want to start anew */
|
||||||
else
|
else
|
||||||
crop->function = CREATING;
|
crop->function = CREATING;
|
||||||
|
@ -247,10 +300,17 @@ crop_button_release (Tool *tool,
|
||||||
|
|
||||||
if (! (bevent->state & GDK_BUTTON3_MASK))
|
if (! (bevent->state & GDK_BUTTON3_MASK))
|
||||||
{
|
{
|
||||||
if (crop->function == CROPPING)
|
switch (crop->function)
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case CROPPING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
break;
|
||||||
|
case REFRAMING:
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
crop_info_update (tool);
|
crop_info_update (tool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -316,17 +376,19 @@ crop_motion (Tool *tool,
|
||||||
{
|
{
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int curx, cury;
|
int curx, cury;
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
gchar size[STATUSBAR_SIZE];
|
gchar size[STATUSBAR_SIZE];
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
/* This is the only case when the motion events should be ignored--
|
/* This is the only case when the motion events should be ignored--
|
||||||
we're just waiting for the button release event to crop the image */
|
we're just waiting for the button release event to crop the image */
|
||||||
if (crop->function == CROPPING)
|
if (crop->function == CROPPING || crop->function == REFRAMING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &curx, &cury, TRUE, FALSE);
|
||||||
|
@ -344,18 +406,56 @@ crop_motion (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
switch (crop->function)
|
switch (crop->function)
|
||||||
{
|
{
|
||||||
case CREATING :
|
case CREATING :
|
||||||
x1 = BOUNDS (x1, 0, gdisp->gimage->width);
|
if (clamp)
|
||||||
y1 = BOUNDS (y1, 0, gdisp->gimage->height);
|
{
|
||||||
x2 = BOUNDS (x2, 0, gdisp->gimage->width);
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
y2 = BOUNDS (y2, 0, gdisp->gimage->height);
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_LEFT :
|
case RESIZING_LEFT :
|
||||||
x1 = BOUNDS (crop->tx1 + inc_x, 0, gdisp->gimage->width);
|
x1 = crop->tx1 + inc_x;
|
||||||
y1 = BOUNDS (crop->ty1 + inc_y, 0, gdisp->gimage->height);
|
y1 = crop->ty1 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x1 = BOUNDS (x1, min_x, max_x);
|
||||||
|
y1 = BOUNDS (y1, min_y, max_y);
|
||||||
|
}
|
||||||
x2 = MAXIMUM (x1, crop->tx2);
|
x2 = MAXIMUM (x1, crop->tx2);
|
||||||
y2 = MAXIMUM (y1, crop->ty2);
|
y2 = MAXIMUM (y1, crop->ty2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -363,8 +463,13 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESIZING_RIGHT :
|
case RESIZING_RIGHT :
|
||||||
x2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
x2 = crop->tx2 + inc_x;
|
||||||
y2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
y2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
x2 = BOUNDS (x2, min_x, max_x);
|
||||||
|
y2 = BOUNDS (y2, min_y, max_y);
|
||||||
|
}
|
||||||
x1 = MINIMUM (crop->tx1, x2);
|
x1 = MINIMUM (crop->tx1, x2);
|
||||||
y1 = MINIMUM (crop->ty1, y2);
|
y1 = MINIMUM (crop->ty1, y2);
|
||||||
crop->startx = curx;
|
crop->startx = curx;
|
||||||
|
@ -372,8 +477,11 @@ crop_motion (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOVING :
|
case MOVING :
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
if (clamp)
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
{
|
||||||
|
inc_x = BOUNDS (inc_x, min_x - crop->tx1, max_x - crop->tx2);
|
||||||
|
inc_y = BOUNDS (inc_y, min_y - crop->ty1, max_y - crop->ty2);
|
||||||
|
}
|
||||||
x1 = crop->tx1 + inc_x;
|
x1 = crop->tx1 + inc_x;
|
||||||
x2 = crop->tx2 + inc_x;
|
x2 = crop->tx2 + inc_x;
|
||||||
y1 = crop->ty1 + inc_y;
|
y1 = crop->ty1 + inc_y;
|
||||||
|
@ -456,7 +564,22 @@ crop_cursor_update (Tool *tool,
|
||||||
ctype = GDK_FLEUR;
|
ctype = GDK_FLEUR;
|
||||||
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
else if (mevent->x > crop->x1 && mevent->x < crop->x2 &&
|
||||||
mevent->y > crop->y1 && mevent->y < crop->y2)
|
mevent->y > crop->y1 && mevent->y < crop->y2)
|
||||||
|
{
|
||||||
|
if ( options.default_to_crop )
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
else
|
||||||
ctype = GDK_ICON;
|
ctype = GDK_ICON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mevent->state & GDK_SHIFT_MASK )
|
||||||
|
ctype = GDK_ICON;
|
||||||
|
else
|
||||||
|
ctype = GDK_SIZING;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ctype = GDK_CROSS;
|
ctype = GDK_CROSS;
|
||||||
|
|
||||||
|
@ -470,7 +593,10 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
{
|
{
|
||||||
int inc_x, inc_y;
|
int inc_x, inc_y;
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
Layer * layer;
|
||||||
Crop * crop;
|
Crop * crop;
|
||||||
|
int clamp;
|
||||||
|
int min_x, min_y, max_x, max_y;
|
||||||
|
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
|
|
||||||
|
@ -496,17 +622,55 @@ crop_arrow_keys_func (Tool *tool,
|
||||||
|
|
||||||
draw_core_pause (crop->core, tool);
|
draw_core_pause (crop->core, tool);
|
||||||
|
|
||||||
|
/* shall we clamp the coordinates to the image dimensions? */
|
||||||
|
if (options.default_to_enlarge)
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = TRUE;
|
||||||
|
else
|
||||||
|
clamp = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (kevent->state & GDK_MOD1_MASK)
|
||||||
|
clamp = FALSE;
|
||||||
|
else
|
||||||
|
clamp = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.layer_only)
|
||||||
|
{
|
||||||
|
layer = (gdisp->gimage)->active_layer;
|
||||||
|
drawable_offsets (GIMP_DRAWABLE(layer), &min_x, &min_y);
|
||||||
|
max_x = drawable_width (GIMP_DRAWABLE(layer)) + min_x;
|
||||||
|
max_y = drawable_height (GIMP_DRAWABLE(layer)) + min_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_x = min_y = 0;
|
||||||
|
max_x = gdisp->gimage->width;
|
||||||
|
max_y = gdisp->gimage->height;
|
||||||
|
}
|
||||||
|
|
||||||
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
if (kevent->state & GDK_CONTROL_MASK) /* RESIZING */
|
||||||
{
|
{
|
||||||
crop->tx2 = BOUNDS (crop->tx2 + inc_x, 0, gdisp->gimage->width);
|
crop->tx2 = crop->tx2 + inc_x;
|
||||||
crop->ty2 = BOUNDS (crop->ty2 + inc_y, 0, gdisp->gimage->height);
|
crop->ty2 = crop->ty2 + inc_y;
|
||||||
|
if (clamp)
|
||||||
|
{
|
||||||
|
crop->tx2 = BOUNDS (crop->tx2, min_x, max_x);
|
||||||
|
crop->ty2 = BOUNDS (crop->ty2, min_y, max_y);
|
||||||
|
}
|
||||||
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
crop->tx1 = MINIMUM (crop->tx1, crop->tx2);
|
||||||
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
crop->ty1 = MINIMUM (crop->ty1, crop->ty2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (clamp)
|
||||||
{
|
{
|
||||||
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
inc_x = BOUNDS (inc_x, -crop->tx1, gdisp->gimage->width - crop->tx2);
|
||||||
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
inc_y = BOUNDS (inc_y, -crop->ty1, gdisp->gimage->height - crop->ty2);
|
||||||
|
}
|
||||||
crop->tx1 += inc_x;
|
crop->tx1 += inc_x;
|
||||||
crop->tx2 += inc_x;
|
crop->tx2 += inc_x;
|
||||||
crop->ty1 += inc_y;
|
crop->ty1 += inc_y;
|
||||||
|
@ -638,7 +802,9 @@ crop_image (GImage *gimage,
|
||||||
int x1,
|
int x1,
|
||||||
int y1,
|
int y1,
|
||||||
int x2,
|
int x2,
|
||||||
int y2)
|
int y2,
|
||||||
|
int layer_only,
|
||||||
|
int crop_layers)
|
||||||
{
|
{
|
||||||
Layer *layer;
|
Layer *layer;
|
||||||
Layer *floating_layer;
|
Layer *floating_layer;
|
||||||
|
@ -659,7 +825,7 @@ crop_image (GImage *gimage,
|
||||||
{
|
{
|
||||||
gimp_add_busy_cursors();
|
gimp_add_busy_cursors();
|
||||||
|
|
||||||
if (options.layer_only)
|
if (layer_only)
|
||||||
{
|
{
|
||||||
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
undo_push_group_start (gimage, LAYER_RESIZE_UNDO);
|
||||||
|
|
||||||
|
@ -718,6 +884,8 @@ crop_image (GImage *gimage,
|
||||||
|
|
||||||
layer_translate (layer, -x1, -y1);
|
layer_translate (layer, -x1, -y1);
|
||||||
|
|
||||||
|
if (crop_layers)
|
||||||
|
{
|
||||||
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
|
||||||
|
|
||||||
lx1 = BOUNDS (off_x, 0, gimage->width);
|
lx1 = BOUNDS (off_x, 0, gimage->width);
|
||||||
|
@ -727,8 +895,6 @@ crop_image (GImage *gimage,
|
||||||
width = lx2 - lx1;
|
width = lx2 - lx1;
|
||||||
height = ly2 - ly1;
|
height = ly2 - ly1;
|
||||||
|
|
||||||
list = g_slist_next (list);
|
|
||||||
|
|
||||||
if (width && height)
|
if (width && height)
|
||||||
layer_resize (layer, width, height,
|
layer_resize (layer, width, height,
|
||||||
-(lx1 - off_x),
|
-(lx1 - off_x),
|
||||||
|
@ -737,6 +903,9 @@ crop_image (GImage *gimage,
|
||||||
gimage_remove_layer (gimage, layer);
|
gimage_remove_layer (gimage, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list = g_slist_next (list);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the projection matches the gimage size */
|
/* Make sure the projection matches the gimage size */
|
||||||
gimage_projection_realloc (gimage);
|
gimage_projection_realloc (gimage);
|
||||||
|
|
||||||
|
@ -839,10 +1008,11 @@ crop_start (Tool *tool,
|
||||||
/* Crop dialog functions */
|
/* Crop dialog functions */
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
static ActionAreaItem action_items[3] =
|
static ActionAreaItem action_items[4] =
|
||||||
{
|
{
|
||||||
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
{ N_("Crop"), crop_ok_callback, NULL, NULL },
|
||||||
{ N_("Selection"), crop_selection_callback, NULL, NULL },
|
{ N_("Resize"), crop_resize_callback, NULL, NULL },
|
||||||
|
/* { N_("Selection"), crop_selection_callback, NULL, NULL }, */
|
||||||
{ N_("Close"), crop_close_callback, NULL, NULL },
|
{ N_("Close"), crop_close_callback, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -949,7 +1119,28 @@ crop_ok_callback (GtkWidget *w,
|
||||||
tool = active_tool;
|
tool = active_tool;
|
||||||
crop = (Crop *) tool->private;
|
crop = (Crop *) tool->private;
|
||||||
gdisp = (GDisplay *) tool->gdisp_ptr;
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2);
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, TRUE);
|
||||||
|
|
||||||
|
/* Finish the tool */
|
||||||
|
draw_core_stop (crop->core, tool);
|
||||||
|
info_dialog_popdown (crop_info);
|
||||||
|
tool->state = INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
crop_resize_callback (GtkWidget *w,
|
||||||
|
gpointer client_data)
|
||||||
|
{
|
||||||
|
Tool * tool;
|
||||||
|
Crop * crop;
|
||||||
|
GDisplay * gdisp;
|
||||||
|
|
||||||
|
tool = active_tool;
|
||||||
|
crop = (Crop *) tool->private;
|
||||||
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
|
crop_image (gdisp->gimage, crop->tx1, crop->ty1, crop->tx2, crop->ty2,
|
||||||
|
options.layer_only, FALSE);
|
||||||
|
|
||||||
/* Finish the tool */
|
/* Finish the tool */
|
||||||
draw_core_stop (crop->core, tool);
|
draw_core_stop (crop->core, tool);
|
||||||
|
@ -1113,11 +1304,14 @@ crop_invoker (Argument *args)
|
||||||
int int_value;
|
int int_value;
|
||||||
int new_width, new_height;
|
int new_width, new_height;
|
||||||
int offx, offy;
|
int offx, offy;
|
||||||
|
int layer_only, crop_layers ;
|
||||||
|
|
||||||
new_width = 1;
|
new_width = 1;
|
||||||
new_height = 1;
|
new_height = 1;
|
||||||
offx = 0;
|
offx = 0;
|
||||||
offy = 0;
|
offy = 0;
|
||||||
|
layer_only = FALSE;
|
||||||
|
crop_layers = TRUE;
|
||||||
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
if (success)
|
if (success)
|
||||||
|
@ -1147,7 +1341,8 @@ crop_invoker (Argument *args)
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
crop_image (gimage, offx, offy, offx + new_width, offy + new_height,
|
||||||
|
layer_only, crop_layers);
|
||||||
|
|
||||||
return procedural_db_return_args (&crop_proc, success);
|
return procedural_db_return_args (&crop_proc, success);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ void tools_free_crop (Tool *);
|
||||||
/* tool options */
|
/* tool options */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int layer_only;
|
int layer_only;
|
||||||
|
int default_to_enlarge;
|
||||||
|
int default_to_crop;
|
||||||
} CropToolOptions;
|
} CropToolOptions;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,3 +38,5 @@ typedef struct {
|
||||||
extern ProcRecord crop_proc;
|
extern ProcRecord crop_proc;
|
||||||
|
|
||||||
#endif /* __CROP_H__ */
|
#endif /* __CROP_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue