From 6107e511220e5ab70ae3fc1c0a4041af514524bd Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 7 Feb 2001 02:37:49 +0000 Subject: [PATCH] app/Makefile.am new object with own implementations of "create_preview" 2001-02-07 Michael Natterer * app/Makefile.am * app/gimpimagepreview.[ch]: new object with own implementations of "create_preview" and "create_popup". * app/gimpdrawablepreview.c: stuff... still unused. * app/gimppreview.c: fixed idle rendering crashes, don't forget popups on GDK_2BUTTON_PRESS. * app/app_procs.c: gimpbrushlist.h doesn't exist any more. * app/gimpobject.h: removed the GimpObject typedef because it is in apptypes.h --- ChangeLog | 17 +- app/Makefile.am | 2 + app/app_procs.c | 1 - app/core/gimpobject.h | 2 +- app/gimpdrawablepreview.c | 13 ++ app/gimpimagepreview.c | 230 ++++++++++++++++++++++ app/gimpimagepreview.h | 61 ++++++ app/gimpobject.h | 2 +- app/gimppreview.c | 69 +++++-- app/widgets/gimpdrawablepreview.c | 13 ++ app/widgets/gimpimagepreview.c | 230 ++++++++++++++++++++++ app/widgets/gimpimagepreview.h | 61 ++++++ app/widgets/gimppreview.c | 69 +++++-- app/widgets/gimppreviewrenderer.c | 69 +++++-- app/widgets/gimppreviewrendererdrawable.c | 13 ++ app/widgets/gimppreviewrendererimage.c | 230 ++++++++++++++++++++++ app/widgets/gimppreviewrendererimage.h | 61 ++++++ app/widgets/gimpview.c | 69 +++++-- app/widgets/gimpviewrenderer.c | 69 +++++-- app/widgets/gimpviewrendererdrawable.c | 13 ++ app/widgets/gimpviewrendererimage.c | 230 ++++++++++++++++++++++ app/widgets/gimpviewrendererimage.h | 61 ++++++ 22 files changed, 1486 insertions(+), 99 deletions(-) create mode 100644 app/gimpimagepreview.c create mode 100644 app/gimpimagepreview.h create mode 100644 app/widgets/gimpimagepreview.c create mode 100644 app/widgets/gimpimagepreview.h create mode 100644 app/widgets/gimppreviewrendererimage.c create mode 100644 app/widgets/gimppreviewrendererimage.h create mode 100644 app/widgets/gimpviewrendererimage.c create mode 100644 app/widgets/gimpviewrendererimage.h diff --git a/ChangeLog b/ChangeLog index e5523952c0..8d11b9fe7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-02-07 Michael Natterer + + * app/Makefile.am + * app/gimpimagepreview.[ch]: new object with own implementations + of "create_preview" and "create_popup". + + * app/gimpdrawablepreview.c: stuff... still unused. + + * app/gimppreview.c: fixed idle rendering crashes, don't + forget popups on GDK_2BUTTON_PRESS. + + * app/app_procs.c: gimpbrushlist.h doesn't exist any more. + + * app/gimpobject.h: removed the GimpObject typedef because it + is in apptypes.h + 2001-02-07 Hans Breuer * */makefile.msc : Gimp 1.3 for win32 (msc) builds and runs at @@ -40,7 +56,6 @@ the application or libgimp. This allows to resolve the double dependency for currently 11 functions - 2001-02-07 Michael Natterer * app/Makefile.am diff --git a/app/Makefile.am b/app/Makefile.am index 5448be0153..8dd4912548 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -292,6 +292,8 @@ gimp_SOURCES = \ gimpcontainerview.c \ gimpdrawablepreview.c \ gimpdrawablepreview.h \ + gimpimagepreview.h \ + gimpimagepreview.c \ gimppatternpreview.h \ gimppatternpreview.c \ gimppreview.h \ diff --git a/app/app_procs.c b/app/app_procs.c index 759501cd05..5f0df6c789 100644 --- a/app/app_procs.c +++ b/app/app_procs.c @@ -57,7 +57,6 @@ #include "fileops.h" #include "gdisplay.h" #include "gdisplay_ops.h" -#include "gimpbrushlist.h" #include "gimpcontext.h" #include "gimpimage.h" #include "gimprc.h" diff --git a/app/core/gimpobject.h b/app/core/gimpobject.h index df446bd2db..29165eb20c 100644 --- a/app/core/gimpobject.h +++ b/app/core/gimpobject.h @@ -29,7 +29,7 @@ #define GIMP_IS_OBJECT(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_OBJECT)) #define GIMP_IS_OBJECT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OBJECT)) -typedef struct _GimpObject GimpObject; + typedef struct _GimpObjectClass GimpObjectClass; struct _GimpObject diff --git a/app/gimpdrawablepreview.c b/app/gimpdrawablepreview.c index 460afe8002..468b607793 100644 --- a/app/gimpdrawablepreview.c +++ b/app/gimpdrawablepreview.c @@ -31,6 +31,9 @@ static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static TempBuf * gimp_drawable_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_drawable_preview_create_popup (GimpPreview *preview); + static GimpPreviewClass *parent_class = NULL; @@ -76,3 +79,13 @@ static void gimp_drawable_preview_init (GimpDrawablePreview *preview) { } + +static TempBuf * +gimp_drawable_preview_create_preview (GimpPreview *preview) +{ +} + +static GtkWidget * +gimp_drawable_preview_create_popup (GimpPreview *preview) +{ +} diff --git a/app/gimpimagepreview.c b/app/gimpimagepreview.c new file mode 100644 index 0000000000..1ba2e8f1a5 --- /dev/null +++ b/app/gimpimagepreview.c @@ -0,0 +1,230 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "apptypes.h" + +#include "gimpimage.h" +#include "gimpimagepreview.h" +#include "gimpviewable.h" +#include "temp_buf.h" + + +static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); +static void gimp_image_preview_init (GimpImagePreview *preview); + +static TempBuf * gimp_image_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_image_preview_create_popup (GimpPreview *preview); +static void gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up); + + +static GimpPreviewClass *parent_class = NULL; + + +GtkType +gimp_image_preview_get_type (void) +{ + static GtkType preview_type = 0; + + if (! preview_type) + { + GtkTypeInfo preview_info = + { + "GimpImagePreview", + sizeof (GimpImagePreview), + sizeof (GimpImagePreviewClass), + (GtkClassInitFunc) gimp_image_preview_class_init, + (GtkObjectInitFunc) gimp_image_preview_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + preview_type = gtk_type_unique (GIMP_TYPE_PREVIEW, &preview_info); + } + + return preview_type; +} + +static void +gimp_image_preview_class_init (GimpImagePreviewClass *klass) +{ + GtkObjectClass *object_class; + GimpPreviewClass *preview_class; + + object_class = (GtkObjectClass *) klass; + preview_class = (GimpPreviewClass *) klass; + + parent_class = gtk_type_class (GIMP_TYPE_PREVIEW); + + preview_class->create_preview = gimp_image_preview_create_preview; + preview_class->create_popup = gimp_image_preview_create_popup; +} + +static void +gimp_image_preview_init (GimpImagePreview *preview) +{ +} + +static TempBuf * +gimp_image_preview_create_preview (GimpPreview *preview) +{ + GimpImage *gimage; + gint width; + gint height; + gint preview_width; + gint preview_height; + gboolean scaling_up; + TempBuf *return_buf; + + gimage = GIMP_IMAGE (preview->viewable); + + width = GTK_WIDGET (preview)->allocation.width; + height = GTK_WIDGET (preview)->allocation.height; + + gimp_image_preview_calc_size (gimage, + width, + height, + &preview_width, + &preview_height, + &scaling_up); + + if (scaling_up) + { + TempBuf *temp_buf; + + temp_buf = gimp_viewable_get_new_preview (preview->viewable, + gimage->width, + gimage->height); + return_buf = temp_buf_scale (temp_buf, preview_width, preview_height); + + temp_buf_free (temp_buf); + } + else + { + return_buf = gimp_viewable_get_new_preview (preview->viewable, + preview_width, + preview_height); + } + + if (preview_width < width) return_buf->x = (width - preview_width) / 2; + if (preview_height < height) return_buf->y = (height - preview_height) / 2; + + if (return_buf->x || return_buf->y) + { + TempBuf *temp_buf; + guchar white[4] = { 255, 255, 255, 255 }; + + temp_buf = temp_buf_new (width, height, + return_buf->bytes, + 0, 0, + white); + + temp_buf_copy_area (return_buf, temp_buf, + 0, 0, + return_buf->width, + return_buf->height, + return_buf->x, + return_buf->y); + + temp_buf_free (return_buf); + + return temp_buf; + } + + return return_buf; +} + +static GtkWidget * +gimp_image_preview_create_popup (GimpPreview *preview) +{ + GimpImage *gimage; + gint popup_width; + gint popup_height; + gboolean scaling_up; + + gimage = GIMP_IMAGE (preview->viewable); + + gimp_image_preview_calc_size + (gimage, + MIN (GTK_WIDGET (preview)->allocation.width * 2, 256), + MIN (GTK_WIDGET (preview)->allocation.height * 2, 256), + &popup_width, + &popup_height, + &scaling_up); + + if (scaling_up) + { + return gimp_preview_new (preview->viewable, + gimage->width, + gimage->height, + FALSE, + FALSE); + } + else + { + return gimp_preview_new (preview->viewable, + popup_width, + popup_height, + FALSE, + FALSE); + } +} + +static void +gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up) +{ + gdouble ratio; + + if (gimage->width > gimage->height) + { + ratio = (gdouble) width / (gdouble) gimage->width; + } + else + { + ratio = (gdouble) height / (gdouble) gimage->height; + } + + width = RINT (ratio * (gdouble) gimage->width); + height = RINT (ratio * (gdouble) gimage->height); + + if (width < 1) width = 1; + if (height < 1) height = 1; + + *return_width = width; + *return_height = height; + *scaling_up = (ratio > 1.0); +} diff --git a/app/gimpimagepreview.h b/app/gimpimagepreview.h new file mode 100644 index 0000000000..4dfa40e6c7 --- /dev/null +++ b/app/gimpimagepreview.h @@ -0,0 +1,61 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_IMAGE_PREVIEW_H__ +#define __GIMP_IMAGE_PREVIEW_H__ + + +#include "gimppreview.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) +#define GIMP_IMAGE_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) +#define GIMP_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +#define GIMP_IS_IMAGE_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) +#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) + + +typedef struct _GimpImagePreviewClass GimpImagePreviewClass; + +struct _GimpImagePreview +{ + GimpPreview parent_instance; +}; + +struct _GimpImagePreviewClass +{ + GimpPreviewClass parent_class; +}; + + +GtkType gimp_image_preview_get_type (void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_IMAGE_PREVIEW_H__ */ diff --git a/app/gimpobject.h b/app/gimpobject.h index df446bd2db..29165eb20c 100644 --- a/app/gimpobject.h +++ b/app/gimpobject.h @@ -29,7 +29,7 @@ #define GIMP_IS_OBJECT(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_OBJECT)) #define GIMP_IS_OBJECT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OBJECT)) -typedef struct _GimpObject GimpObject; + typedef struct _GimpObjectClass GimpObjectClass; struct _GimpObject diff --git a/app/gimppreview.c b/app/gimppreview.c index 26cb351387..d15cf4e591 100644 --- a/app/gimppreview.c +++ b/app/gimppreview.c @@ -29,11 +29,12 @@ #include "apptypes.h" -#include "gimpimage.h" #include "gimpbrush.h" #include "gimpbrushpreview.h" #include "gimpdrawable.h" #include "gimpdrawablepreview.h" +#include "gimpimage.h" +#include "gimpimagepreview.h" #include "gimpmarshal.h" #include "gimppattern.h" #include "gimppatternpreview.h" @@ -194,6 +195,17 @@ gimp_preview_init (GimpPreview *preview) static void gimp_preview_destroy (GtkObject *object) { + GimpPreview *preview; + + preview = GIMP_PREVIEW (object); + + if (preview->idle_id) + { + g_source_remove (preview->idle_id); + } + + gimp_preview_popup_hide (preview); + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -220,6 +232,10 @@ gimp_preview_new (GimpViewable *viewable, { preview = gtk_type_new (GIMP_TYPE_DRAWABLE_PREVIEW); } + else if (GIMP_IS_IMAGE (viewable)) + { + preview = gtk_type_new (GIMP_TYPE_IMAGE_PREVIEW); + } else if (GIMP_IS_PATTERN (viewable)) { preview = gtk_type_new (GIMP_TYPE_PATTERN_PREVIEW); @@ -256,16 +272,23 @@ gimp_preview_button_press_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - if (bevent->button == 1) - { - gtk_grab_add (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; - if (preview->show_popup) - { - gimp_preview_popup_show (preview, - bevent->x, - bevent->y); - } + if (bevent->type == GDK_BUTTON_PRESS) + { + if (bevent->button == 1) + { + gtk_grab_add (widget); + + if (preview->show_popup) + { + gimp_preview_popup_show (preview, + bevent->x, + bevent->y); + } + } } return TRUE; @@ -280,17 +303,22 @@ gimp_preview_button_release_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; + if (bevent->button == 1) { - gtk_grab_remove (widget); - if (preview->show_popup) { fast_click = (preview->popup_id != 0); - - gimp_preview_popup_hide (preview); } + gimp_preview_popup_hide (preview); + + /* remove the grab _after_ hiding the popup */ + gtk_grab_remove (widget); + if (preview->clickable && fast_click && preview->in_button) { gtk_signal_emit (GTK_OBJECT (widget), preview_signals[CLICKED]); @@ -486,11 +514,14 @@ static void gimp_preview_paint (GimpPreview *preview) { if (preview->idle_id) - return; + { + g_source_remove (preview->idle_id); + } - preview->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_paint, preview, - NULL); + preview->idle_id = + g_idle_add_full (G_PRIORITY_LOW, + (GSourceFunc) gimp_preview_idle_paint, preview, + NULL); } static gboolean @@ -557,7 +588,7 @@ gimp_preview_idle_paint (GimpPreview *preview) if (has_alpha) { - buf = render_check_buf; + buf = render_check_buf; alpha = ((color) ? ALPHA_PIX : ((channel != -1) ? (temp_buf->bytes - 1) : ALPHA_G_PIX)); diff --git a/app/widgets/gimpdrawablepreview.c b/app/widgets/gimpdrawablepreview.c index 460afe8002..468b607793 100644 --- a/app/widgets/gimpdrawablepreview.c +++ b/app/widgets/gimpdrawablepreview.c @@ -31,6 +31,9 @@ static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static TempBuf * gimp_drawable_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_drawable_preview_create_popup (GimpPreview *preview); + static GimpPreviewClass *parent_class = NULL; @@ -76,3 +79,13 @@ static void gimp_drawable_preview_init (GimpDrawablePreview *preview) { } + +static TempBuf * +gimp_drawable_preview_create_preview (GimpPreview *preview) +{ +} + +static GtkWidget * +gimp_drawable_preview_create_popup (GimpPreview *preview) +{ +} diff --git a/app/widgets/gimpimagepreview.c b/app/widgets/gimpimagepreview.c new file mode 100644 index 0000000000..1ba2e8f1a5 --- /dev/null +++ b/app/widgets/gimpimagepreview.c @@ -0,0 +1,230 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "apptypes.h" + +#include "gimpimage.h" +#include "gimpimagepreview.h" +#include "gimpviewable.h" +#include "temp_buf.h" + + +static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); +static void gimp_image_preview_init (GimpImagePreview *preview); + +static TempBuf * gimp_image_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_image_preview_create_popup (GimpPreview *preview); +static void gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up); + + +static GimpPreviewClass *parent_class = NULL; + + +GtkType +gimp_image_preview_get_type (void) +{ + static GtkType preview_type = 0; + + if (! preview_type) + { + GtkTypeInfo preview_info = + { + "GimpImagePreview", + sizeof (GimpImagePreview), + sizeof (GimpImagePreviewClass), + (GtkClassInitFunc) gimp_image_preview_class_init, + (GtkObjectInitFunc) gimp_image_preview_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + preview_type = gtk_type_unique (GIMP_TYPE_PREVIEW, &preview_info); + } + + return preview_type; +} + +static void +gimp_image_preview_class_init (GimpImagePreviewClass *klass) +{ + GtkObjectClass *object_class; + GimpPreviewClass *preview_class; + + object_class = (GtkObjectClass *) klass; + preview_class = (GimpPreviewClass *) klass; + + parent_class = gtk_type_class (GIMP_TYPE_PREVIEW); + + preview_class->create_preview = gimp_image_preview_create_preview; + preview_class->create_popup = gimp_image_preview_create_popup; +} + +static void +gimp_image_preview_init (GimpImagePreview *preview) +{ +} + +static TempBuf * +gimp_image_preview_create_preview (GimpPreview *preview) +{ + GimpImage *gimage; + gint width; + gint height; + gint preview_width; + gint preview_height; + gboolean scaling_up; + TempBuf *return_buf; + + gimage = GIMP_IMAGE (preview->viewable); + + width = GTK_WIDGET (preview)->allocation.width; + height = GTK_WIDGET (preview)->allocation.height; + + gimp_image_preview_calc_size (gimage, + width, + height, + &preview_width, + &preview_height, + &scaling_up); + + if (scaling_up) + { + TempBuf *temp_buf; + + temp_buf = gimp_viewable_get_new_preview (preview->viewable, + gimage->width, + gimage->height); + return_buf = temp_buf_scale (temp_buf, preview_width, preview_height); + + temp_buf_free (temp_buf); + } + else + { + return_buf = gimp_viewable_get_new_preview (preview->viewable, + preview_width, + preview_height); + } + + if (preview_width < width) return_buf->x = (width - preview_width) / 2; + if (preview_height < height) return_buf->y = (height - preview_height) / 2; + + if (return_buf->x || return_buf->y) + { + TempBuf *temp_buf; + guchar white[4] = { 255, 255, 255, 255 }; + + temp_buf = temp_buf_new (width, height, + return_buf->bytes, + 0, 0, + white); + + temp_buf_copy_area (return_buf, temp_buf, + 0, 0, + return_buf->width, + return_buf->height, + return_buf->x, + return_buf->y); + + temp_buf_free (return_buf); + + return temp_buf; + } + + return return_buf; +} + +static GtkWidget * +gimp_image_preview_create_popup (GimpPreview *preview) +{ + GimpImage *gimage; + gint popup_width; + gint popup_height; + gboolean scaling_up; + + gimage = GIMP_IMAGE (preview->viewable); + + gimp_image_preview_calc_size + (gimage, + MIN (GTK_WIDGET (preview)->allocation.width * 2, 256), + MIN (GTK_WIDGET (preview)->allocation.height * 2, 256), + &popup_width, + &popup_height, + &scaling_up); + + if (scaling_up) + { + return gimp_preview_new (preview->viewable, + gimage->width, + gimage->height, + FALSE, + FALSE); + } + else + { + return gimp_preview_new (preview->viewable, + popup_width, + popup_height, + FALSE, + FALSE); + } +} + +static void +gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up) +{ + gdouble ratio; + + if (gimage->width > gimage->height) + { + ratio = (gdouble) width / (gdouble) gimage->width; + } + else + { + ratio = (gdouble) height / (gdouble) gimage->height; + } + + width = RINT (ratio * (gdouble) gimage->width); + height = RINT (ratio * (gdouble) gimage->height); + + if (width < 1) width = 1; + if (height < 1) height = 1; + + *return_width = width; + *return_height = height; + *scaling_up = (ratio > 1.0); +} diff --git a/app/widgets/gimpimagepreview.h b/app/widgets/gimpimagepreview.h new file mode 100644 index 0000000000..4dfa40e6c7 --- /dev/null +++ b/app/widgets/gimpimagepreview.h @@ -0,0 +1,61 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_IMAGE_PREVIEW_H__ +#define __GIMP_IMAGE_PREVIEW_H__ + + +#include "gimppreview.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) +#define GIMP_IMAGE_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) +#define GIMP_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +#define GIMP_IS_IMAGE_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) +#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) + + +typedef struct _GimpImagePreviewClass GimpImagePreviewClass; + +struct _GimpImagePreview +{ + GimpPreview parent_instance; +}; + +struct _GimpImagePreviewClass +{ + GimpPreviewClass parent_class; +}; + + +GtkType gimp_image_preview_get_type (void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_IMAGE_PREVIEW_H__ */ diff --git a/app/widgets/gimppreview.c b/app/widgets/gimppreview.c index 26cb351387..d15cf4e591 100644 --- a/app/widgets/gimppreview.c +++ b/app/widgets/gimppreview.c @@ -29,11 +29,12 @@ #include "apptypes.h" -#include "gimpimage.h" #include "gimpbrush.h" #include "gimpbrushpreview.h" #include "gimpdrawable.h" #include "gimpdrawablepreview.h" +#include "gimpimage.h" +#include "gimpimagepreview.h" #include "gimpmarshal.h" #include "gimppattern.h" #include "gimppatternpreview.h" @@ -194,6 +195,17 @@ gimp_preview_init (GimpPreview *preview) static void gimp_preview_destroy (GtkObject *object) { + GimpPreview *preview; + + preview = GIMP_PREVIEW (object); + + if (preview->idle_id) + { + g_source_remove (preview->idle_id); + } + + gimp_preview_popup_hide (preview); + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -220,6 +232,10 @@ gimp_preview_new (GimpViewable *viewable, { preview = gtk_type_new (GIMP_TYPE_DRAWABLE_PREVIEW); } + else if (GIMP_IS_IMAGE (viewable)) + { + preview = gtk_type_new (GIMP_TYPE_IMAGE_PREVIEW); + } else if (GIMP_IS_PATTERN (viewable)) { preview = gtk_type_new (GIMP_TYPE_PATTERN_PREVIEW); @@ -256,16 +272,23 @@ gimp_preview_button_press_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - if (bevent->button == 1) - { - gtk_grab_add (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; - if (preview->show_popup) - { - gimp_preview_popup_show (preview, - bevent->x, - bevent->y); - } + if (bevent->type == GDK_BUTTON_PRESS) + { + if (bevent->button == 1) + { + gtk_grab_add (widget); + + if (preview->show_popup) + { + gimp_preview_popup_show (preview, + bevent->x, + bevent->y); + } + } } return TRUE; @@ -280,17 +303,22 @@ gimp_preview_button_release_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; + if (bevent->button == 1) { - gtk_grab_remove (widget); - if (preview->show_popup) { fast_click = (preview->popup_id != 0); - - gimp_preview_popup_hide (preview); } + gimp_preview_popup_hide (preview); + + /* remove the grab _after_ hiding the popup */ + gtk_grab_remove (widget); + if (preview->clickable && fast_click && preview->in_button) { gtk_signal_emit (GTK_OBJECT (widget), preview_signals[CLICKED]); @@ -486,11 +514,14 @@ static void gimp_preview_paint (GimpPreview *preview) { if (preview->idle_id) - return; + { + g_source_remove (preview->idle_id); + } - preview->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_paint, preview, - NULL); + preview->idle_id = + g_idle_add_full (G_PRIORITY_LOW, + (GSourceFunc) gimp_preview_idle_paint, preview, + NULL); } static gboolean @@ -557,7 +588,7 @@ gimp_preview_idle_paint (GimpPreview *preview) if (has_alpha) { - buf = render_check_buf; + buf = render_check_buf; alpha = ((color) ? ALPHA_PIX : ((channel != -1) ? (temp_buf->bytes - 1) : ALPHA_G_PIX)); diff --git a/app/widgets/gimppreviewrenderer.c b/app/widgets/gimppreviewrenderer.c index 26cb351387..d15cf4e591 100644 --- a/app/widgets/gimppreviewrenderer.c +++ b/app/widgets/gimppreviewrenderer.c @@ -29,11 +29,12 @@ #include "apptypes.h" -#include "gimpimage.h" #include "gimpbrush.h" #include "gimpbrushpreview.h" #include "gimpdrawable.h" #include "gimpdrawablepreview.h" +#include "gimpimage.h" +#include "gimpimagepreview.h" #include "gimpmarshal.h" #include "gimppattern.h" #include "gimppatternpreview.h" @@ -194,6 +195,17 @@ gimp_preview_init (GimpPreview *preview) static void gimp_preview_destroy (GtkObject *object) { + GimpPreview *preview; + + preview = GIMP_PREVIEW (object); + + if (preview->idle_id) + { + g_source_remove (preview->idle_id); + } + + gimp_preview_popup_hide (preview); + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -220,6 +232,10 @@ gimp_preview_new (GimpViewable *viewable, { preview = gtk_type_new (GIMP_TYPE_DRAWABLE_PREVIEW); } + else if (GIMP_IS_IMAGE (viewable)) + { + preview = gtk_type_new (GIMP_TYPE_IMAGE_PREVIEW); + } else if (GIMP_IS_PATTERN (viewable)) { preview = gtk_type_new (GIMP_TYPE_PATTERN_PREVIEW); @@ -256,16 +272,23 @@ gimp_preview_button_press_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - if (bevent->button == 1) - { - gtk_grab_add (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; - if (preview->show_popup) - { - gimp_preview_popup_show (preview, - bevent->x, - bevent->y); - } + if (bevent->type == GDK_BUTTON_PRESS) + { + if (bevent->button == 1) + { + gtk_grab_add (widget); + + if (preview->show_popup) + { + gimp_preview_popup_show (preview, + bevent->x, + bevent->y); + } + } } return TRUE; @@ -280,17 +303,22 @@ gimp_preview_button_release_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; + if (bevent->button == 1) { - gtk_grab_remove (widget); - if (preview->show_popup) { fast_click = (preview->popup_id != 0); - - gimp_preview_popup_hide (preview); } + gimp_preview_popup_hide (preview); + + /* remove the grab _after_ hiding the popup */ + gtk_grab_remove (widget); + if (preview->clickable && fast_click && preview->in_button) { gtk_signal_emit (GTK_OBJECT (widget), preview_signals[CLICKED]); @@ -486,11 +514,14 @@ static void gimp_preview_paint (GimpPreview *preview) { if (preview->idle_id) - return; + { + g_source_remove (preview->idle_id); + } - preview->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_paint, preview, - NULL); + preview->idle_id = + g_idle_add_full (G_PRIORITY_LOW, + (GSourceFunc) gimp_preview_idle_paint, preview, + NULL); } static gboolean @@ -557,7 +588,7 @@ gimp_preview_idle_paint (GimpPreview *preview) if (has_alpha) { - buf = render_check_buf; + buf = render_check_buf; alpha = ((color) ? ALPHA_PIX : ((channel != -1) ? (temp_buf->bytes - 1) : ALPHA_G_PIX)); diff --git a/app/widgets/gimppreviewrendererdrawable.c b/app/widgets/gimppreviewrendererdrawable.c index 460afe8002..468b607793 100644 --- a/app/widgets/gimppreviewrendererdrawable.c +++ b/app/widgets/gimppreviewrendererdrawable.c @@ -31,6 +31,9 @@ static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static TempBuf * gimp_drawable_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_drawable_preview_create_popup (GimpPreview *preview); + static GimpPreviewClass *parent_class = NULL; @@ -76,3 +79,13 @@ static void gimp_drawable_preview_init (GimpDrawablePreview *preview) { } + +static TempBuf * +gimp_drawable_preview_create_preview (GimpPreview *preview) +{ +} + +static GtkWidget * +gimp_drawable_preview_create_popup (GimpPreview *preview) +{ +} diff --git a/app/widgets/gimppreviewrendererimage.c b/app/widgets/gimppreviewrendererimage.c new file mode 100644 index 0000000000..1ba2e8f1a5 --- /dev/null +++ b/app/widgets/gimppreviewrendererimage.c @@ -0,0 +1,230 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "apptypes.h" + +#include "gimpimage.h" +#include "gimpimagepreview.h" +#include "gimpviewable.h" +#include "temp_buf.h" + + +static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); +static void gimp_image_preview_init (GimpImagePreview *preview); + +static TempBuf * gimp_image_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_image_preview_create_popup (GimpPreview *preview); +static void gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up); + + +static GimpPreviewClass *parent_class = NULL; + + +GtkType +gimp_image_preview_get_type (void) +{ + static GtkType preview_type = 0; + + if (! preview_type) + { + GtkTypeInfo preview_info = + { + "GimpImagePreview", + sizeof (GimpImagePreview), + sizeof (GimpImagePreviewClass), + (GtkClassInitFunc) gimp_image_preview_class_init, + (GtkObjectInitFunc) gimp_image_preview_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + preview_type = gtk_type_unique (GIMP_TYPE_PREVIEW, &preview_info); + } + + return preview_type; +} + +static void +gimp_image_preview_class_init (GimpImagePreviewClass *klass) +{ + GtkObjectClass *object_class; + GimpPreviewClass *preview_class; + + object_class = (GtkObjectClass *) klass; + preview_class = (GimpPreviewClass *) klass; + + parent_class = gtk_type_class (GIMP_TYPE_PREVIEW); + + preview_class->create_preview = gimp_image_preview_create_preview; + preview_class->create_popup = gimp_image_preview_create_popup; +} + +static void +gimp_image_preview_init (GimpImagePreview *preview) +{ +} + +static TempBuf * +gimp_image_preview_create_preview (GimpPreview *preview) +{ + GimpImage *gimage; + gint width; + gint height; + gint preview_width; + gint preview_height; + gboolean scaling_up; + TempBuf *return_buf; + + gimage = GIMP_IMAGE (preview->viewable); + + width = GTK_WIDGET (preview)->allocation.width; + height = GTK_WIDGET (preview)->allocation.height; + + gimp_image_preview_calc_size (gimage, + width, + height, + &preview_width, + &preview_height, + &scaling_up); + + if (scaling_up) + { + TempBuf *temp_buf; + + temp_buf = gimp_viewable_get_new_preview (preview->viewable, + gimage->width, + gimage->height); + return_buf = temp_buf_scale (temp_buf, preview_width, preview_height); + + temp_buf_free (temp_buf); + } + else + { + return_buf = gimp_viewable_get_new_preview (preview->viewable, + preview_width, + preview_height); + } + + if (preview_width < width) return_buf->x = (width - preview_width) / 2; + if (preview_height < height) return_buf->y = (height - preview_height) / 2; + + if (return_buf->x || return_buf->y) + { + TempBuf *temp_buf; + guchar white[4] = { 255, 255, 255, 255 }; + + temp_buf = temp_buf_new (width, height, + return_buf->bytes, + 0, 0, + white); + + temp_buf_copy_area (return_buf, temp_buf, + 0, 0, + return_buf->width, + return_buf->height, + return_buf->x, + return_buf->y); + + temp_buf_free (return_buf); + + return temp_buf; + } + + return return_buf; +} + +static GtkWidget * +gimp_image_preview_create_popup (GimpPreview *preview) +{ + GimpImage *gimage; + gint popup_width; + gint popup_height; + gboolean scaling_up; + + gimage = GIMP_IMAGE (preview->viewable); + + gimp_image_preview_calc_size + (gimage, + MIN (GTK_WIDGET (preview)->allocation.width * 2, 256), + MIN (GTK_WIDGET (preview)->allocation.height * 2, 256), + &popup_width, + &popup_height, + &scaling_up); + + if (scaling_up) + { + return gimp_preview_new (preview->viewable, + gimage->width, + gimage->height, + FALSE, + FALSE); + } + else + { + return gimp_preview_new (preview->viewable, + popup_width, + popup_height, + FALSE, + FALSE); + } +} + +static void +gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up) +{ + gdouble ratio; + + if (gimage->width > gimage->height) + { + ratio = (gdouble) width / (gdouble) gimage->width; + } + else + { + ratio = (gdouble) height / (gdouble) gimage->height; + } + + width = RINT (ratio * (gdouble) gimage->width); + height = RINT (ratio * (gdouble) gimage->height); + + if (width < 1) width = 1; + if (height < 1) height = 1; + + *return_width = width; + *return_height = height; + *scaling_up = (ratio > 1.0); +} diff --git a/app/widgets/gimppreviewrendererimage.h b/app/widgets/gimppreviewrendererimage.h new file mode 100644 index 0000000000..4dfa40e6c7 --- /dev/null +++ b/app/widgets/gimppreviewrendererimage.h @@ -0,0 +1,61 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_IMAGE_PREVIEW_H__ +#define __GIMP_IMAGE_PREVIEW_H__ + + +#include "gimppreview.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) +#define GIMP_IMAGE_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) +#define GIMP_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +#define GIMP_IS_IMAGE_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) +#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) + + +typedef struct _GimpImagePreviewClass GimpImagePreviewClass; + +struct _GimpImagePreview +{ + GimpPreview parent_instance; +}; + +struct _GimpImagePreviewClass +{ + GimpPreviewClass parent_class; +}; + + +GtkType gimp_image_preview_get_type (void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_IMAGE_PREVIEW_H__ */ diff --git a/app/widgets/gimpview.c b/app/widgets/gimpview.c index 26cb351387..d15cf4e591 100644 --- a/app/widgets/gimpview.c +++ b/app/widgets/gimpview.c @@ -29,11 +29,12 @@ #include "apptypes.h" -#include "gimpimage.h" #include "gimpbrush.h" #include "gimpbrushpreview.h" #include "gimpdrawable.h" #include "gimpdrawablepreview.h" +#include "gimpimage.h" +#include "gimpimagepreview.h" #include "gimpmarshal.h" #include "gimppattern.h" #include "gimppatternpreview.h" @@ -194,6 +195,17 @@ gimp_preview_init (GimpPreview *preview) static void gimp_preview_destroy (GtkObject *object) { + GimpPreview *preview; + + preview = GIMP_PREVIEW (object); + + if (preview->idle_id) + { + g_source_remove (preview->idle_id); + } + + gimp_preview_popup_hide (preview); + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -220,6 +232,10 @@ gimp_preview_new (GimpViewable *viewable, { preview = gtk_type_new (GIMP_TYPE_DRAWABLE_PREVIEW); } + else if (GIMP_IS_IMAGE (viewable)) + { + preview = gtk_type_new (GIMP_TYPE_IMAGE_PREVIEW); + } else if (GIMP_IS_PATTERN (viewable)) { preview = gtk_type_new (GIMP_TYPE_PATTERN_PREVIEW); @@ -256,16 +272,23 @@ gimp_preview_button_press_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - if (bevent->button == 1) - { - gtk_grab_add (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; - if (preview->show_popup) - { - gimp_preview_popup_show (preview, - bevent->x, - bevent->y); - } + if (bevent->type == GDK_BUTTON_PRESS) + { + if (bevent->button == 1) + { + gtk_grab_add (widget); + + if (preview->show_popup) + { + gimp_preview_popup_show (preview, + bevent->x, + bevent->y); + } + } } return TRUE; @@ -280,17 +303,22 @@ gimp_preview_button_release_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; + if (bevent->button == 1) { - gtk_grab_remove (widget); - if (preview->show_popup) { fast_click = (preview->popup_id != 0); - - gimp_preview_popup_hide (preview); } + gimp_preview_popup_hide (preview); + + /* remove the grab _after_ hiding the popup */ + gtk_grab_remove (widget); + if (preview->clickable && fast_click && preview->in_button) { gtk_signal_emit (GTK_OBJECT (widget), preview_signals[CLICKED]); @@ -486,11 +514,14 @@ static void gimp_preview_paint (GimpPreview *preview) { if (preview->idle_id) - return; + { + g_source_remove (preview->idle_id); + } - preview->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_paint, preview, - NULL); + preview->idle_id = + g_idle_add_full (G_PRIORITY_LOW, + (GSourceFunc) gimp_preview_idle_paint, preview, + NULL); } static gboolean @@ -557,7 +588,7 @@ gimp_preview_idle_paint (GimpPreview *preview) if (has_alpha) { - buf = render_check_buf; + buf = render_check_buf; alpha = ((color) ? ALPHA_PIX : ((channel != -1) ? (temp_buf->bytes - 1) : ALPHA_G_PIX)); diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c index 26cb351387..d15cf4e591 100644 --- a/app/widgets/gimpviewrenderer.c +++ b/app/widgets/gimpviewrenderer.c @@ -29,11 +29,12 @@ #include "apptypes.h" -#include "gimpimage.h" #include "gimpbrush.h" #include "gimpbrushpreview.h" #include "gimpdrawable.h" #include "gimpdrawablepreview.h" +#include "gimpimage.h" +#include "gimpimagepreview.h" #include "gimpmarshal.h" #include "gimppattern.h" #include "gimppatternpreview.h" @@ -194,6 +195,17 @@ gimp_preview_init (GimpPreview *preview) static void gimp_preview_destroy (GtkObject *object) { + GimpPreview *preview; + + preview = GIMP_PREVIEW (object); + + if (preview->idle_id) + { + g_source_remove (preview->idle_id); + } + + gimp_preview_popup_hide (preview); + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -220,6 +232,10 @@ gimp_preview_new (GimpViewable *viewable, { preview = gtk_type_new (GIMP_TYPE_DRAWABLE_PREVIEW); } + else if (GIMP_IS_IMAGE (viewable)) + { + preview = gtk_type_new (GIMP_TYPE_IMAGE_PREVIEW); + } else if (GIMP_IS_PATTERN (viewable)) { preview = gtk_type_new (GIMP_TYPE_PATTERN_PREVIEW); @@ -256,16 +272,23 @@ gimp_preview_button_press_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - if (bevent->button == 1) - { - gtk_grab_add (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; - if (preview->show_popup) - { - gimp_preview_popup_show (preview, - bevent->x, - bevent->y); - } + if (bevent->type == GDK_BUTTON_PRESS) + { + if (bevent->button == 1) + { + gtk_grab_add (widget); + + if (preview->show_popup) + { + gimp_preview_popup_show (preview, + bevent->x, + bevent->y); + } + } } return TRUE; @@ -280,17 +303,22 @@ gimp_preview_button_release_event (GtkWidget *widget, preview = GIMP_PREVIEW (widget); + if (! preview->clickable && + ! preview->show_popup) + return FALSE; + if (bevent->button == 1) { - gtk_grab_remove (widget); - if (preview->show_popup) { fast_click = (preview->popup_id != 0); - - gimp_preview_popup_hide (preview); } + gimp_preview_popup_hide (preview); + + /* remove the grab _after_ hiding the popup */ + gtk_grab_remove (widget); + if (preview->clickable && fast_click && preview->in_button) { gtk_signal_emit (GTK_OBJECT (widget), preview_signals[CLICKED]); @@ -486,11 +514,14 @@ static void gimp_preview_paint (GimpPreview *preview) { if (preview->idle_id) - return; + { + g_source_remove (preview->idle_id); + } - preview->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_paint, preview, - NULL); + preview->idle_id = + g_idle_add_full (G_PRIORITY_LOW, + (GSourceFunc) gimp_preview_idle_paint, preview, + NULL); } static gboolean @@ -557,7 +588,7 @@ gimp_preview_idle_paint (GimpPreview *preview) if (has_alpha) { - buf = render_check_buf; + buf = render_check_buf; alpha = ((color) ? ALPHA_PIX : ((channel != -1) ? (temp_buf->bytes - 1) : ALPHA_G_PIX)); diff --git a/app/widgets/gimpviewrendererdrawable.c b/app/widgets/gimpviewrendererdrawable.c index 460afe8002..468b607793 100644 --- a/app/widgets/gimpviewrendererdrawable.c +++ b/app/widgets/gimpviewrendererdrawable.c @@ -31,6 +31,9 @@ static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static TempBuf * gimp_drawable_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_drawable_preview_create_popup (GimpPreview *preview); + static GimpPreviewClass *parent_class = NULL; @@ -76,3 +79,13 @@ static void gimp_drawable_preview_init (GimpDrawablePreview *preview) { } + +static TempBuf * +gimp_drawable_preview_create_preview (GimpPreview *preview) +{ +} + +static GtkWidget * +gimp_drawable_preview_create_popup (GimpPreview *preview) +{ +} diff --git a/app/widgets/gimpviewrendererimage.c b/app/widgets/gimpviewrendererimage.c new file mode 100644 index 0000000000..1ba2e8f1a5 --- /dev/null +++ b/app/widgets/gimpviewrendererimage.c @@ -0,0 +1,230 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "apptypes.h" + +#include "gimpimage.h" +#include "gimpimagepreview.h" +#include "gimpviewable.h" +#include "temp_buf.h" + + +static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); +static void gimp_image_preview_init (GimpImagePreview *preview); + +static TempBuf * gimp_image_preview_create_preview (GimpPreview *preview); +static GtkWidget * gimp_image_preview_create_popup (GimpPreview *preview); +static void gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up); + + +static GimpPreviewClass *parent_class = NULL; + + +GtkType +gimp_image_preview_get_type (void) +{ + static GtkType preview_type = 0; + + if (! preview_type) + { + GtkTypeInfo preview_info = + { + "GimpImagePreview", + sizeof (GimpImagePreview), + sizeof (GimpImagePreviewClass), + (GtkClassInitFunc) gimp_image_preview_class_init, + (GtkObjectInitFunc) gimp_image_preview_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + preview_type = gtk_type_unique (GIMP_TYPE_PREVIEW, &preview_info); + } + + return preview_type; +} + +static void +gimp_image_preview_class_init (GimpImagePreviewClass *klass) +{ + GtkObjectClass *object_class; + GimpPreviewClass *preview_class; + + object_class = (GtkObjectClass *) klass; + preview_class = (GimpPreviewClass *) klass; + + parent_class = gtk_type_class (GIMP_TYPE_PREVIEW); + + preview_class->create_preview = gimp_image_preview_create_preview; + preview_class->create_popup = gimp_image_preview_create_popup; +} + +static void +gimp_image_preview_init (GimpImagePreview *preview) +{ +} + +static TempBuf * +gimp_image_preview_create_preview (GimpPreview *preview) +{ + GimpImage *gimage; + gint width; + gint height; + gint preview_width; + gint preview_height; + gboolean scaling_up; + TempBuf *return_buf; + + gimage = GIMP_IMAGE (preview->viewable); + + width = GTK_WIDGET (preview)->allocation.width; + height = GTK_WIDGET (preview)->allocation.height; + + gimp_image_preview_calc_size (gimage, + width, + height, + &preview_width, + &preview_height, + &scaling_up); + + if (scaling_up) + { + TempBuf *temp_buf; + + temp_buf = gimp_viewable_get_new_preview (preview->viewable, + gimage->width, + gimage->height); + return_buf = temp_buf_scale (temp_buf, preview_width, preview_height); + + temp_buf_free (temp_buf); + } + else + { + return_buf = gimp_viewable_get_new_preview (preview->viewable, + preview_width, + preview_height); + } + + if (preview_width < width) return_buf->x = (width - preview_width) / 2; + if (preview_height < height) return_buf->y = (height - preview_height) / 2; + + if (return_buf->x || return_buf->y) + { + TempBuf *temp_buf; + guchar white[4] = { 255, 255, 255, 255 }; + + temp_buf = temp_buf_new (width, height, + return_buf->bytes, + 0, 0, + white); + + temp_buf_copy_area (return_buf, temp_buf, + 0, 0, + return_buf->width, + return_buf->height, + return_buf->x, + return_buf->y); + + temp_buf_free (return_buf); + + return temp_buf; + } + + return return_buf; +} + +static GtkWidget * +gimp_image_preview_create_popup (GimpPreview *preview) +{ + GimpImage *gimage; + gint popup_width; + gint popup_height; + gboolean scaling_up; + + gimage = GIMP_IMAGE (preview->viewable); + + gimp_image_preview_calc_size + (gimage, + MIN (GTK_WIDGET (preview)->allocation.width * 2, 256), + MIN (GTK_WIDGET (preview)->allocation.height * 2, 256), + &popup_width, + &popup_height, + &scaling_up); + + if (scaling_up) + { + return gimp_preview_new (preview->viewable, + gimage->width, + gimage->height, + FALSE, + FALSE); + } + else + { + return gimp_preview_new (preview->viewable, + popup_width, + popup_height, + FALSE, + FALSE); + } +} + +static void +gimp_image_preview_calc_size (GimpImage *gimage, + gint width, + gint height, + gint *return_width, + gint *return_height, + gboolean *scaling_up) +{ + gdouble ratio; + + if (gimage->width > gimage->height) + { + ratio = (gdouble) width / (gdouble) gimage->width; + } + else + { + ratio = (gdouble) height / (gdouble) gimage->height; + } + + width = RINT (ratio * (gdouble) gimage->width); + height = RINT (ratio * (gdouble) gimage->height); + + if (width < 1) width = 1; + if (height < 1) height = 1; + + *return_width = width; + *return_height = height; + *scaling_up = (ratio > 1.0); +} diff --git a/app/widgets/gimpviewrendererimage.h b/app/widgets/gimpviewrendererimage.h new file mode 100644 index 0000000000..4dfa40e6c7 --- /dev/null +++ b/app/widgets/gimpviewrendererimage.h @@ -0,0 +1,61 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_IMAGE_PREVIEW_H__ +#define __GIMP_IMAGE_PREVIEW_H__ + + +#include "gimppreview.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) +#define GIMP_IMAGE_PREVIEW(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) +#define GIMP_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +#define GIMP_IS_IMAGE_PREVIEW(obj) (GTK_CHECK_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) +#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) + + +typedef struct _GimpImagePreviewClass GimpImagePreviewClass; + +struct _GimpImagePreview +{ + GimpPreview parent_instance; +}; + +struct _GimpImagePreviewClass +{ + GimpPreviewClass parent_class; +}; + + +GtkType gimp_image_preview_get_type (void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_IMAGE_PREVIEW_H__ */