diff --git a/ChangeLog b/ChangeLog index 124c4edfc7..d9573d052d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,54 @@ +2003-03-01 Michael Natterer + + * app/core/gimpbuffer.c: don't scale the preview up if the + buffer is too small. + + * app/core/gimppattern.c: don't add a white border around the + preview if the pattern is too small. + + * app/widgets/gimppreviewrenderer.[ch]: new object. A buffer + that updates itself on GimpViewable changes and can render + itself to any widget. Basically GimpPreview reduced to the + render and draw code. + + * app/widgets/gimppreview.[ch]: removed all rendering and drawing + code and keep a GimpPreviewRenderer instance. Connect to its + "update" signal for queuing draws on the preview. + + * app/widgets/gimpcellrendererviewable.[ch] + * app/widgets/gimpcontainertreeview.c: same here: removed + rendering and drawing code and keep GimpPreviewRenderers in the + list store. Delays preview creation for GtkTreeViews until the + buffer is really needed for drawing and adds idle preview updating + on viewable changes. + + * app/widgets/gimppreview-utils.[ch] + * app/widgets/gimpbrushpreview.[ch] + * app/widgets/gimpbufferpreview.[ch] + * app/widgets/gimpdrawablepreview.[ch] + * app/widgets/gimpimagepreview.[ch]: removed... + + * app/widgets/gimppreviewrenderer-utils.[ch] + * app/widgets/gimppreviewrendererbrush.[ch] + * app/widgets/gimppreviewrendererdrawable.[ch] + * app/widgets/gimppreviewrendererimage.[ch]: ...and converted to + GimpPreviewRenderer subclasses. + + * app/display/gimpnavigationview.c + * app/gui/palette-import-dialog.c + * app/widgets/Makefile.am + * app/widgets/widgets-enums.h + * app/widgets/widgets-types.h + * app/widgets/gimpchannellistview.c + * app/widgets/gimpcomponentlistitem.c + * app/widgets/gimpcontainergridview.c + * app/widgets/gimpcontainermenuimpl.c + * app/widgets/gimplayerlistitem.c + * app/widgets/gimplistitem.c + * app/widgets/gimpnavigationpreview.[ch] + * app/widgets/gimpselectioneditor.c + * app/widgets/gimpvectorslistview.c: changed accordingly. + 2003-03-01 Michael Natterer * app/tools/gimpblendtool.c: removed useless includes. diff --git a/app/core/gimpbuffer.c b/app/core/gimpbuffer.c index ed13a8cb70..6875a75c87 100644 --- a/app/core/gimpbuffer.c +++ b/app/core/gimpbuffer.c @@ -225,7 +225,6 @@ gimp_buffer_get_new_preview (GimpViewable *viewable, PixelRegion srcPR; PixelRegion destPR; gint bytes; - gint subsample; buffer = GIMP_BUFFER (viewable); buffer_width = tile_manager_width (buffer->tiles); @@ -233,30 +232,48 @@ gimp_buffer_get_new_preview (GimpViewable *viewable, bytes = tile_manager_bpp (buffer->tiles); - /* calculate 'acceptable' subsample */ - subsample = 1; - - while ((width * (subsample + 1) * 2 < buffer_width) && - (height * (subsample + 1) * 2 < buffer_height)) - subsample += 1; - pixel_region_init (&srcPR, buffer->tiles, 0, 0, buffer_width, buffer_height, FALSE); - temp_buf = temp_buf_new (width, height, bytes, 0, 0, NULL); + if (buffer_height > height || buffer_width > width) + temp_buf = temp_buf_new (width, height, bytes, 0, 0, NULL); + else + temp_buf = temp_buf_new (buffer_width, buffer_height, bytes, 0, 0, NULL); destPR.bytes = temp_buf->bytes; destPR.x = 0; destPR.y = 0; - destPR.w = width; - destPR.h = height; - destPR.rowstride = width * destPR.bytes; + destPR.w = temp_buf->width; + destPR.h = temp_buf->height; + destPR.rowstride = temp_buf->width * destPR.bytes; destPR.data = temp_buf_data (temp_buf); - subsample_region (&srcPR, &destPR, subsample); + if (buffer_height > height || buffer_width > width) + { + gint subsample; + + /* calculate 'acceptable' subsample */ + subsample = 1; + + while ((width * (subsample + 1) * 2 < buffer_width) && + (height * (subsample + 1) * 2 < buffer_height)) + subsample += 1; + + subsample_region (&srcPR, &destPR, subsample); + } + else + { + copy_region (&srcPR, &destPR); + } + + if (buffer_width < width) + temp_buf->x = (width - buffer_width) / 2; + + if (buffer_height < height) + temp_buf->y = (height - buffer_height) / 2; return temp_buf; } diff --git a/app/core/gimppattern-load.c b/app/core/gimppattern-load.c index 732fdb5755..2d2b2b7b49 100644 --- a/app/core/gimppattern-load.c +++ b/app/core/gimppattern-load.c @@ -198,28 +198,26 @@ gimp_pattern_get_new_preview (GimpViewable *viewable, { GimpPattern *pattern; TempBuf *temp_buf; - guchar white[MAX_CHANNELS] = { 255, 255, 255, 255 }; gint copy_width; gint copy_height; - gint x, y; pattern = GIMP_PATTERN (viewable); copy_width = MIN (width, pattern->mask->width); copy_height = MIN (height, pattern->mask->height); - x = (copy_width == width) ? 0 : (width - copy_width) / 2; - y = (copy_height == height) ? 0 : (height - copy_height) / 2; - - temp_buf = temp_buf_new (width, height, + temp_buf = temp_buf_new (copy_width, copy_height, pattern->mask->bytes, - 0, 0, - white); + 0, 0, NULL); temp_buf_copy_area (pattern->mask, temp_buf, - 0, 0, - copy_width, copy_height, - x, y); + 0, 0, copy_width, copy_height, 0, 0); + + if (width > copy_width) + temp_buf->x = (width - copy_width) / 2; + + if (height > copy_height) + temp_buf->y = (height - copy_height) / 2; return temp_buf; } diff --git a/app/core/gimppattern.c b/app/core/gimppattern.c index 732fdb5755..2d2b2b7b49 100644 --- a/app/core/gimppattern.c +++ b/app/core/gimppattern.c @@ -198,28 +198,26 @@ gimp_pattern_get_new_preview (GimpViewable *viewable, { GimpPattern *pattern; TempBuf *temp_buf; - guchar white[MAX_CHANNELS] = { 255, 255, 255, 255 }; gint copy_width; gint copy_height; - gint x, y; pattern = GIMP_PATTERN (viewable); copy_width = MIN (width, pattern->mask->width); copy_height = MIN (height, pattern->mask->height); - x = (copy_width == width) ? 0 : (width - copy_width) / 2; - y = (copy_height == height) ? 0 : (height - copy_height) / 2; - - temp_buf = temp_buf_new (width, height, + temp_buf = temp_buf_new (copy_width, copy_height, pattern->mask->bytes, - 0, 0, - white); + 0, 0, NULL); temp_buf_copy_area (pattern->mask, temp_buf, - 0, 0, - copy_width, copy_height, - x, y); + 0, 0, copy_width, copy_height, 0, 0); + + if (width > copy_width) + temp_buf->x = (width - copy_width) / 2; + + if (height > copy_height) + temp_buf->y = (height - copy_height) / 2; return temp_buf; } diff --git a/app/dialogs/palette-import-dialog.c b/app/dialogs/palette-import-dialog.c index 60b738bebd..8d1a894565 100644 --- a/app/dialogs/palette-import-dialog.c +++ b/app/dialogs/palette-import-dialog.c @@ -40,6 +40,7 @@ #include "widgets/gimpcontainermenuimpl.h" #include "widgets/gimpdnd.h" #include "widgets/gimppreview.h" +#include "widgets/gimppreviewrenderer.h" #include "widgets/gimpviewabledialog.h" #include "gradient-select.h" @@ -351,7 +352,7 @@ palette_import_dialog_new (Gimp *gimp) import_dialog->preview = gimp_preview_new_by_type (GIMP_TYPE_PALETTE, 64, 1, TRUE); - GIMP_PREVIEW (import_dialog->preview)->size = -1; + GIMP_PREVIEW (import_dialog->preview)->renderer->size = -1; gimp_preview_set_size_full (GIMP_PREVIEW (import_dialog->preview), 192, 192, 1); gtk_container_add (GTK_CONTAINER (abox), import_dialog->preview); diff --git a/app/display/gimpnavigationeditor.c b/app/display/gimpnavigationeditor.c index 9ee28a6c1f..9d6d8702ec 100644 --- a/app/display/gimpnavigationeditor.c +++ b/app/display/gimpnavigationeditor.c @@ -37,6 +37,7 @@ #include "core/gimpimage.h" #include "widgets/gimpnavigationpreview.h" +#include "widgets/gimppreviewrenderer.h" #include "gimpdisplay.h" #include "gimpdisplayshell.h" @@ -322,10 +323,10 @@ gimp_navigation_view_popup (GimpDisplayShell *shell, * Warping the pointer would be another solution ... */ x = CLAMP (x, 0, (gdk_screen_width () - - GIMP_PREVIEW (preview)->width - + GIMP_PREVIEW (preview)->renderer->width - 4 * widget->style->xthickness)); y = CLAMP (y, 0, (gdk_screen_height () - - GIMP_PREVIEW (preview)->height - + GIMP_PREVIEW (preview)->renderer->height - 4 * widget->style->ythickness)); gtk_window_move (GTK_WINDOW (shell->nav_popup), x, y); @@ -366,7 +367,7 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, gimp_preview_set_size (preview, config->nav_preview_size * 3, - preview->border_width); + preview->renderer->border_width); } else { @@ -478,10 +479,10 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, if (! preview->viewable) return; - if (preview->width > allocation->width || - preview->height > allocation->height || - (preview->width != allocation->width && - preview->height != allocation->height)) + if (preview->renderer->width > allocation->width || + preview->renderer->height > allocation->height || + (preview->renderer->width != allocation->width && + preview->renderer->height != allocation->height)) { GimpNavigationPreview *nav_preview; GimpImage *gimage; @@ -498,7 +499,7 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, GIMP_PREVIEW_MAX_SIZE), MIN (allocation->height, GIMP_PREVIEW_MAX_SIZE), - preview->dot_for_dot, + preview->renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &width, @@ -516,8 +517,8 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, height = height * allocation->height / height; } - gimp_preview_set_size_full (preview, - width, height, preview->border_width); + gimp_preview_set_size_full (preview, width, height, + preview->renderer->border_width); /* FIXME: the GimpNavigationPreview should handle this stuff itself */ @@ -745,7 +746,8 @@ gimp_navigation_view_update_marker (GimpNavigationView *view) xratio = SCALEFACTOR_X (view->shell); yratio = SCALEFACTOR_Y (view->shell); - if (GIMP_PREVIEW (view->preview)->dot_for_dot != view->shell->dot_for_dot) + if (GIMP_PREVIEW (view->preview)->renderer->dot_for_dot != + view->shell->dot_for_dot) gimp_preview_set_dot_for_dot (GIMP_PREVIEW (view->preview), view->shell->dot_for_dot); diff --git a/app/display/gimpnavigationview.c b/app/display/gimpnavigationview.c index 9ee28a6c1f..9d6d8702ec 100644 --- a/app/display/gimpnavigationview.c +++ b/app/display/gimpnavigationview.c @@ -37,6 +37,7 @@ #include "core/gimpimage.h" #include "widgets/gimpnavigationpreview.h" +#include "widgets/gimppreviewrenderer.h" #include "gimpdisplay.h" #include "gimpdisplayshell.h" @@ -322,10 +323,10 @@ gimp_navigation_view_popup (GimpDisplayShell *shell, * Warping the pointer would be another solution ... */ x = CLAMP (x, 0, (gdk_screen_width () - - GIMP_PREVIEW (preview)->width - + GIMP_PREVIEW (preview)->renderer->width - 4 * widget->style->xthickness)); y = CLAMP (y, 0, (gdk_screen_height () - - GIMP_PREVIEW (preview)->height - + GIMP_PREVIEW (preview)->renderer->height - 4 * widget->style->ythickness)); gtk_window_move (GTK_WINDOW (shell->nav_popup), x, y); @@ -366,7 +367,7 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, gimp_preview_set_size (preview, config->nav_preview_size * 3, - preview->border_width); + preview->renderer->border_width); } else { @@ -478,10 +479,10 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, if (! preview->viewable) return; - if (preview->width > allocation->width || - preview->height > allocation->height || - (preview->width != allocation->width && - preview->height != allocation->height)) + if (preview->renderer->width > allocation->width || + preview->renderer->height > allocation->height || + (preview->renderer->width != allocation->width && + preview->renderer->height != allocation->height)) { GimpNavigationPreview *nav_preview; GimpImage *gimage; @@ -498,7 +499,7 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, GIMP_PREVIEW_MAX_SIZE), MIN (allocation->height, GIMP_PREVIEW_MAX_SIZE), - preview->dot_for_dot, + preview->renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &width, @@ -516,8 +517,8 @@ gimp_navigation_view_abox_resized (GtkWidget *widget, height = height * allocation->height / height; } - gimp_preview_set_size_full (preview, - width, height, preview->border_width); + gimp_preview_set_size_full (preview, width, height, + preview->renderer->border_width); /* FIXME: the GimpNavigationPreview should handle this stuff itself */ @@ -745,7 +746,8 @@ gimp_navigation_view_update_marker (GimpNavigationView *view) xratio = SCALEFACTOR_X (view->shell); yratio = SCALEFACTOR_Y (view->shell); - if (GIMP_PREVIEW (view->preview)->dot_for_dot != view->shell->dot_for_dot) + if (GIMP_PREVIEW (view->preview)->renderer->dot_for_dot != + view->shell->dot_for_dot) gimp_preview_set_dot_for_dot (GIMP_PREVIEW (view->preview), view->shell->dot_for_dot); diff --git a/app/gui/palette-import-dialog.c b/app/gui/palette-import-dialog.c index 60b738bebd..8d1a894565 100644 --- a/app/gui/palette-import-dialog.c +++ b/app/gui/palette-import-dialog.c @@ -40,6 +40,7 @@ #include "widgets/gimpcontainermenuimpl.h" #include "widgets/gimpdnd.h" #include "widgets/gimppreview.h" +#include "widgets/gimppreviewrenderer.h" #include "widgets/gimpviewabledialog.h" #include "gradient-select.h" @@ -351,7 +352,7 @@ palette_import_dialog_new (Gimp *gimp) import_dialog->preview = gimp_preview_new_by_type (GIMP_TYPE_PALETTE, 64, 1, TRUE); - GIMP_PREVIEW (import_dialog->preview)->size = -1; + GIMP_PREVIEW (import_dialog->preview)->renderer->size = -1; gimp_preview_set_size_full (GIMP_PREVIEW (import_dialog->preview), 192, 192, 1); gtk_container_add (GTK_CONTAINER (abox), import_dialog->preview); diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index 08c308eb63..a3a2454040 100644 --- a/app/widgets/Makefile.am +++ b/app/widgets/Makefile.am @@ -23,10 +23,6 @@ libappwidgets_a_sources = \ gimpbrusheditor.h \ gimpbrushfactoryview.c \ gimpbrushfactoryview.h \ - gimpbrushpreview.c \ - gimpbrushpreview.h \ - gimpbufferpreview.c \ - gimpbufferpreview.h \ gimpbufferview.c \ gimpbufferview.h \ gimpcellrendererviewable.c \ @@ -85,8 +81,6 @@ libappwidgets_a_sources = \ gimpdrawablelistitem.h \ gimpdrawablelistview.c \ gimpdrawablelistview.h \ - gimpdrawablepreview.c \ - gimpdrawablepreview.h \ gimpeditor.c \ gimpeditor.h \ gimpenummenu.c \ @@ -107,8 +101,6 @@ libappwidgets_a_sources = \ gimpimagedock.h \ gimpimageeditor.c \ gimpimageeditor.h \ - gimpimagepreview.c \ - gimpimagepreview.h \ gimpimageview.c \ gimpimageview.h \ gimpitemfactory.c \ @@ -135,8 +127,16 @@ libappwidgets_a_sources = \ gimppreview.h \ gimppreview-popup.c \ gimppreview-popup.h \ - gimppreview-utils.c \ - gimppreview-utils.h \ + gimppreviewrenderer.c \ + gimppreviewrenderer.h \ + gimppreviewrenderer-utils.c \ + gimppreviewrenderer-utils.h \ + gimppreviewrendererbrush.c \ + gimppreviewrendererbrush.h \ + gimppreviewrendererdrawable.c \ + gimppreviewrendererdrawable.h \ + gimppreviewrendererimage.c \ + gimppreviewrendererimage.h \ gimppropwidgets.c \ gimppropwidgets.h \ gimpselectioneditor.c \ diff --git a/app/widgets/gimpbrushpreview.c b/app/widgets/gimpbrushpreview.c deleted file mode 100644 index c73639d8ee..0000000000 --- a/app/widgets/gimpbrushpreview.c +++ /dev/null @@ -1,336 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpbrushpreview.c - * 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 "widgets-types.h" - -#include "base/temp-buf.h" - -#include "core/gimpbrush.h" -#include "core/gimpbrushpipe.h" - -#include "gimpbrushpreview.h" -#include "gimpdnd.h" - - -static void gimp_brush_preview_class_init (GimpBrushPreviewClass *klass); -static void gimp_brush_preview_init (GimpBrushPreview *preview); - -static void gimp_brush_preview_destroy (GtkObject *object); -static void gimp_brush_preview_render (GimpPreview *preview); - -static gboolean gimp_brush_preview_render_timeout (gpointer data); - - -static GimpPreviewClass *parent_class = NULL; - - -GType -gimp_brush_preview_get_type (void) -{ - static GType preview_type = 0; - - if (! preview_type) - { - static const GTypeInfo preview_info = - { - sizeof (GimpBrushPreviewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gimp_brush_preview_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpBrushPreview), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_brush_preview_init, - }; - - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpBrushPreview", - &preview_info, 0); - } - - return preview_type; -} - -static void -gimp_brush_preview_class_init (GimpBrushPreviewClass *klass) -{ - GtkObjectClass *object_class; - GimpPreviewClass *preview_class; - - object_class = GTK_OBJECT_CLASS (klass); - preview_class = GIMP_PREVIEW_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->destroy = gimp_brush_preview_destroy; - - preview_class->render = gimp_brush_preview_render; -} - -static void -gimp_brush_preview_init (GimpBrushPreview *brush_preview) -{ - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; -} - -static void -gimp_brush_preview_destroy (GtkObject *object) -{ - GimpBrushPreview *brush_preview; - - brush_preview = GIMP_BRUSH_PREVIEW (object); - - if (brush_preview->pipe_timeout_id) - { - g_source_remove (brush_preview->pipe_timeout_id); - - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; - } - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -gimp_brush_preview_render (GimpPreview *preview) -{ - GimpBrushPreview *brush_preview; - GimpBrush *brush; - TempBuf *temp_buf; - gint width; - gint height; - gint brush_width; - gint brush_height; - - brush_preview = GIMP_BRUSH_PREVIEW (preview); - - if (brush_preview->pipe_timeout_id) - { - g_source_remove (brush_preview->pipe_timeout_id); - brush_preview->pipe_timeout_id = 0; - } - - brush = GIMP_BRUSH (preview->viewable); - brush_width = brush->mask->width; - brush_height = brush->mask->height; - - width = preview->width; - height = preview->height; - - temp_buf = gimp_viewable_get_new_preview (preview->viewable, - width, height); - - if (temp_buf->width < width) - temp_buf->x = (width - temp_buf->width) / 2; - - if (temp_buf->height < height) - temp_buf->y = (height - temp_buf->height) / 2; - - if (preview->is_popup) - { - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); - - temp_buf_free (temp_buf); - - if (GIMP_IS_BRUSH_PIPE (brush)) - { - if (width != brush_width || height != brush_height) - { - g_warning ("%s(): non-fullsize pipe popups are not supported yet.", - G_GNUC_FUNCTION); - return; - } - - brush_preview->pipe_animation_index = 0; - brush_preview->pipe_timeout_id = - g_timeout_add (300, gimp_brush_preview_render_timeout, - brush_preview); - } - - return; - } - -#define INDICATOR_WIDTH 7 -#define INDICATOR_HEIGHT 7 - - if (temp_buf->width >= INDICATOR_WIDTH && - temp_buf->height >= INDICATOR_HEIGHT && - (width < brush_width || - height < brush_height || - GIMP_IS_BRUSH_PIPE (brush))) - { -#define WHT { 255, 255, 255 } -#define BLK { 0, 0, 0 } -#define RED { 255, 127, 127 } - - static const guchar scale_indicator_bits[7][7][3] = - { - { WHT, WHT, WHT, WHT, WHT, WHT, WHT }, - { WHT, WHT, WHT, BLK, WHT, WHT, WHT }, - { WHT, WHT, WHT, BLK, WHT, WHT, WHT }, - { WHT, BLK, BLK, BLK, BLK, BLK, WHT }, - { WHT, WHT, WHT, BLK, WHT, WHT, WHT }, - { WHT, WHT, WHT, BLK, WHT, WHT, WHT }, - { WHT, WHT, WHT, WHT, WHT, WHT, WHT } - }; - - static const guchar scale_pipe_indicator_bits[7][7][3] = - { - { WHT, WHT, WHT, WHT, WHT, WHT, WHT }, - { WHT, WHT, WHT, BLK, WHT, WHT, RED }, - { WHT, WHT, WHT, BLK, WHT, RED, RED }, - { WHT, BLK, BLK, BLK, BLK, BLK, RED }, - { WHT, WHT, WHT, BLK, RED, RED, RED }, - { WHT, WHT, RED, BLK, RED, RED, RED }, - { WHT, RED, RED, RED, RED, RED, RED } - }; - - static const guchar pipe_indicator_bits[7][7][3] = - { - { WHT, WHT, WHT, WHT, WHT, WHT, WHT }, - { WHT, WHT, WHT, WHT, WHT, WHT, RED }, - { WHT, WHT, WHT, WHT, WHT, RED, RED }, - { WHT, WHT, WHT, WHT, RED, RED, RED }, - { WHT, WHT, WHT, RED, RED, RED, RED }, - { WHT, WHT, RED, RED, RED, RED, RED }, - { WHT, RED, RED, RED, RED, RED, RED } - }; - -#undef WHT -#undef BLK -#undef RED - - guchar *buf; - gint x, y; - gint offset_x; - gint offset_y; - gboolean alpha; - gboolean pipe; - gboolean scale; - - buf = temp_buf_data (temp_buf); - - offset_x = temp_buf->width - INDICATOR_WIDTH; - offset_y = temp_buf->height - INDICATOR_HEIGHT; - - buf += (offset_y * temp_buf->width + offset_x) * temp_buf->bytes; - - pipe = GIMP_IS_BRUSH_PIPE (brush); - scale = (width < brush_width || height < brush_height); - alpha = (temp_buf->bytes == 4); - - for (y = 0; y < INDICATOR_HEIGHT; y++) - { - for (x = 0; x < INDICATOR_WIDTH; x++) - { - if (scale) - { - if (pipe) - { - *buf++ = scale_pipe_indicator_bits[y][x][0]; - *buf++ = scale_pipe_indicator_bits[y][x][1]; - *buf++ = scale_pipe_indicator_bits[y][x][2]; - } - else - { - *buf++ = scale_indicator_bits[y][x][0]; - *buf++ = scale_indicator_bits[y][x][1]; - *buf++ = scale_indicator_bits[y][x][2]; - } - } - else if (pipe) - { - *buf++ = pipe_indicator_bits[y][x][0]; - *buf++ = pipe_indicator_bits[y][x][1]; - *buf++ = pipe_indicator_bits[y][x][2]; - } - - if (alpha) - *buf++ = 255; - } - - buf += (temp_buf->width - INDICATOR_WIDTH) * temp_buf->bytes; - } - } - -#undef INDICATOR_WIDTH -#undef INDICATOR_HEIGHT - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); - - temp_buf_free (temp_buf); -} - -static gboolean -gimp_brush_preview_render_timeout (gpointer data) -{ - GimpBrushPreview *brush_preview; - GimpPreview *preview; - GimpBrushPipe *brush_pipe; - GimpBrush *brush; - TempBuf *temp_buf; - - brush_preview = GIMP_BRUSH_PREVIEW (data); - - preview = GIMP_PREVIEW (brush_preview); - - if (! preview->viewable) - { - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; - - return FALSE; - } - - brush_pipe = GIMP_BRUSH_PIPE (preview->viewable); - - brush_preview->pipe_animation_index++; - - if (brush_preview->pipe_animation_index >= brush_pipe->nbrushes) - brush_preview->pipe_animation_index = 0; - - brush = - GIMP_BRUSH (brush_pipe->brushes[brush_preview->pipe_animation_index]); - - temp_buf = gimp_viewable_get_new_preview (GIMP_VIEWABLE (brush), - preview->width, - preview->height); - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); - - temp_buf_free (temp_buf); - - gtk_widget_queue_draw (GTK_WIDGET (preview)); - - return TRUE; -} diff --git a/app/widgets/gimpbrushpreview.h b/app/widgets/gimpbrushpreview.h deleted file mode 100644 index b626748a95..0000000000 --- a/app/widgets/gimpbrushpreview.h +++ /dev/null @@ -1,55 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpbrushpreview.h - * 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_BRUSH_PREVIEW_H__ -#define __GIMP_BRUSH_PREVIEW_H__ - -#include "gimppreview.h" - - -#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ()) -#define GIMP_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview)) -#define GIMP_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) -#define GIMP_IS_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_BRUSH_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) - - -typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass; - -struct _GimpBrushPreview -{ - GimpPreview parent_instance; - - guint pipe_timeout_id; - gint pipe_animation_index; -}; - -struct _GimpBrushPreviewClass -{ - GimpPreviewClass parent_class; -}; - - -GType gimp_brush_preview_get_type (void) G_GNUC_CONST; - - -#endif /* __GIMP_BRUSH_PREVIEW_H__ */ diff --git a/app/widgets/gimpbufferpreview.c b/app/widgets/gimpbufferpreview.c deleted file mode 100644 index 48f770c719..0000000000 --- a/app/widgets/gimpbufferpreview.c +++ /dev/null @@ -1,153 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpbufferpreview.c - * 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 "widgets-types.h" - -#include "base/temp-buf.h" - -#include "core/gimpbuffer.h" - -#include "gimpbufferpreview.h" - - -static void gimp_buffer_preview_class_init (GimpBufferPreviewClass *klass); -static void gimp_buffer_preview_init (GimpBufferPreview *preview); - -static void gimp_buffer_preview_render (GimpPreview *preview); - - -static GimpPreviewClass *parent_class = NULL; - - -GType -gimp_buffer_preview_get_type (void) -{ - static GType preview_type = 0; - - if (! preview_type) - { - static const GTypeInfo preview_info = - { - sizeof (GimpBufferPreviewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gimp_buffer_preview_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpBufferPreview), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_buffer_preview_init, - }; - - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpBufferPreview", - &preview_info, 0); - } - - return preview_type; -} - -static void -gimp_buffer_preview_class_init (GimpBufferPreviewClass *klass) -{ - GimpPreviewClass *preview_class; - - preview_class = GIMP_PREVIEW_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - preview_class->render = gimp_buffer_preview_render; -} - -static void -gimp_buffer_preview_init (GimpBufferPreview *buffer_preview) -{ -} - -static void -gimp_buffer_preview_render (GimpPreview *preview) -{ - GimpBuffer *buffer; - gint buffer_width; - gint buffer_height; - gint width; - gint height; - gint preview_width; - gint preview_height; - gboolean scaling_up; - TempBuf *render_buf; - - buffer = GIMP_BUFFER (preview->viewable); - - buffer_width = gimp_buffer_get_width (buffer); - buffer_height = gimp_buffer_get_height (buffer); - - width = preview->width; - height = preview->height; - - gimp_viewable_calc_preview_size (preview->viewable, - buffer_width, - buffer_height, - width, - height, - preview->dot_for_dot, - 1.0, - 1.0, - &preview_width, - &preview_height, - &scaling_up); - - if (scaling_up) - { - TempBuf *temp_buf; - - temp_buf = gimp_viewable_get_new_preview (preview->viewable, - buffer_width, - buffer_height); - render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); - - temp_buf_free (temp_buf); - } - else - { - render_buf = gimp_viewable_get_new_preview (preview->viewable, - preview_width, - preview_height); - } - - if (preview_width < width) - render_buf->x = (width - preview_width) / 2; - - if (preview_height < height) - render_buf->y = (height - preview_height) / 2; - - gimp_preview_render_preview (preview, - render_buf, - -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); - - temp_buf_free (render_buf); -} diff --git a/app/widgets/gimpbufferpreview.h b/app/widgets/gimpbufferpreview.h deleted file mode 100644 index 3561eda626..0000000000 --- a/app/widgets/gimpbufferpreview.h +++ /dev/null @@ -1,52 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpbufferpreview.h - * 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_BUFFER_PREVIEW_H__ -#define __GIMP_BUFFER_PREVIEW_H__ - -#include "gimppreview.h" - - -#define GIMP_TYPE_BUFFER_PREVIEW (gimp_buffer_preview_get_type ()) -#define GIMP_BUFFER_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BUFFER_PREVIEW, GimpBufferPreview)) -#define GIMP_BUFFER_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BUFFER_PREVIEW, GimpBufferPreviewClass)) -#define GIMP_IS_BUFFER_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_BUFFER_PREVIEW)) -#define GIMP_IS_BUFFER_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BUFFER_PREVIEW)) -#define GIMP_BUFFER_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BUFFER_PREVIEW, GimpBufferPreviewClass)) - - -typedef struct _GimpBufferPreviewClass GimpBufferPreviewClass; - -struct _GimpBufferPreview -{ - GimpPreview parent_instance; -}; - -struct _GimpBufferPreviewClass -{ - GimpPreviewClass parent_class; -}; - - -GType gimp_buffer_preview_get_type (void) G_GNUC_CONST; - - -#endif /* __GIMP_BUFFER_PREVIEW_H__ */ diff --git a/app/widgets/gimpcellrendererviewable.c b/app/widgets/gimpcellrendererviewable.c index 86677f7c42..dbd3d525c8 100644 --- a/app/widgets/gimpcellrendererviewable.c +++ b/app/widgets/gimpcellrendererviewable.c @@ -29,13 +29,13 @@ #include "gimpcellrendererviewable.h" #include "gimppreview-popup.h" +#include "gimppreviewrenderer.h" enum { PROP_0, - PROP_VIEWABLE, - PROP_PREVIEW_SIZE + PROP_RENDERER }; @@ -73,7 +73,7 @@ static gboolean gimp_cell_renderer_viewable_activate (GtkCellRenderer *cell, GtkCellRendererState flags); -GtkCellRendererPixbufClass *parent_class = NULL; +GtkCellRendererClass *parent_class = NULL; GType @@ -96,7 +96,7 @@ gimp_cell_renderer_viewable_get_type (void) (GInstanceInitFunc) gimp_cell_renderer_viewable_init, }; - cell_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_PIXBUF, + cell_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererViewable", &cell_info, 0); } @@ -123,18 +123,11 @@ gimp_cell_renderer_viewable_class_init (GimpCellRendererViewableClass *klass) cell_class->activate = gimp_cell_renderer_viewable_activate; g_object_class_install_property (object_class, - PROP_VIEWABLE, - g_param_spec_object ("viewable", + PROP_RENDERER, + g_param_spec_object ("renderer", NULL, NULL, - GIMP_TYPE_VIEWABLE, + GIMP_TYPE_PREVIEW_RENDERER, G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_PREVIEW_SIZE, - g_param_spec_int ("preview-size", - NULL, NULL, - 0, 1024, 16, - G_PARAM_READWRITE)); } static void @@ -155,12 +148,8 @@ gimp_cell_renderer_viewable_get_property (GObject *object, switch (param_id) { - case PROP_VIEWABLE: - g_value_set_object (value, cell->viewable); - break; - - case PROP_PREVIEW_SIZE: - g_value_set_int (value, cell->preview_size); + case PROP_RENDERER: + g_value_set_object (value, cell->renderer); break; default: @@ -176,25 +165,15 @@ gimp_cell_renderer_viewable_set_property (GObject *object, GParamSpec *pspec) { GimpCellRendererViewable *cell; - GimpViewable *viewable; cell = GIMP_CELL_RENDERER_VIEWABLE (object); switch (param_id) { - case PROP_VIEWABLE: - viewable = (GimpViewable *) g_value_get_object (value); - if (cell->viewable) - g_object_remove_weak_pointer (G_OBJECT (cell->viewable), - (gpointer) &cell->viewable); - cell->viewable = viewable; - if (cell->viewable) - g_object_add_weak_pointer (G_OBJECT (cell->viewable), - (gpointer) &cell->viewable); - break; - - case PROP_PREVIEW_SIZE: - cell->preview_size = g_value_get_int (value); + case PROP_RENDERER: + if (cell->renderer) + g_object_unref (cell->renderer); + cell->renderer = (GimpPreviewRenderer *) g_value_dup_object (value); break; default: @@ -220,18 +199,12 @@ gimp_cell_renderer_viewable_get_size (GtkCellRenderer *cell, cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell); - if (cellviewable->viewable) + if (cellviewable->renderer) { - gimp_viewable_get_preview_size (cellviewable->viewable, - cellviewable->preview_size, - FALSE, TRUE, - &preview_width, - &preview_height); - } - else - { - preview_width = cellviewable->preview_size; - preview_height = cellviewable->preview_size; + preview_width = (cellviewable->renderer->width + + 2 * cellviewable->renderer->border_width); + preview_height = (cellviewable->renderer->height + + 2 * cellviewable->renderer->border_width); } calc_width = (gint) GTK_CELL_RENDERER (cell)->xpad * 2 + preview_width; @@ -274,98 +247,12 @@ gimp_cell_renderer_viewable_render (GtkCellRenderer *cell, GtkCellRendererState flags) { GimpCellRendererViewable *cellviewable; - GtkCellRendererPixbuf *cellpixbuf; cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell); - cellpixbuf = GTK_CELL_RENDERER_PIXBUF (cell); - if (! cellpixbuf->pixbuf && cellviewable->viewable) - { - GimpViewable *viewable; - GtkIconSet *icon_set; - GtkIconSize *sizes; - gint n_sizes; - gint i; - gint width_diff = 1024; - gint height_diff = 1024; - GtkIconSize icon_size = GTK_ICON_SIZE_MENU; - GdkPixbuf *pixbuf; - const gchar *stock_id; - - viewable = cellviewable->viewable; - - stock_id = gimp_viewable_get_stock_id (viewable); - icon_set = gtk_style_lookup_icon_set (widget->style, stock_id); - - gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes); - - for (i = 0; i < n_sizes; i++) - { - gint width; - gint height; - - if (gtk_icon_size_lookup (sizes[i], &width, &height)) - { - if (width <= cell_area->width && - height <= cell_area->height && - (ABS (width - cell_area->width) < width_diff || - ABS (height - cell_area->height) < height_diff)) - { - width_diff = ABS (width - cell_area->width); - height_diff = ABS (height - cell_area->height); - - icon_size = sizes[i]; - } - } - } - - g_free (sizes); - - pixbuf = gtk_icon_set_render_icon (icon_set, - widget->style, - gtk_widget_get_direction (widget), - widget->state, - GTK_ICON_SIZE_DIALOG, - widget, NULL); - - if (pixbuf) - { - if (gdk_pixbuf_get_width (pixbuf) > cell_area->width || - gdk_pixbuf_get_height (pixbuf) > cell_area->height) - { - GdkPixbuf *scaled_pixbuf; - gint pixbuf_width; - gint pixbuf_height; - - gimp_viewable_calc_preview_size (viewable, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - cell_area->width, - cell_area->height, - TRUE, 1.0, 1.0, - &pixbuf_width, - &pixbuf_height, - NULL); - - scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, - pixbuf_width, - pixbuf_height, - GDK_INTERP_BILINEAR); - - g_object_unref (pixbuf); - pixbuf = scaled_pixbuf; - } - - g_object_set (cell, "pixbuf", pixbuf, NULL); - g_object_unref (pixbuf); - } - } - - GTK_CELL_RENDERER_CLASS (parent_class)->render (cell, window, widget, - background_area, - cell_area, - expose_area, - flags); + if (cellviewable->renderer) + gimp_preview_renderer_draw (cellviewable->renderer, window, widget, + cell_area, expose_area); } static gboolean @@ -381,25 +268,18 @@ gimp_cell_renderer_viewable_activate (GtkCellRenderer *cell, cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell); - if (cellviewable->viewable && - ((GdkEventAny *) event)->type == GDK_BUTTON_PRESS && - ((GdkEventButton *) event)->button == 1) + if (cellviewable->renderer && event) { - gint preview_width; - gint preview_height; - - gimp_viewable_get_preview_size (cellviewable->viewable, - cellviewable->preview_size, - FALSE, TRUE, - &preview_width, - &preview_height); - - return gimp_preview_popup_show (widget, - (GdkEventButton *) event, - cellviewable->viewable, - preview_width, - preview_height, - TRUE); + if (((GdkEventAny *) event)->type == GDK_BUTTON_PRESS && + ((GdkEventButton *) event)->button == 1) + { + return gimp_preview_popup_show (widget, + (GdkEventButton *) event, + cellviewable->renderer->viewable, + cellviewable->renderer->width, + cellviewable->renderer->height, + TRUE); + } } return FALSE; diff --git a/app/widgets/gimpcellrendererviewable.h b/app/widgets/gimpcellrendererviewable.h index dfb3d26a88..11544c7d28 100644 --- a/app/widgets/gimpcellrendererviewable.h +++ b/app/widgets/gimpcellrendererviewable.h @@ -23,7 +23,7 @@ #define __GIMP_CELL_RENDERER_PIXBUF_H__ -#include +#include #define GIMP_TYPE_CELL_RENDERER_VIEWABLE (gimp_cell_renderer_viewable_get_type ()) @@ -38,15 +38,14 @@ typedef struct _GimpCellRendererViewableClass GimpCellRendererViewableClass; struct _GimpCellRendererViewable { - GtkCellRendererPixbuf parent_instance; + GtkCellRenderer parent_instance; - GimpViewable *viewable; - gint preview_size; + GimpPreviewRenderer *renderer; }; struct _GimpCellRendererViewableClass { - GtkCellRendererPixbufClass parent_class; + GtkCellRendererClass parent_class; }; diff --git a/app/widgets/gimpchannellistview.c b/app/widgets/gimpchannellistview.c index 4aa89e6a99..99183714a0 100644 --- a/app/widgets/gimpchannellistview.c +++ b/app/widgets/gimpchannellistview.c @@ -41,7 +41,6 @@ #include "gimpchannellistview.h" #include "gimpcomponentlistitem.h" #include "gimpdnd.h" -#include "gimpimagepreview.h" #include "gimplistitem.h" #include "gimpwidgets-utils.h" diff --git a/app/widgets/gimpchanneltreeview.c b/app/widgets/gimpchanneltreeview.c index 4aa89e6a99..99183714a0 100644 --- a/app/widgets/gimpchanneltreeview.c +++ b/app/widgets/gimpchanneltreeview.c @@ -41,7 +41,6 @@ #include "gimpchannellistview.h" #include "gimpcomponentlistitem.h" #include "gimpdnd.h" -#include "gimpimagepreview.h" #include "gimplistitem.h" #include "gimpwidgets-utils.h" diff --git a/app/widgets/gimpcomponentlistitem.c b/app/widgets/gimpcomponentlistitem.c index ee82ac6603..c0820bcf33 100644 --- a/app/widgets/gimpcomponentlistitem.c +++ b/app/widgets/gimpcomponentlistitem.c @@ -32,8 +32,8 @@ #include "gimpcomponentlistitem.h" #include "gimpdnd.h" -#include "gimpimagepreview.h" #include "gimppreview.h" +#include "gimppreviewrendererimage.h" #include "libgimp/gimpintl.h" @@ -219,7 +219,7 @@ gimp_component_list_item_set_viewable (GimpListItem *list_item, g_assert_not_reached (); } - GIMP_IMAGE_PREVIEW (list_item->preview)->channel = pixel; + GIMP_PREVIEW_RENDERER_IMAGE (GIMP_PREVIEW (list_item->preview)->renderer)->channel = pixel; if (! visible) { diff --git a/app/widgets/gimpcontainergridview.c b/app/widgets/gimpcontainergridview.c index 0795361899..5b90111ac9 100644 --- a/app/widgets/gimpcontainergridview.c +++ b/app/widgets/gimpcontainergridview.c @@ -34,6 +34,7 @@ #include "gimpcontainergridview.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" #include "gtkhwrapbox.h" #include "libgimp/gimpintl.h" @@ -229,8 +230,7 @@ gimp_container_grid_view_insert_item (GimpContainerView *view, view->preview_size, 1, FALSE, TRUE, TRUE); - - GIMP_PREVIEW (preview)->border_color = white_color; + gimp_preview_set_border_color (GIMP_PREVIEW (preview), &white_color); gtk_wrap_box_pack (GTK_WRAP_BOX (grid_view->wrap_box), preview, FALSE, FALSE, FALSE, FALSE); @@ -335,7 +335,8 @@ gimp_container_grid_view_set_preview_size (GimpContainerView *view) preview = GIMP_PREVIEW (child->widget); - gimp_preview_set_size (preview, view->preview_size, preview->border_width); + gimp_preview_set_size (preview, view->preview_size, + preview->renderer->border_width); } gtk_widget_queue_resize (grid_view->wrap_box); diff --git a/app/widgets/gimpcontainermenuimpl.c b/app/widgets/gimpcontainermenuimpl.c index 814c84f21c..7dc91dc23d 100644 --- a/app/widgets/gimpcontainermenuimpl.c +++ b/app/widgets/gimpcontainermenuimpl.c @@ -33,6 +33,7 @@ #include "gimpcontainermenuimpl.h" #include "gimpmenuitem.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" static void gimp_container_menu_impl_class_init (GimpContainerMenuImplClass *klass); @@ -294,7 +295,7 @@ gimp_container_menu_impl_set_preview_size (GimpContainerMenu *menu) gimp_preview_set_size (GIMP_PREVIEW (menu_item->preview), menu->preview_size, - GIMP_PREVIEW (menu_item->preview)->border_width); + GIMP_PREVIEW (menu_item->preview)->renderer->border_width); } } } diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c index f3f6d9f2f0..b444e2670b 100644 --- a/app/widgets/gimpcontainertreeview.c +++ b/app/widgets/gimpcontainertreeview.c @@ -35,12 +35,13 @@ #include "gimpcontainertreeview.h" #include "gimpdnd.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" enum { COLUMN_VIEWABLE, - COLUMN_PIXBUF, + COLUMN_RENDERER, COLUMN_NAME, NUM_COLUMNS }; @@ -74,16 +75,8 @@ static gboolean gimp_container_tree_view_button_press (GtkWidget *w GdkEventButton *bevent, GimpContainerTreeView *tree_view); -#if 0 -static void gimp_container_tree_view_rows_reordered (GtkTreeModel *tree_model, - GtkTreePath *path, - GtkTreeIter *iter, - gint *new_order, - GimpContainerTreeView *tree_view); -#endif - -static void gimp_container_tree_view_invalidate_preview (GimpViewable *viewable, - GimpContainerTreeView *tree_view); +static void gimp_container_tree_view_renderer_update (GimpPreviewRenderer *renderer, + GimpContainerTreeView *tree_view); static void gimp_container_tree_view_name_changed (GimpObject *object, GimpContainerTreeView *tree_view); @@ -142,75 +135,6 @@ gimp_container_tree_view_class_init (GimpContainerTreeViewClass *klass) container_view_class->insert_data_free = (GDestroyNotify) g_free; } -static void -gimp_container_tree_view_set_viewable_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GimpContainerTreeView *tree_view; - GimpViewable *viewable; - GdkPixbuf *pixbuf; - gint preview_size; - - tree_view = GIMP_CONTAINER_TREE_VIEW (data); - - gtk_tree_model_get (GTK_TREE_MODEL (tree_view->list), iter, - COLUMN_VIEWABLE, &viewable, - COLUMN_PIXBUF, &pixbuf, - -1); - - preview_size = GIMP_CONTAINER_VIEW (tree_view)->preview_size; - - if (! pixbuf && GTK_WIDGET_DRAWABLE (tree_view)) - { - TempBuf *temp_buf; - gint width; - gint height; - - gimp_viewable_get_preview_size (viewable, preview_size, - FALSE, TRUE, - &width, &height); - - temp_buf = gimp_viewable_get_preview (viewable, width, height); - - if (temp_buf) - { - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, - temp_buf->width, - temp_buf->height); - - gimp_preview_render_to_buffer (temp_buf, -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE, - gdk_pixbuf_get_pixels (pixbuf), - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - gdk_pixbuf_get_rowstride (pixbuf)); - } - - if (pixbuf) - { - gtk_list_store_set (tree_view->list, iter, - COLUMN_PIXBUF, pixbuf, - -1); - return; - } - } - - g_object_set (cell, - "viewable", viewable, - "preview-size", preview_size, - "pixbuf", pixbuf, - NULL); - - g_object_unref (viewable); - - if (pixbuf) - g_object_unref (pixbuf); -} - static void gimp_container_tree_view_init (GimpContainerTreeView *tree_view) { @@ -229,7 +153,7 @@ gimp_container_tree_view_init (GimpContainerTreeView *tree_view) tree_view->list = gtk_list_store_new (NUM_COLUMNS, GIMP_TYPE_VIEWABLE, - GDK_TYPE_PIXBUF, + GIMP_TYPE_PREVIEW_RENDERER, G_TYPE_STRING); tree_view->view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_view->list))); @@ -245,9 +169,9 @@ gimp_container_tree_view_init (GimpContainerTreeView *tree_view) cell = gimp_cell_renderer_viewable_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_set_cell_data_func (column, cell, - gimp_container_tree_view_set_viewable_func, - tree_view, NULL); + gtk_tree_view_column_set_attributes (column, cell, + "renderer", COLUMN_RENDERER, + NULL); gtk_tree_view_insert_column_with_attributes (tree_view->view, 1, NULL, @@ -311,57 +235,39 @@ gimp_container_tree_view_new (GimpContainer *container, if (context) gimp_container_view_set_context (view, context); -#if 0 - if (reorderable) - { - gtk_tree_view_set_reorderable (tree_view->view, TRUE); - - g_signal_connect (tree_view->list, "rows_reordered", - G_CALLBACK (gimp_container_tree_view_rows_reordered), - tree_view); - } -#endif - return GTK_WIDGET (tree_view); } - static void gimp_container_tree_view_set (GimpContainerTreeView *tree_view, GtkTreeIter *iter, - GimpViewable *viewable, - gboolean set_preview, - gboolean set_name) + GimpViewable *viewable) { - GimpContainerView *view; - gchar *name = NULL; + GimpContainerView *view; + GimpPreviewRenderer *renderer; + gchar *name; view = GIMP_CONTAINER_VIEW (tree_view); - if (set_name) - { - if (view->get_name_func) - name = view->get_name_func (G_OBJECT (viewable), NULL); - else - name = g_strdup (gimp_object_get_name (GIMP_OBJECT (viewable))); - } + if (view->get_name_func) + name = view->get_name_func (G_OBJECT (viewable), NULL); + else + name = g_strdup (gimp_object_get_name (GIMP_OBJECT (viewable))); - if (! (set_preview || name)) - return; + renderer = gimp_preview_renderer_new (viewable, view->preview_size, 1, FALSE); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_container_tree_view_renderer_update), + tree_view); gtk_list_store_set (tree_view->list, iter, COLUMN_VIEWABLE, viewable, - - set_preview ? COLUMN_PIXBUF : COLUMN_NAME, - set_preview ? NULL : (gpointer) name, - - set_preview ? (name ? COLUMN_NAME : -1) : -1, - set_preview ? (name ? name : NULL) : NULL, - + COLUMN_RENDERER, renderer, + COLUMN_NAME, name, -1); - if (name) - g_free (name); + g_object_unref (renderer); + g_free (name); } /* GimpContainerView methods */ @@ -376,8 +282,6 @@ gimp_container_tree_view_set_container (GimpContainerView *view, if (view->container) { - gimp_container_remove_handler (view->container, - tree_view->invalidate_preview_handler_id); gimp_container_remove_handler (view->container, tree_view->name_changed_handler_id); @@ -421,11 +325,6 @@ gimp_container_tree_view_set_container (GimpContainerView *view, { GimpViewableClass *viewable_class; - tree_view->invalidate_preview_handler_id = - gimp_container_add_handler (view->container, "invalidate_preview", - G_CALLBACK (gimp_container_tree_view_invalidate_preview), - tree_view); - viewable_class = g_type_class_ref (container->children_type); tree_view->name_changed_handler_id = @@ -455,7 +354,7 @@ gimp_container_tree_view_insert_item (GimpContainerView *view, else gtk_list_store_insert (tree_view->list, iter, index); - gimp_container_tree_view_set (tree_view, iter, viewable, TRUE, TRUE); + gimp_container_tree_view_set (tree_view, iter, viewable); return (gpointer) iter; } @@ -529,7 +428,7 @@ gimp_container_tree_view_reorder_item (GimpContainerView *view, else gtk_list_store_insert (tree_view->list, iter, new_index); - gimp_container_tree_view_set (tree_view, iter, viewable, TRUE, TRUE); + gimp_container_tree_view_set (tree_view, iter, viewable); if (selected) { @@ -646,9 +545,19 @@ gimp_container_tree_view_set_preview_size (GimpContainerView *view) { do { - gtk_list_store_set (tree_view->list, &iter, - COLUMN_PIXBUF, NULL, + GimpPreviewRenderer *renderer; + + gtk_tree_model_get (GTK_TREE_MODEL (tree_view->list), &iter, + COLUMN_RENDERER, &renderer, -1); + + gimp_preview_renderer_set_size (renderer, view->preview_size, 1); + + gtk_list_store_set (tree_view->list, &iter, + COLUMN_RENDERER, renderer, + -1); + + g_object_unref (renderer); } while (gtk_tree_model_iter_next (tree_model, &iter)); } @@ -735,43 +644,28 @@ gimp_container_tree_view_button_press (GtkWidget *widget, return retval; } -#if 0 static void -gimp_container_tree_view_rows_reordered (GtkTreeModel *tree_model, - GtkTreePath *path, - GtkTreeIter *iter, - gint *new_order, - GimpContainerTreeView *tree_view) -{ - gint n_children; - gint i; - - g_print ("rows_reordered\n"); - - n_children = - gimp_container_num_children (GIMP_CONTAINER_VIEW (tree_view)->container); - - for (i = 0; i < n_children; i++) - { - if (new_order[i] != i) - g_print ("reordered: %d -> %d\n", i, new_order[i]); - } -} -#endif - -static void -gimp_container_tree_view_invalidate_preview (GimpViewable *viewable, - GimpContainerTreeView *tree_view) +gimp_container_tree_view_renderer_update (GimpPreviewRenderer *renderer, + GimpContainerTreeView *tree_view) { GimpContainerView *view; GtkTreeIter *iter; view = GIMP_CONTAINER_VIEW (tree_view); - iter = g_hash_table_lookup (view->hash_table, viewable); + iter = g_hash_table_lookup (view->hash_table, renderer->viewable); if (iter) - gimp_container_tree_view_set (tree_view, iter, viewable, TRUE, FALSE); + { + GtkTreePath *path; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_view->list), iter); + + gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_view->list), + path, iter); + + gtk_tree_path_free (path); + } } static void @@ -786,8 +680,20 @@ gimp_container_tree_view_name_changed (GimpObject *object, iter = g_hash_table_lookup (view->hash_table, object); if (iter) - gimp_container_tree_view_set (tree_view, iter, GIMP_VIEWABLE (object), - FALSE, TRUE); + { + gchar *name; + + if (view->get_name_func) + name = view->get_name_func (G_OBJECT (object), NULL); + else + name = g_strdup (gimp_object_get_name (object)); + + gtk_list_store_set (tree_view->list, iter, + COLUMN_NAME, name, + -1); + + g_free (name); + } } static GimpViewable * diff --git a/app/widgets/gimpdrawablepreview.c b/app/widgets/gimpdrawablepreview.c deleted file mode 100644 index e09558173b..0000000000 --- a/app/widgets/gimpdrawablepreview.c +++ /dev/null @@ -1,190 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpdrawablepreview.c - * 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 "widgets-types.h" - -#include "base/temp-buf.h" - -#include "core/gimpdrawable.h" -#include "core/gimpimage.h" - -#include "gimpdrawablepreview.h" - - -static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); -static void gimp_drawable_preview_init (GimpDrawablePreview *preview); - -static void gimp_drawable_preview_render (GimpPreview *preview); - - -static GimpPreviewClass *parent_class = NULL; - - -GType -gimp_drawable_preview_get_type (void) -{ - static GType preview_type = 0; - - if (! preview_type) - { - static const GTypeInfo preview_info = - { - sizeof (GimpDrawablePreviewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gimp_drawable_preview_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpDrawablePreview), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_drawable_preview_init, - }; - - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpDrawablePreview", - &preview_info, 0); - } - - return preview_type; -} - -static void -gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass) -{ - GimpPreviewClass *preview_class; - - preview_class = GIMP_PREVIEW_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - preview_class->render = gimp_drawable_preview_render; -} - -static void -gimp_drawable_preview_init (GimpDrawablePreview *preview) -{ -} - -static void -gimp_drawable_preview_render (GimpPreview *preview) -{ - GimpDrawable *drawable; - GimpImage *gimage; - gint width; - gint height; - gint preview_width; - gint preview_height; - gboolean scaling_up; - TempBuf *render_buf; - - drawable = GIMP_DRAWABLE (preview->viewable); - gimage = gimp_item_get_image (GIMP_ITEM (drawable)); - - width = preview->width; - height = preview->height; - - if (gimage && ! preview->is_popup) - { - width = MAX (1, ROUND ((((gdouble) width / (gdouble) gimage->width) * - (gdouble) drawable->width))); - height = MAX (1, ROUND ((((gdouble) height / (gdouble) gimage->height) * - (gdouble) drawable->height))); - - gimp_viewable_calc_preview_size (preview->viewable, - drawable->width, - drawable->height, - width, - height, - preview->dot_for_dot, - gimage->xresolution, - gimage->yresolution, - &preview_width, - &preview_height, - &scaling_up); - } - else - { - gimp_viewable_calc_preview_size (preview->viewable, - drawable->width, - drawable->height, - width, - height, - preview->dot_for_dot, - gimage ? gimage->xresolution : 1.0, - gimage ? gimage->yresolution : 1.0, - &preview_width, - &preview_height, - &scaling_up); - } - - if (scaling_up) - { - TempBuf *temp_buf; - - temp_buf = gimp_viewable_get_new_preview (preview->viewable, - drawable->width, - drawable->height); - render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); - - temp_buf_free (temp_buf); - } - else - { - render_buf = gimp_viewable_get_new_preview (preview->viewable, - preview_width, - preview_height); - } - - if (gimage && ! preview->is_popup) - { - if (drawable->offset_x != 0) - render_buf->x = - ROUND ((((gdouble) preview->width / (gdouble) gimage->width) * - (gdouble) drawable->offset_x)); - - if (drawable->offset_y != 0) - render_buf->y = - ROUND ((((gdouble) preview->height / (gdouble) gimage->height) * - (gdouble) drawable->offset_y)); - } - else - { - if (preview_width < width) - render_buf->x = (width - preview_width) / 2; - - if (preview_height < height) - render_buf->y = (height - preview_height) / 2; - } - - gimp_preview_render_preview (preview, - render_buf, - -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_CHECKS); - - temp_buf_free (render_buf); -} diff --git a/app/widgets/gimpdrawablepreview.h b/app/widgets/gimpdrawablepreview.h deleted file mode 100644 index 1a6f5db73d..0000000000 --- a/app/widgets/gimpdrawablepreview.h +++ /dev/null @@ -1,52 +0,0 @@ -/* The GIMP -- an image manipulation program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpdrawablepreview.h - * 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_DRAWABLE_PREVIEW_H__ -#define __GIMP_DRAWABLE_PREVIEW_H__ - -#include "gimppreview.h" - - -#define GIMP_TYPE_DRAWABLE_PREVIEW (gimp_drawable_preview_get_type ()) -#define GIMP_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreview)) -#define GIMP_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) -#define GIMP_IS_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_IS_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_DRAWABLE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) - - -typedef struct _GimpDrawablePreviewClass GimpDrawablePreviewClass; - -struct _GimpDrawablePreview -{ - GimpPreview parent_instance; -}; - -struct _GimpDrawablePreviewClass -{ - GimpPreviewClass parent_class; -}; - - -GType gimp_drawable_preview_get_type (void) G_GNUC_CONST; - - -#endif /* __GIMP_DRAWABLE_PREVIEW_H__ */ diff --git a/app/widgets/gimpimagepreview.c b/app/widgets/gimpimagepreview.c deleted file mode 100644 index d2e5828dc6..0000000000 --- a/app/widgets/gimpimagepreview.c +++ /dev/null @@ -1,156 +0,0 @@ -/* 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 "widgets-types.h" - -#include "base/temp-buf.h" - -#include "core/gimpimage.h" - -#include "gimpimagepreview.h" - - -static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); -static void gimp_image_preview_init (GimpImagePreview *preview); - -static void gimp_image_preview_render (GimpPreview *preview); - - -static GimpPreviewClass *parent_class = NULL; - - -GType -gimp_image_preview_get_type (void) -{ - static GType preview_type = 0; - - if (! preview_type) - { - static const GTypeInfo preview_info = - { - sizeof (GimpImagePreviewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gimp_image_preview_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpImagePreview), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_image_preview_init, - }; - - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpImagePreview", - &preview_info, 0); - } - - return preview_type; -} - -static void -gimp_image_preview_class_init (GimpImagePreviewClass *klass) -{ - GimpPreviewClass *preview_class; - - preview_class = GIMP_PREVIEW_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - preview_class->render = gimp_image_preview_render; -} - -static void -gimp_image_preview_init (GimpImagePreview *preview) -{ - preview->channel = -1; -} - -static void -gimp_image_preview_render (GimpPreview *preview) -{ - GimpImage *gimage; - gint width; - gint height; - gint preview_width; - gint preview_height; - gboolean scaling_up; - TempBuf *render_buf; - - gimage = GIMP_IMAGE (preview->viewable); - - width = preview->width; - height = preview->height; - - gimp_viewable_calc_preview_size (preview->viewable, - gimage->width, - gimage->height, - width, - height, - preview->dot_for_dot, - gimage->xresolution, - gimage->yresolution, - &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); - render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); - - temp_buf_free (temp_buf); - } - else - { - render_buf = gimp_viewable_get_new_preview (preview->viewable, - preview_width, - preview_height); - } - - /* xresolution != yresolution */ - if (preview_width > width || preview_height > height) - { - TempBuf *temp_buf; - - temp_buf = temp_buf_scale (render_buf, width, height); - - temp_buf_free (render_buf); - render_buf = temp_buf; - } - - if (preview_width < width) render_buf->x = (width - preview_width) / 2; - if (preview_height < height) render_buf->y = (height - preview_height) / 2; - - gimp_preview_render_preview (preview, render_buf, - GIMP_IMAGE_PREVIEW (preview)->channel, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); - - temp_buf_free (render_buf); -} diff --git a/app/widgets/gimpimagepreview.h b/app/widgets/gimpimagepreview.h deleted file mode 100644 index ceb15bc49c..0000000000 --- a/app/widgets/gimpimagepreview.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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" - - -#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) -#define GIMP_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) -#define GIMP_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) -#define GIMP_IS_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IMAGE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) - - -typedef struct _GimpImagePreviewClass GimpImagePreviewClass; - -struct _GimpImagePreview -{ - GimpPreview parent_instance; - - gint channel; -}; - -struct _GimpImagePreviewClass -{ - GimpPreviewClass parent_class; -}; - - -GType gimp_image_preview_get_type (void) G_GNUC_CONST; - - -#endif /* __GIMP_IMAGE_PREVIEW_H__ */ diff --git a/app/widgets/gimplayerlistitem.c b/app/widgets/gimplayerlistitem.c index 9d6938c745..15132dff1c 100644 --- a/app/widgets/gimplayerlistitem.c +++ b/app/widgets/gimplayerlistitem.c @@ -41,6 +41,7 @@ #include "gimpdnd.h" #include "gimplayerlistitem.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" static void gimp_layer_list_item_class_init (GimpLayerListItemClass *klass); @@ -251,7 +252,8 @@ gimp_layer_list_item_set_preview_size (GimpListItem *list_item) preview = GIMP_PREVIEW (layer_item->mask_preview); gimp_preview_set_size (preview, - list_item->preview_size, preview->border_width); + list_item->preview_size, + preview->renderer->border_width); } } diff --git a/app/widgets/gimplistitem.c b/app/widgets/gimplistitem.c index 9f3f4d3ded..b528a52731 100644 --- a/app/widgets/gimplistitem.c +++ b/app/widgets/gimplistitem.c @@ -43,6 +43,7 @@ #include "gimplayerlistitem.h" #include "gimplistitem.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" static void gimp_list_item_class_init (GimpListItemClass *klass); @@ -361,7 +362,8 @@ gimp_list_item_real_set_preview_size (GimpListItem *list_item) preview = GIMP_PREVIEW (list_item->preview); gimp_preview_set_size (preview, - list_item->preview_size, preview->border_width); + list_item->preview_size, + preview->renderer->border_width); } void diff --git a/app/widgets/gimpnavigationpreview.c b/app/widgets/gimpnavigationpreview.c index 24358ad895..299d98abb9 100644 --- a/app/widgets/gimpnavigationpreview.c +++ b/app/widgets/gimpnavigationpreview.c @@ -31,12 +31,11 @@ #include "widgets-types.h" -#include "base/temp-buf.h" - #include "core/gimpimage.h" #include "core/gimpmarshal.h" #include "gimpnavigationpreview.h" +#include "gimppreviewrenderer.h" #define BORDER_PEN_WIDTH 3 @@ -74,7 +73,7 @@ static void gimp_navigation_preview_draw_marker (GimpNavigationPreview *na static guint preview_signals[LAST_SIGNAL] = { 0 }; -static GimpImagePreviewClass *parent_class = NULL; +static GimpPreviewClass *parent_class = NULL; GType @@ -97,7 +96,7 @@ gimp_navigation_preview_get_type (void) (GInstanceInitFunc) gimp_navigation_preview_init, }; - preview_type = g_type_register_static (GIMP_TYPE_IMAGE_PREVIEW, + preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, "GimpNavigationPreview", &preview_info, 0); } @@ -248,17 +247,17 @@ gimp_navigation_preview_move_to (GimpNavigationPreview *nav_preview, if (! preview->viewable) return; - tx = CLAMP (tx, 0, preview->width); - ty = CLAMP (ty, 0, preview->height); + tx = CLAMP (tx, 0, preview->renderer->width); + ty = CLAMP (ty, 0, preview->renderer->height); - if ((tx + nav_preview->p_width) >= preview->width) + if ((tx + nav_preview->p_width) >= preview->renderer->width) { - tx = preview->width - nav_preview->p_width; + tx = preview->renderer->width - nav_preview->p_width; } - if ((ty + nav_preview->p_height) >= preview->height) + if ((ty + nav_preview->p_height) >= preview->renderer->height) { - ty = preview->height - nav_preview->p_height; + ty = preview->renderer->height - nav_preview->p_height; } if (nav_preview->p_x == tx && nav_preview->p_y == ty) @@ -267,8 +266,8 @@ gimp_navigation_preview_move_to (GimpNavigationPreview *nav_preview, gimage = GIMP_IMAGE (preview->viewable); /* transform to image coordinates */ - ratiox = ((gdouble) preview->width / (gdouble) gimage->width); - ratioy = ((gdouble) preview->height / (gdouble) gimage->height); + ratiox = ((gdouble) preview->renderer->width / (gdouble) gimage->width); + ratioy = ((gdouble) preview->renderer->height / (gdouble) gimage->height); x = RINT (tx / ratiox); y = RINT (ty / ratioy); @@ -431,8 +430,8 @@ gimp_navigation_preview_motion_notify (GtkWidget *widget, if (nav_preview->p_x == 0 && nav_preview->p_y == 0 && - nav_preview->p_width == GIMP_PREVIEW (widget)->width && - nav_preview->p_height == GIMP_PREVIEW (widget)->height) + nav_preview->p_width == GIMP_PREVIEW (widget)->renderer->width && + nav_preview->p_height == GIMP_PREVIEW (widget)->renderer->height) { gdk_window_set_cursor (widget->window, NULL); return FALSE; @@ -549,26 +548,19 @@ GtkWidget * gimp_navigation_preview_new (GimpImage *gimage, gint size) { - GimpPreview *preview; + GtkWidget *preview; g_return_val_if_fail (! gimage || GIMP_IS_IMAGE (gimage), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); - preview = g_object_new (GIMP_TYPE_NAVIGATION_PREVIEW, NULL); - - preview->is_popup = TRUE; + preview = gimp_preview_new_by_types (GIMP_TYPE_NAVIGATION_PREVIEW, + GIMP_TYPE_IMAGE, + size, 0, TRUE); if (gimage) - { - gimp_preview_set_viewable (preview, GIMP_VIEWABLE (gimage)); - gimp_preview_set_size (preview, size, 0); - } - else - { - preview->size = size; - } + gimp_preview_set_viewable (GIMP_PREVIEW (preview), GIMP_VIEWABLE (gimage)); - return GTK_WIDGET (preview); + return preview; } void @@ -607,8 +599,8 @@ gimp_navigation_preview_set_marker (GimpNavigationPreview *nav_preview, nav_preview->height = CLAMP (height, 1, gimage->height - nav_preview->y); /* transform to preview coordinates */ - ratiox = ((gdouble) preview->width / (gdouble) gimage->width); - ratioy = ((gdouble) preview->height / (gdouble) gimage->height); + ratiox = ((gdouble) preview->renderer->width / (gdouble) gimage->width); + ratioy = ((gdouble) preview->renderer->height / (gdouble) gimage->height); nav_preview->p_x = RINT (nav_preview->x * ratiox); nav_preview->p_y = RINT (nav_preview->y * ratioy); diff --git a/app/widgets/gimpnavigationpreview.h b/app/widgets/gimpnavigationpreview.h index a71c682bb0..89e2287fdf 100644 --- a/app/widgets/gimpnavigationpreview.h +++ b/app/widgets/gimpnavigationpreview.h @@ -25,7 +25,7 @@ #ifndef __GIMP_NAVIGATION_PREVIEW_H__ #define __GIMP_NAVIGATION_PREVIEW_H__ -#include "gimpimagepreview.h" +#include "gimppreview.h" #define GIMP_TYPE_NAVIGATION_PREVIEW (gimp_navigation_preview_get_type ()) @@ -40,25 +40,25 @@ typedef struct _GimpNavigationPreviewClass GimpNavigationPreviewClass; struct _GimpNavigationPreview { - GimpImagePreview parent_instance; + GimpPreview parent_instance; /* values in image coordinates */ - gint x; - gint y; - gint width; - gint height; + gint x; + gint y; + gint width; + gint height; /* values in preview coordinates */ - gint p_x; - gint p_y; - gint p_width; - gint p_height; + gint p_x; + gint p_y; + gint p_width; + gint p_height; - gint motion_offset_x; - gint motion_offset_y; - gboolean has_grab; + gint motion_offset_x; + gint motion_offset_y; + gboolean has_grab; - GdkGC *gc; + GdkGC *gc; }; struct _GimpNavigationPreviewClass diff --git a/app/widgets/gimpnavigationview.c b/app/widgets/gimpnavigationview.c index 24358ad895..299d98abb9 100644 --- a/app/widgets/gimpnavigationview.c +++ b/app/widgets/gimpnavigationview.c @@ -31,12 +31,11 @@ #include "widgets-types.h" -#include "base/temp-buf.h" - #include "core/gimpimage.h" #include "core/gimpmarshal.h" #include "gimpnavigationpreview.h" +#include "gimppreviewrenderer.h" #define BORDER_PEN_WIDTH 3 @@ -74,7 +73,7 @@ static void gimp_navigation_preview_draw_marker (GimpNavigationPreview *na static guint preview_signals[LAST_SIGNAL] = { 0 }; -static GimpImagePreviewClass *parent_class = NULL; +static GimpPreviewClass *parent_class = NULL; GType @@ -97,7 +96,7 @@ gimp_navigation_preview_get_type (void) (GInstanceInitFunc) gimp_navigation_preview_init, }; - preview_type = g_type_register_static (GIMP_TYPE_IMAGE_PREVIEW, + preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, "GimpNavigationPreview", &preview_info, 0); } @@ -248,17 +247,17 @@ gimp_navigation_preview_move_to (GimpNavigationPreview *nav_preview, if (! preview->viewable) return; - tx = CLAMP (tx, 0, preview->width); - ty = CLAMP (ty, 0, preview->height); + tx = CLAMP (tx, 0, preview->renderer->width); + ty = CLAMP (ty, 0, preview->renderer->height); - if ((tx + nav_preview->p_width) >= preview->width) + if ((tx + nav_preview->p_width) >= preview->renderer->width) { - tx = preview->width - nav_preview->p_width; + tx = preview->renderer->width - nav_preview->p_width; } - if ((ty + nav_preview->p_height) >= preview->height) + if ((ty + nav_preview->p_height) >= preview->renderer->height) { - ty = preview->height - nav_preview->p_height; + ty = preview->renderer->height - nav_preview->p_height; } if (nav_preview->p_x == tx && nav_preview->p_y == ty) @@ -267,8 +266,8 @@ gimp_navigation_preview_move_to (GimpNavigationPreview *nav_preview, gimage = GIMP_IMAGE (preview->viewable); /* transform to image coordinates */ - ratiox = ((gdouble) preview->width / (gdouble) gimage->width); - ratioy = ((gdouble) preview->height / (gdouble) gimage->height); + ratiox = ((gdouble) preview->renderer->width / (gdouble) gimage->width); + ratioy = ((gdouble) preview->renderer->height / (gdouble) gimage->height); x = RINT (tx / ratiox); y = RINT (ty / ratioy); @@ -431,8 +430,8 @@ gimp_navigation_preview_motion_notify (GtkWidget *widget, if (nav_preview->p_x == 0 && nav_preview->p_y == 0 && - nav_preview->p_width == GIMP_PREVIEW (widget)->width && - nav_preview->p_height == GIMP_PREVIEW (widget)->height) + nav_preview->p_width == GIMP_PREVIEW (widget)->renderer->width && + nav_preview->p_height == GIMP_PREVIEW (widget)->renderer->height) { gdk_window_set_cursor (widget->window, NULL); return FALSE; @@ -549,26 +548,19 @@ GtkWidget * gimp_navigation_preview_new (GimpImage *gimage, gint size) { - GimpPreview *preview; + GtkWidget *preview; g_return_val_if_fail (! gimage || GIMP_IS_IMAGE (gimage), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); - preview = g_object_new (GIMP_TYPE_NAVIGATION_PREVIEW, NULL); - - preview->is_popup = TRUE; + preview = gimp_preview_new_by_types (GIMP_TYPE_NAVIGATION_PREVIEW, + GIMP_TYPE_IMAGE, + size, 0, TRUE); if (gimage) - { - gimp_preview_set_viewable (preview, GIMP_VIEWABLE (gimage)); - gimp_preview_set_size (preview, size, 0); - } - else - { - preview->size = size; - } + gimp_preview_set_viewable (GIMP_PREVIEW (preview), GIMP_VIEWABLE (gimage)); - return GTK_WIDGET (preview); + return preview; } void @@ -607,8 +599,8 @@ gimp_navigation_preview_set_marker (GimpNavigationPreview *nav_preview, nav_preview->height = CLAMP (height, 1, gimage->height - nav_preview->y); /* transform to preview coordinates */ - ratiox = ((gdouble) preview->width / (gdouble) gimage->width); - ratioy = ((gdouble) preview->height / (gdouble) gimage->height); + ratiox = ((gdouble) preview->renderer->width / (gdouble) gimage->width); + ratioy = ((gdouble) preview->renderer->height / (gdouble) gimage->height); nav_preview->p_x = RINT (nav_preview->x * ratiox); nav_preview->p_y = RINT (nav_preview->y * ratioy); diff --git a/app/widgets/gimpnavigationview.h b/app/widgets/gimpnavigationview.h index a71c682bb0..89e2287fdf 100644 --- a/app/widgets/gimpnavigationview.h +++ b/app/widgets/gimpnavigationview.h @@ -25,7 +25,7 @@ #ifndef __GIMP_NAVIGATION_PREVIEW_H__ #define __GIMP_NAVIGATION_PREVIEW_H__ -#include "gimpimagepreview.h" +#include "gimppreview.h" #define GIMP_TYPE_NAVIGATION_PREVIEW (gimp_navigation_preview_get_type ()) @@ -40,25 +40,25 @@ typedef struct _GimpNavigationPreviewClass GimpNavigationPreviewClass; struct _GimpNavigationPreview { - GimpImagePreview parent_instance; + GimpPreview parent_instance; /* values in image coordinates */ - gint x; - gint y; - gint width; - gint height; + gint x; + gint y; + gint width; + gint height; /* values in preview coordinates */ - gint p_x; - gint p_y; - gint p_width; - gint p_height; + gint p_x; + gint p_y; + gint p_width; + gint p_height; - gint motion_offset_x; - gint motion_offset_y; - gboolean has_grab; + gint motion_offset_x; + gint motion_offset_y; + gboolean has_grab; - GdkGC *gc; + GdkGC *gc; }; struct _GimpNavigationPreviewClass diff --git a/app/widgets/gimppreview.c b/app/widgets/gimppreview.c index f04c7ffdf8..a86e0752f3 100644 --- a/app/widgets/gimppreview.c +++ b/app/widgets/gimppreview.c @@ -32,26 +32,16 @@ #include "widgets-types.h" -#ifdef __GNUC__ -#warning FIXME #include "display/display-types.h" -#endif -#include "display/display-types.h" - -#include "base/temp-buf.h" - #include "core/gimpmarshal.h" #include "core/gimpviewable.h" -#include "display/gimpdisplayshell-render.h" - #include "gimpdnd.h" #include "gimppreview.h" #include "gimppreview-popup.h" -#include "gimppreview-utils.h" +#include "gimppreviewrenderer.h" +#include "gimppreviewrenderer-utils.h" -#define PREVIEW_BYTES 3 - #define PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \ GDK_BUTTON_RELEASE_MASK | \ GDK_ENTER_NOTIFY_MASK | \ @@ -84,12 +74,9 @@ static gboolean gimp_preview_enter_notify_event (GtkWidget *widget, static gboolean gimp_preview_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event); -static gboolean gimp_preview_idle_update (GimpPreview *preview); -static void gimp_preview_render (GimpPreview *preview); -static void gimp_preview_real_render (GimpPreview *preview); +static void gimp_preview_update_callback (GimpPreviewRenderer *renderer, + GimpPreview *preview); -static void gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable); static GimpViewable * gimp_preview_drag_viewable (GtkWidget *widget, gpointer data); @@ -189,36 +176,19 @@ gimp_preview_class_init (GimpPreviewClass *klass) klass->double_clicked = NULL; klass->extended_clicked = NULL; klass->context = NULL; - klass->render = gimp_preview_real_render; } static void gimp_preview_init (GimpPreview *preview) { preview->viewable = NULL; + preview->renderer = NULL; - preview->width = 8; - preview->height = 8; - preview->border_width = 0; - preview->dot_for_dot = TRUE; - - gimp_rgba_set (&preview->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); - preview->border_gc = NULL; - - preview->is_popup = FALSE; preview->clickable = FALSE; preview->eat_button_events = TRUE; preview->show_popup = FALSE; - preview->buffer = NULL; - preview->rowstride = 0; - - preview->no_preview_pixbuf = NULL; - - preview->size = -1; preview->in_button = FALSE; - preview->idle_id = 0; - preview->needs_render = TRUE; gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_EVENT_MASK); } @@ -230,31 +200,13 @@ gimp_preview_destroy (GtkObject *object) preview = GIMP_PREVIEW (object); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - preview->idle_id = 0; - } - if (preview->viewable) gimp_preview_set_viewable (preview, NULL); - if (preview->buffer) + if (preview->renderer) { - g_free (preview->buffer); - preview->buffer = NULL; - } - - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } - - if (preview->border_gc) - { - g_object_unref (preview->border_gc); - preview->border_gc = NULL; + g_object_unref (preview->renderer); + preview->renderer = NULL; } GTK_OBJECT_CLASS (parent_class)->destroy (object); @@ -270,8 +222,10 @@ gimp_preview_size_allocate (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - width = preview->width + 2 * preview->border_width; - height = preview->height + 2 * preview->border_width; + width = (preview->renderer->width + + 2 * preview->renderer->border_width); + height = (preview->renderer->height + + 2 * preview->renderer->border_width); if (allocation->width > width) allocation->x += (allocation->width - width) / 2; @@ -282,8 +236,6 @@ gimp_preview_size_allocate (GtkWidget *widget, allocation->width = width; allocation->height = height; - preview->needs_render = TRUE; - if (GTK_WIDGET_CLASS (parent_class)->size_allocate) GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); } @@ -293,132 +245,21 @@ gimp_preview_expose_event (GtkWidget *widget, GdkEventExpose *event) { GimpPreview *preview; - guchar *buf; - GdkRectangle border_rect; - GdkRectangle buf_rect; - GdkRectangle render_rect; + GdkRectangle rect; preview = GIMP_PREVIEW (widget); - if (preview->needs_render) - gimp_preview_render (preview); - if (! GTK_WIDGET_DRAWABLE (widget)) return FALSE; - border_rect.x = 0; - border_rect.y = 0; - border_rect.width = preview->width + 2 * preview->border_width; - border_rect.height = preview->height + 2 * preview->border_width; + rect = widget->allocation; - if (widget->allocation.width > border_rect.width) - border_rect.x = (widget->allocation.width - border_rect.width) / 2; + rect.x = rect.y = 0; - if (widget->allocation.height > border_rect.height) - border_rect.y = (widget->allocation.height - border_rect.height) / 2; - - if (preview->no_preview_pixbuf) - { - buf_rect.width = gdk_pixbuf_get_width (preview->no_preview_pixbuf); - buf_rect.height = gdk_pixbuf_get_height (preview->no_preview_pixbuf); - buf_rect.x = (widget->allocation.width - buf_rect.width) / 2; - buf_rect.y = (widget->allocation.height - buf_rect.height) / 2; - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - /* FIXME: remove when we no longer support GTK 2.0.x */ -#if GTK_CHECK_VERSION(2,2,0) - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - preview->no_preview_pixbuf, - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#else - gdk_pixbuf_render_to_drawable (preview->no_preview_pixbuf, - GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#endif - } - } - else if (preview->buffer) - { - if (preview->border_width > 0) - { - buf_rect.x = border_rect.x + preview->border_width; - buf_rect.y = border_rect.y + preview->border_width; - buf_rect.width = border_rect.width - 2 * preview->border_width; - buf_rect.height = border_rect.height - 2 * preview->border_width; - } - else - { - buf_rect = border_rect; - } - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - buf = (preview->buffer + - (render_rect.y - buf_rect.y) * preview->rowstride + - (render_rect.x - buf_rect.x) * PREVIEW_BYTES); - - gdk_draw_rgb_image_dithalign (widget->window, - widget->style->black_gc, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - buf, - preview->rowstride, - event->area.x, - event->area.y); - } - } - - if (preview->border_width > 0) - { - gint i; - - if (! preview->border_gc) - { - GdkColor color; - guchar r, g, b; - - preview->border_gc = gdk_gc_new (widget->window); - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - color.red = r | r << 8; - color.green = g | g << 8; - color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &color); - } - - for (i = 0; i < preview->border_width; i++) - gdk_draw_rectangle (widget->window, - preview->border_gc, - FALSE, - border_rect.x + i, - border_rect.y + i, - border_rect.width - 2 * i - 1, - border_rect.height - 2 * i - 1); - } + gimp_preview_renderer_draw (preview->renderer, + widget->window, widget, + &rect, + &event->area); return FALSE; } @@ -465,9 +306,9 @@ gimp_preview_button_press_event (GtkWidget *widget, { gimp_preview_popup_show (widget, bevent, preview->viewable, - preview->width, - preview->height, - preview->dot_for_dot); + preview->renderer->width, + preview->renderer->height, + preview->renderer->dot_for_dot); } } else @@ -581,23 +422,28 @@ gimp_preview_new (GimpViewable *viewable, gint border_width, gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GimpPreview *preview; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - viewable_type = G_TYPE_FROM_INSTANCE (viewable); + renderer = gimp_preview_renderer_new (viewable, size, + border_width, is_popup); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + g_return_val_if_fail (renderer != NULL, NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; gimp_preview_set_viewable (preview, viewable); - gimp_preview_set_size (preview, size, border_width); return GTK_WIDGET (preview); @@ -612,8 +458,8 @@ gimp_preview_new_full (GimpViewable *viewable, gboolean clickable, gboolean show_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GimpPreview *preview; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -621,17 +467,22 @@ gimp_preview_new_full (GimpViewable *viewable, g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - viewable_type = G_TYPE_FROM_INSTANCE (viewable); + renderer = gimp_preview_renderer_new_full (viewable, width, height, + border_width, is_popup); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + g_return_val_if_fail (renderer != NULL, NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; preview->clickable = clickable ? TRUE : FALSE; preview->show_popup = show_popup ? TRUE : FALSE; gimp_preview_set_viewable (preview, viewable); - gimp_preview_set_size_full (preview, width, height, border_width); return GTK_WIDGET (preview); @@ -643,19 +494,43 @@ gimp_preview_new_by_type (GType viewable_type, gint border_width, gboolean is_popup) { - GimpPreview *preview; - g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + return gimp_preview_new_by_types (GIMP_TYPE_PREVIEW, viewable_type, + size, border_width, is_popup); +} - preview->is_popup = is_popup ? TRUE : FALSE; - preview->size = size; - preview->border_width = border_width; +GtkWidget * +gimp_preview_new_by_types (GType preview_type, + GType viewable_type, + gint size, + gint border_width, + gboolean is_popup) +{ + GimpPreviewRenderer *renderer; + GimpPreview *preview; + + g_return_val_if_fail (g_type_is_a (preview_type, GIMP_TYPE_PREVIEW), NULL); + g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); + g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); + g_return_val_if_fail (border_width >= 0 && + border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); + + renderer = gimp_preview_renderer_new_by_type (viewable_type, size, + border_width, is_popup); + + g_return_val_if_fail (renderer != NULL, NULL); + + preview = g_object_new (preview_type, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; return GTK_WIDGET (preview); } @@ -673,33 +548,19 @@ gimp_preview_set_viewable (GimpPreview *preview, { viewable_type = G_TYPE_FROM_INSTANCE (viewable); - g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview), - gimp_preview_type_from_viewable_type (viewable_type))); + g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview->renderer), + gimp_preview_renderer_type_from_viewable_type (viewable_type))); } if (viewable == preview->viewable) return; - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - if (preview->viewable) { g_object_remove_weak_pointer (G_OBJECT (preview->viewable), (gpointer *) &preview->viewable); - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (! viewable && ! preview->is_popup) + if (! viewable && ! preview->renderer->is_popup) { if (gimp_dnd_viewable_source_unset (GTK_WIDGET (preview), G_TYPE_FROM_INSTANCE (preview->viewable))) @@ -708,7 +569,7 @@ gimp_preview_set_viewable (GimpPreview *preview, } } } - else if (viewable && ! preview->is_popup) + else if (viewable && ! preview->renderer->is_popup) { if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (preview), GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, @@ -722,6 +583,7 @@ gimp_preview_set_viewable (GimpPreview *preview, } } + gimp_preview_renderer_set_viewable (preview->renderer, viewable); preview->viewable = viewable; if (preview->viewable) @@ -729,23 +591,6 @@ gimp_preview_set_viewable (GimpPreview *preview, g_object_add_weak_pointer (G_OBJECT (preview->viewable), (gpointer *) &preview->viewable); - g_signal_connect_swapped (preview->viewable, - "invalidate_preview", - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_connect_swapped (preview->viewable, - "size_changed", - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } - gimp_preview_update (preview); } } @@ -755,33 +600,13 @@ gimp_preview_set_size (GimpPreview *preview, gint preview_size, gint border_width) { - gint width, height; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); g_return_if_fail (preview_size > 0 && preview_size <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->size = preview_size; - - if (preview->viewable) - { - gimp_viewable_get_preview_size (preview->viewable, - preview_size, - preview->is_popup, - preview->dot_for_dot, - &width, &height); - } - else - { - width = preview_size; - height = preview_size; - } - - gimp_preview_set_size_full (preview, - width, - height, - border_width); + gimp_preview_renderer_set_size (preview->renderer, preview_size, + border_width); } void @@ -796,26 +621,8 @@ gimp_preview_set_size_full (GimpPreview *preview, g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->width = width; - preview->height = height; - preview->border_width = border_width; - - if (((width + 2 * border_width) != GTK_WIDGET (preview)->requisition.width) || - ((height + 2 * border_width) != GTK_WIDGET (preview)->requisition.height)) - { - GTK_WIDGET (preview)->requisition.width = width + 2 * border_width; - GTK_WIDGET (preview)->requisition.height = height + 2 * border_width; - - preview->rowstride = (preview->width * PREVIEW_BYTES + 3) & ~3; - - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - - gtk_widget_queue_resize (GTK_WIDGET (preview)); - } + gimp_preview_renderer_set_size_full (preview->renderer, width, height, + border_width); } void @@ -824,19 +631,7 @@ gimp_preview_set_dot_for_dot (GimpPreview *preview, { g_return_if_fail (GIMP_IS_PREVIEW (preview)); - if (dot_for_dot != preview->dot_for_dot) - { - preview->dot_for_dot = dot_for_dot ? TRUE: FALSE; - - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } - - gimp_preview_update (preview); - } + gimp_preview_renderer_set_dot_for_dot (preview->renderer, dot_for_dot); } void @@ -846,26 +641,7 @@ gimp_preview_set_border_color (GimpPreview *preview, g_return_if_fail (GIMP_IS_PREVIEW (preview)); g_return_if_fail (color != NULL); - if (gimp_rgb_distance (&preview->border_color, color)) - { - preview->border_color = *color; - - if (preview->border_gc) - { - GdkColor gdk_color; - guchar r, g, b; - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - gdk_color.red = r | r << 8; - gdk_color.green = g | g << 8; - gdk_color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &gdk_color); - } - - gtk_widget_queue_draw (GTK_WIDGET (preview)); - } + gimp_preview_renderer_set_border_color (preview->renderer, color); } void @@ -873,137 +649,38 @@ gimp_preview_update (GimpPreview *preview) { g_return_if_fail (GIMP_IS_PREVIEW (preview)); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - } - - preview->idle_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_update, preview, - NULL); + gimp_preview_renderer_update (preview->renderer); } /* private functions */ -static gboolean -gimp_preview_idle_update (GimpPreview *preview) -{ - preview->idle_id = 0; - - if (preview->viewable) - { - preview->needs_render = TRUE; - gtk_widget_queue_draw (GTK_WIDGET (preview)); - } - - return FALSE; -} - static void -gimp_preview_render (GimpPreview *preview) +gimp_preview_update_callback (GimpPreviewRenderer *renderer, + GimpPreview *preview) { - if (! preview->viewable) - return; + GtkWidget *widget; + gint width; + gint height; + gint border_width; - GIMP_PREVIEW_GET_CLASS (preview)->render (preview); -} + widget = GTK_WIDGET (preview); -static void -gimp_preview_real_render (GimpPreview *preview) -{ - TempBuf *temp_buf; + width = renderer->width; + height = renderer->height; + border_width = renderer->border_width; - temp_buf = gimp_viewable_get_preview (preview->viewable, - preview->width, - preview->height); - - if (temp_buf) + if (width + 2 * border_width != widget->requisition.width || + height + 2 * border_width != widget->requisition.height) { - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } + widget->requisition.width = width + 2 * border_width; + widget->requisition.height = height + 2 * border_width; - if (temp_buf->width < preview->width) - temp_buf->x = (preview->width - temp_buf->width) / 2; - - if (temp_buf->height < preview->height) - temp_buf->y = (preview->height - temp_buf->height) / 2; - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); - } - else /* no preview available */ - { - GdkPixbuf *pixbuf; - const gchar *stock_id; - gint width, height; - - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } - - stock_id = gimp_viewable_get_stock_id (preview->viewable); - pixbuf = gtk_widget_render_icon (GTK_WIDGET (preview), - stock_id, - GTK_ICON_SIZE_DIALOG, - NULL); - if (pixbuf) - { - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - if (width > preview->width || height > preview->height) - { - gdouble ratio = - MIN ((gdouble) preview->width / (gdouble) width, - (gdouble) preview->height / (gdouble) height); - - width = ratio * (gdouble) width; - height = ratio * (gdouble) height; - - preview->no_preview_pixbuf = - gdk_pixbuf_scale_simple (pixbuf, width, height, - GDK_INTERP_BILINEAR); - g_object_unref (pixbuf); - } - else - { - preview->no_preview_pixbuf = pixbuf; - } - } - - preview->needs_render = FALSE; - } -} - -static void -gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable) -{ - if (preview->size != -1) - { - g_print ("size_changed (%d)\n", preview->size); - - gimp_preview_set_size (preview, - preview->size, - preview->border_width); + gtk_widget_queue_resize (widget); } else { - gimp_preview_update (preview); + gtk_widget_queue_draw (widget); } } @@ -1013,206 +690,3 @@ gimp_preview_drag_viewable (GtkWidget *widget, { return GIMP_PREVIEW (widget)->viewable; } - - -/* protected functions */ - -void -gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride) -{ - guchar *src, *s; - guchar *cb; - guchar *pad_buf; - gint a; - gint i, j, b; - gint x1, y1, x2, y2; - gint rowstride; - gboolean color; - gboolean has_alpha; - gboolean render_composite; - gint red_component; - gint green_component; - gint blue_component; - gint alpha_component; - gint offset; - - /* Here are the different cases this functions handles correctly: - * 1) Offset temp_buf which does not necessarily cover full image area - * 2) Color conversion of temp_buf if it is gray and image is color - * 3) Background check buffer for transparent temp_bufs - * 4) Using the optional "channel" argument, one channel can be extracted - * from a multi-channel temp_buf and composited as a grayscale - * Prereqs: - * 1) Grayscale temp_bufs have bytes == {1, 2} - * 2) Color temp_bufs have bytes == {3, 4} - * 3) If image is gray, then temp_buf should have bytes == {1, 2} - */ - - color = (temp_buf->bytes == 3 || temp_buf->bytes == 4); - has_alpha = (temp_buf->bytes == 2 || temp_buf->bytes == 4); - render_composite = (channel == -1); - rowstride = temp_buf->width * temp_buf->bytes; - - /* render the checkerboard only if the temp_buf has alpha *and* - * we render a composite preview - */ - if (has_alpha && render_composite && outside_bg == GIMP_PREVIEW_BG_CHECKS) - pad_buf = render_check_buf; - else if (outside_bg == GIMP_PREVIEW_BG_WHITE) - pad_buf = render_white_buf; - else - pad_buf = render_empty_buf; - - if (render_composite) - { - if (color) - { - red_component = RED_PIX; - green_component = GREEN_PIX; - blue_component = BLUE_PIX; - alpha_component = ALPHA_PIX; - } - else - { - red_component = GRAY_PIX; - green_component = GRAY_PIX; - blue_component = GRAY_PIX; - alpha_component = ALPHA_G_PIX; - } - } - else - { - red_component = channel; - green_component = channel; - blue_component = channel; - alpha_component = 0; - } - - x1 = CLAMP (temp_buf->x, 0, dest_width); - y1 = CLAMP (temp_buf->y, 0, dest_height); - x2 = CLAMP (temp_buf->x + temp_buf->width, 0, dest_width); - y2 = CLAMP (temp_buf->y + temp_buf->height, 0, dest_height); - - src = temp_buf_data (temp_buf) + ((y1 - temp_buf->y) * rowstride + - (x1 - temp_buf->x) * temp_buf->bytes); - - for (i = 0; i < dest_height; i++) - { - if (i & 0x4) - { - offset = 4; - cb = pad_buf + offset * 3; - } - else - { - offset = 0; - cb = pad_buf; - } - - /* The interesting stuff between leading & trailing - * vertical transparency - */ - if (i >= y1 && i < y2) - { - /* Handle the leading transparency */ - for (j = 0; j < x1; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - - /* The stuff in the middle */ - s = src; - for (j = x1; j < x2; j++) - { - if (has_alpha && render_composite) - { - a = s[alpha_component] << 8; - - if (inside_bg == GIMP_PREVIEW_BG_CHECKS) - { - if ((j + offset) & 0x4) - { - render_temp_buf[j * 3 + 0] = - render_blend_dark_check [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_dark_check [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_dark_check [(a | s[blue_component])]; - } - else - { - render_temp_buf[j * 3 + 0] = - render_blend_light_check [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_light_check [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_light_check [(a | s[blue_component])]; - } - } - else /* GIMP_PREVIEW_BG_WHITE */ - { - render_temp_buf[j * 3 + 0] = - render_blend_white [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_white [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_white [(a | s[blue_component])]; - } - } - else - { - render_temp_buf[j * 3 + 0] = s[red_component]; - render_temp_buf[j * 3 + 1] = s[green_component]; - render_temp_buf[j * 3 + 2] = s[blue_component]; - } - - s += temp_buf->bytes; - } - - /* Handle the trailing transparency */ - for (j = x2; j < dest_width; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - - src += rowstride; - } - else - { - for (j = 0; j < dest_width; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - } - - memcpy (dest_buffer + i * dest_rowstride, - render_temp_buf, - dest_width * PREVIEW_BYTES); - } -} - -void -gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg) -{ - if (! preview->buffer) - preview->buffer = g_new0 (guchar, preview->height * preview->rowstride); - - gimp_preview_render_to_buffer (temp_buf, - channel, - inside_bg, - outside_bg, - preview->buffer, - preview->width, - preview->height, - preview->rowstride); - - preview->needs_render = FALSE; -} diff --git a/app/widgets/gimppreview.h b/app/widgets/gimppreview.h index 5ba2aacdb5..201be04a80 100644 --- a/app/widgets/gimppreview.h +++ b/app/widgets/gimppreview.h @@ -42,34 +42,18 @@ typedef struct _GimpPreviewClass GimpPreviewClass; struct _GimpPreview { - GtkDrawingArea parent_instance; + GtkDrawingArea parent_instance; - GimpViewable *viewable; + GimpViewable *viewable; + GimpPreviewRenderer *renderer; - gint width; - gint height; - gint border_width; - gboolean dot_for_dot; - - GimpRGB border_color; - GdkGC *border_gc; - - gboolean is_popup; - gboolean clickable; - gboolean eat_button_events; - gboolean show_popup; + gboolean clickable; + gboolean eat_button_events; + gboolean show_popup; /*< private >*/ - guchar *buffer; - gint rowstride; - - GdkPixbuf *no_preview_pixbuf; - - gint size; - gboolean in_button; - guint press_state; - guint idle_id; - gboolean needs_render; + gboolean in_button; + guint press_state; }; struct _GimpPreviewClass @@ -82,9 +66,6 @@ struct _GimpPreviewClass void (* extended_clicked) (GimpPreview *preview, guint modifier_state); void (* context) (GimpPreview *preview); - - /* virtual functions */ - void (* render) (GimpPreview *preview); }; @@ -103,6 +84,11 @@ GtkWidget * gimp_preview_new_full (GimpViewable *viewable, gboolean show_popup); GtkWidget * gimp_preview_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup); +GtkWidget * gimp_preview_new_by_types (GType preview_type, + GType viewable_type, gint size, gint border_width, gboolean is_popup); @@ -129,20 +115,6 @@ void gimp_preview_update (GimpPreview *preview); /* protected */ -typedef enum -{ - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE -} GimpPreviewBG; - -void gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride); void gimp_preview_render_preview (GimpPreview *preview, TempBuf *temp_buf, gint channel, diff --git a/app/widgets/gimppreview-utils.c b/app/widgets/gimppreviewrenderer-utils.c similarity index 70% rename from app/widgets/gimppreview-utils.c rename to app/widgets/gimppreviewrenderer-utils.c index 263e385681..c88a7e5cc4 100644 --- a/app/widgets/gimppreview-utils.c +++ b/app/widgets/gimppreviewrenderer-utils.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview-utils.c - * Copyright (C) 2001-2002 Michael Natterer + * gimppreviewrenderer-utils.c + * Copyright (C) 2003 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 @@ -26,39 +26,33 @@ #include "widgets-types.h" #include "core/gimpbrush.h" -#include "core/gimpbuffer.h" #include "core/gimpdrawable.h" #include "core/gimpimage.h" -#include "gimpbrushpreview.h" -#include "gimpbufferpreview.h" -#include "gimpdrawablepreview.h" -#include "gimpimagepreview.h" +#include "gimppreviewrendererbrush.h" +#include "gimppreviewrendererdrawable.h" +#include "gimppreviewrendererimage.h" GType -gimp_preview_type_from_viewable_type (GType viewable_type) +gimp_preview_renderer_type_from_viewable_type (GType viewable_type) { - GType type = GIMP_TYPE_PREVIEW; + GType type = GIMP_TYPE_PREVIEW_RENDERER; g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), G_TYPE_NONE); if (g_type_is_a (viewable_type, GIMP_TYPE_BRUSH)) { - type = GIMP_TYPE_BRUSH_PREVIEW; - } - else if (g_type_is_a (viewable_type, GIMP_TYPE_DRAWABLE)) - { - type = GIMP_TYPE_DRAWABLE_PREVIEW; + type = GIMP_TYPE_PREVIEW_RENDERER_BRUSH; } else if (g_type_is_a (viewable_type, GIMP_TYPE_IMAGE)) { - type = GIMP_TYPE_IMAGE_PREVIEW; + type = GIMP_TYPE_PREVIEW_RENDERER_IMAGE; } - else if (g_type_is_a (viewable_type, GIMP_TYPE_BUFFER)) + else if (g_type_is_a (viewable_type, GIMP_TYPE_DRAWABLE)) { - type = GIMP_TYPE_BUFFER_PREVIEW; + type = GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE; } return type; diff --git a/app/widgets/gimppreview-utils.h b/app/widgets/gimppreviewrenderer-utils.h similarity index 73% rename from app/widgets/gimppreview-utils.h rename to app/widgets/gimppreviewrenderer-utils.h index 0b5b3fa38f..a43a8bed78 100644 --- a/app/widgets/gimppreview-utils.h +++ b/app/widgets/gimppreviewrenderer-utils.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview.h - * Copyright (C) 2001 Michael Natterer + * gimppreviewrenderer-utils.h + * Copyright (C) 2003 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 @@ -19,11 +19,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_PREVIEW_UTILS_H__ -#define __GIMP_PREVIEW_UTILS_H__ +#ifndef __GIMP_PREVIEW_RENDERER_UTILS_H__ +#define __GIMP_PREVIEW_RENDERER_UTILS_H__ -GType gimp_preview_type_from_viewable_type (GType viewable_type); +GType gimp_preview_renderer_type_from_viewable_type (GType viewable_type); -#endif /* __GIMP_PREVIEW_UTILS_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_UTILS_H__ */ diff --git a/app/widgets/gimppreviewrenderer.c b/app/widgets/gimppreviewrenderer.c index f04c7ffdf8..7f5cc99e3b 100644 --- a/app/widgets/gimppreviewrenderer.c +++ b/app/widgets/gimppreviewrenderer.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview.c - * Copyright (C) 2001 Michael Natterer + * gimppreviewrenderer.c + * Copyright (C) 2003 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 @@ -44,545 +44,161 @@ #include "display/gimpdisplayshell-render.h" -#include "gimpdnd.h" -#include "gimppreview.h" -#include "gimppreview-popup.h" -#include "gimppreview-utils.h" +#include "gimppreviewrenderer.h" +#include "gimppreviewrenderer-utils.h" -#define PREVIEW_BYTES 3 +#define PREVIEW_BYTES 3 -#define PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \ - GDK_BUTTON_RELEASE_MASK | \ - GDK_ENTER_NOTIFY_MASK | \ - GDK_LEAVE_NOTIFY_MASK) enum { - CLICKED, - DOUBLE_CLICKED, - EXTENDED_CLICKED, - CONTEXT, + UPDATE, LAST_SIGNAL }; -static void gimp_preview_class_init (GimpPreviewClass *klass); -static void gimp_preview_init (GimpPreview *preview); +static void gimp_preview_renderer_class_init (GimpPreviewRendererClass *klass); +static void gimp_preview_renderer_init (GimpPreviewRenderer *renderer); -static void gimp_preview_destroy (GtkObject *object); -static void gimp_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean gimp_preview_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static gboolean gimp_preview_button_press_event (GtkWidget *widget, - GdkEventButton *bevent); -static gboolean gimp_preview_button_release_event (GtkWidget *widget, - GdkEventButton *bevent); -static gboolean gimp_preview_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event); -static gboolean gimp_preview_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event); +static void gimp_preview_renderer_finalize (GObject *object); -static gboolean gimp_preview_idle_update (GimpPreview *preview); -static void gimp_preview_render (GimpPreview *preview); -static void gimp_preview_real_render (GimpPreview *preview); +static gboolean gimp_preview_renderer_idle_update (GimpPreviewRenderer *renderer); +static void gimp_preview_renderer_real_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static void gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable); -static GimpViewable * gimp_preview_drag_viewable (GtkWidget *widget, - gpointer data); +static void gimp_preview_renderer_size_changed (GimpPreviewRenderer *renderer, + GimpViewable *viewable); -static guint preview_signals[LAST_SIGNAL] = { 0 }; +static guint renderer_signals[LAST_SIGNAL] = { 0 }; -static GtkDrawingAreaClass *parent_class = NULL; +static GObjectClass *parent_class = NULL; GType -gimp_preview_get_type (void) +gimp_preview_renderer_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpPreviewClass), + sizeof (GimpPreviewRendererClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpPreview), + sizeof (GimpPreviewRenderer), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_init, }; - preview_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, - "GimpPreview", - &preview_info, 0); + renderer_type = g_type_register_static (G_TYPE_OBJECT, + "GimpPreviewRenderer", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_preview_class_init (GimpPreviewClass *klass) +gimp_preview_renderer_class_init (GimpPreviewRendererClass *klass) { - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; + GObjectClass *object_class; - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_signals[CLICKED] = - g_signal_new ("clicked", + renderer_signals[UPDATE] = + g_signal_new ("update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, clicked), + G_STRUCT_OFFSET (GimpPreviewRendererClass, update), NULL, NULL, gimp_marshal_VOID__VOID, G_TYPE_NONE, 0); - preview_signals[DOUBLE_CLICKED] = - g_signal_new ("double_clicked", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, double_clicked), - NULL, NULL, - gimp_marshal_VOID__VOID, - G_TYPE_NONE, 0); + object_class->finalize = gimp_preview_renderer_finalize; - preview_signals[EXTENDED_CLICKED] = - g_signal_new ("extended_clicked", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, extended_clicked), - NULL, NULL, - gimp_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - preview_signals[CONTEXT] = - g_signal_new ("context", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, context), - NULL, NULL, - gimp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->destroy = gimp_preview_destroy; - - widget_class->activate_signal = preview_signals[CLICKED]; - widget_class->size_allocate = gimp_preview_size_allocate; - widget_class->expose_event = gimp_preview_expose_event; - widget_class->button_press_event = gimp_preview_button_press_event; - widget_class->button_release_event = gimp_preview_button_release_event; - widget_class->enter_notify_event = gimp_preview_enter_notify_event; - widget_class->leave_notify_event = gimp_preview_leave_notify_event; - - klass->clicked = NULL; - klass->double_clicked = NULL; - klass->extended_clicked = NULL; - klass->context = NULL; - klass->render = gimp_preview_real_render; + klass->render = gimp_preview_renderer_real_render; } static void -gimp_preview_init (GimpPreview *preview) +gimp_preview_renderer_init (GimpPreviewRenderer *renderer) { - preview->viewable = NULL; + renderer->viewable = NULL; - preview->width = 8; - preview->height = 8; - preview->border_width = 0; - preview->dot_for_dot = TRUE; + renderer->width = 8; + renderer->height = 8; + renderer->border_width = 0; + renderer->dot_for_dot = TRUE; + renderer->is_popup = FALSE; - gimp_rgba_set (&preview->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); - preview->border_gc = NULL; + gimp_rgba_set (&renderer->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); + renderer->border_gc = NULL; - preview->is_popup = FALSE; - preview->clickable = FALSE; - preview->eat_button_events = TRUE; - preview->show_popup = FALSE; + renderer->buffer = NULL; + renderer->rowstride = 0; - preview->buffer = NULL; - preview->rowstride = 0; + renderer->no_preview_pixbuf = NULL; - preview->no_preview_pixbuf = NULL; - - preview->size = -1; - preview->in_button = FALSE; - preview->idle_id = 0; - preview->needs_render = TRUE; - - gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_EVENT_MASK); + renderer->size = -1; + renderer->needs_render = TRUE; + renderer->idle_id = 0; } static void -gimp_preview_destroy (GtkObject *object) +gimp_preview_renderer_finalize (GObject *object) { - GimpPreview *preview; + GimpPreviewRenderer *renderer; - preview = GIMP_PREVIEW (object); + renderer = GIMP_PREVIEW_RENDERER (object); - if (preview->idle_id) + if (renderer->idle_id) { - g_source_remove (preview->idle_id); - preview->idle_id = 0; + g_source_remove (renderer->idle_id); + renderer->idle_id = 0; } - if (preview->viewable) - gimp_preview_set_viewable (preview, NULL); + if (renderer->viewable) + gimp_preview_renderer_set_viewable (renderer, NULL); - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->no_preview_pixbuf) + if (renderer->no_preview_pixbuf) { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; } - if (preview->border_gc) + if (renderer->border_gc) { - g_object_unref (preview->border_gc); - preview->border_gc = NULL; + g_object_unref (renderer->border_gc); + renderer->border_gc = NULL; } - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -gimp_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GimpPreview *preview; - gint width; - gint height; - - preview = GIMP_PREVIEW (widget); - - width = preview->width + 2 * preview->border_width; - height = preview->height + 2 * preview->border_width; - - if (allocation->width > width) - allocation->x += (allocation->width - width) / 2; - - if (allocation->height > height) - allocation->y += (allocation->height - height) / 2; - - allocation->width = width; - allocation->height = height; - - preview->needs_render = TRUE; - - if (GTK_WIDGET_CLASS (parent_class)->size_allocate) - GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); -} - -static gboolean -gimp_preview_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - GimpPreview *preview; - guchar *buf; - GdkRectangle border_rect; - GdkRectangle buf_rect; - GdkRectangle render_rect; - - preview = GIMP_PREVIEW (widget); - - if (preview->needs_render) - gimp_preview_render (preview); - - if (! GTK_WIDGET_DRAWABLE (widget)) - return FALSE; - - border_rect.x = 0; - border_rect.y = 0; - border_rect.width = preview->width + 2 * preview->border_width; - border_rect.height = preview->height + 2 * preview->border_width; - - if (widget->allocation.width > border_rect.width) - border_rect.x = (widget->allocation.width - border_rect.width) / 2; - - if (widget->allocation.height > border_rect.height) - border_rect.y = (widget->allocation.height - border_rect.height) / 2; - - if (preview->no_preview_pixbuf) - { - buf_rect.width = gdk_pixbuf_get_width (preview->no_preview_pixbuf); - buf_rect.height = gdk_pixbuf_get_height (preview->no_preview_pixbuf); - buf_rect.x = (widget->allocation.width - buf_rect.width) / 2; - buf_rect.y = (widget->allocation.height - buf_rect.height) / 2; - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - /* FIXME: remove when we no longer support GTK 2.0.x */ -#if GTK_CHECK_VERSION(2,2,0) - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - preview->no_preview_pixbuf, - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#else - gdk_pixbuf_render_to_drawable (preview->no_preview_pixbuf, - GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#endif - } - } - else if (preview->buffer) - { - if (preview->border_width > 0) - { - buf_rect.x = border_rect.x + preview->border_width; - buf_rect.y = border_rect.y + preview->border_width; - buf_rect.width = border_rect.width - 2 * preview->border_width; - buf_rect.height = border_rect.height - 2 * preview->border_width; - } - else - { - buf_rect = border_rect; - } - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - buf = (preview->buffer + - (render_rect.y - buf_rect.y) * preview->rowstride + - (render_rect.x - buf_rect.x) * PREVIEW_BYTES); - - gdk_draw_rgb_image_dithalign (widget->window, - widget->style->black_gc, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - buf, - preview->rowstride, - event->area.x, - event->area.y); - } - } - - if (preview->border_width > 0) - { - gint i; - - if (! preview->border_gc) - { - GdkColor color; - guchar r, g, b; - - preview->border_gc = gdk_gc_new (widget->window); - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - color.red = r | r << 8; - color.green = g | g << 8; - color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &color); - } - - for (i = 0; i < preview->border_width; i++) - gdk_draw_rectangle (widget->window, - preview->border_gc, - FALSE, - border_rect.x + i, - border_rect.y + i, - border_rect.width - 2 * i - 1, - border_rect.height - 2 * i - 1); - } - - return FALSE; -} - - -#define DEBUG_MEMSIZE 1 - -#ifdef DEBUG_MEMSIZE -extern gboolean gimp_debug_memsize; -#endif - -static gboolean -gimp_preview_button_press_event (GtkWidget *widget, - GdkEventButton *bevent) -{ - GimpPreview *preview; - - preview = GIMP_PREVIEW (widget); - -#ifdef DEBUG_MEMSIZE - if (bevent->type == GDK_BUTTON_PRESS && bevent->button == 2) - { - gimp_debug_memsize = TRUE; - - gimp_object_get_memsize (GIMP_OBJECT (preview->viewable)); - - gimp_debug_memsize = FALSE; - } -#endif /* DEBUG_MEMSIZE */ - - if (! preview->clickable && - ! preview->show_popup) - return FALSE; - - if (bevent->type == GDK_BUTTON_PRESS) - { - if (bevent->button == 1) - { - gtk_grab_add (widget); - - preview->press_state = bevent->state; - - if (preview->show_popup) - { - gimp_preview_popup_show (widget, bevent, - preview->viewable, - preview->width, - preview->height, - preview->dot_for_dot); - } - } - else - { - preview->press_state = 0; - - if (bevent->button == 3) - { - g_signal_emit (widget, preview_signals[CONTEXT], 0); - } - else - { - return FALSE; - } - } - } - else if (bevent->type == GDK_2BUTTON_PRESS) - { - if (bevent->button == 1) - { - g_signal_emit (widget, preview_signals[DOUBLE_CLICKED], 0); - } - } - - return preview->eat_button_events ? TRUE : FALSE; -} - -static gboolean -gimp_preview_button_release_event (GtkWidget *widget, - GdkEventButton *bevent) -{ - GimpPreview *preview; - - preview = GIMP_PREVIEW (widget); - - if (! preview->clickable && - ! preview->show_popup) - return FALSE; - - if (bevent->button == 1) - { - gtk_grab_remove (widget); - - if (preview->clickable && preview->in_button) - { - if (preview->press_state & - (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) - { - g_signal_emit (widget, - preview_signals[EXTENDED_CLICKED], 0, - preview->press_state); - } - else - { - g_signal_emit (widget, preview_signals[CLICKED], 0); - } - } - } - else - { - return FALSE; - } - - return preview->eat_button_events ? TRUE : FALSE; -} - -static gboolean -gimp_preview_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event) -{ - GimpPreview *preview; - GtkWidget *event_widget; - - preview = GIMP_PREVIEW (widget); - event_widget = gtk_get_event_widget ((GdkEvent *) event); - - if ((event_widget == widget) && - (event->detail != GDK_NOTIFY_INFERIOR)) - { - preview->in_button = TRUE; - } - - return FALSE; -} - -static gboolean -gimp_preview_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) -{ - GimpPreview *preview; - GtkWidget *event_widget; - - preview = GIMP_PREVIEW (widget); - event_widget = gtk_get_event_widget ((GdkEvent *) event); - - if ((event_widget == widget) && - (event->detail != GDK_NOTIFY_INFERIOR)) - { - preview->in_button = FALSE; - } - - return FALSE; + G_OBJECT_CLASS (parent_class)->finalize (object); } /* public functions */ -GtkWidget * -gimp_preview_new (GimpViewable *viewable, - gint size, - gint border_width, - gboolean is_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new (GimpViewable *viewable, + gint size, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GType viewable_type; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -591,29 +207,26 @@ gimp_preview_new (GimpViewable *viewable, viewable_type = G_TYPE_FROM_INSTANCE (viewable); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + renderer->is_popup = is_popup ? TRUE : FALSE; - gimp_preview_set_viewable (preview, viewable); + gimp_preview_renderer_set_viewable (renderer, viewable); + gimp_preview_renderer_set_size (renderer, size, border_width); - gimp_preview_set_size (preview, size, border_width); - - return GTK_WIDGET (preview); + return renderer; } -GtkWidget * -gimp_preview_new_full (GimpViewable *viewable, - gint width, - gint height, - gint border_width, - gboolean is_popup, - gboolean clickable, - gboolean show_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new_full (GimpViewable *viewable, + gint width, + gint height, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GType viewable_type; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -623,153 +236,131 @@ gimp_preview_new_full (GimpViewable *viewable, viewable_type = G_TYPE_FROM_INSTANCE (viewable); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; - preview->clickable = clickable ? TRUE : FALSE; - preview->show_popup = show_popup ? TRUE : FALSE; + renderer->is_popup = is_popup ? TRUE : FALSE; - gimp_preview_set_viewable (preview, viewable); + gimp_preview_renderer_set_viewable (renderer, viewable); + gimp_preview_renderer_set_size_full (renderer, width, height, border_width); - gimp_preview_set_size_full (preview, width, height, border_width); - - return GTK_WIDGET (preview); + return renderer; } -GtkWidget * -gimp_preview_new_by_type (GType viewable_type, - gint size, - gint border_width, - gboolean is_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; + GimpPreviewRenderer *renderer; g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; - preview->size = size; - preview->border_width = border_width; + renderer->is_popup = is_popup ? TRUE : FALSE; + renderer->size = size; + renderer->border_width = border_width; - return GTK_WIDGET (preview); + return renderer; } void -gimp_preview_set_viewable (GimpPreview *preview, - GimpViewable *viewable) +gimp_preview_renderer_set_viewable (GimpPreviewRenderer *renderer, + GimpViewable *viewable) { GType viewable_type = G_TYPE_NONE; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (! viewable || GIMP_IS_VIEWABLE (viewable)); if (viewable) { viewable_type = G_TYPE_FROM_INSTANCE (viewable); - g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview), - gimp_preview_type_from_viewable_type (viewable_type))); + g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (renderer), + gimp_preview_renderer_type_from_viewable_type (viewable_type))); } - if (viewable == preview->viewable) + if (viewable == renderer->viewable) return; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->viewable) + if (renderer->no_preview_pixbuf) { - g_object_remove_weak_pointer (G_OBJECT (preview->viewable), - (gpointer *) &preview->viewable); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (! viewable && ! preview->is_popup) - { - if (gimp_dnd_viewable_source_unset (GTK_WIDGET (preview), - G_TYPE_FROM_INSTANCE (preview->viewable))) - { - gtk_drag_source_unset (GTK_WIDGET (preview)); - } - } - } - else if (viewable && ! preview->is_popup) - { - if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (preview), - GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, - viewable_type, - GDK_ACTION_COPY)) - { - gimp_dnd_viewable_source_set (GTK_WIDGET (preview), - viewable_type, - gimp_preview_drag_viewable, - NULL); - } + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; } - preview->viewable = viewable; - - if (preview->viewable) + if (renderer->viewable) { - g_object_add_weak_pointer (G_OBJECT (preview->viewable), - (gpointer *) &preview->viewable); + g_object_remove_weak_pointer (G_OBJECT (renderer->viewable), + (gpointer *) &renderer->viewable); - g_signal_connect_swapped (preview->viewable, + g_signal_handlers_disconnect_by_func (renderer->viewable, + G_CALLBACK (gimp_preview_renderer_update), + renderer); + + g_signal_handlers_disconnect_by_func (renderer->viewable, + G_CALLBACK (gimp_preview_renderer_size_changed), + renderer); + } + + renderer->viewable = viewable; + + if (renderer->viewable) + { + g_object_add_weak_pointer (G_OBJECT (renderer->viewable), + (gpointer *) &renderer->viewable); + + g_signal_connect_swapped (renderer->viewable, "invalidate_preview", - G_CALLBACK (gimp_preview_update), - preview); + G_CALLBACK (gimp_preview_renderer_update), + renderer); - g_signal_connect_swapped (preview->viewable, + g_signal_connect_swapped (renderer->viewable, "size_changed", - G_CALLBACK (gimp_preview_size_changed), - preview); + G_CALLBACK (gimp_preview_renderer_size_changed), + renderer); - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); - gimp_preview_update (preview); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_size (GimpPreview *preview, - gint preview_size, - gint border_width) +gimp_preview_renderer_set_size (GimpPreviewRenderer *renderer, + gint preview_size, + gint border_width) { gint width, height; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (preview_size > 0 && preview_size <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->size = preview_size; + renderer->size = preview_size; - if (preview->viewable) + if (renderer->viewable) { - gimp_viewable_get_preview_size (preview->viewable, + gimp_viewable_get_preview_size (renderer->viewable, preview_size, - preview->is_popup, - preview->dot_for_dot, + renderer->is_popup, + renderer->dot_for_dot, &width, &height); } else @@ -778,240 +369,386 @@ gimp_preview_set_size (GimpPreview *preview, height = preview_size; } - gimp_preview_set_size_full (preview, - width, - height, - border_width); + gimp_preview_renderer_set_size_full (renderer, width, height, border_width); } void -gimp_preview_set_size_full (GimpPreview *preview, - gint width, - gint height, - gint border_width) +gimp_preview_renderer_set_size_full (GimpPreviewRenderer *renderer, + gint width, + gint height, + gint border_width) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (height > 0 && height <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->width = width; - preview->height = height; - preview->border_width = border_width; - - if (((width + 2 * border_width) != GTK_WIDGET (preview)->requisition.width) || - ((height + 2 * border_width) != GTK_WIDGET (preview)->requisition.height)) + if (width != renderer->width || + height != renderer->height || + border_width != renderer->border_width) { - GTK_WIDGET (preview)->requisition.width = width + 2 * border_width; - GTK_WIDGET (preview)->requisition.height = height + 2 * border_width; + renderer->width = width; + renderer->height = height; + renderer->border_width = border_width; - preview->rowstride = (preview->width * PREVIEW_BYTES + 3) & ~3; + renderer->rowstride = (renderer->width * PREVIEW_BYTES + 3) & ~3; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - gtk_widget_queue_resize (GTK_WIDGET (preview)); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_dot_for_dot (GimpPreview *preview, - gboolean dot_for_dot) +gimp_preview_renderer_set_dot_for_dot (GimpPreviewRenderer *renderer, + gboolean dot_for_dot) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); - if (dot_for_dot != preview->dot_for_dot) + if (dot_for_dot != renderer->dot_for_dot) { - preview->dot_for_dot = dot_for_dot ? TRUE: FALSE; + renderer->dot_for_dot = dot_for_dot ? TRUE: FALSE; - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); - gimp_preview_update (preview); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_border_color (GimpPreview *preview, - const GimpRGB *color) +gimp_preview_renderer_set_border_color (GimpPreviewRenderer *renderer, + const GimpRGB *color) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (color != NULL); - if (gimp_rgb_distance (&preview->border_color, color)) + if (gimp_rgb_distance (&renderer->border_color, color)) { - preview->border_color = *color; + renderer->border_color = *color; - if (preview->border_gc) + if (renderer->border_gc) { GdkColor gdk_color; guchar r, g, b; - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); + gimp_rgb_get_uchar (&renderer->border_color, &r, &g, &b); gdk_color.red = r | r << 8; gdk_color.green = g | g << 8; gdk_color.blue = b | b << 8; - gdk_gc_set_rgb_fg_color (preview->border_gc, &gdk_color); + gdk_gc_set_rgb_fg_color (renderer->border_gc, &gdk_color); } - gtk_widget_queue_draw (GTK_WIDGET (preview)); + g_signal_emit (renderer, renderer_signals[UPDATE], 0); } } void -gimp_preview_update (GimpPreview *preview) +gimp_preview_renderer_update (GimpPreviewRenderer *renderer) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - } + if (renderer->idle_id) + g_source_remove (renderer->idle_id); - preview->idle_id = + renderer->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_update, preview, + (GSourceFunc) gimp_preview_renderer_idle_update, renderer, NULL); } +void +gimp_preview_renderer_draw (GimpPreviewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *draw_area, + GdkRectangle *expose_area) +{ + GdkRectangle border_rect; + GdkRectangle buf_rect; + GdkRectangle render_rect; + + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (draw_area != NULL); + g_return_if_fail (expose_area != NULL); + + if (! GTK_WIDGET_DRAWABLE (widget) || ! renderer->viewable) + return; + + if (renderer->needs_render) + GIMP_PREVIEW_RENDERER_GET_CLASS (renderer)->render (renderer, widget); + + border_rect.x = draw_area->x; + border_rect.y = draw_area->y; + border_rect.width = renderer->width + 2 * renderer->border_width; + border_rect.height = renderer->height + 2 * renderer->border_width; + + if (draw_area->width > border_rect.width) + border_rect.x += (draw_area->width - border_rect.width) / 2; + + if (draw_area->height > border_rect.height) + border_rect.y += (draw_area->height - border_rect.height) / 2; + + if (renderer->no_preview_pixbuf) + { + buf_rect.width = gdk_pixbuf_get_width (renderer->no_preview_pixbuf); + buf_rect.height = gdk_pixbuf_get_height (renderer->no_preview_pixbuf); + buf_rect.x = (draw_area->width - buf_rect.width) / 2; + buf_rect.y = (draw_area->height - buf_rect.height) / 2; + + buf_rect.x += draw_area->x; + buf_rect.y += draw_area->y; + + if (gdk_rectangle_intersect (&buf_rect, expose_area, &render_rect)) + { + /* FIXME: remove when we no longer support GTK 2.0.x */ +#if GTK_CHECK_VERSION(2,2,0) + gdk_draw_pixbuf (GDK_DRAWABLE (window), + widget->style->bg_gc[widget->state], + renderer->no_preview_pixbuf, + render_rect.x - buf_rect.x, + render_rect.y - buf_rect.y, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); +#else + gdk_pixbuf_render_to_drawable (renderer->no_preview_pixbuf, + window, + widget->style->bg_gc[widget->state], + render_rect.x - buf_rect.x, + render_rect.y - buf_rect.y, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); +#endif + } + } + else if (renderer->buffer) + { + if (renderer->border_width > 0) + { + buf_rect.x = border_rect.x + renderer->border_width; + buf_rect.y = border_rect.y + renderer->border_width; + buf_rect.width = border_rect.width - 2 * renderer->border_width; + buf_rect.height = border_rect.height - 2 * renderer->border_width; + } + else + { + buf_rect = border_rect; + } + + if (gdk_rectangle_intersect (&buf_rect, expose_area, &render_rect)) + { + guchar *buf; + + buf = (renderer->buffer + + (render_rect.y - buf_rect.y) * renderer->rowstride + + (render_rect.x - buf_rect.x) * PREVIEW_BYTES); + + gdk_draw_rgb_image_dithalign (window, + widget->style->black_gc, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + buf, + renderer->rowstride, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); + } + } + + if (renderer->border_width > 0) + { + gint i; + + if (! renderer->border_gc) + { + GdkColor color; + guchar r, g, b; + + renderer->border_gc = gdk_gc_new (window); + + gimp_rgb_get_uchar (&renderer->border_color, &r, &g, &b); + + color.red = r | r << 8; + color.green = g | g << 8; + color.blue = b | b << 8; + + gdk_gc_set_rgb_fg_color (renderer->border_gc, &color); + } + + for (i = 0; i < renderer->border_width; i++) + gdk_draw_rectangle (window, + renderer->border_gc, + FALSE, + border_rect.x + i, + border_rect.y + i, + border_rect.width - 2 * i - 1, + border_rect.height - 2 * i - 1); + } +} /* private functions */ static gboolean -gimp_preview_idle_update (GimpPreview *preview) +gimp_preview_renderer_idle_update (GimpPreviewRenderer *renderer) { - preview->idle_id = 0; + renderer->idle_id = 0; - if (preview->viewable) + if (renderer->viewable) { - preview->needs_render = TRUE; - gtk_widget_queue_draw (GTK_WIDGET (preview)); + renderer->needs_render = TRUE; + + g_signal_emit (renderer, renderer_signals[UPDATE], 0); } return FALSE; } static void -gimp_preview_render (GimpPreview *preview) -{ - if (! preview->viewable) - return; - - GIMP_PREVIEW_GET_CLASS (preview)->render (preview); -} - -static void -gimp_preview_real_render (GimpPreview *preview) +gimp_preview_renderer_real_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_preview (preview->viewable, - preview->width, - preview->height); + if (renderer->no_preview_pixbuf) + { + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; + } + + temp_buf = gimp_viewable_get_preview (renderer->viewable, + renderer->width, + renderer->height); if (temp_buf) { - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } + if (temp_buf->width < renderer->width) + temp_buf->x = (renderer->width - temp_buf->width) / 2; - if (temp_buf->width < preview->width) - temp_buf->x = (preview->width - temp_buf->width) / 2; + if (temp_buf->height < renderer->height) + temp_buf->y = (renderer->height - temp_buf->height) / 2; - if (temp_buf->height < preview->height) - temp_buf->y = (preview->height - temp_buf->height) / 2; - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_WHITE); } else /* no preview available */ { - GdkPixbuf *pixbuf; - const gchar *stock_id; - gint width, height; + GdkPixbuf *pixbuf; + GtkIconSet *icon_set; + GtkIconSize *sizes; + gint n_sizes; + gint i; + gint width_diff = 1024; + gint height_diff = 1024; + GtkIconSize icon_size = GTK_ICON_SIZE_MENU; + const gchar *stock_id; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->no_preview_pixbuf) + stock_id = gimp_viewable_get_stock_id (renderer->viewable); + icon_set = gtk_style_lookup_icon_set (widget->style, stock_id); + + gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes); + + for (i = 0; i < n_sizes; i++) { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; + gint icon_width; + gint icon_height; + + if (gtk_icon_size_lookup (sizes[i], &icon_width, &icon_height)) + { + if (icon_width <= renderer->width && + icon_height <= renderer->height && + (ABS (icon_width - renderer->width) < width_diff || + ABS (icon_height - renderer->height) < height_diff)) + { + width_diff = ABS (icon_width - renderer->width); + height_diff = ABS (icon_height - renderer->height); + + icon_size = sizes[i]; + } + } } - stock_id = gimp_viewable_get_stock_id (preview->viewable); - pixbuf = gtk_widget_render_icon (GTK_WIDGET (preview), - stock_id, - GTK_ICON_SIZE_DIALOG, - NULL); + g_free (sizes); + + pixbuf = gtk_icon_set_render_icon (icon_set, + widget->style, + gtk_widget_get_direction (widget), + widget->state, + icon_size, + widget, NULL); + if (pixbuf) { - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - if (width > preview->width || height > preview->height) + if (gdk_pixbuf_get_width (pixbuf) > renderer->width || + gdk_pixbuf_get_height (pixbuf) > renderer->height) { - gdouble ratio = - MIN ((gdouble) preview->width / (gdouble) width, - (gdouble) preview->height / (gdouble) height); + GdkPixbuf *scaled_pixbuf; + gint pixbuf_width; + gint pixbuf_height; - width = ratio * (gdouble) width; - height = ratio * (gdouble) height; + gimp_viewable_calc_preview_size (renderer->viewable, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + renderer->width, + renderer->height, + TRUE, 1.0, 1.0, + &pixbuf_width, + &pixbuf_height, + NULL); + + scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, + pixbuf_width, + pixbuf_height, + GDK_INTERP_BILINEAR); - preview->no_preview_pixbuf = - gdk_pixbuf_scale_simple (pixbuf, width, height, - GDK_INTERP_BILINEAR); g_object_unref (pixbuf); + pixbuf = scaled_pixbuf; } - else - { - preview->no_preview_pixbuf = pixbuf; - } + + renderer->no_preview_pixbuf = pixbuf; } - preview->needs_render = FALSE; + renderer->needs_render = FALSE; } } static void -gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable) +gimp_preview_renderer_size_changed (GimpPreviewRenderer *renderer, + GimpViewable *viewable) { - if (preview->size != -1) - { - g_print ("size_changed (%d)\n", preview->size); - - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); else - { - gimp_preview_update (preview); - } -} - -static GimpViewable * -gimp_preview_drag_viewable (GtkWidget *widget, - gpointer data) -{ - return GIMP_PREVIEW (widget)->viewable; + gimp_preview_renderer_update (renderer); } @@ -1196,23 +933,23 @@ gimp_preview_render_to_buffer (TempBuf *temp_buf, } void -gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg) +gimp_preview_renderer_render_preview (GimpPreviewRenderer *renderer, + TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg) { - if (! preview->buffer) - preview->buffer = g_new0 (guchar, preview->height * preview->rowstride); + if (! renderer->buffer) + renderer->buffer = g_new0 (guchar, renderer->height * renderer->rowstride); gimp_preview_render_to_buffer (temp_buf, channel, inside_bg, outside_bg, - preview->buffer, - preview->width, - preview->height, - preview->rowstride); + renderer->buffer, + renderer->width, + renderer->height, + renderer->rowstride); - preview->needs_render = FALSE; + renderer->needs_render = FALSE; } diff --git a/app/widgets/gimppreviewrenderer.h b/app/widgets/gimppreviewrenderer.h index 5ba2aacdb5..de02f72736 100644 --- a/app/widgets/gimppreviewrenderer.h +++ b/app/widgets/gimppreviewrenderer.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview.h - * Copyright (C) 2001 Michael Natterer + * gimppreviewrenderer.h + * Copyright (C) 2003 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 @@ -19,135 +19,117 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_PREVIEW_H__ -#define __GIMP_PREVIEW_H__ - - -#include +#ifndef __GIMP_PREVIEW_RENDERER_H__ +#define __GIMP_PREVIEW_RENDERER_H__ #define GIMP_PREVIEW_MAX_SIZE 1024 #define GIMP_PREVIEW_MAX_BORDER_WIDTH 16 -#define GIMP_TYPE_PREVIEW (gimp_preview_get_type ()) -#define GIMP_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW, GimpPreview)) -#define GIMP_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW, GimpPreviewClass)) -#define GIMP_IS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW)) -#define GIMP_IS_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW)) -#define GIMP_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW, GimpPreviewClass)) +#define GIMP_TYPE_PREVIEW_RENDERER (gimp_preview_renderer_get_type ()) +#define GIMP_PREVIEW_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRenderer)) +#define GIMP_PREVIEW_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRendererClass)) +#define GIMP_IS_PREVIEW_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER)) +#define GIMP_IS_PREVIEW_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER)) +#define GIMP_PREVIEW_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRendererClass)) -typedef struct _GimpPreviewClass GimpPreviewClass; +typedef struct _GimpPreviewRendererClass GimpPreviewRendererClass; -struct _GimpPreview +struct _GimpPreviewRenderer { - GtkDrawingArea parent_instance; + GObject parent_instance; - GimpViewable *viewable; + GimpViewable *viewable; - gint width; - gint height; - gint border_width; - gboolean dot_for_dot; + gint width; + gint height; + gint border_width; + gboolean dot_for_dot; + gboolean is_popup; - GimpRGB border_color; - GdkGC *border_gc; - - gboolean is_popup; - gboolean clickable; - gboolean eat_button_events; - gboolean show_popup; + GimpRGB border_color; + GdkGC *border_gc; /*< private >*/ - guchar *buffer; - gint rowstride; + guchar *buffer; + gint rowstride; - GdkPixbuf *no_preview_pixbuf; + GdkPixbuf *no_preview_pixbuf; - gint size; - gboolean in_button; - guint press_state; - guint idle_id; - gboolean needs_render; + gint size; + gboolean needs_render; + guint idle_id; }; -struct _GimpPreviewClass +struct _GimpPreviewRendererClass { - GtkDrawingAreaClass parent_class; + GObjectClass parent_class; /* signals */ - void (* clicked) (GimpPreview *preview); - void (* double_clicked) (GimpPreview *preview); - void (* extended_clicked) (GimpPreview *preview, - guint modifier_state); - void (* context) (GimpPreview *preview); + void (* update) (GimpPreviewRenderer *renderer); /* virtual functions */ - void (* render) (GimpPreview *preview); + void (* render) (GimpPreviewRenderer *renderer, + GtkWidget *widget); }; -GType gimp_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_preview_new (GimpViewable *viewable, - gint size, - gint border_width, - gboolean is_popup); -GtkWidget * gimp_preview_new_full (GimpViewable *viewable, - gint width, - gint height, - gint border_width, - gboolean is_popup, - gboolean clickable, - gboolean show_popup); +GimpPreviewRenderer * gimp_preview_renderer_new (GimpViewable *viewable, + gint size, + gint border_width, + gboolean is_popup); +GimpPreviewRenderer * gimp_preview_renderer_new_full (GimpViewable *viewable, + gint width, + gint height, + gint border_width, + gboolean is_popup); +GimpPreviewRenderer * gimp_preview_renderer_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup); -GtkWidget * gimp_preview_new_by_type (GType viewable_type, - gint size, - gint border_width, - gboolean is_popup); +void gimp_preview_renderer_set_viewable (GimpPreviewRenderer *renderer, + GimpViewable *viewable); +void gimp_preview_renderer_set_size (GimpPreviewRenderer *renderer, + gint size, + gint border_width); +void gimp_preview_renderer_set_size_full (GimpPreviewRenderer *renderer, + gint width, + gint height, + gint border_width); +void gimp_preview_renderer_set_dot_for_dot (GimpPreviewRenderer *renderer, + gboolean dot_for_dot); +void gimp_preview_renderer_set_border_color (GimpPreviewRenderer *renderer, + const GimpRGB *border_color); -void gimp_preview_set_viewable (GimpPreview *preview, - GimpViewable *viewable); +void gimp_preview_renderer_update (GimpPreviewRenderer *renderer); -void gimp_preview_set_size (GimpPreview *preview, - gint size, - gint border_width); -void gimp_preview_set_size_full (GimpPreview *preview, - gint width, - gint height, - gint border_width); - -void gimp_preview_set_dot_for_dot (GimpPreview *preview, - gboolean dot_for_dot); - -void gimp_preview_set_border_color (GimpPreview *preview, - const GimpRGB *border_color); - -void gimp_preview_update (GimpPreview *preview); +void gimp_preview_renderer_draw (GimpPreviewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *draw_area, + GdkRectangle *expose_area); /* protected */ -typedef enum -{ - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE -} GimpPreviewBG; - -void gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride); -void gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg); +void gimp_preview_render_to_buffer (TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg, + guchar *dest_buffer, + gint dest_width, + gint dest_height, + gint dest_rowstride); +void gimp_preview_renderer_render_preview (GimpPreviewRenderer *renderer, + TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg); -#endif /* __GIMP_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_H__ */ diff --git a/app/widgets/gimppreviewrendererbrush.c b/app/widgets/gimppreviewrendererbrush.c index c73639d8ee..2f6764517e 100644 --- a/app/widgets/gimppreviewrendererbrush.c +++ b/app/widgets/gimppreviewrendererbrush.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpbrushpreview.c - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererbrush.c + * Copyright (C) 2003 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 @@ -30,147 +30,145 @@ #include "core/gimpbrush.h" #include "core/gimpbrushpipe.h" -#include "gimpbrushpreview.h" -#include "gimpdnd.h" +#include "gimppreviewrendererbrush.h" -static void gimp_brush_preview_class_init (GimpBrushPreviewClass *klass); -static void gimp_brush_preview_init (GimpBrushPreview *preview); +static void gimp_preview_renderer_brush_class_init (GimpPreviewRendererBrushClass *klass); +static void gimp_preview_renderer_brush_init (GimpPreviewRendererBrush *preview); -static void gimp_brush_preview_destroy (GtkObject *object); -static void gimp_brush_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_brush_finalize (GObject *object); +static void gimp_preview_renderer_brush_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static gboolean gimp_brush_preview_render_timeout (gpointer data); +static gboolean gimp_preview_renderer_brush_render_timeout (gpointer data); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_brush_preview_get_type (void) +gimp_preview_renderer_brush_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpBrushPreviewClass), + sizeof (GimpPreviewRendererBrushClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_brush_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_brush_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpBrushPreview), + sizeof (GimpPreviewRendererBrush), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_brush_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_brush_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpBrushPreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererBrush", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_brush_preview_class_init (GimpBrushPreviewClass *klass) +gimp_preview_renderer_brush_class_init (GimpPreviewRendererBrushClass *klass) { - GtkObjectClass *object_class; - GimpPreviewClass *preview_class; + GObjectClass *object_class; + GimpPreviewRendererClass *renderer_class; - object_class = GTK_OBJECT_CLASS (klass); - preview_class = GIMP_PREVIEW_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - object_class->destroy = gimp_brush_preview_destroy; + object_class->finalize = gimp_preview_renderer_brush_finalize; - preview_class->render = gimp_brush_preview_render; + renderer_class->render = gimp_preview_renderer_brush_render; } static void -gimp_brush_preview_init (GimpBrushPreview *brush_preview) +gimp_preview_renderer_brush_init (GimpPreviewRendererBrush *renderer) { - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + renderer->pipe_timeout_id = 0; + renderer->pipe_animation_index = 0; + renderer->pipe_animation_widget = NULL; } static void -gimp_brush_preview_destroy (GtkObject *object) +gimp_preview_renderer_brush_finalize (GObject *object) { - GimpBrushPreview *brush_preview; + GimpPreviewRendererBrush *renderer; - brush_preview = GIMP_BRUSH_PREVIEW (object); + renderer = GIMP_PREVIEW_RENDERER_BRUSH (object); - if (brush_preview->pipe_timeout_id) + if (renderer->pipe_timeout_id) { - g_source_remove (brush_preview->pipe_timeout_id); - - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + g_source_remove (renderer->pipe_timeout_id); + renderer->pipe_timeout_id = 0; } - GTK_OBJECT_CLASS (parent_class)->destroy (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -gimp_brush_preview_render (GimpPreview *preview) +gimp_preview_renderer_brush_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { - GimpBrushPreview *brush_preview; - GimpBrush *brush; - TempBuf *temp_buf; - gint width; - gint height; - gint brush_width; - gint brush_height; + GimpPreviewRendererBrush *renderbrush; + GimpBrush *brush; + TempBuf *temp_buf; + gint brush_width; + gint brush_height; - brush_preview = GIMP_BRUSH_PREVIEW (preview); + renderbrush = GIMP_PREVIEW_RENDERER_BRUSH (renderer); - if (brush_preview->pipe_timeout_id) + if (renderbrush->pipe_timeout_id) { - g_source_remove (brush_preview->pipe_timeout_id); - brush_preview->pipe_timeout_id = 0; + g_source_remove (renderbrush->pipe_timeout_id); + renderbrush->pipe_timeout_id = 0; } - brush = GIMP_BRUSH (preview->viewable); + brush = GIMP_BRUSH (renderer->viewable); brush_width = brush->mask->width; brush_height = brush->mask->height; - width = preview->width; - height = preview->height; + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, + renderer->width, + renderer->height); - temp_buf = gimp_viewable_get_new_preview (preview->viewable, - width, height); + if (temp_buf->width < renderer->width) + temp_buf->x = (renderer->width - temp_buf->width) / 2; - if (temp_buf->width < width) - temp_buf->x = (width - temp_buf->width) / 2; + if (temp_buf->height < renderer->height) + temp_buf->y = (renderer->height - temp_buf->height) / 2; - if (temp_buf->height < height) - temp_buf->y = (height - temp_buf->height) / 2; - - if (preview->is_popup) + if (renderer->is_popup) { - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); if (GIMP_IS_BRUSH_PIPE (brush)) { - if (width != brush_width || height != brush_height) + if (renderer->width != brush_width || + renderer->height != brush_height) { g_warning ("%s(): non-fullsize pipe popups are not supported yet.", G_GNUC_FUNCTION); return; } - brush_preview->pipe_animation_index = 0; - brush_preview->pipe_timeout_id = - g_timeout_add (300, gimp_brush_preview_render_timeout, - brush_preview); + renderbrush->pipe_animation_widget = widget; + renderbrush->pipe_animation_index = 0; + renderbrush->pipe_timeout_id = + g_timeout_add (300, gimp_preview_renderer_brush_render_timeout, + renderbrush); } return; @@ -181,8 +179,8 @@ gimp_brush_preview_render (GimpPreview *preview) if (temp_buf->width >= INDICATOR_WIDTH && temp_buf->height >= INDICATOR_HEIGHT && - (width < brush_width || - height < brush_height || + (renderer->width < brush_width || + renderer->height < brush_height || GIMP_IS_BRUSH_PIPE (brush))) { #define WHT { 255, 255, 255 } @@ -242,7 +240,8 @@ gimp_brush_preview_render (GimpPreview *preview) buf += (offset_y * temp_buf->width + offset_x) * temp_buf->bytes; pipe = GIMP_IS_BRUSH_PIPE (brush); - scale = (width < brush_width || height < brush_height); + scale = (renderer->width < brush_width || + renderer->height < brush_height); alpha = (temp_buf->bytes == 4); for (y = 0; y < INDICATOR_HEIGHT; y++) @@ -282,55 +281,55 @@ gimp_brush_preview_render (GimpPreview *preview) #undef INDICATOR_WIDTH #undef INDICATOR_HEIGHT - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); } static gboolean -gimp_brush_preview_render_timeout (gpointer data) +gimp_preview_renderer_brush_render_timeout (gpointer data) { - GimpBrushPreview *brush_preview; - GimpPreview *preview; - GimpBrushPipe *brush_pipe; - GimpBrush *brush; - TempBuf *temp_buf; + GimpPreviewRendererBrush *renderbrush; + GimpPreviewRenderer *renderer; + GimpBrushPipe *brush_pipe; + GimpBrush *brush; + TempBuf *temp_buf; - brush_preview = GIMP_BRUSH_PREVIEW (data); + renderbrush = GIMP_PREVIEW_RENDERER_BRUSH (data); + renderer = GIMP_PREVIEW_RENDERER (data); - preview = GIMP_PREVIEW (brush_preview); - - if (! preview->viewable) + if (! renderer->viewable) { - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + renderbrush->pipe_timeout_id = 0; + renderbrush->pipe_animation_index = 0; + renderbrush->pipe_animation_widget = NULL; return FALSE; } - brush_pipe = GIMP_BRUSH_PIPE (preview->viewable); + brush_pipe = GIMP_BRUSH_PIPE (renderer->viewable); - brush_preview->pipe_animation_index++; + renderbrush->pipe_animation_index++; - if (brush_preview->pipe_animation_index >= brush_pipe->nbrushes) - brush_preview->pipe_animation_index = 0; + if (renderbrush->pipe_animation_index >= brush_pipe->nbrushes) + renderbrush->pipe_animation_index = 0; brush = - GIMP_BRUSH (brush_pipe->brushes[brush_preview->pipe_animation_index]); + GIMP_BRUSH (brush_pipe->brushes[renderbrush->pipe_animation_index]); temp_buf = gimp_viewable_get_new_preview (GIMP_VIEWABLE (brush), - preview->width, - preview->height); + renderer->width, + renderer->height); - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); - gtk_widget_queue_draw (GTK_WIDGET (preview)); + gtk_widget_queue_draw (renderbrush->pipe_animation_widget); return TRUE; } diff --git a/app/widgets/gimppreviewrendererbrush.h b/app/widgets/gimppreviewrendererbrush.h index b626748a95..544704689b 100644 --- a/app/widgets/gimppreviewrendererbrush.h +++ b/app/widgets/gimppreviewrendererbrush.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpbrushpreview.h - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererbrush.h + * Copyright (C) 2003 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 @@ -19,37 +19,37 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_BRUSH_PREVIEW_H__ -#define __GIMP_BRUSH_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_BRUSH_H__ +#define __GIMP_PREVIEW_RENDERER_BRUSH_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_BRUSH (gimp_preview_renderer_brush_get_type ()) +#define GIMP_PREVIEW_RENDERER_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrush)) +#define GIMP_PREVIEW_RENDERER_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrushClass)) +#define GIMP_IS_PREVIEW_RENDERER_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_BRUSH)) +#define GIMP_IS_PREVIEW_RENDERER_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_BRUSH)) +#define GIMP_PREVIEW_RENDERER_BRUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrushClass)) -#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ()) -#define GIMP_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview)) -#define GIMP_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) -#define GIMP_IS_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_BRUSH_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) +typedef struct _GimpPreviewRendererBrushClass GimpPreviewRendererBrushClass; - -typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass; - -struct _GimpBrushPreview +struct _GimpPreviewRendererBrush { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; - guint pipe_timeout_id; - gint pipe_animation_index; + guint pipe_timeout_id; + gint pipe_animation_index; + GtkWidget *pipe_animation_widget; }; -struct _GimpBrushPreviewClass +struct _GimpPreviewRendererBrushClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_brush_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_brush_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_BRUSH_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_BRUSH_H__ */ diff --git a/app/widgets/gimppreviewrendererdrawable.c b/app/widgets/gimppreviewrendererdrawable.c index e09558173b..c5ac27ff1c 100644 --- a/app/widgets/gimppreviewrendererdrawable.c +++ b/app/widgets/gimppreviewrendererdrawable.c @@ -32,65 +32,67 @@ #include "core/gimpdrawable.h" #include "core/gimpimage.h" -#include "gimpdrawablepreview.h" +#include "gimppreviewrendererdrawable.h" -static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); -static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static void gimp_preview_renderer_drawable_class_init (GimpPreviewRendererDrawableClass *klass); +static void gimp_preview_renderer_drawable_init (GimpPreviewRendererDrawable *preview); -static void gimp_drawable_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_drawable_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_drawable_preview_get_type (void) +gimp_preview_renderer_drawable_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpDrawablePreviewClass), + sizeof (GimpPreviewRendererDrawableClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_drawable_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_drawable_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpDrawablePreview), + sizeof (GimpPreviewRendererDrawable), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_drawable_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_drawable_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpDrawablePreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererDrawable", + &renderer_info, 0); } - - return preview_type; + + return renderer_type; } static void -gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass) +gimp_preview_renderer_drawable_class_init (GimpPreviewRendererDrawableClass *klass) { - GimpPreviewClass *preview_class; + GimpPreviewRendererClass *renderer_class; - preview_class = GIMP_PREVIEW_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_class->render = gimp_drawable_preview_render; + renderer_class->render = gimp_preview_renderer_drawable_render; } static void -gimp_drawable_preview_init (GimpDrawablePreview *preview) +gimp_preview_renderer_drawable_init (GimpPreviewRendererDrawable *preview) { } static void -gimp_drawable_preview_render (GimpPreview *preview) +gimp_preview_renderer_drawable_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { GimpDrawable *drawable; GimpImage *gimage; @@ -101,25 +103,25 @@ gimp_drawable_preview_render (GimpPreview *preview) gboolean scaling_up; TempBuf *render_buf; - drawable = GIMP_DRAWABLE (preview->viewable); + drawable = GIMP_DRAWABLE (renderer->viewable); gimage = gimp_item_get_image (GIMP_ITEM (drawable)); - width = preview->width; - height = preview->height; + width = renderer->width; + height = renderer->height; - if (gimage && ! preview->is_popup) + if (gimage && ! renderer->is_popup) { width = MAX (1, ROUND ((((gdouble) width / (gdouble) gimage->width) * (gdouble) drawable->width))); height = MAX (1, ROUND ((((gdouble) height / (gdouble) gimage->height) * (gdouble) drawable->height))); - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, drawable->width, drawable->height, width, height, - preview->dot_for_dot, + renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &preview_width, @@ -128,12 +130,12 @@ gimp_drawable_preview_render (GimpPreview *preview) } else { - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, drawable->width, drawable->height, width, height, - preview->dot_for_dot, + renderer->dot_for_dot, gimage ? gimage->xresolution : 1.0, gimage ? gimage->yresolution : 1.0, &preview_width, @@ -145,7 +147,7 @@ gimp_drawable_preview_render (GimpPreview *preview) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_new_preview (preview->viewable, + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, drawable->width, drawable->height); render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); @@ -154,21 +156,21 @@ gimp_drawable_preview_render (GimpPreview *preview) } else { - render_buf = gimp_viewable_get_new_preview (preview->viewable, + render_buf = gimp_viewable_get_new_preview (renderer->viewable, preview_width, preview_height); } - if (gimage && ! preview->is_popup) + if (gimage && ! renderer->is_popup) { if (drawable->offset_x != 0) render_buf->x = - ROUND ((((gdouble) preview->width / (gdouble) gimage->width) * + ROUND ((((gdouble) renderer->width / (gdouble) gimage->width) * (gdouble) drawable->offset_x)); if (drawable->offset_y != 0) render_buf->y = - ROUND ((((gdouble) preview->height / (gdouble) gimage->height) * + ROUND ((((gdouble) renderer->height / (gdouble) gimage->height) * (gdouble) drawable->offset_y)); } else @@ -180,11 +182,9 @@ gimp_drawable_preview_render (GimpPreview *preview) render_buf->y = (height - preview_height) / 2; } - gimp_preview_render_preview (preview, - render_buf, - -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_CHECKS); + gimp_preview_renderer_render_preview (renderer, render_buf, -1, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_CHECKS); temp_buf_free (render_buf); } diff --git a/app/widgets/gimppreviewrendererdrawable.h b/app/widgets/gimppreviewrendererdrawable.h index 1a6f5db73d..c986b39cb2 100644 --- a/app/widgets/gimppreviewrendererdrawable.h +++ b/app/widgets/gimppreviewrendererdrawable.h @@ -1,7 +1,7 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpdrawablepreview.h + * gimppreviewrendererdrawable.h * Copyright (C) 2001 Michael Natterer * * This program is free software; you can redistribute it and/or modify @@ -19,34 +19,33 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_DRAWABLE_PREVIEW_H__ -#define __GIMP_DRAWABLE_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ +#define __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE (gimp_preview_renderer_drawable_get_type ()) +#define GIMP_PREVIEW_RENDERER_DRAWABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawable)) +#define GIMP_PREVIEW_RENDERER_DRAWABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawableClass)) +#define GIMP_IS_PREVIEW_RENDERER_DRAWABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE)) +#define GIMP_IS_PREVIEW_RENDERER_DRAWABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE)) +#define GIMP_PREVIEW_RENDERER_DRAWABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawableClass)) -#define GIMP_TYPE_DRAWABLE_PREVIEW (gimp_drawable_preview_get_type ()) -#define GIMP_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreview)) -#define GIMP_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) -#define GIMP_IS_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_IS_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_DRAWABLE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) +typedef struct _GimpPreviewRendererDrawableClass GimpPreviewRendererDrawableClass; - -typedef struct _GimpDrawablePreviewClass GimpDrawablePreviewClass; - -struct _GimpDrawablePreview +struct _GimpPreviewRendererDrawable { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; }; -struct _GimpDrawablePreviewClass +struct _GimpPreviewRendererDrawableClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_drawable_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_drawable_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_DRAWABLE_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ */ diff --git a/app/widgets/gimppreviewrendererimage.c b/app/widgets/gimppreviewrendererimage.c index d2e5828dc6..ac6db4b0d1 100644 --- a/app/widgets/gimppreviewrendererimage.c +++ b/app/widgets/gimppreviewrendererimage.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * GimpImagePreview Widget - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererimage.c + * Copyright (C) 2003 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 @@ -29,86 +29,83 @@ #include "core/gimpimage.h" -#include "gimpimagepreview.h" +#include "gimppreviewrendererimage.h" -static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); -static void gimp_image_preview_init (GimpImagePreview *preview); +static void gimp_preview_renderer_image_class_init (GimpPreviewRendererImageClass *klass); +static void gimp_preview_renderer_image_init (GimpPreviewRendererImage *preview); -static void gimp_image_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_image_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_image_preview_get_type (void) +gimp_preview_renderer_image_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpImagePreviewClass), + sizeof (GimpPreviewRendererImageClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_image_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_image_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpImagePreview), + sizeof (GimpPreviewRendererImage), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_image_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_image_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpImagePreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererImage", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_image_preview_class_init (GimpImagePreviewClass *klass) +gimp_preview_renderer_image_class_init (GimpPreviewRendererImageClass *klass) { - GimpPreviewClass *preview_class; + GimpPreviewRendererClass *renderer_class; - preview_class = GIMP_PREVIEW_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_class->render = gimp_image_preview_render; + renderer_class->render = gimp_preview_renderer_image_render; } static void -gimp_image_preview_init (GimpImagePreview *preview) +gimp_preview_renderer_image_init (GimpPreviewRendererImage *renderer) { - preview->channel = -1; + renderer->channel = -1; } static void -gimp_image_preview_render (GimpPreview *preview) +gimp_preview_renderer_image_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { GimpImage *gimage; - gint width; - gint height; gint preview_width; gint preview_height; gboolean scaling_up; TempBuf *render_buf; - gimage = GIMP_IMAGE (preview->viewable); + gimage = GIMP_IMAGE (renderer->viewable); - width = preview->width; - height = preview->height; - - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, gimage->width, gimage->height, - width, - height, - preview->dot_for_dot, + renderer->width, + renderer->height, + renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &preview_width, @@ -119,7 +116,7 @@ gimp_image_preview_render (GimpPreview *preview) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_new_preview (preview->viewable, + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, gimage->width, gimage->height); render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); @@ -128,29 +125,32 @@ gimp_image_preview_render (GimpPreview *preview) } else { - render_buf = gimp_viewable_get_new_preview (preview->viewable, + render_buf = gimp_viewable_get_new_preview (renderer->viewable, preview_width, preview_height); } /* xresolution != yresolution */ - if (preview_width > width || preview_height > height) + if (preview_width > renderer->width || preview_height > renderer->height) { TempBuf *temp_buf; - temp_buf = temp_buf_scale (render_buf, width, height); + temp_buf = temp_buf_scale (render_buf, renderer->width, renderer->height); temp_buf_free (render_buf); render_buf = temp_buf; } - if (preview_width < width) render_buf->x = (width - preview_width) / 2; - if (preview_height < height) render_buf->y = (height - preview_height) / 2; + if (preview_width < renderer->width) + render_buf->x = (renderer->width - preview_width) / 2; - gimp_preview_render_preview (preview, render_buf, - GIMP_IMAGE_PREVIEW (preview)->channel, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); + if (preview_height < renderer->height) + render_buf->y = (renderer->height - preview_height) / 2; + + gimp_preview_renderer_render_preview (renderer, render_buf, + GIMP_PREVIEW_RENDERER_IMAGE (renderer)->channel, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (render_buf); } diff --git a/app/widgets/gimppreviewrendererimage.h b/app/widgets/gimppreviewrendererimage.h index ceb15bc49c..6cd21850f4 100644 --- a/app/widgets/gimppreviewrendererimage.h +++ b/app/widgets/gimppreviewrendererimage.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * GimpImagePreview Widget - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererimage.h + * Copyright (C) 2003 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 @@ -19,36 +19,35 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_IMAGE_PREVIEW_H__ -#define __GIMP_IMAGE_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_IMAGE_H__ +#define __GIMP_PREVIEW_RENDERER_IMAGE_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_IMAGE (gimp_preview_renderer_image_get_type ()) +#define GIMP_PREVIEW_RENDERER_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImage)) +#define GIMP_PREVIEW_RENDERER_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImageClass)) +#define GIMP_IS_PREVIEW_RENDERER_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_IMAGE)) +#define GIMP_IS_PREVIEW_RENDERER_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_IMAGE)) +#define GIMP_PREVIEW_RENDERER_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImageClass)) -#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) -#define GIMP_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) -#define GIMP_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) -#define GIMP_IS_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IMAGE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +typedef struct _GimpPreviewRendererImageClass GimpPreviewRendererImageClass; - -typedef struct _GimpImagePreviewClass GimpImagePreviewClass; - -struct _GimpImagePreview +struct _GimpPreviewRendererImage { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; - gint channel; + gint channel; }; -struct _GimpImagePreviewClass +struct _GimpPreviewRendererImageClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_image_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_image_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_IMAGE_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_IMAGE_H__ */ diff --git a/app/widgets/gimpselectioneditor.c b/app/widgets/gimpselectioneditor.c index 75aad7616d..5e77c54fb7 100644 --- a/app/widgets/gimpselectioneditor.c +++ b/app/widgets/gimpselectioneditor.c @@ -48,6 +48,7 @@ #include "gimpselectioneditor.h" #include "gimpdnd.h" #include "gimppreview.h" +#include "gimppreviewrenderer.h" #include "libgimp/gimpintl.h" @@ -264,10 +265,10 @@ gimp_selection_editor_abox_resized (GtkWidget *widget, if (! preview->viewable) return; - if (preview->width > allocation->width || - preview->height > allocation->height || - (preview->width != allocation->width && - preview->height != allocation->height)) + if (preview->renderer->width > allocation->width || + preview->renderer->height > allocation->height || + (preview->renderer->width != allocation->width && + preview->renderer->height != allocation->height)) { gint width; gint height; @@ -280,7 +281,7 @@ gimp_selection_editor_abox_resized (GtkWidget *widget, GIMP_PREVIEW_MAX_SIZE), MIN (allocation->height, GIMP_PREVIEW_MAX_SIZE), - preview->dot_for_dot, + preview->renderer->dot_for_dot, image_editor->gimage->xresolution, image_editor->gimage->yresolution, &width, @@ -298,7 +299,8 @@ gimp_selection_editor_abox_resized (GtkWidget *widget, height = height * allocation->height / height; } - gimp_preview_set_size_full (preview, width, height, preview->border_width); + gimp_preview_set_size_full (preview, width, height, + preview->renderer->border_width); } } diff --git a/app/widgets/gimpvectorslistview.c b/app/widgets/gimpvectorslistview.c index 45e56508ab..339b0b2283 100644 --- a/app/widgets/gimpvectorslistview.c +++ b/app/widgets/gimpvectorslistview.c @@ -38,7 +38,6 @@ #include "gimpvectorslistview.h" #include "gimpcomponentlistitem.h" #include "gimpdnd.h" -#include "gimpimagepreview.h" #include "gimplistitem.h" #include "gimpwidgets-utils.h" diff --git a/app/widgets/gimpvectorstreeview.c b/app/widgets/gimpvectorstreeview.c index 45e56508ab..339b0b2283 100644 --- a/app/widgets/gimpvectorstreeview.c +++ b/app/widgets/gimpvectorstreeview.c @@ -38,7 +38,6 @@ #include "gimpvectorslistview.h" #include "gimpcomponentlistitem.h" #include "gimpdnd.h" -#include "gimpimagepreview.h" #include "gimplistitem.h" #include "gimpwidgets-utils.h" diff --git a/app/widgets/gimpview.c b/app/widgets/gimpview.c index f04c7ffdf8..a86e0752f3 100644 --- a/app/widgets/gimpview.c +++ b/app/widgets/gimpview.c @@ -32,26 +32,16 @@ #include "widgets-types.h" -#ifdef __GNUC__ -#warning FIXME #include "display/display-types.h" -#endif -#include "display/display-types.h" - -#include "base/temp-buf.h" - #include "core/gimpmarshal.h" #include "core/gimpviewable.h" -#include "display/gimpdisplayshell-render.h" - #include "gimpdnd.h" #include "gimppreview.h" #include "gimppreview-popup.h" -#include "gimppreview-utils.h" +#include "gimppreviewrenderer.h" +#include "gimppreviewrenderer-utils.h" -#define PREVIEW_BYTES 3 - #define PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \ GDK_BUTTON_RELEASE_MASK | \ GDK_ENTER_NOTIFY_MASK | \ @@ -84,12 +74,9 @@ static gboolean gimp_preview_enter_notify_event (GtkWidget *widget, static gboolean gimp_preview_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event); -static gboolean gimp_preview_idle_update (GimpPreview *preview); -static void gimp_preview_render (GimpPreview *preview); -static void gimp_preview_real_render (GimpPreview *preview); +static void gimp_preview_update_callback (GimpPreviewRenderer *renderer, + GimpPreview *preview); -static void gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable); static GimpViewable * gimp_preview_drag_viewable (GtkWidget *widget, gpointer data); @@ -189,36 +176,19 @@ gimp_preview_class_init (GimpPreviewClass *klass) klass->double_clicked = NULL; klass->extended_clicked = NULL; klass->context = NULL; - klass->render = gimp_preview_real_render; } static void gimp_preview_init (GimpPreview *preview) { preview->viewable = NULL; + preview->renderer = NULL; - preview->width = 8; - preview->height = 8; - preview->border_width = 0; - preview->dot_for_dot = TRUE; - - gimp_rgba_set (&preview->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); - preview->border_gc = NULL; - - preview->is_popup = FALSE; preview->clickable = FALSE; preview->eat_button_events = TRUE; preview->show_popup = FALSE; - preview->buffer = NULL; - preview->rowstride = 0; - - preview->no_preview_pixbuf = NULL; - - preview->size = -1; preview->in_button = FALSE; - preview->idle_id = 0; - preview->needs_render = TRUE; gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_EVENT_MASK); } @@ -230,31 +200,13 @@ gimp_preview_destroy (GtkObject *object) preview = GIMP_PREVIEW (object); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - preview->idle_id = 0; - } - if (preview->viewable) gimp_preview_set_viewable (preview, NULL); - if (preview->buffer) + if (preview->renderer) { - g_free (preview->buffer); - preview->buffer = NULL; - } - - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } - - if (preview->border_gc) - { - g_object_unref (preview->border_gc); - preview->border_gc = NULL; + g_object_unref (preview->renderer); + preview->renderer = NULL; } GTK_OBJECT_CLASS (parent_class)->destroy (object); @@ -270,8 +222,10 @@ gimp_preview_size_allocate (GtkWidget *widget, preview = GIMP_PREVIEW (widget); - width = preview->width + 2 * preview->border_width; - height = preview->height + 2 * preview->border_width; + width = (preview->renderer->width + + 2 * preview->renderer->border_width); + height = (preview->renderer->height + + 2 * preview->renderer->border_width); if (allocation->width > width) allocation->x += (allocation->width - width) / 2; @@ -282,8 +236,6 @@ gimp_preview_size_allocate (GtkWidget *widget, allocation->width = width; allocation->height = height; - preview->needs_render = TRUE; - if (GTK_WIDGET_CLASS (parent_class)->size_allocate) GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); } @@ -293,132 +245,21 @@ gimp_preview_expose_event (GtkWidget *widget, GdkEventExpose *event) { GimpPreview *preview; - guchar *buf; - GdkRectangle border_rect; - GdkRectangle buf_rect; - GdkRectangle render_rect; + GdkRectangle rect; preview = GIMP_PREVIEW (widget); - if (preview->needs_render) - gimp_preview_render (preview); - if (! GTK_WIDGET_DRAWABLE (widget)) return FALSE; - border_rect.x = 0; - border_rect.y = 0; - border_rect.width = preview->width + 2 * preview->border_width; - border_rect.height = preview->height + 2 * preview->border_width; + rect = widget->allocation; - if (widget->allocation.width > border_rect.width) - border_rect.x = (widget->allocation.width - border_rect.width) / 2; + rect.x = rect.y = 0; - if (widget->allocation.height > border_rect.height) - border_rect.y = (widget->allocation.height - border_rect.height) / 2; - - if (preview->no_preview_pixbuf) - { - buf_rect.width = gdk_pixbuf_get_width (preview->no_preview_pixbuf); - buf_rect.height = gdk_pixbuf_get_height (preview->no_preview_pixbuf); - buf_rect.x = (widget->allocation.width - buf_rect.width) / 2; - buf_rect.y = (widget->allocation.height - buf_rect.height) / 2; - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - /* FIXME: remove when we no longer support GTK 2.0.x */ -#if GTK_CHECK_VERSION(2,2,0) - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - preview->no_preview_pixbuf, - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#else - gdk_pixbuf_render_to_drawable (preview->no_preview_pixbuf, - GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#endif - } - } - else if (preview->buffer) - { - if (preview->border_width > 0) - { - buf_rect.x = border_rect.x + preview->border_width; - buf_rect.y = border_rect.y + preview->border_width; - buf_rect.width = border_rect.width - 2 * preview->border_width; - buf_rect.height = border_rect.height - 2 * preview->border_width; - } - else - { - buf_rect = border_rect; - } - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - buf = (preview->buffer + - (render_rect.y - buf_rect.y) * preview->rowstride + - (render_rect.x - buf_rect.x) * PREVIEW_BYTES); - - gdk_draw_rgb_image_dithalign (widget->window, - widget->style->black_gc, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - buf, - preview->rowstride, - event->area.x, - event->area.y); - } - } - - if (preview->border_width > 0) - { - gint i; - - if (! preview->border_gc) - { - GdkColor color; - guchar r, g, b; - - preview->border_gc = gdk_gc_new (widget->window); - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - color.red = r | r << 8; - color.green = g | g << 8; - color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &color); - } - - for (i = 0; i < preview->border_width; i++) - gdk_draw_rectangle (widget->window, - preview->border_gc, - FALSE, - border_rect.x + i, - border_rect.y + i, - border_rect.width - 2 * i - 1, - border_rect.height - 2 * i - 1); - } + gimp_preview_renderer_draw (preview->renderer, + widget->window, widget, + &rect, + &event->area); return FALSE; } @@ -465,9 +306,9 @@ gimp_preview_button_press_event (GtkWidget *widget, { gimp_preview_popup_show (widget, bevent, preview->viewable, - preview->width, - preview->height, - preview->dot_for_dot); + preview->renderer->width, + preview->renderer->height, + preview->renderer->dot_for_dot); } } else @@ -581,23 +422,28 @@ gimp_preview_new (GimpViewable *viewable, gint border_width, gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GimpPreview *preview; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - viewable_type = G_TYPE_FROM_INSTANCE (viewable); + renderer = gimp_preview_renderer_new (viewable, size, + border_width, is_popup); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + g_return_val_if_fail (renderer != NULL, NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; gimp_preview_set_viewable (preview, viewable); - gimp_preview_set_size (preview, size, border_width); return GTK_WIDGET (preview); @@ -612,8 +458,8 @@ gimp_preview_new_full (GimpViewable *viewable, gboolean clickable, gboolean show_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GimpPreview *preview; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -621,17 +467,22 @@ gimp_preview_new_full (GimpViewable *viewable, g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - viewable_type = G_TYPE_FROM_INSTANCE (viewable); + renderer = gimp_preview_renderer_new_full (viewable, width, height, + border_width, is_popup); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + g_return_val_if_fail (renderer != NULL, NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; preview->clickable = clickable ? TRUE : FALSE; preview->show_popup = show_popup ? TRUE : FALSE; gimp_preview_set_viewable (preview, viewable); - gimp_preview_set_size_full (preview, width, height, border_width); return GTK_WIDGET (preview); @@ -643,19 +494,43 @@ gimp_preview_new_by_type (GType viewable_type, gint border_width, gboolean is_popup) { - GimpPreview *preview; - g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + return gimp_preview_new_by_types (GIMP_TYPE_PREVIEW, viewable_type, + size, border_width, is_popup); +} - preview->is_popup = is_popup ? TRUE : FALSE; - preview->size = size; - preview->border_width = border_width; +GtkWidget * +gimp_preview_new_by_types (GType preview_type, + GType viewable_type, + gint size, + gint border_width, + gboolean is_popup) +{ + GimpPreviewRenderer *renderer; + GimpPreview *preview; + + g_return_val_if_fail (g_type_is_a (preview_type, GIMP_TYPE_PREVIEW), NULL); + g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); + g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); + g_return_val_if_fail (border_width >= 0 && + border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); + + renderer = gimp_preview_renderer_new_by_type (viewable_type, size, + border_width, is_popup); + + g_return_val_if_fail (renderer != NULL, NULL); + + preview = g_object_new (preview_type, NULL); + + g_signal_connect (renderer, "update", + G_CALLBACK (gimp_preview_update_callback), + preview); + + preview->renderer = renderer; return GTK_WIDGET (preview); } @@ -673,33 +548,19 @@ gimp_preview_set_viewable (GimpPreview *preview, { viewable_type = G_TYPE_FROM_INSTANCE (viewable); - g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview), - gimp_preview_type_from_viewable_type (viewable_type))); + g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview->renderer), + gimp_preview_renderer_type_from_viewable_type (viewable_type))); } if (viewable == preview->viewable) return; - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - if (preview->viewable) { g_object_remove_weak_pointer (G_OBJECT (preview->viewable), (gpointer *) &preview->viewable); - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (! viewable && ! preview->is_popup) + if (! viewable && ! preview->renderer->is_popup) { if (gimp_dnd_viewable_source_unset (GTK_WIDGET (preview), G_TYPE_FROM_INSTANCE (preview->viewable))) @@ -708,7 +569,7 @@ gimp_preview_set_viewable (GimpPreview *preview, } } } - else if (viewable && ! preview->is_popup) + else if (viewable && ! preview->renderer->is_popup) { if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (preview), GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, @@ -722,6 +583,7 @@ gimp_preview_set_viewable (GimpPreview *preview, } } + gimp_preview_renderer_set_viewable (preview->renderer, viewable); preview->viewable = viewable; if (preview->viewable) @@ -729,23 +591,6 @@ gimp_preview_set_viewable (GimpPreview *preview, g_object_add_weak_pointer (G_OBJECT (preview->viewable), (gpointer *) &preview->viewable); - g_signal_connect_swapped (preview->viewable, - "invalidate_preview", - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_connect_swapped (preview->viewable, - "size_changed", - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } - gimp_preview_update (preview); } } @@ -755,33 +600,13 @@ gimp_preview_set_size (GimpPreview *preview, gint preview_size, gint border_width) { - gint width, height; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); g_return_if_fail (preview_size > 0 && preview_size <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->size = preview_size; - - if (preview->viewable) - { - gimp_viewable_get_preview_size (preview->viewable, - preview_size, - preview->is_popup, - preview->dot_for_dot, - &width, &height); - } - else - { - width = preview_size; - height = preview_size; - } - - gimp_preview_set_size_full (preview, - width, - height, - border_width); + gimp_preview_renderer_set_size (preview->renderer, preview_size, + border_width); } void @@ -796,26 +621,8 @@ gimp_preview_set_size_full (GimpPreview *preview, g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->width = width; - preview->height = height; - preview->border_width = border_width; - - if (((width + 2 * border_width) != GTK_WIDGET (preview)->requisition.width) || - ((height + 2 * border_width) != GTK_WIDGET (preview)->requisition.height)) - { - GTK_WIDGET (preview)->requisition.width = width + 2 * border_width; - GTK_WIDGET (preview)->requisition.height = height + 2 * border_width; - - preview->rowstride = (preview->width * PREVIEW_BYTES + 3) & ~3; - - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - - gtk_widget_queue_resize (GTK_WIDGET (preview)); - } + gimp_preview_renderer_set_size_full (preview->renderer, width, height, + border_width); } void @@ -824,19 +631,7 @@ gimp_preview_set_dot_for_dot (GimpPreview *preview, { g_return_if_fail (GIMP_IS_PREVIEW (preview)); - if (dot_for_dot != preview->dot_for_dot) - { - preview->dot_for_dot = dot_for_dot ? TRUE: FALSE; - - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } - - gimp_preview_update (preview); - } + gimp_preview_renderer_set_dot_for_dot (preview->renderer, dot_for_dot); } void @@ -846,26 +641,7 @@ gimp_preview_set_border_color (GimpPreview *preview, g_return_if_fail (GIMP_IS_PREVIEW (preview)); g_return_if_fail (color != NULL); - if (gimp_rgb_distance (&preview->border_color, color)) - { - preview->border_color = *color; - - if (preview->border_gc) - { - GdkColor gdk_color; - guchar r, g, b; - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - gdk_color.red = r | r << 8; - gdk_color.green = g | g << 8; - gdk_color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &gdk_color); - } - - gtk_widget_queue_draw (GTK_WIDGET (preview)); - } + gimp_preview_renderer_set_border_color (preview->renderer, color); } void @@ -873,137 +649,38 @@ gimp_preview_update (GimpPreview *preview) { g_return_if_fail (GIMP_IS_PREVIEW (preview)); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - } - - preview->idle_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_update, preview, - NULL); + gimp_preview_renderer_update (preview->renderer); } /* private functions */ -static gboolean -gimp_preview_idle_update (GimpPreview *preview) -{ - preview->idle_id = 0; - - if (preview->viewable) - { - preview->needs_render = TRUE; - gtk_widget_queue_draw (GTK_WIDGET (preview)); - } - - return FALSE; -} - static void -gimp_preview_render (GimpPreview *preview) +gimp_preview_update_callback (GimpPreviewRenderer *renderer, + GimpPreview *preview) { - if (! preview->viewable) - return; + GtkWidget *widget; + gint width; + gint height; + gint border_width; - GIMP_PREVIEW_GET_CLASS (preview)->render (preview); -} + widget = GTK_WIDGET (preview); -static void -gimp_preview_real_render (GimpPreview *preview) -{ - TempBuf *temp_buf; + width = renderer->width; + height = renderer->height; + border_width = renderer->border_width; - temp_buf = gimp_viewable_get_preview (preview->viewable, - preview->width, - preview->height); - - if (temp_buf) + if (width + 2 * border_width != widget->requisition.width || + height + 2 * border_width != widget->requisition.height) { - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } + widget->requisition.width = width + 2 * border_width; + widget->requisition.height = height + 2 * border_width; - if (temp_buf->width < preview->width) - temp_buf->x = (preview->width - temp_buf->width) / 2; - - if (temp_buf->height < preview->height) - temp_buf->y = (preview->height - temp_buf->height) / 2; - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); - } - else /* no preview available */ - { - GdkPixbuf *pixbuf; - const gchar *stock_id; - gint width, height; - - if (preview->buffer) - { - g_free (preview->buffer); - preview->buffer = NULL; - } - - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } - - stock_id = gimp_viewable_get_stock_id (preview->viewable); - pixbuf = gtk_widget_render_icon (GTK_WIDGET (preview), - stock_id, - GTK_ICON_SIZE_DIALOG, - NULL); - if (pixbuf) - { - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - if (width > preview->width || height > preview->height) - { - gdouble ratio = - MIN ((gdouble) preview->width / (gdouble) width, - (gdouble) preview->height / (gdouble) height); - - width = ratio * (gdouble) width; - height = ratio * (gdouble) height; - - preview->no_preview_pixbuf = - gdk_pixbuf_scale_simple (pixbuf, width, height, - GDK_INTERP_BILINEAR); - g_object_unref (pixbuf); - } - else - { - preview->no_preview_pixbuf = pixbuf; - } - } - - preview->needs_render = FALSE; - } -} - -static void -gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable) -{ - if (preview->size != -1) - { - g_print ("size_changed (%d)\n", preview->size); - - gimp_preview_set_size (preview, - preview->size, - preview->border_width); + gtk_widget_queue_resize (widget); } else { - gimp_preview_update (preview); + gtk_widget_queue_draw (widget); } } @@ -1013,206 +690,3 @@ gimp_preview_drag_viewable (GtkWidget *widget, { return GIMP_PREVIEW (widget)->viewable; } - - -/* protected functions */ - -void -gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride) -{ - guchar *src, *s; - guchar *cb; - guchar *pad_buf; - gint a; - gint i, j, b; - gint x1, y1, x2, y2; - gint rowstride; - gboolean color; - gboolean has_alpha; - gboolean render_composite; - gint red_component; - gint green_component; - gint blue_component; - gint alpha_component; - gint offset; - - /* Here are the different cases this functions handles correctly: - * 1) Offset temp_buf which does not necessarily cover full image area - * 2) Color conversion of temp_buf if it is gray and image is color - * 3) Background check buffer for transparent temp_bufs - * 4) Using the optional "channel" argument, one channel can be extracted - * from a multi-channel temp_buf and composited as a grayscale - * Prereqs: - * 1) Grayscale temp_bufs have bytes == {1, 2} - * 2) Color temp_bufs have bytes == {3, 4} - * 3) If image is gray, then temp_buf should have bytes == {1, 2} - */ - - color = (temp_buf->bytes == 3 || temp_buf->bytes == 4); - has_alpha = (temp_buf->bytes == 2 || temp_buf->bytes == 4); - render_composite = (channel == -1); - rowstride = temp_buf->width * temp_buf->bytes; - - /* render the checkerboard only if the temp_buf has alpha *and* - * we render a composite preview - */ - if (has_alpha && render_composite && outside_bg == GIMP_PREVIEW_BG_CHECKS) - pad_buf = render_check_buf; - else if (outside_bg == GIMP_PREVIEW_BG_WHITE) - pad_buf = render_white_buf; - else - pad_buf = render_empty_buf; - - if (render_composite) - { - if (color) - { - red_component = RED_PIX; - green_component = GREEN_PIX; - blue_component = BLUE_PIX; - alpha_component = ALPHA_PIX; - } - else - { - red_component = GRAY_PIX; - green_component = GRAY_PIX; - blue_component = GRAY_PIX; - alpha_component = ALPHA_G_PIX; - } - } - else - { - red_component = channel; - green_component = channel; - blue_component = channel; - alpha_component = 0; - } - - x1 = CLAMP (temp_buf->x, 0, dest_width); - y1 = CLAMP (temp_buf->y, 0, dest_height); - x2 = CLAMP (temp_buf->x + temp_buf->width, 0, dest_width); - y2 = CLAMP (temp_buf->y + temp_buf->height, 0, dest_height); - - src = temp_buf_data (temp_buf) + ((y1 - temp_buf->y) * rowstride + - (x1 - temp_buf->x) * temp_buf->bytes); - - for (i = 0; i < dest_height; i++) - { - if (i & 0x4) - { - offset = 4; - cb = pad_buf + offset * 3; - } - else - { - offset = 0; - cb = pad_buf; - } - - /* The interesting stuff between leading & trailing - * vertical transparency - */ - if (i >= y1 && i < y2) - { - /* Handle the leading transparency */ - for (j = 0; j < x1; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - - /* The stuff in the middle */ - s = src; - for (j = x1; j < x2; j++) - { - if (has_alpha && render_composite) - { - a = s[alpha_component] << 8; - - if (inside_bg == GIMP_PREVIEW_BG_CHECKS) - { - if ((j + offset) & 0x4) - { - render_temp_buf[j * 3 + 0] = - render_blend_dark_check [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_dark_check [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_dark_check [(a | s[blue_component])]; - } - else - { - render_temp_buf[j * 3 + 0] = - render_blend_light_check [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_light_check [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_light_check [(a | s[blue_component])]; - } - } - else /* GIMP_PREVIEW_BG_WHITE */ - { - render_temp_buf[j * 3 + 0] = - render_blend_white [(a | s[red_component])]; - render_temp_buf[j * 3 + 1] = - render_blend_white [(a | s[green_component])]; - render_temp_buf[j * 3 + 2] = - render_blend_white [(a | s[blue_component])]; - } - } - else - { - render_temp_buf[j * 3 + 0] = s[red_component]; - render_temp_buf[j * 3 + 1] = s[green_component]; - render_temp_buf[j * 3 + 2] = s[blue_component]; - } - - s += temp_buf->bytes; - } - - /* Handle the trailing transparency */ - for (j = x2; j < dest_width; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - - src += rowstride; - } - else - { - for (j = 0; j < dest_width; j++) - for (b = 0; b < PREVIEW_BYTES; b++) - render_temp_buf[j * PREVIEW_BYTES + b] = cb[j * 3 + b]; - } - - memcpy (dest_buffer + i * dest_rowstride, - render_temp_buf, - dest_width * PREVIEW_BYTES); - } -} - -void -gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg) -{ - if (! preview->buffer) - preview->buffer = g_new0 (guchar, preview->height * preview->rowstride); - - gimp_preview_render_to_buffer (temp_buf, - channel, - inside_bg, - outside_bg, - preview->buffer, - preview->width, - preview->height, - preview->rowstride); - - preview->needs_render = FALSE; -} diff --git a/app/widgets/gimpview.h b/app/widgets/gimpview.h index 5ba2aacdb5..201be04a80 100644 --- a/app/widgets/gimpview.h +++ b/app/widgets/gimpview.h @@ -42,34 +42,18 @@ typedef struct _GimpPreviewClass GimpPreviewClass; struct _GimpPreview { - GtkDrawingArea parent_instance; + GtkDrawingArea parent_instance; - GimpViewable *viewable; + GimpViewable *viewable; + GimpPreviewRenderer *renderer; - gint width; - gint height; - gint border_width; - gboolean dot_for_dot; - - GimpRGB border_color; - GdkGC *border_gc; - - gboolean is_popup; - gboolean clickable; - gboolean eat_button_events; - gboolean show_popup; + gboolean clickable; + gboolean eat_button_events; + gboolean show_popup; /*< private >*/ - guchar *buffer; - gint rowstride; - - GdkPixbuf *no_preview_pixbuf; - - gint size; - gboolean in_button; - guint press_state; - guint idle_id; - gboolean needs_render; + gboolean in_button; + guint press_state; }; struct _GimpPreviewClass @@ -82,9 +66,6 @@ struct _GimpPreviewClass void (* extended_clicked) (GimpPreview *preview, guint modifier_state); void (* context) (GimpPreview *preview); - - /* virtual functions */ - void (* render) (GimpPreview *preview); }; @@ -103,6 +84,11 @@ GtkWidget * gimp_preview_new_full (GimpViewable *viewable, gboolean show_popup); GtkWidget * gimp_preview_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup); +GtkWidget * gimp_preview_new_by_types (GType preview_type, + GType viewable_type, gint size, gint border_width, gboolean is_popup); @@ -129,20 +115,6 @@ void gimp_preview_update (GimpPreview *preview); /* protected */ -typedef enum -{ - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE -} GimpPreviewBG; - -void gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride); void gimp_preview_render_preview (GimpPreview *preview, TempBuf *temp_buf, gint channel, diff --git a/app/widgets/gimpviewrenderer-utils.c b/app/widgets/gimpviewrenderer-utils.c new file mode 100644 index 0000000000..c88a7e5cc4 --- /dev/null +++ b/app/widgets/gimpviewrenderer-utils.c @@ -0,0 +1,59 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimppreviewrenderer-utils.c + * Copyright (C) 2003 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 "widgets-types.h" + +#include "core/gimpbrush.h" +#include "core/gimpdrawable.h" +#include "core/gimpimage.h" + +#include "gimppreviewrendererbrush.h" +#include "gimppreviewrendererdrawable.h" +#include "gimppreviewrendererimage.h" + + +GType +gimp_preview_renderer_type_from_viewable_type (GType viewable_type) +{ + GType type = GIMP_TYPE_PREVIEW_RENDERER; + + g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), + G_TYPE_NONE); + + if (g_type_is_a (viewable_type, GIMP_TYPE_BRUSH)) + { + type = GIMP_TYPE_PREVIEW_RENDERER_BRUSH; + } + else if (g_type_is_a (viewable_type, GIMP_TYPE_IMAGE)) + { + type = GIMP_TYPE_PREVIEW_RENDERER_IMAGE; + } + else if (g_type_is_a (viewable_type, GIMP_TYPE_DRAWABLE)) + { + type = GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE; + } + + return type; +} diff --git a/app/widgets/gimpviewrenderer-utils.h b/app/widgets/gimpviewrenderer-utils.h new file mode 100644 index 0000000000..a43a8bed78 --- /dev/null +++ b/app/widgets/gimpviewrenderer-utils.h @@ -0,0 +1,29 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimppreviewrenderer-utils.h + * Copyright (C) 2003 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_PREVIEW_RENDERER_UTILS_H__ +#define __GIMP_PREVIEW_RENDERER_UTILS_H__ + + +GType gimp_preview_renderer_type_from_viewable_type (GType viewable_type); + + +#endif /* __GIMP_PREVIEW_RENDERER_UTILS_H__ */ diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c index f04c7ffdf8..7f5cc99e3b 100644 --- a/app/widgets/gimpviewrenderer.c +++ b/app/widgets/gimpviewrenderer.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview.c - * Copyright (C) 2001 Michael Natterer + * gimppreviewrenderer.c + * Copyright (C) 2003 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 @@ -44,545 +44,161 @@ #include "display/gimpdisplayshell-render.h" -#include "gimpdnd.h" -#include "gimppreview.h" -#include "gimppreview-popup.h" -#include "gimppreview-utils.h" +#include "gimppreviewrenderer.h" +#include "gimppreviewrenderer-utils.h" -#define PREVIEW_BYTES 3 +#define PREVIEW_BYTES 3 -#define PREVIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK | \ - GDK_BUTTON_RELEASE_MASK | \ - GDK_ENTER_NOTIFY_MASK | \ - GDK_LEAVE_NOTIFY_MASK) enum { - CLICKED, - DOUBLE_CLICKED, - EXTENDED_CLICKED, - CONTEXT, + UPDATE, LAST_SIGNAL }; -static void gimp_preview_class_init (GimpPreviewClass *klass); -static void gimp_preview_init (GimpPreview *preview); +static void gimp_preview_renderer_class_init (GimpPreviewRendererClass *klass); +static void gimp_preview_renderer_init (GimpPreviewRenderer *renderer); -static void gimp_preview_destroy (GtkObject *object); -static void gimp_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean gimp_preview_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static gboolean gimp_preview_button_press_event (GtkWidget *widget, - GdkEventButton *bevent); -static gboolean gimp_preview_button_release_event (GtkWidget *widget, - GdkEventButton *bevent); -static gboolean gimp_preview_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event); -static gboolean gimp_preview_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event); +static void gimp_preview_renderer_finalize (GObject *object); -static gboolean gimp_preview_idle_update (GimpPreview *preview); -static void gimp_preview_render (GimpPreview *preview); -static void gimp_preview_real_render (GimpPreview *preview); +static gboolean gimp_preview_renderer_idle_update (GimpPreviewRenderer *renderer); +static void gimp_preview_renderer_real_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static void gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable); -static GimpViewable * gimp_preview_drag_viewable (GtkWidget *widget, - gpointer data); +static void gimp_preview_renderer_size_changed (GimpPreviewRenderer *renderer, + GimpViewable *viewable); -static guint preview_signals[LAST_SIGNAL] = { 0 }; +static guint renderer_signals[LAST_SIGNAL] = { 0 }; -static GtkDrawingAreaClass *parent_class = NULL; +static GObjectClass *parent_class = NULL; GType -gimp_preview_get_type (void) +gimp_preview_renderer_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpPreviewClass), + sizeof (GimpPreviewRendererClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpPreview), + sizeof (GimpPreviewRenderer), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_init, }; - preview_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, - "GimpPreview", - &preview_info, 0); + renderer_type = g_type_register_static (G_TYPE_OBJECT, + "GimpPreviewRenderer", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_preview_class_init (GimpPreviewClass *klass) +gimp_preview_renderer_class_init (GimpPreviewRendererClass *klass) { - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; + GObjectClass *object_class; - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_signals[CLICKED] = - g_signal_new ("clicked", + renderer_signals[UPDATE] = + g_signal_new ("update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, clicked), + G_STRUCT_OFFSET (GimpPreviewRendererClass, update), NULL, NULL, gimp_marshal_VOID__VOID, G_TYPE_NONE, 0); - preview_signals[DOUBLE_CLICKED] = - g_signal_new ("double_clicked", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, double_clicked), - NULL, NULL, - gimp_marshal_VOID__VOID, - G_TYPE_NONE, 0); + object_class->finalize = gimp_preview_renderer_finalize; - preview_signals[EXTENDED_CLICKED] = - g_signal_new ("extended_clicked", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, extended_clicked), - NULL, NULL, - gimp_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - preview_signals[CONTEXT] = - g_signal_new ("context", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GimpPreviewClass, context), - NULL, NULL, - gimp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->destroy = gimp_preview_destroy; - - widget_class->activate_signal = preview_signals[CLICKED]; - widget_class->size_allocate = gimp_preview_size_allocate; - widget_class->expose_event = gimp_preview_expose_event; - widget_class->button_press_event = gimp_preview_button_press_event; - widget_class->button_release_event = gimp_preview_button_release_event; - widget_class->enter_notify_event = gimp_preview_enter_notify_event; - widget_class->leave_notify_event = gimp_preview_leave_notify_event; - - klass->clicked = NULL; - klass->double_clicked = NULL; - klass->extended_clicked = NULL; - klass->context = NULL; - klass->render = gimp_preview_real_render; + klass->render = gimp_preview_renderer_real_render; } static void -gimp_preview_init (GimpPreview *preview) +gimp_preview_renderer_init (GimpPreviewRenderer *renderer) { - preview->viewable = NULL; + renderer->viewable = NULL; - preview->width = 8; - preview->height = 8; - preview->border_width = 0; - preview->dot_for_dot = TRUE; + renderer->width = 8; + renderer->height = 8; + renderer->border_width = 0; + renderer->dot_for_dot = TRUE; + renderer->is_popup = FALSE; - gimp_rgba_set (&preview->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); - preview->border_gc = NULL; + gimp_rgba_set (&renderer->border_color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE); + renderer->border_gc = NULL; - preview->is_popup = FALSE; - preview->clickable = FALSE; - preview->eat_button_events = TRUE; - preview->show_popup = FALSE; + renderer->buffer = NULL; + renderer->rowstride = 0; - preview->buffer = NULL; - preview->rowstride = 0; + renderer->no_preview_pixbuf = NULL; - preview->no_preview_pixbuf = NULL; - - preview->size = -1; - preview->in_button = FALSE; - preview->idle_id = 0; - preview->needs_render = TRUE; - - gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_EVENT_MASK); + renderer->size = -1; + renderer->needs_render = TRUE; + renderer->idle_id = 0; } static void -gimp_preview_destroy (GtkObject *object) +gimp_preview_renderer_finalize (GObject *object) { - GimpPreview *preview; + GimpPreviewRenderer *renderer; - preview = GIMP_PREVIEW (object); + renderer = GIMP_PREVIEW_RENDERER (object); - if (preview->idle_id) + if (renderer->idle_id) { - g_source_remove (preview->idle_id); - preview->idle_id = 0; + g_source_remove (renderer->idle_id); + renderer->idle_id = 0; } - if (preview->viewable) - gimp_preview_set_viewable (preview, NULL); + if (renderer->viewable) + gimp_preview_renderer_set_viewable (renderer, NULL); - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->no_preview_pixbuf) + if (renderer->no_preview_pixbuf) { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; } - if (preview->border_gc) + if (renderer->border_gc) { - g_object_unref (preview->border_gc); - preview->border_gc = NULL; + g_object_unref (renderer->border_gc); + renderer->border_gc = NULL; } - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -gimp_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - GimpPreview *preview; - gint width; - gint height; - - preview = GIMP_PREVIEW (widget); - - width = preview->width + 2 * preview->border_width; - height = preview->height + 2 * preview->border_width; - - if (allocation->width > width) - allocation->x += (allocation->width - width) / 2; - - if (allocation->height > height) - allocation->y += (allocation->height - height) / 2; - - allocation->width = width; - allocation->height = height; - - preview->needs_render = TRUE; - - if (GTK_WIDGET_CLASS (parent_class)->size_allocate) - GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); -} - -static gboolean -gimp_preview_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - GimpPreview *preview; - guchar *buf; - GdkRectangle border_rect; - GdkRectangle buf_rect; - GdkRectangle render_rect; - - preview = GIMP_PREVIEW (widget); - - if (preview->needs_render) - gimp_preview_render (preview); - - if (! GTK_WIDGET_DRAWABLE (widget)) - return FALSE; - - border_rect.x = 0; - border_rect.y = 0; - border_rect.width = preview->width + 2 * preview->border_width; - border_rect.height = preview->height + 2 * preview->border_width; - - if (widget->allocation.width > border_rect.width) - border_rect.x = (widget->allocation.width - border_rect.width) / 2; - - if (widget->allocation.height > border_rect.height) - border_rect.y = (widget->allocation.height - border_rect.height) / 2; - - if (preview->no_preview_pixbuf) - { - buf_rect.width = gdk_pixbuf_get_width (preview->no_preview_pixbuf); - buf_rect.height = gdk_pixbuf_get_height (preview->no_preview_pixbuf); - buf_rect.x = (widget->allocation.width - buf_rect.width) / 2; - buf_rect.y = (widget->allocation.height - buf_rect.height) / 2; - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - /* FIXME: remove when we no longer support GTK 2.0.x */ -#if GTK_CHECK_VERSION(2,2,0) - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - preview->no_preview_pixbuf, - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#else - gdk_pixbuf_render_to_drawable (preview->no_preview_pixbuf, - GDK_DRAWABLE (widget->window), - widget->style->bg_gc[widget->state], - render_rect.x - buf_rect.x, - render_rect.y - buf_rect.y, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - event->area.x, - event->area.y); -#endif - } - } - else if (preview->buffer) - { - if (preview->border_width > 0) - { - buf_rect.x = border_rect.x + preview->border_width; - buf_rect.y = border_rect.y + preview->border_width; - buf_rect.width = border_rect.width - 2 * preview->border_width; - buf_rect.height = border_rect.height - 2 * preview->border_width; - } - else - { - buf_rect = border_rect; - } - - if (gdk_rectangle_intersect (&buf_rect, &event->area, &render_rect)) - { - buf = (preview->buffer + - (render_rect.y - buf_rect.y) * preview->rowstride + - (render_rect.x - buf_rect.x) * PREVIEW_BYTES); - - gdk_draw_rgb_image_dithalign (widget->window, - widget->style->black_gc, - render_rect.x, - render_rect.y, - render_rect.width, - render_rect.height, - GDK_RGB_DITHER_NORMAL, - buf, - preview->rowstride, - event->area.x, - event->area.y); - } - } - - if (preview->border_width > 0) - { - gint i; - - if (! preview->border_gc) - { - GdkColor color; - guchar r, g, b; - - preview->border_gc = gdk_gc_new (widget->window); - - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); - - color.red = r | r << 8; - color.green = g | g << 8; - color.blue = b | b << 8; - - gdk_gc_set_rgb_fg_color (preview->border_gc, &color); - } - - for (i = 0; i < preview->border_width; i++) - gdk_draw_rectangle (widget->window, - preview->border_gc, - FALSE, - border_rect.x + i, - border_rect.y + i, - border_rect.width - 2 * i - 1, - border_rect.height - 2 * i - 1); - } - - return FALSE; -} - - -#define DEBUG_MEMSIZE 1 - -#ifdef DEBUG_MEMSIZE -extern gboolean gimp_debug_memsize; -#endif - -static gboolean -gimp_preview_button_press_event (GtkWidget *widget, - GdkEventButton *bevent) -{ - GimpPreview *preview; - - preview = GIMP_PREVIEW (widget); - -#ifdef DEBUG_MEMSIZE - if (bevent->type == GDK_BUTTON_PRESS && bevent->button == 2) - { - gimp_debug_memsize = TRUE; - - gimp_object_get_memsize (GIMP_OBJECT (preview->viewable)); - - gimp_debug_memsize = FALSE; - } -#endif /* DEBUG_MEMSIZE */ - - if (! preview->clickable && - ! preview->show_popup) - return FALSE; - - if (bevent->type == GDK_BUTTON_PRESS) - { - if (bevent->button == 1) - { - gtk_grab_add (widget); - - preview->press_state = bevent->state; - - if (preview->show_popup) - { - gimp_preview_popup_show (widget, bevent, - preview->viewable, - preview->width, - preview->height, - preview->dot_for_dot); - } - } - else - { - preview->press_state = 0; - - if (bevent->button == 3) - { - g_signal_emit (widget, preview_signals[CONTEXT], 0); - } - else - { - return FALSE; - } - } - } - else if (bevent->type == GDK_2BUTTON_PRESS) - { - if (bevent->button == 1) - { - g_signal_emit (widget, preview_signals[DOUBLE_CLICKED], 0); - } - } - - return preview->eat_button_events ? TRUE : FALSE; -} - -static gboolean -gimp_preview_button_release_event (GtkWidget *widget, - GdkEventButton *bevent) -{ - GimpPreview *preview; - - preview = GIMP_PREVIEW (widget); - - if (! preview->clickable && - ! preview->show_popup) - return FALSE; - - if (bevent->button == 1) - { - gtk_grab_remove (widget); - - if (preview->clickable && preview->in_button) - { - if (preview->press_state & - (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) - { - g_signal_emit (widget, - preview_signals[EXTENDED_CLICKED], 0, - preview->press_state); - } - else - { - g_signal_emit (widget, preview_signals[CLICKED], 0); - } - } - } - else - { - return FALSE; - } - - return preview->eat_button_events ? TRUE : FALSE; -} - -static gboolean -gimp_preview_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event) -{ - GimpPreview *preview; - GtkWidget *event_widget; - - preview = GIMP_PREVIEW (widget); - event_widget = gtk_get_event_widget ((GdkEvent *) event); - - if ((event_widget == widget) && - (event->detail != GDK_NOTIFY_INFERIOR)) - { - preview->in_button = TRUE; - } - - return FALSE; -} - -static gboolean -gimp_preview_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) -{ - GimpPreview *preview; - GtkWidget *event_widget; - - preview = GIMP_PREVIEW (widget); - event_widget = gtk_get_event_widget ((GdkEvent *) event); - - if ((event_widget == widget) && - (event->detail != GDK_NOTIFY_INFERIOR)) - { - preview->in_button = FALSE; - } - - return FALSE; + G_OBJECT_CLASS (parent_class)->finalize (object); } /* public functions */ -GtkWidget * -gimp_preview_new (GimpViewable *viewable, - gint size, - gint border_width, - gboolean is_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new (GimpViewable *viewable, + gint size, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GType viewable_type; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -591,29 +207,26 @@ gimp_preview_new (GimpViewable *viewable, viewable_type = G_TYPE_FROM_INSTANCE (viewable); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; + renderer->is_popup = is_popup ? TRUE : FALSE; - gimp_preview_set_viewable (preview, viewable); + gimp_preview_renderer_set_viewable (renderer, viewable); + gimp_preview_renderer_set_size (renderer, size, border_width); - gimp_preview_set_size (preview, size, border_width); - - return GTK_WIDGET (preview); + return renderer; } -GtkWidget * -gimp_preview_new_full (GimpViewable *viewable, - gint width, - gint height, - gint border_width, - gboolean is_popup, - gboolean clickable, - gboolean show_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new_full (GimpViewable *viewable, + gint width, + gint height, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; - GType viewable_type; + GimpPreviewRenderer *renderer; + GType viewable_type; g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL); g_return_val_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE, NULL); @@ -623,153 +236,131 @@ gimp_preview_new_full (GimpViewable *viewable, viewable_type = G_TYPE_FROM_INSTANCE (viewable); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; - preview->clickable = clickable ? TRUE : FALSE; - preview->show_popup = show_popup ? TRUE : FALSE; + renderer->is_popup = is_popup ? TRUE : FALSE; - gimp_preview_set_viewable (preview, viewable); + gimp_preview_renderer_set_viewable (renderer, viewable); + gimp_preview_renderer_set_size_full (renderer, width, height, border_width); - gimp_preview_set_size_full (preview, width, height, border_width); - - return GTK_WIDGET (preview); + return renderer; } -GtkWidget * -gimp_preview_new_by_type (GType viewable_type, - gint size, - gint border_width, - gboolean is_popup) +GimpPreviewRenderer * +gimp_preview_renderer_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup) { - GimpPreview *preview; + GimpPreviewRenderer *renderer; g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL); g_return_val_if_fail (size > 0 && size <= GIMP_PREVIEW_MAX_SIZE, NULL); g_return_val_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); - preview = g_object_new (gimp_preview_type_from_viewable_type (viewable_type), - NULL); + renderer = g_object_new (gimp_preview_renderer_type_from_viewable_type (viewable_type), + NULL); - preview->is_popup = is_popup ? TRUE : FALSE; - preview->size = size; - preview->border_width = border_width; + renderer->is_popup = is_popup ? TRUE : FALSE; + renderer->size = size; + renderer->border_width = border_width; - return GTK_WIDGET (preview); + return renderer; } void -gimp_preview_set_viewable (GimpPreview *preview, - GimpViewable *viewable) +gimp_preview_renderer_set_viewable (GimpPreviewRenderer *renderer, + GimpViewable *viewable) { GType viewable_type = G_TYPE_NONE; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (! viewable || GIMP_IS_VIEWABLE (viewable)); if (viewable) { viewable_type = G_TYPE_FROM_INSTANCE (viewable); - g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (preview), - gimp_preview_type_from_viewable_type (viewable_type))); + g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (renderer), + gimp_preview_renderer_type_from_viewable_type (viewable_type))); } - if (viewable == preview->viewable) + if (viewable == renderer->viewable) return; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->viewable) + if (renderer->no_preview_pixbuf) { - g_object_remove_weak_pointer (G_OBJECT (preview->viewable), - (gpointer *) &preview->viewable); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_update), - preview); - - g_signal_handlers_disconnect_by_func (preview->viewable, - G_CALLBACK (gimp_preview_size_changed), - preview); - - if (! viewable && ! preview->is_popup) - { - if (gimp_dnd_viewable_source_unset (GTK_WIDGET (preview), - G_TYPE_FROM_INSTANCE (preview->viewable))) - { - gtk_drag_source_unset (GTK_WIDGET (preview)); - } - } - } - else if (viewable && ! preview->is_popup) - { - if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (preview), - GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, - viewable_type, - GDK_ACTION_COPY)) - { - gimp_dnd_viewable_source_set (GTK_WIDGET (preview), - viewable_type, - gimp_preview_drag_viewable, - NULL); - } + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; } - preview->viewable = viewable; - - if (preview->viewable) + if (renderer->viewable) { - g_object_add_weak_pointer (G_OBJECT (preview->viewable), - (gpointer *) &preview->viewable); + g_object_remove_weak_pointer (G_OBJECT (renderer->viewable), + (gpointer *) &renderer->viewable); - g_signal_connect_swapped (preview->viewable, + g_signal_handlers_disconnect_by_func (renderer->viewable, + G_CALLBACK (gimp_preview_renderer_update), + renderer); + + g_signal_handlers_disconnect_by_func (renderer->viewable, + G_CALLBACK (gimp_preview_renderer_size_changed), + renderer); + } + + renderer->viewable = viewable; + + if (renderer->viewable) + { + g_object_add_weak_pointer (G_OBJECT (renderer->viewable), + (gpointer *) &renderer->viewable); + + g_signal_connect_swapped (renderer->viewable, "invalidate_preview", - G_CALLBACK (gimp_preview_update), - preview); + G_CALLBACK (gimp_preview_renderer_update), + renderer); - g_signal_connect_swapped (preview->viewable, + g_signal_connect_swapped (renderer->viewable, "size_changed", - G_CALLBACK (gimp_preview_size_changed), - preview); + G_CALLBACK (gimp_preview_renderer_size_changed), + renderer); - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); - gimp_preview_update (preview); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_size (GimpPreview *preview, - gint preview_size, - gint border_width) +gimp_preview_renderer_set_size (GimpPreviewRenderer *renderer, + gint preview_size, + gint border_width) { gint width, height; - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (preview_size > 0 && preview_size <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->size = preview_size; + renderer->size = preview_size; - if (preview->viewable) + if (renderer->viewable) { - gimp_viewable_get_preview_size (preview->viewable, + gimp_viewable_get_preview_size (renderer->viewable, preview_size, - preview->is_popup, - preview->dot_for_dot, + renderer->is_popup, + renderer->dot_for_dot, &width, &height); } else @@ -778,240 +369,386 @@ gimp_preview_set_size (GimpPreview *preview, height = preview_size; } - gimp_preview_set_size_full (preview, - width, - height, - border_width); + gimp_preview_renderer_set_size_full (renderer, width, height, border_width); } void -gimp_preview_set_size_full (GimpPreview *preview, - gint width, - gint height, - gint border_width) +gimp_preview_renderer_set_size_full (GimpPreviewRenderer *renderer, + gint width, + gint height, + gint border_width) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (width > 0 && width <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (height > 0 && height <= GIMP_PREVIEW_MAX_SIZE); g_return_if_fail (border_width >= 0 && border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH); - preview->width = width; - preview->height = height; - preview->border_width = border_width; - - if (((width + 2 * border_width) != GTK_WIDGET (preview)->requisition.width) || - ((height + 2 * border_width) != GTK_WIDGET (preview)->requisition.height)) + if (width != renderer->width || + height != renderer->height || + border_width != renderer->border_width) { - GTK_WIDGET (preview)->requisition.width = width + 2 * border_width; - GTK_WIDGET (preview)->requisition.height = height + 2 * border_width; + renderer->width = width; + renderer->height = height; + renderer->border_width = border_width; - preview->rowstride = (preview->width * PREVIEW_BYTES + 3) & ~3; + renderer->rowstride = (renderer->width * PREVIEW_BYTES + 3) & ~3; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - gtk_widget_queue_resize (GTK_WIDGET (preview)); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_dot_for_dot (GimpPreview *preview, - gboolean dot_for_dot) +gimp_preview_renderer_set_dot_for_dot (GimpPreviewRenderer *renderer, + gboolean dot_for_dot) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); - if (dot_for_dot != preview->dot_for_dot) + if (dot_for_dot != renderer->dot_for_dot) { - preview->dot_for_dot = dot_for_dot ? TRUE: FALSE; + renderer->dot_for_dot = dot_for_dot ? TRUE: FALSE; - if (preview->size != -1) - { - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); - gimp_preview_update (preview); + gimp_preview_renderer_update (renderer); } } void -gimp_preview_set_border_color (GimpPreview *preview, - const GimpRGB *color) +gimp_preview_renderer_set_border_color (GimpPreviewRenderer *renderer, + const GimpRGB *color) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); g_return_if_fail (color != NULL); - if (gimp_rgb_distance (&preview->border_color, color)) + if (gimp_rgb_distance (&renderer->border_color, color)) { - preview->border_color = *color; + renderer->border_color = *color; - if (preview->border_gc) + if (renderer->border_gc) { GdkColor gdk_color; guchar r, g, b; - gimp_rgb_get_uchar (&preview->border_color, &r, &g, &b); + gimp_rgb_get_uchar (&renderer->border_color, &r, &g, &b); gdk_color.red = r | r << 8; gdk_color.green = g | g << 8; gdk_color.blue = b | b << 8; - gdk_gc_set_rgb_fg_color (preview->border_gc, &gdk_color); + gdk_gc_set_rgb_fg_color (renderer->border_gc, &gdk_color); } - gtk_widget_queue_draw (GTK_WIDGET (preview)); + g_signal_emit (renderer, renderer_signals[UPDATE], 0); } } void -gimp_preview_update (GimpPreview *preview) +gimp_preview_renderer_update (GimpPreviewRenderer *renderer) { - g_return_if_fail (GIMP_IS_PREVIEW (preview)); + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); - if (preview->idle_id) - { - g_source_remove (preview->idle_id); - } + if (renderer->idle_id) + g_source_remove (renderer->idle_id); - preview->idle_id = + renderer->idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) gimp_preview_idle_update, preview, + (GSourceFunc) gimp_preview_renderer_idle_update, renderer, NULL); } +void +gimp_preview_renderer_draw (GimpPreviewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *draw_area, + GdkRectangle *expose_area) +{ + GdkRectangle border_rect; + GdkRectangle buf_rect; + GdkRectangle render_rect; + + g_return_if_fail (GIMP_IS_PREVIEW_RENDERER (renderer)); + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (draw_area != NULL); + g_return_if_fail (expose_area != NULL); + + if (! GTK_WIDGET_DRAWABLE (widget) || ! renderer->viewable) + return; + + if (renderer->needs_render) + GIMP_PREVIEW_RENDERER_GET_CLASS (renderer)->render (renderer, widget); + + border_rect.x = draw_area->x; + border_rect.y = draw_area->y; + border_rect.width = renderer->width + 2 * renderer->border_width; + border_rect.height = renderer->height + 2 * renderer->border_width; + + if (draw_area->width > border_rect.width) + border_rect.x += (draw_area->width - border_rect.width) / 2; + + if (draw_area->height > border_rect.height) + border_rect.y += (draw_area->height - border_rect.height) / 2; + + if (renderer->no_preview_pixbuf) + { + buf_rect.width = gdk_pixbuf_get_width (renderer->no_preview_pixbuf); + buf_rect.height = gdk_pixbuf_get_height (renderer->no_preview_pixbuf); + buf_rect.x = (draw_area->width - buf_rect.width) / 2; + buf_rect.y = (draw_area->height - buf_rect.height) / 2; + + buf_rect.x += draw_area->x; + buf_rect.y += draw_area->y; + + if (gdk_rectangle_intersect (&buf_rect, expose_area, &render_rect)) + { + /* FIXME: remove when we no longer support GTK 2.0.x */ +#if GTK_CHECK_VERSION(2,2,0) + gdk_draw_pixbuf (GDK_DRAWABLE (window), + widget->style->bg_gc[widget->state], + renderer->no_preview_pixbuf, + render_rect.x - buf_rect.x, + render_rect.y - buf_rect.y, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); +#else + gdk_pixbuf_render_to_drawable (renderer->no_preview_pixbuf, + window, + widget->style->bg_gc[widget->state], + render_rect.x - buf_rect.x, + render_rect.y - buf_rect.y, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); +#endif + } + } + else if (renderer->buffer) + { + if (renderer->border_width > 0) + { + buf_rect.x = border_rect.x + renderer->border_width; + buf_rect.y = border_rect.y + renderer->border_width; + buf_rect.width = border_rect.width - 2 * renderer->border_width; + buf_rect.height = border_rect.height - 2 * renderer->border_width; + } + else + { + buf_rect = border_rect; + } + + if (gdk_rectangle_intersect (&buf_rect, expose_area, &render_rect)) + { + guchar *buf; + + buf = (renderer->buffer + + (render_rect.y - buf_rect.y) * renderer->rowstride + + (render_rect.x - buf_rect.x) * PREVIEW_BYTES); + + gdk_draw_rgb_image_dithalign (window, + widget->style->black_gc, + render_rect.x, + render_rect.y, + render_rect.width, + render_rect.height, + GDK_RGB_DITHER_NORMAL, + buf, + renderer->rowstride, + expose_area->x - draw_area->x, + expose_area->y - draw_area->y); + } + } + + if (renderer->border_width > 0) + { + gint i; + + if (! renderer->border_gc) + { + GdkColor color; + guchar r, g, b; + + renderer->border_gc = gdk_gc_new (window); + + gimp_rgb_get_uchar (&renderer->border_color, &r, &g, &b); + + color.red = r | r << 8; + color.green = g | g << 8; + color.blue = b | b << 8; + + gdk_gc_set_rgb_fg_color (renderer->border_gc, &color); + } + + for (i = 0; i < renderer->border_width; i++) + gdk_draw_rectangle (window, + renderer->border_gc, + FALSE, + border_rect.x + i, + border_rect.y + i, + border_rect.width - 2 * i - 1, + border_rect.height - 2 * i - 1); + } +} /* private functions */ static gboolean -gimp_preview_idle_update (GimpPreview *preview) +gimp_preview_renderer_idle_update (GimpPreviewRenderer *renderer) { - preview->idle_id = 0; + renderer->idle_id = 0; - if (preview->viewable) + if (renderer->viewable) { - preview->needs_render = TRUE; - gtk_widget_queue_draw (GTK_WIDGET (preview)); + renderer->needs_render = TRUE; + + g_signal_emit (renderer, renderer_signals[UPDATE], 0); } return FALSE; } static void -gimp_preview_render (GimpPreview *preview) -{ - if (! preview->viewable) - return; - - GIMP_PREVIEW_GET_CLASS (preview)->render (preview); -} - -static void -gimp_preview_real_render (GimpPreview *preview) +gimp_preview_renderer_real_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_preview (preview->viewable, - preview->width, - preview->height); + if (renderer->no_preview_pixbuf) + { + g_object_unref (renderer->no_preview_pixbuf); + renderer->no_preview_pixbuf = NULL; + } + + temp_buf = gimp_viewable_get_preview (renderer->viewable, + renderer->width, + renderer->height); if (temp_buf) { - if (preview->no_preview_pixbuf) - { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; - } + if (temp_buf->width < renderer->width) + temp_buf->x = (renderer->width - temp_buf->width) / 2; - if (temp_buf->width < preview->width) - temp_buf->x = (preview->width - temp_buf->width) / 2; + if (temp_buf->height < renderer->height) + temp_buf->y = (renderer->height - temp_buf->height) / 2; - if (temp_buf->height < preview->height) - temp_buf->y = (preview->height - temp_buf->height) / 2; - - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_WHITE); } else /* no preview available */ { - GdkPixbuf *pixbuf; - const gchar *stock_id; - gint width, height; + GdkPixbuf *pixbuf; + GtkIconSet *icon_set; + GtkIconSize *sizes; + gint n_sizes; + gint i; + gint width_diff = 1024; + gint height_diff = 1024; + GtkIconSize icon_size = GTK_ICON_SIZE_MENU; + const gchar *stock_id; - if (preview->buffer) + if (renderer->buffer) { - g_free (preview->buffer); - preview->buffer = NULL; + g_free (renderer->buffer); + renderer->buffer = NULL; } - if (preview->no_preview_pixbuf) + stock_id = gimp_viewable_get_stock_id (renderer->viewable); + icon_set = gtk_style_lookup_icon_set (widget->style, stock_id); + + gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes); + + for (i = 0; i < n_sizes; i++) { - g_object_unref (preview->no_preview_pixbuf); - preview->no_preview_pixbuf = NULL; + gint icon_width; + gint icon_height; + + if (gtk_icon_size_lookup (sizes[i], &icon_width, &icon_height)) + { + if (icon_width <= renderer->width && + icon_height <= renderer->height && + (ABS (icon_width - renderer->width) < width_diff || + ABS (icon_height - renderer->height) < height_diff)) + { + width_diff = ABS (icon_width - renderer->width); + height_diff = ABS (icon_height - renderer->height); + + icon_size = sizes[i]; + } + } } - stock_id = gimp_viewable_get_stock_id (preview->viewable); - pixbuf = gtk_widget_render_icon (GTK_WIDGET (preview), - stock_id, - GTK_ICON_SIZE_DIALOG, - NULL); + g_free (sizes); + + pixbuf = gtk_icon_set_render_icon (icon_set, + widget->style, + gtk_widget_get_direction (widget), + widget->state, + icon_size, + widget, NULL); + if (pixbuf) { - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - if (width > preview->width || height > preview->height) + if (gdk_pixbuf_get_width (pixbuf) > renderer->width || + gdk_pixbuf_get_height (pixbuf) > renderer->height) { - gdouble ratio = - MIN ((gdouble) preview->width / (gdouble) width, - (gdouble) preview->height / (gdouble) height); + GdkPixbuf *scaled_pixbuf; + gint pixbuf_width; + gint pixbuf_height; - width = ratio * (gdouble) width; - height = ratio * (gdouble) height; + gimp_viewable_calc_preview_size (renderer->viewable, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + renderer->width, + renderer->height, + TRUE, 1.0, 1.0, + &pixbuf_width, + &pixbuf_height, + NULL); + + scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, + pixbuf_width, + pixbuf_height, + GDK_INTERP_BILINEAR); - preview->no_preview_pixbuf = - gdk_pixbuf_scale_simple (pixbuf, width, height, - GDK_INTERP_BILINEAR); g_object_unref (pixbuf); + pixbuf = scaled_pixbuf; } - else - { - preview->no_preview_pixbuf = pixbuf; - } + + renderer->no_preview_pixbuf = pixbuf; } - preview->needs_render = FALSE; + renderer->needs_render = FALSE; } } static void -gimp_preview_size_changed (GimpPreview *preview, - GimpViewable *viewable) +gimp_preview_renderer_size_changed (GimpPreviewRenderer *renderer, + GimpViewable *viewable) { - if (preview->size != -1) - { - g_print ("size_changed (%d)\n", preview->size); - - gimp_preview_set_size (preview, - preview->size, - preview->border_width); - } + if (renderer->size != -1) + gimp_preview_renderer_set_size (renderer, renderer->size, + renderer->border_width); else - { - gimp_preview_update (preview); - } -} - -static GimpViewable * -gimp_preview_drag_viewable (GtkWidget *widget, - gpointer data) -{ - return GIMP_PREVIEW (widget)->viewable; + gimp_preview_renderer_update (renderer); } @@ -1196,23 +933,23 @@ gimp_preview_render_to_buffer (TempBuf *temp_buf, } void -gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg) +gimp_preview_renderer_render_preview (GimpPreviewRenderer *renderer, + TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg) { - if (! preview->buffer) - preview->buffer = g_new0 (guchar, preview->height * preview->rowstride); + if (! renderer->buffer) + renderer->buffer = g_new0 (guchar, renderer->height * renderer->rowstride); gimp_preview_render_to_buffer (temp_buf, channel, inside_bg, outside_bg, - preview->buffer, - preview->width, - preview->height, - preview->rowstride); + renderer->buffer, + renderer->width, + renderer->height, + renderer->rowstride); - preview->needs_render = FALSE; + renderer->needs_render = FALSE; } diff --git a/app/widgets/gimpviewrenderer.h b/app/widgets/gimpviewrenderer.h index 5ba2aacdb5..de02f72736 100644 --- a/app/widgets/gimpviewrenderer.h +++ b/app/widgets/gimpviewrenderer.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimppreview.h - * Copyright (C) 2001 Michael Natterer + * gimppreviewrenderer.h + * Copyright (C) 2003 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 @@ -19,135 +19,117 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_PREVIEW_H__ -#define __GIMP_PREVIEW_H__ - - -#include +#ifndef __GIMP_PREVIEW_RENDERER_H__ +#define __GIMP_PREVIEW_RENDERER_H__ #define GIMP_PREVIEW_MAX_SIZE 1024 #define GIMP_PREVIEW_MAX_BORDER_WIDTH 16 -#define GIMP_TYPE_PREVIEW (gimp_preview_get_type ()) -#define GIMP_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW, GimpPreview)) -#define GIMP_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW, GimpPreviewClass)) -#define GIMP_IS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW)) -#define GIMP_IS_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW)) -#define GIMP_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW, GimpPreviewClass)) +#define GIMP_TYPE_PREVIEW_RENDERER (gimp_preview_renderer_get_type ()) +#define GIMP_PREVIEW_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRenderer)) +#define GIMP_PREVIEW_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRendererClass)) +#define GIMP_IS_PREVIEW_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER)) +#define GIMP_IS_PREVIEW_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER)) +#define GIMP_PREVIEW_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER, GimpPreviewRendererClass)) -typedef struct _GimpPreviewClass GimpPreviewClass; +typedef struct _GimpPreviewRendererClass GimpPreviewRendererClass; -struct _GimpPreview +struct _GimpPreviewRenderer { - GtkDrawingArea parent_instance; + GObject parent_instance; - GimpViewable *viewable; + GimpViewable *viewable; - gint width; - gint height; - gint border_width; - gboolean dot_for_dot; + gint width; + gint height; + gint border_width; + gboolean dot_for_dot; + gboolean is_popup; - GimpRGB border_color; - GdkGC *border_gc; - - gboolean is_popup; - gboolean clickable; - gboolean eat_button_events; - gboolean show_popup; + GimpRGB border_color; + GdkGC *border_gc; /*< private >*/ - guchar *buffer; - gint rowstride; + guchar *buffer; + gint rowstride; - GdkPixbuf *no_preview_pixbuf; + GdkPixbuf *no_preview_pixbuf; - gint size; - gboolean in_button; - guint press_state; - guint idle_id; - gboolean needs_render; + gint size; + gboolean needs_render; + guint idle_id; }; -struct _GimpPreviewClass +struct _GimpPreviewRendererClass { - GtkDrawingAreaClass parent_class; + GObjectClass parent_class; /* signals */ - void (* clicked) (GimpPreview *preview); - void (* double_clicked) (GimpPreview *preview); - void (* extended_clicked) (GimpPreview *preview, - guint modifier_state); - void (* context) (GimpPreview *preview); + void (* update) (GimpPreviewRenderer *renderer); /* virtual functions */ - void (* render) (GimpPreview *preview); + void (* render) (GimpPreviewRenderer *renderer, + GtkWidget *widget); }; -GType gimp_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_preview_new (GimpViewable *viewable, - gint size, - gint border_width, - gboolean is_popup); -GtkWidget * gimp_preview_new_full (GimpViewable *viewable, - gint width, - gint height, - gint border_width, - gboolean is_popup, - gboolean clickable, - gboolean show_popup); +GimpPreviewRenderer * gimp_preview_renderer_new (GimpViewable *viewable, + gint size, + gint border_width, + gboolean is_popup); +GimpPreviewRenderer * gimp_preview_renderer_new_full (GimpViewable *viewable, + gint width, + gint height, + gint border_width, + gboolean is_popup); +GimpPreviewRenderer * gimp_preview_renderer_new_by_type (GType viewable_type, + gint size, + gint border_width, + gboolean is_popup); -GtkWidget * gimp_preview_new_by_type (GType viewable_type, - gint size, - gint border_width, - gboolean is_popup); +void gimp_preview_renderer_set_viewable (GimpPreviewRenderer *renderer, + GimpViewable *viewable); +void gimp_preview_renderer_set_size (GimpPreviewRenderer *renderer, + gint size, + gint border_width); +void gimp_preview_renderer_set_size_full (GimpPreviewRenderer *renderer, + gint width, + gint height, + gint border_width); +void gimp_preview_renderer_set_dot_for_dot (GimpPreviewRenderer *renderer, + gboolean dot_for_dot); +void gimp_preview_renderer_set_border_color (GimpPreviewRenderer *renderer, + const GimpRGB *border_color); -void gimp_preview_set_viewable (GimpPreview *preview, - GimpViewable *viewable); +void gimp_preview_renderer_update (GimpPreviewRenderer *renderer); -void gimp_preview_set_size (GimpPreview *preview, - gint size, - gint border_width); -void gimp_preview_set_size_full (GimpPreview *preview, - gint width, - gint height, - gint border_width); - -void gimp_preview_set_dot_for_dot (GimpPreview *preview, - gboolean dot_for_dot); - -void gimp_preview_set_border_color (GimpPreview *preview, - const GimpRGB *border_color); - -void gimp_preview_update (GimpPreview *preview); +void gimp_preview_renderer_draw (GimpPreviewRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *draw_area, + GdkRectangle *expose_area); /* protected */ -typedef enum -{ - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE -} GimpPreviewBG; - -void gimp_preview_render_to_buffer (TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg, - guchar *dest_buffer, - gint dest_width, - gint dest_height, - gint dest_rowstride); -void gimp_preview_render_preview (GimpPreview *preview, - TempBuf *temp_buf, - gint channel, - GimpPreviewBG inside_bg, - GimpPreviewBG outside_bg); +void gimp_preview_render_to_buffer (TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg, + guchar *dest_buffer, + gint dest_width, + gint dest_height, + gint dest_rowstride); +void gimp_preview_renderer_render_preview (GimpPreviewRenderer *renderer, + TempBuf *temp_buf, + gint channel, + GimpPreviewBG inside_bg, + GimpPreviewBG outside_bg); -#endif /* __GIMP_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_H__ */ diff --git a/app/widgets/gimpviewrendererbrush.c b/app/widgets/gimpviewrendererbrush.c index c73639d8ee..2f6764517e 100644 --- a/app/widgets/gimpviewrendererbrush.c +++ b/app/widgets/gimpviewrendererbrush.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpbrushpreview.c - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererbrush.c + * Copyright (C) 2003 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 @@ -30,147 +30,145 @@ #include "core/gimpbrush.h" #include "core/gimpbrushpipe.h" -#include "gimpbrushpreview.h" -#include "gimpdnd.h" +#include "gimppreviewrendererbrush.h" -static void gimp_brush_preview_class_init (GimpBrushPreviewClass *klass); -static void gimp_brush_preview_init (GimpBrushPreview *preview); +static void gimp_preview_renderer_brush_class_init (GimpPreviewRendererBrushClass *klass); +static void gimp_preview_renderer_brush_init (GimpPreviewRendererBrush *preview); -static void gimp_brush_preview_destroy (GtkObject *object); -static void gimp_brush_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_brush_finalize (GObject *object); +static void gimp_preview_renderer_brush_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static gboolean gimp_brush_preview_render_timeout (gpointer data); +static gboolean gimp_preview_renderer_brush_render_timeout (gpointer data); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_brush_preview_get_type (void) +gimp_preview_renderer_brush_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpBrushPreviewClass), + sizeof (GimpPreviewRendererBrushClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_brush_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_brush_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpBrushPreview), + sizeof (GimpPreviewRendererBrush), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_brush_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_brush_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpBrushPreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererBrush", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_brush_preview_class_init (GimpBrushPreviewClass *klass) +gimp_preview_renderer_brush_class_init (GimpPreviewRendererBrushClass *klass) { - GtkObjectClass *object_class; - GimpPreviewClass *preview_class; + GObjectClass *object_class; + GimpPreviewRendererClass *renderer_class; - object_class = GTK_OBJECT_CLASS (klass); - preview_class = GIMP_PREVIEW_CLASS (klass); + object_class = G_OBJECT_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - object_class->destroy = gimp_brush_preview_destroy; + object_class->finalize = gimp_preview_renderer_brush_finalize; - preview_class->render = gimp_brush_preview_render; + renderer_class->render = gimp_preview_renderer_brush_render; } static void -gimp_brush_preview_init (GimpBrushPreview *brush_preview) +gimp_preview_renderer_brush_init (GimpPreviewRendererBrush *renderer) { - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + renderer->pipe_timeout_id = 0; + renderer->pipe_animation_index = 0; + renderer->pipe_animation_widget = NULL; } static void -gimp_brush_preview_destroy (GtkObject *object) +gimp_preview_renderer_brush_finalize (GObject *object) { - GimpBrushPreview *brush_preview; + GimpPreviewRendererBrush *renderer; - brush_preview = GIMP_BRUSH_PREVIEW (object); + renderer = GIMP_PREVIEW_RENDERER_BRUSH (object); - if (brush_preview->pipe_timeout_id) + if (renderer->pipe_timeout_id) { - g_source_remove (brush_preview->pipe_timeout_id); - - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + g_source_remove (renderer->pipe_timeout_id); + renderer->pipe_timeout_id = 0; } - GTK_OBJECT_CLASS (parent_class)->destroy (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -gimp_brush_preview_render (GimpPreview *preview) +gimp_preview_renderer_brush_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { - GimpBrushPreview *brush_preview; - GimpBrush *brush; - TempBuf *temp_buf; - gint width; - gint height; - gint brush_width; - gint brush_height; + GimpPreviewRendererBrush *renderbrush; + GimpBrush *brush; + TempBuf *temp_buf; + gint brush_width; + gint brush_height; - brush_preview = GIMP_BRUSH_PREVIEW (preview); + renderbrush = GIMP_PREVIEW_RENDERER_BRUSH (renderer); - if (brush_preview->pipe_timeout_id) + if (renderbrush->pipe_timeout_id) { - g_source_remove (brush_preview->pipe_timeout_id); - brush_preview->pipe_timeout_id = 0; + g_source_remove (renderbrush->pipe_timeout_id); + renderbrush->pipe_timeout_id = 0; } - brush = GIMP_BRUSH (preview->viewable); + brush = GIMP_BRUSH (renderer->viewable); brush_width = brush->mask->width; brush_height = brush->mask->height; - width = preview->width; - height = preview->height; + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, + renderer->width, + renderer->height); - temp_buf = gimp_viewable_get_new_preview (preview->viewable, - width, height); + if (temp_buf->width < renderer->width) + temp_buf->x = (renderer->width - temp_buf->width) / 2; - if (temp_buf->width < width) - temp_buf->x = (width - temp_buf->width) / 2; + if (temp_buf->height < renderer->height) + temp_buf->y = (renderer->height - temp_buf->height) / 2; - if (temp_buf->height < height) - temp_buf->y = (height - temp_buf->height) / 2; - - if (preview->is_popup) + if (renderer->is_popup) { - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); if (GIMP_IS_BRUSH_PIPE (brush)) { - if (width != brush_width || height != brush_height) + if (renderer->width != brush_width || + renderer->height != brush_height) { g_warning ("%s(): non-fullsize pipe popups are not supported yet.", G_GNUC_FUNCTION); return; } - brush_preview->pipe_animation_index = 0; - brush_preview->pipe_timeout_id = - g_timeout_add (300, gimp_brush_preview_render_timeout, - brush_preview); + renderbrush->pipe_animation_widget = widget; + renderbrush->pipe_animation_index = 0; + renderbrush->pipe_timeout_id = + g_timeout_add (300, gimp_preview_renderer_brush_render_timeout, + renderbrush); } return; @@ -181,8 +179,8 @@ gimp_brush_preview_render (GimpPreview *preview) if (temp_buf->width >= INDICATOR_WIDTH && temp_buf->height >= INDICATOR_HEIGHT && - (width < brush_width || - height < brush_height || + (renderer->width < brush_width || + renderer->height < brush_height || GIMP_IS_BRUSH_PIPE (brush))) { #define WHT { 255, 255, 255 } @@ -242,7 +240,8 @@ gimp_brush_preview_render (GimpPreview *preview) buf += (offset_y * temp_buf->width + offset_x) * temp_buf->bytes; pipe = GIMP_IS_BRUSH_PIPE (brush); - scale = (width < brush_width || height < brush_height); + scale = (renderer->width < brush_width || + renderer->height < brush_height); alpha = (temp_buf->bytes == 4); for (y = 0; y < INDICATOR_HEIGHT; y++) @@ -282,55 +281,55 @@ gimp_brush_preview_render (GimpPreview *preview) #undef INDICATOR_WIDTH #undef INDICATOR_HEIGHT - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); } static gboolean -gimp_brush_preview_render_timeout (gpointer data) +gimp_preview_renderer_brush_render_timeout (gpointer data) { - GimpBrushPreview *brush_preview; - GimpPreview *preview; - GimpBrushPipe *brush_pipe; - GimpBrush *brush; - TempBuf *temp_buf; + GimpPreviewRendererBrush *renderbrush; + GimpPreviewRenderer *renderer; + GimpBrushPipe *brush_pipe; + GimpBrush *brush; + TempBuf *temp_buf; - brush_preview = GIMP_BRUSH_PREVIEW (data); + renderbrush = GIMP_PREVIEW_RENDERER_BRUSH (data); + renderer = GIMP_PREVIEW_RENDERER (data); - preview = GIMP_PREVIEW (brush_preview); - - if (! preview->viewable) + if (! renderer->viewable) { - brush_preview->pipe_timeout_id = 0; - brush_preview->pipe_animation_index = 0; + renderbrush->pipe_timeout_id = 0; + renderbrush->pipe_animation_index = 0; + renderbrush->pipe_animation_widget = NULL; return FALSE; } - brush_pipe = GIMP_BRUSH_PIPE (preview->viewable); + brush_pipe = GIMP_BRUSH_PIPE (renderer->viewable); - brush_preview->pipe_animation_index++; + renderbrush->pipe_animation_index++; - if (brush_preview->pipe_animation_index >= brush_pipe->nbrushes) - brush_preview->pipe_animation_index = 0; + if (renderbrush->pipe_animation_index >= brush_pipe->nbrushes) + renderbrush->pipe_animation_index = 0; brush = - GIMP_BRUSH (brush_pipe->brushes[brush_preview->pipe_animation_index]); + GIMP_BRUSH (brush_pipe->brushes[renderbrush->pipe_animation_index]); temp_buf = gimp_viewable_get_new_preview (GIMP_VIEWABLE (brush), - preview->width, - preview->height); + renderer->width, + renderer->height); - gimp_preview_render_preview (preview, temp_buf, -1, - GIMP_PREVIEW_BG_WHITE, - GIMP_PREVIEW_BG_WHITE); + gimp_preview_renderer_render_preview (renderer, temp_buf, -1, + GIMP_PREVIEW_BG_WHITE, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (temp_buf); - gtk_widget_queue_draw (GTK_WIDGET (preview)); + gtk_widget_queue_draw (renderbrush->pipe_animation_widget); return TRUE; } diff --git a/app/widgets/gimpviewrendererbrush.h b/app/widgets/gimpviewrendererbrush.h index b626748a95..544704689b 100644 --- a/app/widgets/gimpviewrendererbrush.h +++ b/app/widgets/gimpviewrendererbrush.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpbrushpreview.h - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererbrush.h + * Copyright (C) 2003 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 @@ -19,37 +19,37 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_BRUSH_PREVIEW_H__ -#define __GIMP_BRUSH_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_BRUSH_H__ +#define __GIMP_PREVIEW_RENDERER_BRUSH_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_BRUSH (gimp_preview_renderer_brush_get_type ()) +#define GIMP_PREVIEW_RENDERER_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrush)) +#define GIMP_PREVIEW_RENDERER_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrushClass)) +#define GIMP_IS_PREVIEW_RENDERER_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_BRUSH)) +#define GIMP_IS_PREVIEW_RENDERER_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_BRUSH)) +#define GIMP_PREVIEW_RENDERER_BRUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_BRUSH, GimpPreviewRendererBrushClass)) -#define GIMP_TYPE_BRUSH_PREVIEW (gimp_brush_preview_get_type ()) -#define GIMP_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreview)) -#define GIMP_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) -#define GIMP_IS_BRUSH_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_IS_BRUSH_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_PREVIEW)) -#define GIMP_BRUSH_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_PREVIEW, GimpBrushPreviewClass)) +typedef struct _GimpPreviewRendererBrushClass GimpPreviewRendererBrushClass; - -typedef struct _GimpBrushPreviewClass GimpBrushPreviewClass; - -struct _GimpBrushPreview +struct _GimpPreviewRendererBrush { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; - guint pipe_timeout_id; - gint pipe_animation_index; + guint pipe_timeout_id; + gint pipe_animation_index; + GtkWidget *pipe_animation_widget; }; -struct _GimpBrushPreviewClass +struct _GimpPreviewRendererBrushClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_brush_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_brush_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_BRUSH_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_BRUSH_H__ */ diff --git a/app/widgets/gimpviewrendererdrawable.c b/app/widgets/gimpviewrendererdrawable.c index e09558173b..c5ac27ff1c 100644 --- a/app/widgets/gimpviewrendererdrawable.c +++ b/app/widgets/gimpviewrendererdrawable.c @@ -32,65 +32,67 @@ #include "core/gimpdrawable.h" #include "core/gimpimage.h" -#include "gimpdrawablepreview.h" +#include "gimppreviewrendererdrawable.h" -static void gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass); -static void gimp_drawable_preview_init (GimpDrawablePreview *preview); +static void gimp_preview_renderer_drawable_class_init (GimpPreviewRendererDrawableClass *klass); +static void gimp_preview_renderer_drawable_init (GimpPreviewRendererDrawable *preview); -static void gimp_drawable_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_drawable_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_drawable_preview_get_type (void) +gimp_preview_renderer_drawable_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpDrawablePreviewClass), + sizeof (GimpPreviewRendererDrawableClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_drawable_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_drawable_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpDrawablePreview), + sizeof (GimpPreviewRendererDrawable), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_drawable_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_drawable_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpDrawablePreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererDrawable", + &renderer_info, 0); } - - return preview_type; + + return renderer_type; } static void -gimp_drawable_preview_class_init (GimpDrawablePreviewClass *klass) +gimp_preview_renderer_drawable_class_init (GimpPreviewRendererDrawableClass *klass) { - GimpPreviewClass *preview_class; + GimpPreviewRendererClass *renderer_class; - preview_class = GIMP_PREVIEW_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_class->render = gimp_drawable_preview_render; + renderer_class->render = gimp_preview_renderer_drawable_render; } static void -gimp_drawable_preview_init (GimpDrawablePreview *preview) +gimp_preview_renderer_drawable_init (GimpPreviewRendererDrawable *preview) { } static void -gimp_drawable_preview_render (GimpPreview *preview) +gimp_preview_renderer_drawable_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { GimpDrawable *drawable; GimpImage *gimage; @@ -101,25 +103,25 @@ gimp_drawable_preview_render (GimpPreview *preview) gboolean scaling_up; TempBuf *render_buf; - drawable = GIMP_DRAWABLE (preview->viewable); + drawable = GIMP_DRAWABLE (renderer->viewable); gimage = gimp_item_get_image (GIMP_ITEM (drawable)); - width = preview->width; - height = preview->height; + width = renderer->width; + height = renderer->height; - if (gimage && ! preview->is_popup) + if (gimage && ! renderer->is_popup) { width = MAX (1, ROUND ((((gdouble) width / (gdouble) gimage->width) * (gdouble) drawable->width))); height = MAX (1, ROUND ((((gdouble) height / (gdouble) gimage->height) * (gdouble) drawable->height))); - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, drawable->width, drawable->height, width, height, - preview->dot_for_dot, + renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &preview_width, @@ -128,12 +130,12 @@ gimp_drawable_preview_render (GimpPreview *preview) } else { - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, drawable->width, drawable->height, width, height, - preview->dot_for_dot, + renderer->dot_for_dot, gimage ? gimage->xresolution : 1.0, gimage ? gimage->yresolution : 1.0, &preview_width, @@ -145,7 +147,7 @@ gimp_drawable_preview_render (GimpPreview *preview) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_new_preview (preview->viewable, + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, drawable->width, drawable->height); render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); @@ -154,21 +156,21 @@ gimp_drawable_preview_render (GimpPreview *preview) } else { - render_buf = gimp_viewable_get_new_preview (preview->viewable, + render_buf = gimp_viewable_get_new_preview (renderer->viewable, preview_width, preview_height); } - if (gimage && ! preview->is_popup) + if (gimage && ! renderer->is_popup) { if (drawable->offset_x != 0) render_buf->x = - ROUND ((((gdouble) preview->width / (gdouble) gimage->width) * + ROUND ((((gdouble) renderer->width / (gdouble) gimage->width) * (gdouble) drawable->offset_x)); if (drawable->offset_y != 0) render_buf->y = - ROUND ((((gdouble) preview->height / (gdouble) gimage->height) * + ROUND ((((gdouble) renderer->height / (gdouble) gimage->height) * (gdouble) drawable->offset_y)); } else @@ -180,11 +182,9 @@ gimp_drawable_preview_render (GimpPreview *preview) render_buf->y = (height - preview_height) / 2; } - gimp_preview_render_preview (preview, - render_buf, - -1, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_CHECKS); + gimp_preview_renderer_render_preview (renderer, render_buf, -1, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_CHECKS); temp_buf_free (render_buf); } diff --git a/app/widgets/gimpviewrendererdrawable.h b/app/widgets/gimpviewrendererdrawable.h index 1a6f5db73d..c986b39cb2 100644 --- a/app/widgets/gimpviewrendererdrawable.h +++ b/app/widgets/gimpviewrendererdrawable.h @@ -1,7 +1,7 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpdrawablepreview.h + * gimppreviewrendererdrawable.h * Copyright (C) 2001 Michael Natterer * * This program is free software; you can redistribute it and/or modify @@ -19,34 +19,33 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_DRAWABLE_PREVIEW_H__ -#define __GIMP_DRAWABLE_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ +#define __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE (gimp_preview_renderer_drawable_get_type ()) +#define GIMP_PREVIEW_RENDERER_DRAWABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawable)) +#define GIMP_PREVIEW_RENDERER_DRAWABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawableClass)) +#define GIMP_IS_PREVIEW_RENDERER_DRAWABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE)) +#define GIMP_IS_PREVIEW_RENDERER_DRAWABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE)) +#define GIMP_PREVIEW_RENDERER_DRAWABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_DRAWABLE, GimpPreviewRendererDrawableClass)) -#define GIMP_TYPE_DRAWABLE_PREVIEW (gimp_drawable_preview_get_type ()) -#define GIMP_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreview)) -#define GIMP_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) -#define GIMP_IS_DRAWABLE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_IS_DRAWABLE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DRAWABLE_PREVIEW)) -#define GIMP_DRAWABLE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DRAWABLE_PREVIEW, GimpDrawablePreviewClass)) +typedef struct _GimpPreviewRendererDrawableClass GimpPreviewRendererDrawableClass; - -typedef struct _GimpDrawablePreviewClass GimpDrawablePreviewClass; - -struct _GimpDrawablePreview +struct _GimpPreviewRendererDrawable { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; }; -struct _GimpDrawablePreviewClass +struct _GimpPreviewRendererDrawableClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_drawable_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_drawable_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_DRAWABLE_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_DRAWABLE_H__ */ diff --git a/app/widgets/gimpviewrendererimage.c b/app/widgets/gimpviewrendererimage.c index d2e5828dc6..ac6db4b0d1 100644 --- a/app/widgets/gimpviewrendererimage.c +++ b/app/widgets/gimpviewrendererimage.c @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * GimpImagePreview Widget - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererimage.c + * Copyright (C) 2003 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 @@ -29,86 +29,83 @@ #include "core/gimpimage.h" -#include "gimpimagepreview.h" +#include "gimppreviewrendererimage.h" -static void gimp_image_preview_class_init (GimpImagePreviewClass *klass); -static void gimp_image_preview_init (GimpImagePreview *preview); +static void gimp_preview_renderer_image_class_init (GimpPreviewRendererImageClass *klass); +static void gimp_preview_renderer_image_init (GimpPreviewRendererImage *preview); -static void gimp_image_preview_render (GimpPreview *preview); +static void gimp_preview_renderer_image_render (GimpPreviewRenderer *renderer, + GtkWidget *widget); -static GimpPreviewClass *parent_class = NULL; +static GimpPreviewRendererClass *parent_class = NULL; GType -gimp_image_preview_get_type (void) +gimp_preview_renderer_image_get_type (void) { - static GType preview_type = 0; + static GType renderer_type = 0; - if (! preview_type) + if (! renderer_type) { - static const GTypeInfo preview_info = + static const GTypeInfo renderer_info = { - sizeof (GimpImagePreviewClass), + sizeof (GimpPreviewRendererImageClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gimp_image_preview_class_init, + (GClassInitFunc) gimp_preview_renderer_image_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GimpImagePreview), + sizeof (GimpPreviewRendererImage), 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_image_preview_init, + (GInstanceInitFunc) gimp_preview_renderer_image_init, }; - preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, - "GimpImagePreview", - &preview_info, 0); + renderer_type = g_type_register_static (GIMP_TYPE_PREVIEW_RENDERER, + "GimpPreviewRendererImage", + &renderer_info, 0); } - return preview_type; + return renderer_type; } static void -gimp_image_preview_class_init (GimpImagePreviewClass *klass) +gimp_preview_renderer_image_class_init (GimpPreviewRendererImageClass *klass) { - GimpPreviewClass *preview_class; + GimpPreviewRendererClass *renderer_class; - preview_class = GIMP_PREVIEW_CLASS (klass); + renderer_class = GIMP_PREVIEW_RENDERER_CLASS (klass); parent_class = g_type_class_peek_parent (klass); - preview_class->render = gimp_image_preview_render; + renderer_class->render = gimp_preview_renderer_image_render; } static void -gimp_image_preview_init (GimpImagePreview *preview) +gimp_preview_renderer_image_init (GimpPreviewRendererImage *renderer) { - preview->channel = -1; + renderer->channel = -1; } static void -gimp_image_preview_render (GimpPreview *preview) +gimp_preview_renderer_image_render (GimpPreviewRenderer *renderer, + GtkWidget *widget) { GimpImage *gimage; - gint width; - gint height; gint preview_width; gint preview_height; gboolean scaling_up; TempBuf *render_buf; - gimage = GIMP_IMAGE (preview->viewable); + gimage = GIMP_IMAGE (renderer->viewable); - width = preview->width; - height = preview->height; - - gimp_viewable_calc_preview_size (preview->viewable, + gimp_viewable_calc_preview_size (renderer->viewable, gimage->width, gimage->height, - width, - height, - preview->dot_for_dot, + renderer->width, + renderer->height, + renderer->dot_for_dot, gimage->xresolution, gimage->yresolution, &preview_width, @@ -119,7 +116,7 @@ gimp_image_preview_render (GimpPreview *preview) { TempBuf *temp_buf; - temp_buf = gimp_viewable_get_new_preview (preview->viewable, + temp_buf = gimp_viewable_get_new_preview (renderer->viewable, gimage->width, gimage->height); render_buf = temp_buf_scale (temp_buf, preview_width, preview_height); @@ -128,29 +125,32 @@ gimp_image_preview_render (GimpPreview *preview) } else { - render_buf = gimp_viewable_get_new_preview (preview->viewable, + render_buf = gimp_viewable_get_new_preview (renderer->viewable, preview_width, preview_height); } /* xresolution != yresolution */ - if (preview_width > width || preview_height > height) + if (preview_width > renderer->width || preview_height > renderer->height) { TempBuf *temp_buf; - temp_buf = temp_buf_scale (render_buf, width, height); + temp_buf = temp_buf_scale (render_buf, renderer->width, renderer->height); temp_buf_free (render_buf); render_buf = temp_buf; } - if (preview_width < width) render_buf->x = (width - preview_width) / 2; - if (preview_height < height) render_buf->y = (height - preview_height) / 2; + if (preview_width < renderer->width) + render_buf->x = (renderer->width - preview_width) / 2; - gimp_preview_render_preview (preview, render_buf, - GIMP_IMAGE_PREVIEW (preview)->channel, - GIMP_PREVIEW_BG_CHECKS, - GIMP_PREVIEW_BG_WHITE); + if (preview_height < renderer->height) + render_buf->y = (renderer->height - preview_height) / 2; + + gimp_preview_renderer_render_preview (renderer, render_buf, + GIMP_PREVIEW_RENDERER_IMAGE (renderer)->channel, + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_WHITE); temp_buf_free (render_buf); } diff --git a/app/widgets/gimpviewrendererimage.h b/app/widgets/gimpviewrendererimage.h index ceb15bc49c..6cd21850f4 100644 --- a/app/widgets/gimpviewrendererimage.h +++ b/app/widgets/gimpviewrendererimage.h @@ -1,8 +1,8 @@ /* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * GimpImagePreview Widget - * Copyright (C) 2001 Michael Natterer + * gimppreviewrendererimage.h + * Copyright (C) 2003 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 @@ -19,36 +19,35 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __GIMP_IMAGE_PREVIEW_H__ -#define __GIMP_IMAGE_PREVIEW_H__ +#ifndef __GIMP_PREVIEW_RENDERER_IMAGE_H__ +#define __GIMP_PREVIEW_RENDERER_IMAGE_H__ -#include "gimppreview.h" +#include "gimppreviewrenderer.h" + +#define GIMP_TYPE_PREVIEW_RENDERER_IMAGE (gimp_preview_renderer_image_get_type ()) +#define GIMP_PREVIEW_RENDERER_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImage)) +#define GIMP_PREVIEW_RENDERER_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImageClass)) +#define GIMP_IS_PREVIEW_RENDERER_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_PREVIEW_RENDERER_IMAGE)) +#define GIMP_IS_PREVIEW_RENDERER_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PREVIEW_RENDERER_IMAGE)) +#define GIMP_PREVIEW_RENDERER_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PREVIEW_RENDERER_IMAGE, GimpPreviewRendererImageClass)) -#define GIMP_TYPE_IMAGE_PREVIEW (gimp_image_preview_get_type ()) -#define GIMP_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreview)) -#define GIMP_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) -#define GIMP_IS_IMAGE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IS_IMAGE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGE_PREVIEW)) -#define GIMP_IMAGE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_IMAGE_PREVIEW, GimpImagePreviewClass)) +typedef struct _GimpPreviewRendererImageClass GimpPreviewRendererImageClass; - -typedef struct _GimpImagePreviewClass GimpImagePreviewClass; - -struct _GimpImagePreview +struct _GimpPreviewRendererImage { - GimpPreview parent_instance; + GimpPreviewRenderer parent_instance; - gint channel; + gint channel; }; -struct _GimpImagePreviewClass +struct _GimpPreviewRendererImageClass { - GimpPreviewClass parent_class; + GimpPreviewRendererClass parent_class; }; -GType gimp_image_preview_get_type (void) G_GNUC_CONST; +GType gimp_preview_renderer_image_get_type (void) G_GNUC_CONST; -#endif /* __GIMP_IMAGE_PREVIEW_H__ */ +#endif /* __GIMP_PREVIEW_RENDERER_IMAGE_H__ */ diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h index 8367eb2e05..d8b573e2be 100644 --- a/app/widgets/widgets-enums.h +++ b/app/widgets/widgets-enums.h @@ -63,6 +63,12 @@ typedef enum * non-registered enums; register them if needed */ +typedef enum /*< skip >*/ +{ + GIMP_PREVIEW_BG_CHECKS, + GIMP_PREVIEW_BG_WHITE +} GimpPreviewBG; + typedef enum /*< skip >*/ { GIMP_VIEW_TYPE_GRID, diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index 8094a4034c..34e20d90ab 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -29,19 +29,23 @@ /* non-widget objects */ -typedef struct _GimpDeviceInfo GimpDeviceInfo; -typedef struct _GimpDialogFactory GimpDialogFactory; -typedef struct _GimpItemFactory GimpItemFactory; -typedef struct _GimpMenuFactory GimpMenuFactory; +typedef struct _GimpDeviceInfo GimpDeviceInfo; +typedef struct _GimpDialogFactory GimpDialogFactory; +typedef struct _GimpItemFactory GimpItemFactory; +typedef struct _GimpMenuFactory GimpMenuFactory; -typedef struct _GimpCellRendererViewable GimpCellRendererViewable; +typedef struct _GimpCellRendererViewable GimpCellRendererViewable; + +typedef struct _GimpPreviewRenderer GimpPreviewRenderer; +typedef struct _GimpPreviewRendererBrush GimpPreviewRendererBrush; +typedef struct _GimpPreviewRendererDrawable GimpPreviewRendererDrawable; +typedef struct _GimpPreviewRendererImage GimpPreviewRendererImage; /* widgets */ typedef struct _GimpPreview GimpPreview; typedef struct _GimpBrushPreview GimpBrushPreview; -typedef struct _GimpBufferPreview GimpBufferPreview; typedef struct _GimpDrawablePreview GimpDrawablePreview; typedef struct _GimpImagePreview GimpImagePreview; typedef struct _GimpNavigationPreview GimpNavigationPreview;