diff --git a/ChangeLog b/ChangeLog index 0260d3e6ec..9c21dca4b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Sun Feb 14 20:43:55 GMT 1999 Austin Donnelly + + * app/channels_dialog.c: don't #include resize.h - it's not needed + * app/preferences_dialog.c: ditto. + + * app/resize.c: do all dialog creation here to factor out lots of + common code in commands.c and layers_dialog.c. Also cancel + resize/scale dialog on destruction/removal of images/layers - + proper fix for Peter Teichman's bug. + * app/resize.h: new prototype for resize_widget_new() - beginnings + of resolution-aware scaling. + * app/commands.c: pull all the resize/scale dialog creation stuff + out to resize.c + * app/layers_dialog.c: same again. + + * app/layer.c: add REMOVED signal, sent when a layer is removed + from an image. Layers typically aren't destroyed until their + undo info expires. + * app/layer.h: prototype for layer_removed() call. + * app/gimpimage.c: send out removed signal. + Sun Feb 14 02:33:42 CET 1999 Marc Lehmann * app/gimage_cmds.c: Corrected argument name. diff --git a/app/actions/help-commands.c b/app/actions/help-commands.c index 8a8ad6dd83..d218fb7844 100644 --- a/app/actions/help-commands.c +++ b/app/actions/help-commands.c @@ -20,7 +20,6 @@ #include #include "appenv.h" #include "about_dialog.h" -#include "actionarea.h" #include "app_procs.h" #include "brightness_contrast.h" #include "gimpbrushlist.h" @@ -73,7 +72,6 @@ typedef struct { - GtkWidget * shell; Resize * resize; GimpImage* gimage; } ImageResize; @@ -761,104 +759,62 @@ void image_resize_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_resize_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_resize; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_resize = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_resize->gimage = gdisp->gimage; - image_resize->resize = resize_widget_new (ResizeWidget, gdisp->gimage->width, gdisp->gimage->height); + image_resize->gimage = gimage; + image_resize->resize = resize_widget_new (ResizeWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_resize_callback, + image_cancel_callback, + image_delete_callback, + image_resize); - /* the dialog */ - image_resize->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_resize->shell), "image_resize", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_resize->shell), _("Image Resize")); - gtk_window_set_policy (GTK_WINDOW (image_resize->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_resize->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_resize->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_resize); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_resize->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_resize; - action_items[1].user_data = image_resize; - build_action_area (GTK_DIALOG (image_resize->shell), action_items, 2, 0); - - gtk_widget_show (image_resize->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_resize->shell); + gtk_widget_show (image_resize->resize->resize_shell); } void image_scale_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_scale_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_scale; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_scale = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_scale->gimage = gdisp->gimage; - image_scale->resize = resize_widget_new (ScaleWidget, gdisp->gimage->width, gdisp->gimage->height); + image_scale->gimage = gimage; + image_scale->resize = resize_widget_new (ScaleWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_scale_callback, + image_cancel_callback, + image_delete_callback, + image_scale); - /* the dialog */ - image_scale->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_scale->shell), "image_scale", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_scale->shell), _("Image Scale")); - gtk_window_set_policy (GTK_WINDOW (image_scale->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_scale->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_scale->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_scale); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_scale->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_scale->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_scale; - action_items[1].user_data = image_scale; - build_action_area (GTK_DIALOG (image_scale->shell), action_items, 2, 0); - - gtk_widget_show (image_scale->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_scale->shell); + gtk_widget_show (image_scale->resize->resize_shell); } void @@ -1145,10 +1101,6 @@ image_resize_callback (GtkWidget *w, image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - if ((gimage = image_resize->gimage) != NULL) { if (image_resize->resize->width > 0 && @@ -1168,7 +1120,6 @@ image_resize_callback (GtkWidget *w, } } - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } @@ -1182,10 +1133,6 @@ image_scale_callback (GtkWidget *w, image_scale = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - if ((gimage = image_scale->gimage) != NULL) { if (image_scale->resize->width > 0 && @@ -1203,7 +1150,6 @@ image_scale_callback (GtkWidget *w, } } - gtk_widget_destroy (image_scale->shell); resize_widget_free (image_scale->resize); g_free (image_scale); } @@ -1224,14 +1170,8 @@ image_cancel_callback (GtkWidget *w, gpointer client_data) { ImageResize *image_resize; - image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } diff --git a/app/channels_dialog.c b/app/channels_dialog.c index 42b09e98a7..82a9caf4f5 100644 --- a/app/channels_dialog.c +++ b/app/channels_dialog.c @@ -36,7 +36,6 @@ #include "ops_buttons.h" #include "paint_funcs.h" #include "palette.h" -#include "resize.h" #include "tools/eye.xbm" #include "tools/channel.xbm" diff --git a/app/commands.c b/app/commands.c index 8a8ad6dd83..d218fb7844 100644 --- a/app/commands.c +++ b/app/commands.c @@ -20,7 +20,6 @@ #include #include "appenv.h" #include "about_dialog.h" -#include "actionarea.h" #include "app_procs.h" #include "brightness_contrast.h" #include "gimpbrushlist.h" @@ -73,7 +72,6 @@ typedef struct { - GtkWidget * shell; Resize * resize; GimpImage* gimage; } ImageResize; @@ -761,104 +759,62 @@ void image_resize_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_resize_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_resize; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_resize = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_resize->gimage = gdisp->gimage; - image_resize->resize = resize_widget_new (ResizeWidget, gdisp->gimage->width, gdisp->gimage->height); + image_resize->gimage = gimage; + image_resize->resize = resize_widget_new (ResizeWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_resize_callback, + image_cancel_callback, + image_delete_callback, + image_resize); - /* the dialog */ - image_resize->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_resize->shell), "image_resize", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_resize->shell), _("Image Resize")); - gtk_window_set_policy (GTK_WINDOW (image_resize->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_resize->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_resize->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_resize); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_resize->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_resize; - action_items[1].user_data = image_resize; - build_action_area (GTK_DIALOG (image_resize->shell), action_items, 2, 0); - - gtk_widget_show (image_resize->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_resize->shell); + gtk_widget_show (image_resize->resize->resize_shell); } void image_scale_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_scale_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_scale; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_scale = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_scale->gimage = gdisp->gimage; - image_scale->resize = resize_widget_new (ScaleWidget, gdisp->gimage->width, gdisp->gimage->height); + image_scale->gimage = gimage; + image_scale->resize = resize_widget_new (ScaleWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_scale_callback, + image_cancel_callback, + image_delete_callback, + image_scale); - /* the dialog */ - image_scale->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_scale->shell), "image_scale", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_scale->shell), _("Image Scale")); - gtk_window_set_policy (GTK_WINDOW (image_scale->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_scale->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_scale->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_scale); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_scale->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_scale->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_scale; - action_items[1].user_data = image_scale; - build_action_area (GTK_DIALOG (image_scale->shell), action_items, 2, 0); - - gtk_widget_show (image_scale->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_scale->shell); + gtk_widget_show (image_scale->resize->resize_shell); } void @@ -1145,10 +1101,6 @@ image_resize_callback (GtkWidget *w, image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - if ((gimage = image_resize->gimage) != NULL) { if (image_resize->resize->width > 0 && @@ -1168,7 +1120,6 @@ image_resize_callback (GtkWidget *w, } } - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } @@ -1182,10 +1133,6 @@ image_scale_callback (GtkWidget *w, image_scale = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - if ((gimage = image_scale->gimage) != NULL) { if (image_scale->resize->width > 0 && @@ -1203,7 +1150,6 @@ image_scale_callback (GtkWidget *w, } } - gtk_widget_destroy (image_scale->shell); resize_widget_free (image_scale->resize); g_free (image_scale); } @@ -1224,14 +1170,8 @@ image_cancel_callback (GtkWidget *w, gpointer client_data) { ImageResize *image_resize; - image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } diff --git a/app/core/gimpimage-guides.c b/app/core/gimpimage-guides.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage-guides.c +++ b/app/core/gimpimage-guides.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage-merge.c +++ b/app/core/gimpimage-merge.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimpimage-projection.c b/app/core/gimpimage-projection.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage-projection.c +++ b/app/core/gimpimage-projection.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimpimage-resize.c b/app/core/gimpimage-resize.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage-resize.c +++ b/app/core/gimpimage-resize.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimpimage-scale.c b/app/core/gimpimage-scale.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage-scale.c +++ b/app/core/gimpimage-scale.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index 1f9abf6ff0..f4efb65cb5 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -32,6 +32,7 @@ #include "temp_buf.h" #include "parasitelist.h" #include "undo.h" +#include "gimpsignal.h" #include "libgimp/gimpintl.h" @@ -40,6 +41,7 @@ #include "tile.h" /* ick. */ enum { + REMOVED, LAST_SIGNAL }; @@ -53,8 +55,8 @@ static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass); static void gimp_layer_mask_init (GimpLayerMask *layermask); static void gimp_layer_mask_destroy (GtkObject *object); -/* static gint layer_signals[LAST_SIGNAL] = { 0 }; +/* static gint layer_mask_signals[LAST_SIGNAL] = { 0 }; */ @@ -97,9 +99,11 @@ gimp_layer_class_init (GimpLayerClass *class) layer_parent_class = gtk_type_class (gimp_drawable_get_type ()); - /* + layer_signals[REMOVED] = + gimp_signal_new ("removed", + 0, object_class->type, 0, gimp_sigtype_void); + gtk_object_class_add_signals (object_class, layer_signals, LAST_SIGNAL); - */ object_class->destroy = gimp_layer_destroy; drawable_class->invalidate_preview = layer_invalidate_preview; @@ -556,6 +560,21 @@ gimp_layer_destroy (GtkObject *object) (*GTK_OBJECT_CLASS (layer_parent_class)->destroy) (object); } + +/* The removed signal is sent out when the layer is no longer + * associcated with an image. It's needed because layers aren't + * destroyed immediately, but kept around for undo purposes. Connect + * to the removed signal to update bits of UI that are tied to a + * particular layer. */ +void +layer_removed (Layer *layer, gpointer image) +{ + g_return_if_fail (layer != NULL); + g_return_if_fail (GIMP_IS_LAYER (layer)); + + gtk_signal_emit (GTK_OBJECT (layer), layer_signals[REMOVED]); +} + void layer_apply_mask (layer, mode) Layer * layer; diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h index 90d3b46d28..63a96db397 100644 --- a/app/core/gimplayer.h +++ b/app/core/gimplayer.h @@ -89,6 +89,7 @@ LayerMask * layer_add_mask (Layer *, LayerMask *); LayerMask * layer_create_mask (Layer *, AddMaskType); Layer * layer_get_ID (int); void layer_delete (Layer *); +void layer_removed (Layer *, gpointer); void layer_apply_mask (Layer *, int); void layer_temporarily_translate (Layer *, int, int); void layer_translate (Layer *, int, int); diff --git a/app/core/gimpprojection-construct.c b/app/core/gimpprojection-construct.c index 036803f7d0..a9a34c3240 100644 --- a/app/core/gimpprojection-construct.c +++ b/app/core/gimpprojection-construct.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index 9023add084..3d353f49a6 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -38,7 +38,6 @@ #include "patterns.h" #include "plug_in.h" #include "posterize.h" -#include "resize.h" #include "scale.h" #include "session.h" #include "threshold.h" @@ -49,12 +48,6 @@ #include "config.h" #include "libgimp/gimpintl.h" -typedef struct -{ - GtkWidget * shell; - Resize * resize; - int gimage_id; -} ImageResize; /* preferences local functions */ static void file_prefs_ok_callback (GtkWidget *, GtkWidget *); diff --git a/app/dialogs/resize-dialog.c b/app/dialogs/resize-dialog.c index 59132152a7..8483e6fbc2 100644 --- a/app/dialogs/resize-dialog.c +++ b/app/dialogs/resize-dialog.c @@ -20,6 +20,7 @@ #include #include "appenv.h" #include "resize.h" +#include "actionarea.h" #include "libgimp/gimpintl.h" @@ -39,6 +40,9 @@ struct _ResizePrivate GtkWidget *off_y_text; GtkWidget *drawing_area; + GtkObject *object; + guint object_destroy_handler; + double ratio; int constrain; int old_width, old_height; @@ -61,10 +65,25 @@ static gint resize_events (GtkWidget *area, GdkEvent *event); Resize * -resize_widget_new (ResizeType type, - int width, - int height) +resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject *object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data) { + static ActionAreaItem action_items[2] = + { + { N_("OK"), NULL, NULL, NULL }, + { N_("Cancel"), NULL, NULL, NULL } + }; Resize *resize; ResizePrivate *private; GtkWidget *vbox; @@ -77,6 +96,7 @@ resize_widget_new (ResizeType type, char ratio_text[12]; table = NULL; + frame = NULL; resize = g_new (Resize, 1); private = g_new (ResizePrivate, 1); @@ -84,6 +104,8 @@ resize_widget_new (ResizeType type, resize->private_part = private; resize->width = width; resize->height = height; + resize->resolution_x = resolution_x; + resize->resolution_y = resolution_y; resize->ratio_x = 1.0; resize->ratio_y = 1.0; resize->off_x = 0; @@ -91,6 +113,7 @@ resize_widget_new (ResizeType type, private->old_width = width; private->old_height = height; private->constrain = TRUE; + private->object = NULL; /* Get the image width and height variables, based on the gimage */ if (width > height) @@ -100,23 +123,80 @@ resize_widget_new (ResizeType type, private->area_width = (int) (private->ratio * width); private->area_height = (int) (private->ratio * height); - switch (type) - { + /* dialog box */ + { + const char *wmclass = NULL; + const char *window_title = NULL; + + switch (type) { case ScaleWidget: - resize->resize_widget = gtk_frame_new (_("Scale")); - table = gtk_table_new (4, 2, TRUE); - break; + switch (target) { + case ResizeLayer: + wmclass = "scale_layer"; + window_title = _("Scale Layer"); + break; + case ResizeImage: + wmclass = "image_scale"; + window_title = _("Image Scale"); + break; + } + frame = gtk_frame_new (_("Scale")); + table = gtk_table_new (4, 2, TRUE); + break; + case ResizeWidget: - resize->resize_widget = gtk_frame_new (_("Resize")); - table = gtk_table_new (6, 2, TRUE); - break; - } - gtk_frame_set_shadow_type (GTK_FRAME (resize->resize_widget), GTK_SHADOW_ETCHED_IN); + switch (target) { + case ResizeLayer: + wmclass = "resize_layer"; + window_title = _("Resize Layer"); + break; + case ResizeImage: + wmclass = "image_resize"; + window_title = _("Image Resize"); + break; + } + frame = gtk_frame_new (_("Resize")); + table = gtk_table_new (6, 2, TRUE); + break; + } + + resize->resize_shell = gtk_dialog_new(); + gtk_window_set_wmclass (GTK_WINDOW (resize->resize_shell), wmclass,"Gimp"); + gtk_window_set_title (GTK_WINDOW (resize->resize_shell), window_title); + gtk_window_set_policy(GTK_WINDOW (resize->resize_shell), FALSE,FALSE,TRUE); + gtk_window_position (GTK_WINDOW (resize->resize_shell), GTK_WIN_POS_MOUSE); + } + + /* handle the wm close singal */ + if (delete_cb) + gtk_signal_connect (GTK_OBJECT (resize->resize_shell), "delete_event", + GTK_SIGNAL_FUNC (delete_cb), user_data); + + /* handle the image disappearing under our feet */ + if (object) + { + const char *signame; + signame = (target == ResizeLayer)? "removed" : "destroy"; + private->object = object; + private->object_destroy_handler = gtk_signal_connect(GTK_OBJECT (object), + signame, + cancel_cb, user_data); + } + + vbox = gtk_vbox_new (FALSE, 1); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (resize->resize_shell)->vbox), + vbox, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_widget_show (vbox); + + gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); + gtk_widget_show (frame); /* the main vbox */ vbox = gtk_vbox_new (FALSE, 1); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - gtk_container_add (GTK_CONTAINER (resize->resize_widget), vbox); + gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); @@ -261,12 +341,25 @@ resize_widget_new (ResizeType type, gtk_widget_show (table); gtk_widget_show (vbox); + action_items[0].user_data = user_data; + action_items[0].callback = ok_cb; + action_items[1].user_data = user_data; + action_items[1].callback = cancel_cb; + build_action_area (GTK_DIALOG (resize->resize_shell), action_items, 2, 0); + return resize; } void resize_widget_free (Resize *resize) { + ResizePrivate *private = resize->private_part; + + if (private->object) + gtk_signal_disconnect (GTK_OBJECT (private->object), + private->object_destroy_handler); + + gtk_widget_destroy (resize->resize_shell); g_free (resize->private_part); g_free (resize); } diff --git a/app/dialogs/resize-dialog.h b/app/dialogs/resize-dialog.h index c824163afd..0d0f0bf865 100644 --- a/app/dialogs/resize-dialog.h +++ b/app/dialogs/resize-dialog.h @@ -24,16 +24,24 @@ typedef enum ResizeWidget } ResizeType; +typedef enum +{ + ResizeImage, + ResizeLayer +} ResizeTarget; + typedef struct _Resize Resize; struct _Resize { /* The calling procedure is respondible for showing this widget */ - GtkWidget *resize_widget; + GtkWidget *resize_shell; ResizeType type; int width; int height; + float resolution_x; + float resolution_y; double ratio_x; double ratio_y; int off_x; @@ -43,9 +51,22 @@ struct _Resize void * private_part; }; -Resize * resize_widget_new (ResizeType type, - int width, - int height); -void resize_widget_free (Resize * resize); +/* If resolution_x is zero, then don't show resolution modification + * parts of the dialog. If object is non-NULL, then attach the cancel + * callback to its destroy signal. */ +Resize * resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject * object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data); +void resize_widget_free (Resize * resize); #endif /* __RESIZE_H__ */ diff --git a/app/gimpimage.c b/app/gimpimage.c index 036803f7d0..a9a34c3240 100644 --- a/app/gimpimage.c +++ b/app/gimpimage.c @@ -2618,6 +2618,9 @@ gimp_image_remove_layer (GimpImage *gimage, Layer * layer) */ undo_push_layer (gimage, lu); + /* Send out REMOVED signal from layer */ + layer_removed (layer, gimage); + /* invalidate the composite preview */ gimp_image_invalidate_preview (gimage); diff --git a/app/gimplayer.c b/app/gimplayer.c index 1f9abf6ff0..f4efb65cb5 100644 --- a/app/gimplayer.c +++ b/app/gimplayer.c @@ -32,6 +32,7 @@ #include "temp_buf.h" #include "parasitelist.h" #include "undo.h" +#include "gimpsignal.h" #include "libgimp/gimpintl.h" @@ -40,6 +41,7 @@ #include "tile.h" /* ick. */ enum { + REMOVED, LAST_SIGNAL }; @@ -53,8 +55,8 @@ static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass); static void gimp_layer_mask_init (GimpLayerMask *layermask); static void gimp_layer_mask_destroy (GtkObject *object); -/* static gint layer_signals[LAST_SIGNAL] = { 0 }; +/* static gint layer_mask_signals[LAST_SIGNAL] = { 0 }; */ @@ -97,9 +99,11 @@ gimp_layer_class_init (GimpLayerClass *class) layer_parent_class = gtk_type_class (gimp_drawable_get_type ()); - /* + layer_signals[REMOVED] = + gimp_signal_new ("removed", + 0, object_class->type, 0, gimp_sigtype_void); + gtk_object_class_add_signals (object_class, layer_signals, LAST_SIGNAL); - */ object_class->destroy = gimp_layer_destroy; drawable_class->invalidate_preview = layer_invalidate_preview; @@ -556,6 +560,21 @@ gimp_layer_destroy (GtkObject *object) (*GTK_OBJECT_CLASS (layer_parent_class)->destroy) (object); } + +/* The removed signal is sent out when the layer is no longer + * associcated with an image. It's needed because layers aren't + * destroyed immediately, but kept around for undo purposes. Connect + * to the removed signal to update bits of UI that are tied to a + * particular layer. */ +void +layer_removed (Layer *layer, gpointer image) +{ + g_return_if_fail (layer != NULL); + g_return_if_fail (GIMP_IS_LAYER (layer)); + + gtk_signal_emit (GTK_OBJECT (layer), layer_signals[REMOVED]); +} + void layer_apply_mask (layer, mode) Layer * layer; diff --git a/app/gimplayer.h b/app/gimplayer.h index 90d3b46d28..63a96db397 100644 --- a/app/gimplayer.h +++ b/app/gimplayer.h @@ -89,6 +89,7 @@ LayerMask * layer_add_mask (Layer *, LayerMask *); LayerMask * layer_create_mask (Layer *, AddMaskType); Layer * layer_get_ID (int); void layer_delete (Layer *); +void layer_removed (Layer *, gpointer); void layer_apply_mask (Layer *, int); void layer_temporarily_translate (Layer *, int, int); void layer_translate (Layer *, int, int); diff --git a/app/gui/channels-dialog.c b/app/gui/channels-dialog.c index 42b09e98a7..82a9caf4f5 100644 --- a/app/gui/channels-dialog.c +++ b/app/gui/channels-dialog.c @@ -36,7 +36,6 @@ #include "ops_buttons.h" #include "paint_funcs.h" #include "palette.h" -#include "resize.h" #include "tools/eye.xbm" #include "tools/channel.xbm" diff --git a/app/gui/commands.c b/app/gui/commands.c index 8a8ad6dd83..d218fb7844 100644 --- a/app/gui/commands.c +++ b/app/gui/commands.c @@ -20,7 +20,6 @@ #include #include "appenv.h" #include "about_dialog.h" -#include "actionarea.h" #include "app_procs.h" #include "brightness_contrast.h" #include "gimpbrushlist.h" @@ -73,7 +72,6 @@ typedef struct { - GtkWidget * shell; Resize * resize; GimpImage* gimage; } ImageResize; @@ -761,104 +759,62 @@ void image_resize_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_resize_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_resize; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_resize = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_resize->gimage = gdisp->gimage; - image_resize->resize = resize_widget_new (ResizeWidget, gdisp->gimage->width, gdisp->gimage->height); + image_resize->gimage = gimage; + image_resize->resize = resize_widget_new (ResizeWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_resize_callback, + image_cancel_callback, + image_delete_callback, + image_resize); - /* the dialog */ - image_resize->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_resize->shell), "image_resize", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_resize->shell), _("Image Resize")); - gtk_window_set_policy (GTK_WINDOW (image_resize->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_resize->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_resize->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_resize); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_resize->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_resize; - action_items[1].user_data = image_resize; - build_action_area (GTK_DIALOG (image_resize->shell), action_items, 2, 0); - - gtk_widget_show (image_resize->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_resize->shell); + gtk_widget_show (image_resize->resize->resize_shell); } void image_scale_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_scale_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_scale; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_scale = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_scale->gimage = gdisp->gimage; - image_scale->resize = resize_widget_new (ScaleWidget, gdisp->gimage->width, gdisp->gimage->height); + image_scale->gimage = gimage; + image_scale->resize = resize_widget_new (ScaleWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_scale_callback, + image_cancel_callback, + image_delete_callback, + image_scale); - /* the dialog */ - image_scale->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_scale->shell), "image_scale", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_scale->shell), _("Image Scale")); - gtk_window_set_policy (GTK_WINDOW (image_scale->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_scale->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_scale->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_scale); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_scale->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_scale->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_scale; - action_items[1].user_data = image_scale; - build_action_area (GTK_DIALOG (image_scale->shell), action_items, 2, 0); - - gtk_widget_show (image_scale->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_scale->shell); + gtk_widget_show (image_scale->resize->resize_shell); } void @@ -1145,10 +1101,6 @@ image_resize_callback (GtkWidget *w, image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - if ((gimage = image_resize->gimage) != NULL) { if (image_resize->resize->width > 0 && @@ -1168,7 +1120,6 @@ image_resize_callback (GtkWidget *w, } } - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } @@ -1182,10 +1133,6 @@ image_scale_callback (GtkWidget *w, image_scale = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - if ((gimage = image_scale->gimage) != NULL) { if (image_scale->resize->width > 0 && @@ -1203,7 +1150,6 @@ image_scale_callback (GtkWidget *w, } } - gtk_widget_destroy (image_scale->shell); resize_widget_free (image_scale->resize); g_free (image_scale); } @@ -1224,14 +1170,8 @@ image_cancel_callback (GtkWidget *w, gpointer client_data) { ImageResize *image_resize; - image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } diff --git a/app/gui/help-commands.c b/app/gui/help-commands.c index 8a8ad6dd83..d218fb7844 100644 --- a/app/gui/help-commands.c +++ b/app/gui/help-commands.c @@ -20,7 +20,6 @@ #include #include "appenv.h" #include "about_dialog.h" -#include "actionarea.h" #include "app_procs.h" #include "brightness_contrast.h" #include "gimpbrushlist.h" @@ -73,7 +72,6 @@ typedef struct { - GtkWidget * shell; Resize * resize; GimpImage* gimage; } ImageResize; @@ -761,104 +759,62 @@ void image_resize_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_resize_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_resize; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_resize = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_resize->gimage = gdisp->gimage; - image_resize->resize = resize_widget_new (ResizeWidget, gdisp->gimage->width, gdisp->gimage->height); + image_resize->gimage = gimage; + image_resize->resize = resize_widget_new (ResizeWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_resize_callback, + image_cancel_callback, + image_delete_callback, + image_resize); - /* the dialog */ - image_resize->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_resize->shell), "image_resize", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_resize->shell), _("Image Resize")); - gtk_window_set_policy (GTK_WINDOW (image_resize->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_resize->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_resize->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_resize); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_resize->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_resize; - action_items[1].user_data = image_resize; - build_action_area (GTK_DIALOG (image_resize->shell), action_items, 2, 0); - - gtk_widget_show (image_resize->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_resize->shell); + gtk_widget_show (image_resize->resize->resize_shell); } void image_scale_cmd_callback (GtkWidget *widget, gpointer client_data) { - static ActionAreaItem action_items[2] = - { - { N_("OK"), image_scale_callback, NULL, NULL }, - { N_("Cancel"), image_cancel_callback, NULL, NULL } - }; GDisplay * gdisp; - GtkWidget *vbox; + GimpImage * gimage; ImageResize *image_scale; gdisp = gdisplay_active (); + g_return_if_fail (gdisp != NULL); + + gimage = gdisp->gimage; /* the ImageResize structure */ image_scale = (ImageResize *) g_malloc (sizeof (ImageResize)); - image_scale->gimage = gdisp->gimage; - image_scale->resize = resize_widget_new (ScaleWidget, gdisp->gimage->width, gdisp->gimage->height); + image_scale->gimage = gimage; + image_scale->resize = resize_widget_new (ScaleWidget, + ResizeImage, + GTK_OBJECT (gimage), + gimage->width, + gimage->height, + gimage->xresolution, + gimage->yresolution, + image_scale_callback, + image_cancel_callback, + image_delete_callback, + image_scale); - /* the dialog */ - image_scale->shell = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (image_scale->shell), "image_scale", "Gimp"); - gtk_window_set_title (GTK_WINDOW (image_scale->shell), _("Image Scale")); - gtk_window_set_policy (GTK_WINDOW (image_scale->shell), FALSE, FALSE, TRUE); - gtk_window_set_position (GTK_WINDOW (image_scale->shell), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (image_scale->shell), "delete_event", - GTK_SIGNAL_FUNC (image_delete_callback), - image_scale); - - /* handle the image disappearing under our feet */ - gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy", - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 1); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_scale->shell)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), image_scale->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = image_scale; - action_items[1].user_data = image_scale; - build_action_area (GTK_DIALOG (image_scale->shell), action_items, 2, 0); - - gtk_widget_show (image_scale->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (image_scale->shell); + gtk_widget_show (image_scale->resize->resize_shell); } void @@ -1145,10 +1101,6 @@ image_resize_callback (GtkWidget *w, image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - if ((gimage = image_resize->gimage) != NULL) { if (image_resize->resize->width > 0 && @@ -1168,7 +1120,6 @@ image_resize_callback (GtkWidget *w, } } - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } @@ -1182,10 +1133,6 @@ image_scale_callback (GtkWidget *w, image_scale = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_scale); - if ((gimage = image_scale->gimage) != NULL) { if (image_scale->resize->width > 0 && @@ -1203,7 +1150,6 @@ image_scale_callback (GtkWidget *w, } } - gtk_widget_destroy (image_scale->shell); resize_widget_free (image_scale->resize); g_free (image_scale); } @@ -1224,14 +1170,8 @@ image_cancel_callback (GtkWidget *w, gpointer client_data) { ImageResize *image_resize; - image_resize = (ImageResize *) client_data; - gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage), - GTK_SIGNAL_FUNC (image_cancel_callback), - image_resize); - - gtk_widget_destroy (image_resize->shell); resize_widget_free (image_resize->resize); g_free (image_resize); } diff --git a/app/gui/layers-dialog.c b/app/gui/layers-dialog.c index ef31422452..8cd6ff3702 100644 --- a/app/gui/layers-dialog.c +++ b/app/gui/layers-dialog.c @@ -3676,9 +3676,7 @@ layers_dialog_apply_mask_query (Layer *layer) typedef struct _ScaleLayerOptions ScaleLayerOptions; struct _ScaleLayerOptions { - GtkWidget *query_box; - Layer * layer; - + Layer *layer; Resize *resize; }; @@ -3713,7 +3711,6 @@ scale_layer_query_ok_callback (GtkWidget *w, gdisplays_flush (); } - gtk_widget_destroy (options->query_box); resize_widget_free (options->resize); g_free (options); } @@ -3726,9 +3723,8 @@ scale_layer_query_cancel_callback (GtkWidget *w, gpointer client_data) { ScaleLayerOptions *options; - options = (ScaleLayerOptions *) client_data; - gtk_widget_destroy (options->query_box); + resize_widget_free (options->resize); g_free (options); } @@ -3746,46 +3742,23 @@ scale_layer_query_delete_callback (GtkWidget *w, static void layers_dialog_scale_layer_query (Layer *layer) { - static ActionAreaItem action_items[3] = - { - { N_("OK"), scale_layer_query_ok_callback, NULL, NULL }, - { N_("Cancel"), scale_layer_query_cancel_callback, NULL, NULL } - }; ScaleLayerOptions *options; - GtkWidget *vbox; /* the new options structure */ options = (ScaleLayerOptions *) g_malloc (sizeof (ScaleLayerOptions)); options->layer = layer; options->resize = resize_widget_new (ScaleWidget, + ResizeLayer, + GTK_OBJECT (layer), drawable_width (GIMP_DRAWABLE(layer)), - drawable_height (GIMP_DRAWABLE(layer))); + drawable_height (GIMP_DRAWABLE(layer)), + 0.0, 0.0, /* no resolution, please */ + scale_layer_query_ok_callback, + scale_layer_query_cancel_callback, + scale_layer_query_delete_callback, + options); - /* the dialog */ - options->query_box = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (options->query_box), "scale_layer", "Gimp"); - gtk_window_set_title (GTK_WINDOW (options->query_box), _("Scale Layer")); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, FALSE, TRUE); - gtk_window_position (GTK_WINDOW (options->query_box), GTK_WIN_POS_MOUSE); - - /* handle the wm close singal */ - gtk_signal_connect (GTK_OBJECT (options->query_box), "delete_event", - GTK_SIGNAL_FUNC (scale_layer_query_delete_callback), - options); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_border_width (GTK_CONTAINER (vbox), 2); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (options->query_box)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), options->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = options; - action_items[1].user_data = options; - build_action_area (GTK_DIALOG (options->query_box), action_items, 2, 0); - - gtk_widget_show (options->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (options->query_box); + gtk_widget_show (options->resize->resize_shell); } @@ -3796,9 +3769,7 @@ layers_dialog_scale_layer_query (Layer *layer) typedef struct _ResizeLayerOptions ResizeLayerOptions; struct _ResizeLayerOptions { - GtkWidget *query_box; Layer *layer; - Resize *resize; }; @@ -3834,7 +3805,6 @@ resize_layer_query_ok_callback (GtkWidget *w, gdisplays_flush (); } - gtk_widget_destroy (options->query_box); resize_widget_free (options->resize); g_free (options); } @@ -3847,9 +3817,8 @@ resize_layer_query_cancel_callback (GtkWidget *w, gpointer client_data) { ResizeLayerOptions *options; - options = (ResizeLayerOptions *) client_data; - gtk_widget_destroy (options->query_box); + resize_widget_free (options->resize); g_free (options); } @@ -3867,47 +3836,23 @@ resize_layer_query_delete_callback (GtkWidget *w, static void layers_dialog_resize_layer_query (Layer *layer) { - static ActionAreaItem action_items[3] = - { - { N_("OK"), resize_layer_query_ok_callback, NULL, NULL }, - { N_("Cancel"), resize_layer_query_cancel_callback, NULL, NULL } - }; ResizeLayerOptions *options; - GtkWidget *vbox; /* the new options structure */ options = (ResizeLayerOptions *) g_malloc (sizeof (ResizeLayerOptions)); options->layer = layer; options->resize = resize_widget_new (ResizeWidget, + ResizeLayer, + GTK_OBJECT (layer), drawable_width (GIMP_DRAWABLE(layer)), - drawable_height (GIMP_DRAWABLE(layer))); + drawable_height (GIMP_DRAWABLE(layer)), + 0.0, 0.0, /* no resolution, please */ + resize_layer_query_ok_callback, + resize_layer_query_cancel_callback, + resize_layer_query_delete_callback, + options); - /* the dialog */ - options->query_box = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (options->query_box), "resize_layer", "Gimp"); - gtk_window_set_title (GTK_WINDOW (options->query_box), _("Resize Layer")); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, TRUE, TRUE); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, FALSE, TRUE); - gtk_window_position (GTK_WINDOW (options->query_box), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (options->query_box), "delete_event", - GTK_SIGNAL_FUNC (resize_layer_query_delete_callback), - options); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_border_width (GTK_CONTAINER (vbox), 2); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (options->query_box)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), options->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = options; - action_items[1].user_data = options; - build_action_area (GTK_DIALOG (options->query_box), action_items, 2, 0); - - gtk_widget_show (options->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (options->query_box); + gtk_widget_show (options->resize->resize_shell); } diff --git a/app/gui/preferences-dialog.c b/app/gui/preferences-dialog.c index 9023add084..3d353f49a6 100644 --- a/app/gui/preferences-dialog.c +++ b/app/gui/preferences-dialog.c @@ -38,7 +38,6 @@ #include "patterns.h" #include "plug_in.h" #include "posterize.h" -#include "resize.h" #include "scale.h" #include "session.h" #include "threshold.h" @@ -49,12 +48,6 @@ #include "config.h" #include "libgimp/gimpintl.h" -typedef struct -{ - GtkWidget * shell; - Resize * resize; - int gimage_id; -} ImageResize; /* preferences local functions */ static void file_prefs_ok_callback (GtkWidget *, GtkWidget *); diff --git a/app/gui/resize-dialog.c b/app/gui/resize-dialog.c index 59132152a7..8483e6fbc2 100644 --- a/app/gui/resize-dialog.c +++ b/app/gui/resize-dialog.c @@ -20,6 +20,7 @@ #include #include "appenv.h" #include "resize.h" +#include "actionarea.h" #include "libgimp/gimpintl.h" @@ -39,6 +40,9 @@ struct _ResizePrivate GtkWidget *off_y_text; GtkWidget *drawing_area; + GtkObject *object; + guint object_destroy_handler; + double ratio; int constrain; int old_width, old_height; @@ -61,10 +65,25 @@ static gint resize_events (GtkWidget *area, GdkEvent *event); Resize * -resize_widget_new (ResizeType type, - int width, - int height) +resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject *object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data) { + static ActionAreaItem action_items[2] = + { + { N_("OK"), NULL, NULL, NULL }, + { N_("Cancel"), NULL, NULL, NULL } + }; Resize *resize; ResizePrivate *private; GtkWidget *vbox; @@ -77,6 +96,7 @@ resize_widget_new (ResizeType type, char ratio_text[12]; table = NULL; + frame = NULL; resize = g_new (Resize, 1); private = g_new (ResizePrivate, 1); @@ -84,6 +104,8 @@ resize_widget_new (ResizeType type, resize->private_part = private; resize->width = width; resize->height = height; + resize->resolution_x = resolution_x; + resize->resolution_y = resolution_y; resize->ratio_x = 1.0; resize->ratio_y = 1.0; resize->off_x = 0; @@ -91,6 +113,7 @@ resize_widget_new (ResizeType type, private->old_width = width; private->old_height = height; private->constrain = TRUE; + private->object = NULL; /* Get the image width and height variables, based on the gimage */ if (width > height) @@ -100,23 +123,80 @@ resize_widget_new (ResizeType type, private->area_width = (int) (private->ratio * width); private->area_height = (int) (private->ratio * height); - switch (type) - { + /* dialog box */ + { + const char *wmclass = NULL; + const char *window_title = NULL; + + switch (type) { case ScaleWidget: - resize->resize_widget = gtk_frame_new (_("Scale")); - table = gtk_table_new (4, 2, TRUE); - break; + switch (target) { + case ResizeLayer: + wmclass = "scale_layer"; + window_title = _("Scale Layer"); + break; + case ResizeImage: + wmclass = "image_scale"; + window_title = _("Image Scale"); + break; + } + frame = gtk_frame_new (_("Scale")); + table = gtk_table_new (4, 2, TRUE); + break; + case ResizeWidget: - resize->resize_widget = gtk_frame_new (_("Resize")); - table = gtk_table_new (6, 2, TRUE); - break; - } - gtk_frame_set_shadow_type (GTK_FRAME (resize->resize_widget), GTK_SHADOW_ETCHED_IN); + switch (target) { + case ResizeLayer: + wmclass = "resize_layer"; + window_title = _("Resize Layer"); + break; + case ResizeImage: + wmclass = "image_resize"; + window_title = _("Image Resize"); + break; + } + frame = gtk_frame_new (_("Resize")); + table = gtk_table_new (6, 2, TRUE); + break; + } + + resize->resize_shell = gtk_dialog_new(); + gtk_window_set_wmclass (GTK_WINDOW (resize->resize_shell), wmclass,"Gimp"); + gtk_window_set_title (GTK_WINDOW (resize->resize_shell), window_title); + gtk_window_set_policy(GTK_WINDOW (resize->resize_shell), FALSE,FALSE,TRUE); + gtk_window_position (GTK_WINDOW (resize->resize_shell), GTK_WIN_POS_MOUSE); + } + + /* handle the wm close singal */ + if (delete_cb) + gtk_signal_connect (GTK_OBJECT (resize->resize_shell), "delete_event", + GTK_SIGNAL_FUNC (delete_cb), user_data); + + /* handle the image disappearing under our feet */ + if (object) + { + const char *signame; + signame = (target == ResizeLayer)? "removed" : "destroy"; + private->object = object; + private->object_destroy_handler = gtk_signal_connect(GTK_OBJECT (object), + signame, + cancel_cb, user_data); + } + + vbox = gtk_vbox_new (FALSE, 1); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (resize->resize_shell)->vbox), + vbox, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_widget_show (vbox); + + gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); + gtk_widget_show (frame); /* the main vbox */ vbox = gtk_vbox_new (FALSE, 1); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - gtk_container_add (GTK_CONTAINER (resize->resize_widget), vbox); + gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); @@ -261,12 +341,25 @@ resize_widget_new (ResizeType type, gtk_widget_show (table); gtk_widget_show (vbox); + action_items[0].user_data = user_data; + action_items[0].callback = ok_cb; + action_items[1].user_data = user_data; + action_items[1].callback = cancel_cb; + build_action_area (GTK_DIALOG (resize->resize_shell), action_items, 2, 0); + return resize; } void resize_widget_free (Resize *resize) { + ResizePrivate *private = resize->private_part; + + if (private->object) + gtk_signal_disconnect (GTK_OBJECT (private->object), + private->object_destroy_handler); + + gtk_widget_destroy (resize->resize_shell); g_free (resize->private_part); g_free (resize); } diff --git a/app/gui/resize-dialog.h b/app/gui/resize-dialog.h index c824163afd..0d0f0bf865 100644 --- a/app/gui/resize-dialog.h +++ b/app/gui/resize-dialog.h @@ -24,16 +24,24 @@ typedef enum ResizeWidget } ResizeType; +typedef enum +{ + ResizeImage, + ResizeLayer +} ResizeTarget; + typedef struct _Resize Resize; struct _Resize { /* The calling procedure is respondible for showing this widget */ - GtkWidget *resize_widget; + GtkWidget *resize_shell; ResizeType type; int width; int height; + float resolution_x; + float resolution_y; double ratio_x; double ratio_y; int off_x; @@ -43,9 +51,22 @@ struct _Resize void * private_part; }; -Resize * resize_widget_new (ResizeType type, - int width, - int height); -void resize_widget_free (Resize * resize); +/* If resolution_x is zero, then don't show resolution modification + * parts of the dialog. If object is non-NULL, then attach the cancel + * callback to its destroy signal. */ +Resize * resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject * object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data); +void resize_widget_free (Resize * resize); #endif /* __RESIZE_H__ */ diff --git a/app/layer.c b/app/layer.c index 1f9abf6ff0..f4efb65cb5 100644 --- a/app/layer.c +++ b/app/layer.c @@ -32,6 +32,7 @@ #include "temp_buf.h" #include "parasitelist.h" #include "undo.h" +#include "gimpsignal.h" #include "libgimp/gimpintl.h" @@ -40,6 +41,7 @@ #include "tile.h" /* ick. */ enum { + REMOVED, LAST_SIGNAL }; @@ -53,8 +55,8 @@ static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass); static void gimp_layer_mask_init (GimpLayerMask *layermask); static void gimp_layer_mask_destroy (GtkObject *object); -/* static gint layer_signals[LAST_SIGNAL] = { 0 }; +/* static gint layer_mask_signals[LAST_SIGNAL] = { 0 }; */ @@ -97,9 +99,11 @@ gimp_layer_class_init (GimpLayerClass *class) layer_parent_class = gtk_type_class (gimp_drawable_get_type ()); - /* + layer_signals[REMOVED] = + gimp_signal_new ("removed", + 0, object_class->type, 0, gimp_sigtype_void); + gtk_object_class_add_signals (object_class, layer_signals, LAST_SIGNAL); - */ object_class->destroy = gimp_layer_destroy; drawable_class->invalidate_preview = layer_invalidate_preview; @@ -556,6 +560,21 @@ gimp_layer_destroy (GtkObject *object) (*GTK_OBJECT_CLASS (layer_parent_class)->destroy) (object); } + +/* The removed signal is sent out when the layer is no longer + * associcated with an image. It's needed because layers aren't + * destroyed immediately, but kept around for undo purposes. Connect + * to the removed signal to update bits of UI that are tied to a + * particular layer. */ +void +layer_removed (Layer *layer, gpointer image) +{ + g_return_if_fail (layer != NULL); + g_return_if_fail (GIMP_IS_LAYER (layer)); + + gtk_signal_emit (GTK_OBJECT (layer), layer_signals[REMOVED]); +} + void layer_apply_mask (layer, mode) Layer * layer; diff --git a/app/layer.h b/app/layer.h index 90d3b46d28..63a96db397 100644 --- a/app/layer.h +++ b/app/layer.h @@ -89,6 +89,7 @@ LayerMask * layer_add_mask (Layer *, LayerMask *); LayerMask * layer_create_mask (Layer *, AddMaskType); Layer * layer_get_ID (int); void layer_delete (Layer *); +void layer_removed (Layer *, gpointer); void layer_apply_mask (Layer *, int); void layer_temporarily_translate (Layer *, int, int); void layer_translate (Layer *, int, int); diff --git a/app/layers_dialog.c b/app/layers_dialog.c index ef31422452..8cd6ff3702 100644 --- a/app/layers_dialog.c +++ b/app/layers_dialog.c @@ -3676,9 +3676,7 @@ layers_dialog_apply_mask_query (Layer *layer) typedef struct _ScaleLayerOptions ScaleLayerOptions; struct _ScaleLayerOptions { - GtkWidget *query_box; - Layer * layer; - + Layer *layer; Resize *resize; }; @@ -3713,7 +3711,6 @@ scale_layer_query_ok_callback (GtkWidget *w, gdisplays_flush (); } - gtk_widget_destroy (options->query_box); resize_widget_free (options->resize); g_free (options); } @@ -3726,9 +3723,8 @@ scale_layer_query_cancel_callback (GtkWidget *w, gpointer client_data) { ScaleLayerOptions *options; - options = (ScaleLayerOptions *) client_data; - gtk_widget_destroy (options->query_box); + resize_widget_free (options->resize); g_free (options); } @@ -3746,46 +3742,23 @@ scale_layer_query_delete_callback (GtkWidget *w, static void layers_dialog_scale_layer_query (Layer *layer) { - static ActionAreaItem action_items[3] = - { - { N_("OK"), scale_layer_query_ok_callback, NULL, NULL }, - { N_("Cancel"), scale_layer_query_cancel_callback, NULL, NULL } - }; ScaleLayerOptions *options; - GtkWidget *vbox; /* the new options structure */ options = (ScaleLayerOptions *) g_malloc (sizeof (ScaleLayerOptions)); options->layer = layer; options->resize = resize_widget_new (ScaleWidget, + ResizeLayer, + GTK_OBJECT (layer), drawable_width (GIMP_DRAWABLE(layer)), - drawable_height (GIMP_DRAWABLE(layer))); + drawable_height (GIMP_DRAWABLE(layer)), + 0.0, 0.0, /* no resolution, please */ + scale_layer_query_ok_callback, + scale_layer_query_cancel_callback, + scale_layer_query_delete_callback, + options); - /* the dialog */ - options->query_box = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (options->query_box), "scale_layer", "Gimp"); - gtk_window_set_title (GTK_WINDOW (options->query_box), _("Scale Layer")); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, FALSE, TRUE); - gtk_window_position (GTK_WINDOW (options->query_box), GTK_WIN_POS_MOUSE); - - /* handle the wm close singal */ - gtk_signal_connect (GTK_OBJECT (options->query_box), "delete_event", - GTK_SIGNAL_FUNC (scale_layer_query_delete_callback), - options); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_border_width (GTK_CONTAINER (vbox), 2); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (options->query_box)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), options->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = options; - action_items[1].user_data = options; - build_action_area (GTK_DIALOG (options->query_box), action_items, 2, 0); - - gtk_widget_show (options->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (options->query_box); + gtk_widget_show (options->resize->resize_shell); } @@ -3796,9 +3769,7 @@ layers_dialog_scale_layer_query (Layer *layer) typedef struct _ResizeLayerOptions ResizeLayerOptions; struct _ResizeLayerOptions { - GtkWidget *query_box; Layer *layer; - Resize *resize; }; @@ -3834,7 +3805,6 @@ resize_layer_query_ok_callback (GtkWidget *w, gdisplays_flush (); } - gtk_widget_destroy (options->query_box); resize_widget_free (options->resize); g_free (options); } @@ -3847,9 +3817,8 @@ resize_layer_query_cancel_callback (GtkWidget *w, gpointer client_data) { ResizeLayerOptions *options; - options = (ResizeLayerOptions *) client_data; - gtk_widget_destroy (options->query_box); + resize_widget_free (options->resize); g_free (options); } @@ -3867,47 +3836,23 @@ resize_layer_query_delete_callback (GtkWidget *w, static void layers_dialog_resize_layer_query (Layer *layer) { - static ActionAreaItem action_items[3] = - { - { N_("OK"), resize_layer_query_ok_callback, NULL, NULL }, - { N_("Cancel"), resize_layer_query_cancel_callback, NULL, NULL } - }; ResizeLayerOptions *options; - GtkWidget *vbox; /* the new options structure */ options = (ResizeLayerOptions *) g_malloc (sizeof (ResizeLayerOptions)); options->layer = layer; options->resize = resize_widget_new (ResizeWidget, + ResizeLayer, + GTK_OBJECT (layer), drawable_width (GIMP_DRAWABLE(layer)), - drawable_height (GIMP_DRAWABLE(layer))); + drawable_height (GIMP_DRAWABLE(layer)), + 0.0, 0.0, /* no resolution, please */ + resize_layer_query_ok_callback, + resize_layer_query_cancel_callback, + resize_layer_query_delete_callback, + options); - /* the dialog */ - options->query_box = gtk_dialog_new (); - gtk_window_set_wmclass (GTK_WINDOW (options->query_box), "resize_layer", "Gimp"); - gtk_window_set_title (GTK_WINDOW (options->query_box), _("Resize Layer")); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, TRUE, TRUE); - gtk_window_set_policy (GTK_WINDOW (options->query_box), FALSE, FALSE, TRUE); - gtk_window_position (GTK_WINDOW (options->query_box), GTK_WIN_POS_MOUSE); - - /* handle the wm close signal */ - gtk_signal_connect (GTK_OBJECT (options->query_box), "delete_event", - GTK_SIGNAL_FUNC (resize_layer_query_delete_callback), - options); - - /* the main vbox */ - vbox = gtk_vbox_new (FALSE, 1); - gtk_container_border_width (GTK_CONTAINER (vbox), 2); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (options->query_box)->vbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), options->resize->resize_widget, FALSE, FALSE, 0); - - action_items[0].user_data = options; - action_items[1].user_data = options; - build_action_area (GTK_DIALOG (options->query_box), action_items, 2, 0); - - gtk_widget_show (options->resize->resize_widget); - gtk_widget_show (vbox); - gtk_widget_show (options->query_box); + gtk_widget_show (options->resize->resize_shell); } diff --git a/app/preferences_dialog.c b/app/preferences_dialog.c index 9023add084..3d353f49a6 100644 --- a/app/preferences_dialog.c +++ b/app/preferences_dialog.c @@ -38,7 +38,6 @@ #include "patterns.h" #include "plug_in.h" #include "posterize.h" -#include "resize.h" #include "scale.h" #include "session.h" #include "threshold.h" @@ -49,12 +48,6 @@ #include "config.h" #include "libgimp/gimpintl.h" -typedef struct -{ - GtkWidget * shell; - Resize * resize; - int gimage_id; -} ImageResize; /* preferences local functions */ static void file_prefs_ok_callback (GtkWidget *, GtkWidget *); diff --git a/app/resize.c b/app/resize.c index 59132152a7..8483e6fbc2 100644 --- a/app/resize.c +++ b/app/resize.c @@ -20,6 +20,7 @@ #include #include "appenv.h" #include "resize.h" +#include "actionarea.h" #include "libgimp/gimpintl.h" @@ -39,6 +40,9 @@ struct _ResizePrivate GtkWidget *off_y_text; GtkWidget *drawing_area; + GtkObject *object; + guint object_destroy_handler; + double ratio; int constrain; int old_width, old_height; @@ -61,10 +65,25 @@ static gint resize_events (GtkWidget *area, GdkEvent *event); Resize * -resize_widget_new (ResizeType type, - int width, - int height) +resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject *object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data) { + static ActionAreaItem action_items[2] = + { + { N_("OK"), NULL, NULL, NULL }, + { N_("Cancel"), NULL, NULL, NULL } + }; Resize *resize; ResizePrivate *private; GtkWidget *vbox; @@ -77,6 +96,7 @@ resize_widget_new (ResizeType type, char ratio_text[12]; table = NULL; + frame = NULL; resize = g_new (Resize, 1); private = g_new (ResizePrivate, 1); @@ -84,6 +104,8 @@ resize_widget_new (ResizeType type, resize->private_part = private; resize->width = width; resize->height = height; + resize->resolution_x = resolution_x; + resize->resolution_y = resolution_y; resize->ratio_x = 1.0; resize->ratio_y = 1.0; resize->off_x = 0; @@ -91,6 +113,7 @@ resize_widget_new (ResizeType type, private->old_width = width; private->old_height = height; private->constrain = TRUE; + private->object = NULL; /* Get the image width and height variables, based on the gimage */ if (width > height) @@ -100,23 +123,80 @@ resize_widget_new (ResizeType type, private->area_width = (int) (private->ratio * width); private->area_height = (int) (private->ratio * height); - switch (type) - { + /* dialog box */ + { + const char *wmclass = NULL; + const char *window_title = NULL; + + switch (type) { case ScaleWidget: - resize->resize_widget = gtk_frame_new (_("Scale")); - table = gtk_table_new (4, 2, TRUE); - break; + switch (target) { + case ResizeLayer: + wmclass = "scale_layer"; + window_title = _("Scale Layer"); + break; + case ResizeImage: + wmclass = "image_scale"; + window_title = _("Image Scale"); + break; + } + frame = gtk_frame_new (_("Scale")); + table = gtk_table_new (4, 2, TRUE); + break; + case ResizeWidget: - resize->resize_widget = gtk_frame_new (_("Resize")); - table = gtk_table_new (6, 2, TRUE); - break; - } - gtk_frame_set_shadow_type (GTK_FRAME (resize->resize_widget), GTK_SHADOW_ETCHED_IN); + switch (target) { + case ResizeLayer: + wmclass = "resize_layer"; + window_title = _("Resize Layer"); + break; + case ResizeImage: + wmclass = "image_resize"; + window_title = _("Image Resize"); + break; + } + frame = gtk_frame_new (_("Resize")); + table = gtk_table_new (6, 2, TRUE); + break; + } + + resize->resize_shell = gtk_dialog_new(); + gtk_window_set_wmclass (GTK_WINDOW (resize->resize_shell), wmclass,"Gimp"); + gtk_window_set_title (GTK_WINDOW (resize->resize_shell), window_title); + gtk_window_set_policy(GTK_WINDOW (resize->resize_shell), FALSE,FALSE,TRUE); + gtk_window_position (GTK_WINDOW (resize->resize_shell), GTK_WIN_POS_MOUSE); + } + + /* handle the wm close singal */ + if (delete_cb) + gtk_signal_connect (GTK_OBJECT (resize->resize_shell), "delete_event", + GTK_SIGNAL_FUNC (delete_cb), user_data); + + /* handle the image disappearing under our feet */ + if (object) + { + const char *signame; + signame = (target == ResizeLayer)? "removed" : "destroy"; + private->object = object; + private->object_destroy_handler = gtk_signal_connect(GTK_OBJECT (object), + signame, + cancel_cb, user_data); + } + + vbox = gtk_vbox_new (FALSE, 1); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (resize->resize_shell)->vbox), + vbox, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_widget_show (vbox); + + gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); + gtk_widget_show (frame); /* the main vbox */ vbox = gtk_vbox_new (FALSE, 1); gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - gtk_container_add (GTK_CONTAINER (resize->resize_widget), vbox); + gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_container_set_border_width (GTK_CONTAINER (table), 2); gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0); @@ -261,12 +341,25 @@ resize_widget_new (ResizeType type, gtk_widget_show (table); gtk_widget_show (vbox); + action_items[0].user_data = user_data; + action_items[0].callback = ok_cb; + action_items[1].user_data = user_data; + action_items[1].callback = cancel_cb; + build_action_area (GTK_DIALOG (resize->resize_shell), action_items, 2, 0); + return resize; } void resize_widget_free (Resize *resize) { + ResizePrivate *private = resize->private_part; + + if (private->object) + gtk_signal_disconnect (GTK_OBJECT (private->object), + private->object_destroy_handler); + + gtk_widget_destroy (resize->resize_shell); g_free (resize->private_part); g_free (resize); } diff --git a/app/resize.h b/app/resize.h index c824163afd..0d0f0bf865 100644 --- a/app/resize.h +++ b/app/resize.h @@ -24,16 +24,24 @@ typedef enum ResizeWidget } ResizeType; +typedef enum +{ + ResizeImage, + ResizeLayer +} ResizeTarget; + typedef struct _Resize Resize; struct _Resize { /* The calling procedure is respondible for showing this widget */ - GtkWidget *resize_widget; + GtkWidget *resize_shell; ResizeType type; int width; int height; + float resolution_x; + float resolution_y; double ratio_x; double ratio_y; int off_x; @@ -43,9 +51,22 @@ struct _Resize void * private_part; }; -Resize * resize_widget_new (ResizeType type, - int width, - int height); -void resize_widget_free (Resize * resize); +/* If resolution_x is zero, then don't show resolution modification + * parts of the dialog. If object is non-NULL, then attach the cancel + * callback to its destroy signal. */ +Resize * resize_widget_new (ResizeType type, + ResizeTarget target, + GtkObject * object, + int width, + int height, + float resolution_x, + float resolution_y, + GtkSignalFunc ok_cb, + GtkSignalFunc cancel_cb, + gint (*delete_cb) (GtkWidget *, + GdkEvent *, + gpointer), + gpointer user_data); +void resize_widget_free (Resize * resize); #endif /* __RESIZE_H__ */