[gthumb] removed use of the gdk_draw_* functions, use cairo instead
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] removed use of the gdk_draw_* functions, use cairo instead
- Date: Thu, 22 Jul 2010 20:40:35 +0000 (UTC)
commit 6e1a206b6729995c8bd45485c23b97be878fa536
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Jul 22 21:54:03 2010 +0200
removed use of the gdk_draw_* functions, use cairo instead
extensions/gstreamer_tools/gth-media-viewer-page.c | 87 ++--
extensions/image_viewer/gth-image-viewer-page.c | 12 +-
gthumb/Makefile.am | 4 +-
gthumb/gth-cell-renderer-thumbnail.c | 131 ++---
gthumb/gth-empty-list.c | 30 +-
gthumb/gth-image-dragger.c | 4 +-
gthumb/gth-image-navigator.c | 503 +++++++++++++++++
gthumb/gth-image-navigator.h | 58 ++
gthumb/gth-image-selector.c | 112 ++--
gthumb/gth-image-viewer-tool.c | 5 +-
gthumb/gth-image-viewer-tool.h | 6 +-
gthumb/gth-image-viewer.c | 263 ++++-----
gthumb/gth-image-viewer.h | 2 +
gthumb/gth-nav-window.c | 574 --------------------
gthumb/gth-nav-window.h | 58 --
po/POTFILES.in | 4 +-
16 files changed, 870 insertions(+), 983 deletions(-)
---
diff --git a/extensions/gstreamer_tools/gth-media-viewer-page.c b/extensions/gstreamer_tools/gth-media-viewer-page.c
index ccbc6d5..f4139e6 100644
--- a/extensions/gstreamer_tools/gth-media-viewer-page.c
+++ b/extensions/gstreamer_tools/gth-media-viewer-page.c
@@ -99,18 +99,25 @@ _gth_media_viewer_page_update_caption (GthMediaViewerPage *self)
return;
if (self->priv->file_data != NULL) {
- const char *text;
+ GString *description;
GthMetadata *metadata;
- text = NULL;
+ description = g_string_new ("");
metadata = (GthMetadata *) g_file_info_get_attribute_object (self->priv->file_data->info, "general::title");
- if (metadata != NULL)
- text = gth_metadata_get_formatted (metadata);
+ if (metadata != NULL) {
+ g_string_append (description, gth_metadata_get_formatted (metadata));
+ metadata = (GthMetadata *) g_file_info_get_attribute_object (self->priv->file_data->info, "audio-video::general::artist");
+ if (metadata != NULL) {
+ g_string_append (description, "\n");
+ g_string_append (description, gth_metadata_get_formatted (metadata));
+ }
+ }
else
- text = g_file_info_get_display_name (self->priv->file_data->info);
+ g_string_append (description, g_file_info_get_display_name (self->priv->file_data->info));
+
+ pango_layout_set_text (self->priv->caption_layout, description->str, -1);
- if (text != NULL)
- pango_layout_set_text (self->priv->caption_layout, text, -1);
+ g_string_free (description, TRUE);
}
else
pango_layout_set_text (self->priv->caption_layout, "", -1);
@@ -126,6 +133,7 @@ video_area_realize_cb (GtkWidget *widget,
GthMediaViewerPage *self = user_data;
self->priv->caption_layout = gtk_widget_create_pango_layout (widget, "");
+ pango_layout_set_alignment (self->priv->caption_layout, PANGO_ALIGN_CENTER);
_gth_media_viewer_page_update_caption (self);
}
@@ -147,6 +155,9 @@ video_area_expose_event_cb (GtkWidget *widget,
gpointer user_data)
{
GthMediaViewerPage *self = user_data;
+ GtkAllocation allocation;
+ GtkStyle *style;
+ cairo_t *cr;
if (event->count > 0)
return FALSE;
@@ -154,6 +165,9 @@ video_area_expose_event_cb (GtkWidget *widget,
if (self->priv->xwin_assigned && self->priv->has_video)
return FALSE;
+ gtk_widget_get_allocation (widget, &allocation);
+ style = gtk_widget_get_style (widget);
+
if (self->priv->icon == NULL) {
char *type;
GIcon *icon;
@@ -165,9 +179,9 @@ video_area_expose_event_cb (GtkWidget *widget,
if (type == NULL)
type = g_content_type_from_mime_type ("text/plain");
icon = g_content_type_get_icon (type);
- size = widget->allocation.width;
- if (size > widget->allocation.height)
- size = widget->allocation.height;
+ size = allocation.width;
+ if (size > allocation.height)
+ size = allocation.height;
size = size / 3;
self->priv->icon = _g_icon_get_pixbuf (icon, size, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)));
@@ -175,44 +189,49 @@ video_area_expose_event_cb (GtkWidget *widget,
g_free (type);
}
- gdk_draw_rectangle (gtk_widget_get_window (widget),
- self->priv->has_video ? widget->style->black_gc : widget->style->text_gc[GTK_WIDGET_STATE (widget)],
- TRUE,
- event->area.x,
- event->area.y,
- event->area.width,
- event->area.height);
+ cr = gdk_cairo_create (gtk_widget_get_window (widget));
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+ if (self->priv->has_video)
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ else
+ gdk_cairo_set_source_color (cr, &style->text[gtk_widget_get_state (widget)]);
+ gdk_cairo_region (cr, event->region);
+ cairo_fill (cr);
if (self->priv->icon != NULL) {
int icon_w, icon_h;
+ int text_w;
int icon_x, icon_y;
PangoRectangle logical_rect;
int x, y;
icon_w = gdk_pixbuf_get_width (self->priv->icon);
icon_h = gdk_pixbuf_get_height (self->priv->icon);
- pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * (icon_w * 3 / 2));
+
+ text_w = (icon_w * 3 / 2);
+ pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * text_w);
pango_layout_get_extents (self->priv->caption_layout, NULL, &logical_rect);
- icon_x = (widget->allocation.width - icon_w) / 2;
- x = (widget->allocation.width - PANGO_PIXELS (logical_rect.width)) / 2 + PANGO_PIXELS (logical_rect.x);
- icon_y = (widget->allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
+
+ icon_x = (allocation.width - icon_w) / 2;
+ x = (allocation.width - text_w) / 2;
+
+ icon_y = (allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
y = icon_y + icon_h;
- gdk_draw_pixbuf (gtk_widget_get_window (widget),
- widget->style->base_gc[GTK_WIDGET_STATE (widget)],
- self->priv->icon,
- 0, 0,
- icon_x, icon_y,
- icon_w, icon_h,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
- gdk_draw_layout (gtk_widget_get_window (widget),
- widget->style->base_gc[GTK_WIDGET_STATE (widget)],
- x, y,
- self->priv->caption_layout);
+ gdk_cairo_set_source_pixbuf (cr, self->priv->icon, icon_x, icon_y);
+ cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_layout_path (cr, self->priv->caption_layout);
+ gdk_cairo_set_source_color (cr, &style->base[gtk_widget_get_state (widget)]);
+ cairo_fill (cr);
}
- return FALSE;
+ cairo_destroy (cr);
+
+ return TRUE;
}
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index d6ff354..f944861 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -33,7 +33,7 @@
struct _GthImageViewerPagePrivate {
GthBrowser *browser;
- GtkWidget *nav_window;
+ GtkWidget *image_navigator;
GtkWidget *viewer;
GthImagePreloader *preloader;
GtkActionGroup *actions;
@@ -460,10 +460,10 @@ gth_image_viewer_page_real_activate (GthViewerPage *base,
G_CALLBACK (viewer_key_press_cb),
self);
- self->priv->nav_window = gth_nav_window_new (GTH_IMAGE_VIEWER (self->priv->viewer));
- gtk_widget_show (self->priv->nav_window);
+ self->priv->image_navigator = gth_image_navigator_new (GTH_IMAGE_VIEWER (self->priv->viewer));
+ gtk_widget_show (self->priv->image_navigator);
- gth_browser_set_viewer_widget (browser, self->priv->nav_window);
+ gth_browser_set_viewer_widget (browser, self->priv->image_navigator);
gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
/* gconf notifications */
@@ -653,11 +653,11 @@ gth_image_viewer_page_real_fullscreen (GthViewerPage *base,
self = (GthImageViewerPage *) base;
if (active) {
- gth_nav_window_set_scrollbars_visible (GTH_NAV_WINDOW (self->priv->nav_window), FALSE);
+ gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), FALSE);
gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), TRUE);
}
else {
- gth_nav_window_set_scrollbars_visible (GTH_NAV_WINDOW (self->priv->nav_window), TRUE);
+ gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), TRUE);
gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_boolean (PREF_BLACK_BACKGROUND, FALSE));
}
}
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 67ab85b..4daa84a 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -69,6 +69,7 @@ PUBLIC_HEADER_FILES = \
gth-image-dragger.h \
gth-image-history.h \
gth-image-loader.h \
+ gth-image-navigator.h \
gth-image-preloader.h \
gth-image-selector.h \
gth-image-viewer.h \
@@ -81,7 +82,6 @@ PUBLIC_HEADER_FILES = \
gth-metadata-provider.h \
gth-monitor.h \
gth-multipage.h \
- gth-nav-window.h \
gth-overwrite-dialog.h \
gth-pixbuf-task.h \
gth-pixbuf-list-task.h \
@@ -184,6 +184,7 @@ gthumb_SOURCES = \
gth-image-dragger.c \
gth-image-history.c \
gth-image-loader.c \
+ gth-image-navigator.c \
gth-image-preloader.c \
gth-image-selector.c \
gth-image-viewer.c \
@@ -202,7 +203,6 @@ gthumb_SOURCES = \
gth-metadata-provider-file.c \
gth-monitor.c \
gth-multipage.c \
- gth-nav-window.c \
gth-overwrite-dialog.c \
gth-pixbuf-task.c \
gth-pixbuf-list-task.c \
diff --git a/gthumb/gth-cell-renderer-thumbnail.c b/gthumb/gth-cell-renderer-thumbnail.c
index 9a1c40c..a0b99d6 100644
--- a/gthumb/gth-cell-renderer-thumbnail.c
+++ b/gthumb/gth-cell-renderer-thumbnail.c
@@ -347,6 +347,10 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer *cell,
state = ((flags & GTK_CELL_RENDERER_FOCUSED) == GTK_CELL_RENDERER_FOCUSED) ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
if (self->priv->is_icon || ((image_rect.width < self->priv->size) && (image_rect.height < self->priv->size))) {
+
+ /* use a gray rounded box for icons or when the original size
+ * is smaller than the thumbnail size... */
+
if (state == GTK_STATE_NORMAL)
gdk_cairo_set_source_color (cr, &widget->style->bg[state]);
else
@@ -356,8 +360,10 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer *cell,
cairo_close_path (cr);
cairo_fill (cr);
}
+ else {
+
+ /* ...else draw a frame with a drop-shadow effect */
- if (! self->priv->is_icon && ! ((image_rect.width < self->priv->size) && (image_rect.height < self->priv->size))) {
GdkRectangle frame_rect;
if (state == GTK_STATE_ACTIVE)
@@ -379,71 +385,41 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer *cell,
frame_rect = image_rect;
}
- /*
- gdk_cairo_set_source_color (cr, &style->dark[state]);
- _cairo_draw_rounded_box (cr,
- frame_rect.x - border + 2.5,
- frame_rect.y - border + 2.5,
- frame_rect.width + (border * 2) - 1,
- frame_rect.height + (border * 2) - 1,
- 0.0);
- cairo_close_path (cr);
- cairo_fill (cr);
-
cairo_set_line_width (cr, 0.5);
- _cairo_draw_rounded_box (cr,
- frame_rect.x - border + 0.5,
- frame_rect.y - border + 0.5,
- frame_rect.width + (border * 2) - 1,
- frame_rect.height + (border * 2) - 1,
- 0.0);
- cairo_close_path (cr);
- gdk_cairo_set_source_color (cr, &style->base[state]);
- cairo_fill_preserve (cr);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
gdk_cairo_set_source_color (cr, &style->dark[state]);
+
+ /* the outer frame */
+
+ cairo_rectangle (cr,
+ frame_rect.x - border + 0.5,
+ frame_rect.y - border + 0.5,
+ frame_rect.width + (border * 2) - 1,
+ frame_rect.height + (border * 2) - 1);
+
+ /* the drop shadow */
+
+ cairo_move_to (cr,
+ frame_rect.x - (border / 2) + 0.5,
+ frame_rect.y + frame_rect.height + border + 0.5);
+ cairo_line_to (cr,
+ frame_rect.x + frame_rect.width + border + 0.5,
+ frame_rect.y + frame_rect.height + border + 0.5);
+ cairo_line_to (cr,
+ frame_rect.x + frame_rect.width + border + 0.5,
+ frame_rect.y - (border / 2) + 0.5);
+
+ cairo_move_to (cr,
+ frame_rect.x - (border / 2) + 0.5,
+ frame_rect.y + frame_rect.height + border + 1.5);
+ cairo_line_to (cr,
+ frame_rect.x + frame_rect.width + border + 1.5,
+ frame_rect.y + frame_rect.height + border + 1.5);
+ cairo_line_to (cr,
+ frame_rect.x + frame_rect.width + border + 1.5,
+ frame_rect.y - (border / 2) + 0.5);
+
cairo_stroke (cr);
- */
-
- gdk_draw_rectangle (GDK_DRAWABLE (window), style->dark_gc[state], FALSE,
- frame_rect.x - border,
- frame_rect.y - border,
- frame_rect.width + (border * 2) - 1,
- frame_rect.height + (border * 2) - 1);
-
- gdk_draw_line (GDK_DRAWABLE (window), style->dark_gc[state],
- frame_rect.x - (border / 2),
- frame_rect.y + frame_rect.height + border,
- frame_rect.x + frame_rect.width + border,
- frame_rect.y + frame_rect.height + border);
- gdk_draw_line (GDK_DRAWABLE (window), style->dark_gc[state],
- frame_rect.x + frame_rect.width + border,
- frame_rect.y + frame_rect.height + border,
- frame_rect.x + frame_rect.width + border,
- frame_rect.y - (border / 2));
-
- gdk_draw_line (GDK_DRAWABLE (window), style->mid_gc[state],
- frame_rect.x - (border / 2) + 1,
- frame_rect.y + frame_rect.height + border + 1,
- frame_rect.x + frame_rect.width + border + 1,
- frame_rect.y + frame_rect.height + border + 1);
- gdk_draw_line (GDK_DRAWABLE (window), style->mid_gc[state],
- frame_rect.x + frame_rect.width + border + 1,
- frame_rect.y + frame_rect.height + border + 1,
- frame_rect.x + frame_rect.width + border + 1,
- frame_rect.y - (border / 2) + 1);
-
- /*
- gdk_draw_rectangle (GDK_DRAWABLE (window), style->light_gc[state], TRUE,
- frame_rect.x - (border - 1),
- frame_rect.y - (border - 1),
- frame_rect.width + ((border - 1) * 2),
- frame_rect.height + ((border - 1) * 2));
- gdk_draw_rectangle (GDK_DRAWABLE (window), style->mid_gc[state], FALSE,
- image_rect.x - 1,
- image_rect.y - 1,
- image_rect.width + 1,
- image_rect.height + 1);
- */
}
if (! self->priv->checked || ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0)) {
@@ -451,33 +427,12 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer *cell,
pixbuf = colorized;
}
- gdk_draw_pixbuf (GDK_DRAWABLE (window),
- NULL,
- pixbuf,
- 0, 0,
- image_rect.x,
- image_rect.y,
- image_rect.width,
- image_rect.height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
-
- /*if (! self->priv->checked) {
- cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5);
- cairo_set_line_width (cr, 6.0);
-
- cairo_move_to (cr, thumb_rect.x, thumb_rect.y);
- cairo_line_to (cr, thumb_rect.x + thumb_rect.width, thumb_rect.y + thumb_rect.height);
- cairo_stroke (cr);
- cairo_move_to (cr, thumb_rect.x + thumb_rect.width, thumb_rect.y);
- cairo_line_to (cr, thumb_rect.x, thumb_rect.y + thumb_rect.height);
- cairo_stroke (cr);
- }*/
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, image_rect.x, image_rect.y);
+ cairo_rectangle (cr, image_rect.x, image_rect.y, image_rect.width, image_rect.height);
+ cairo_fill (cr);
+ _g_object_unref (colorized);
cairo_destroy (cr);
-
- if (colorized != NULL)
- g_object_unref (colorized);
}
diff --git a/gthumb/gth-empty-list.c b/gthumb/gth-empty-list.c
index 064a02e..9686b43 100644
--- a/gthumb/gth-empty-list.c
+++ b/gthumb/gth-empty-list.c
@@ -238,8 +238,11 @@ static gboolean
gth_empty_list_expose_event (GtkWidget *widget,
GdkEventExpose *event)
{
- GthEmptyList *self = (GthEmptyList*) widget;
- PangoRectangle bounds;
+ GthEmptyList *self = (GthEmptyList*) widget;
+ PangoRectangle bounds;
+ GtkAllocation allocation;
+ GtkStyle *style;
+ cairo_t *cr;
if (event->window != self->priv->bin_window)
return FALSE;
@@ -251,24 +254,29 @@ gth_empty_list_expose_event (GtkWidget *widget,
pango_layout_set_text (self->priv->layout, self->priv->text, strlen (self->priv->text));
pango_layout_get_pixel_extents (self->priv->layout, NULL, &bounds);
- gdk_draw_layout (self->priv->bin_window,
- widget->style->text_gc[GTK_WIDGET_STATE (widget)],
- 0,
- (widget->allocation.height - bounds.height) / 2,
- self->priv->layout);
+ gtk_widget_get_allocation (widget, &allocation);
+ style = gtk_widget_get_style (widget);
+
+ cr = gdk_cairo_create (self->priv->bin_window);
+ cairo_move_to (cr, 0, (allocation.height - bounds.height) / 2);
+ pango_cairo_layout_path (cr, self->priv->layout);
+ gdk_cairo_set_source_color (cr, &style->text[gtk_widget_get_state (widget)]);
+ cairo_fill (cr);
if (GTK_WIDGET_HAS_FOCUS (widget)) {
- gtk_paint_focus (widget->style,
+ gtk_paint_focus (style,
self->priv->bin_window,
- GTK_WIDGET_STATE (widget),
+ gtk_widget_get_state (widget),
&event->area,
widget,
NULL,
1, 1,
- widget->allocation.width - 2,
- widget->allocation.height - 2);
+ allocation.width - 2,
+ allocation.height - 2);
}
+ cairo_destroy (cr);
+
return FALSE;
}
diff --git a/gthumb/gth-image-dragger.c b/gthumb/gth-image-dragger.c
index a6e294e..9088917 100644
--- a/gthumb/gth-image-dragger.c
+++ b/gthumb/gth-image-dragger.c
@@ -128,7 +128,8 @@ gth_image_dragger_unmap (GthImageViewerTool *base)
static void
gth_image_dragger_expose (GthImageViewerTool *self,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
GthImageDragger *dragger;
GthImageViewer *viewer;
@@ -149,6 +150,7 @@ gth_image_dragger_expose (GthImageViewerTool *self,
interp_type = GDK_INTERP_NEAREST;
gth_image_viewer_paint_region (viewer,
+ cr,
gth_image_viewer_get_current_pixbuf (viewer),
viewer->x_offset - viewer->image_area.x,
viewer->y_offset - viewer->image_area.y,
diff --git a/gthumb/gth-image-navigator.c b/gthumb/gth-image-navigator.c
new file mode 100644
index 0000000..8005230
--- /dev/null
+++ b/gthumb/gth-image-navigator.c
@@ -0,0 +1,503 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ *
+ * 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 Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <math.h>
+#include <gdk/gdkkeysyms.h>
+#include "gth-image-navigator.h"
+#include "gth-image-viewer.h"
+#include "gtk-utils.h"
+#include "pixbuf-utils.h"
+#include "icons/nav_button.xpm"
+
+
+#define VISIBLE_AREA_BORDER 3.0
+#define POPUP_BORDER 4
+#define POPUP_BORDER_2 8
+#define POPUP_MAX_WIDTH 112
+#define POPUP_MAX_HEIGHT 112
+
+
+struct _GthImageNavigatorPrivate {
+ GthImageViewer *viewer;
+ GtkWidget *viewer_vscr;
+ GtkWidget *viewer_hscr;
+ GtkWidget *navigator_event_area;
+ gboolean scrollbars_visible;
+};
+
+
+static GtkHBoxClass *parent_class = NULL;
+
+
+static void
+gth_image_navigator_class_init (GthImageNavigatorClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GthImageNavigatorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+}
+
+
+static void
+gth_image_navigator_init (GthImageNavigator *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorPrivate);
+ self->priv->scrollbars_visible = TRUE;
+}
+
+
+GType
+gth_image_navigator_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthImageNavigatorClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_image_navigator_class_init,
+ NULL,
+ NULL,
+ sizeof (GthImageNavigator),
+ 0,
+ (GInstanceInitFunc) gth_image_navigator_init
+ };
+
+ type = g_type_register_static (GTK_TYPE_HBOX,
+ "GthImageNavigator",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+/* -- NavigatorPopup -- */
+
+
+typedef struct {
+ GthImageViewer *viewer;
+ int x_root, y_root;
+ GtkWidget *popup_win;
+ GtkWidget *preview;
+ GdkPixbuf *pixbuf;
+ int image_width, image_height;
+ int window_max_width, window_max_height;
+ int popup_x, popup_y, popup_width, popup_height;
+ GdkRectangle visible_area;
+ double zoom_factor;
+} NavigatorPopup;
+
+
+static void
+get_visible_area_origin_as_double (NavigatorPopup *nav_popup,
+ int mx,
+ int my,
+ double *x,
+ double *y)
+{
+ *x = MIN (mx - POPUP_BORDER, nav_popup->window_max_width);
+ *y = MIN (my - POPUP_BORDER, nav_popup->window_max_height);
+
+ if (*x - nav_popup->visible_area.width / 2.0 < 0.0)
+ *x = nav_popup->visible_area.width / 2.0;
+
+ if (*y - nav_popup->visible_area.height / 2.0 < 0.0)
+ *y = nav_popup->visible_area.height / 2.0;
+
+ if (*x + nav_popup->visible_area.width / 2.0 > nav_popup->popup_width - 0)
+ *x = nav_popup->popup_width - 0 - nav_popup->visible_area.width / 2.0;
+
+ if (*y + nav_popup->visible_area.height / 2.0 > nav_popup->popup_height - 0)
+ *y = nav_popup->popup_height - 0 - nav_popup->visible_area.height / 2.0;
+
+ *x = *x - nav_popup->visible_area.width / 2.0;
+ *y = *y - nav_popup->visible_area.height / 2.0;
+}
+
+
+static void
+update_popup_geometry (NavigatorPopup *nav_popup)
+{
+ int zoomed_width;
+ int zoomed_height;
+ GdkPixbuf *image_pixbuf;
+ GtkAllocation allocation;
+ int scroll_offset_x;
+ int scroll_offset_y;
+
+ zoomed_width = nav_popup->image_width * gth_image_viewer_get_zoom (nav_popup->viewer);
+ zoomed_height = nav_popup->image_height * gth_image_viewer_get_zoom (nav_popup->viewer);
+
+ nav_popup->window_max_width = MIN (zoomed_width, POPUP_MAX_WIDTH);
+ nav_popup->window_max_height = MIN (zoomed_width, POPUP_MAX_HEIGHT);
+
+ nav_popup->zoom_factor = MIN ((double) (nav_popup->window_max_width) / zoomed_width,
+ (double) (nav_popup->window_max_height) / zoomed_height);
+
+ /* popup window size */
+
+ nav_popup->popup_width = MAX ((int) floor (nav_popup->zoom_factor * zoomed_width + 0.5), 1);
+ nav_popup->popup_height = MAX ((int) floor (nav_popup->zoom_factor * zoomed_height + 0.5), 1);
+
+ image_pixbuf = gth_image_viewer_get_current_pixbuf (nav_popup->viewer);
+ g_return_if_fail (image_pixbuf != NULL);
+
+ if (nav_popup->pixbuf != NULL)
+ g_object_unref (nav_popup->pixbuf);
+ nav_popup->pixbuf = _gdk_pixbuf_scale_simple_safe (image_pixbuf,
+ nav_popup->popup_width,
+ nav_popup->popup_height,
+ GDK_INTERP_TILES);
+
+ /* visible area size */
+
+ gtk_widget_get_allocation (GTK_WIDGET (nav_popup->viewer), &allocation);
+ nav_popup->visible_area.width = (allocation.width - GTH_IMAGE_VIEWER_FRAME_BORDER2) * nav_popup->zoom_factor;
+ nav_popup->visible_area.width = MAX (nav_popup->visible_area.width, POPUP_BORDER);
+ nav_popup->visible_area.width = MIN (nav_popup->visible_area.width, nav_popup->popup_width);
+
+ nav_popup->visible_area.height = (allocation.height - GTH_IMAGE_VIEWER_FRAME_BORDER2) * nav_popup->zoom_factor;
+ nav_popup->visible_area.height = MAX (nav_popup->visible_area.height, POPUP_BORDER);
+ nav_popup->visible_area.height = MIN (nav_popup->visible_area.height, nav_popup->popup_height);
+
+ /* visible area position */
+
+ gth_image_viewer_get_scroll_offset (nav_popup->viewer, &scroll_offset_x, &scroll_offset_y);
+ nav_popup->visible_area.x = scroll_offset_x * nav_popup->zoom_factor;
+ nav_popup->visible_area.y = scroll_offset_y * nav_popup->zoom_factor;
+
+ /* popup window position */
+
+ nav_popup->popup_x = MIN ((int) nav_popup->x_root - nav_popup->visible_area.x - POPUP_BORDER - nav_popup->visible_area.width / 2,
+ gdk_screen_width () - nav_popup->popup_width - POPUP_BORDER_2);
+ nav_popup->popup_y = MIN ((int) nav_popup->y_root - nav_popup->visible_area.y - POPUP_BORDER - nav_popup->visible_area.height / 2,
+ gdk_screen_height () - nav_popup->popup_height - POPUP_BORDER_2);
+}
+
+
+static int
+popup_window_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ NavigatorPopup *nav_popup = data;
+ GthImageViewer *viewer = nav_popup->viewer;
+ GdkModifierType mask;
+ int mx, my;
+ double x, y;
+
+ switch (event->type) {
+ case GDK_BUTTON_RELEASE:
+ /* Release keyboard focus. */
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ gtk_grab_remove (nav_popup->popup_win);
+
+ gtk_widget_destroy (nav_popup->popup_win);
+ g_object_unref (nav_popup->pixbuf);
+ g_free (nav_popup);
+
+ return TRUE;
+
+ case GDK_MOTION_NOTIFY:
+ gdk_window_get_pointer (widget->window, &mx, &my, &mask);
+
+ get_visible_area_origin_as_double (nav_popup, mx, my, &x, &y);
+ nav_popup->visible_area.x = (int) x;
+ nav_popup->visible_area.y = (int) y;
+ gtk_widget_queue_draw (widget);
+
+ mx = (int) (x / nav_popup->zoom_factor);
+ my = (int) (y / nav_popup->zoom_factor);
+ gth_image_viewer_scroll_to (viewer, mx, my);
+
+ return TRUE;
+
+ case GDK_KEY_PRESS:
+ switch (event->key.keyval) {
+ case GDK_plus:
+ case GDK_minus:
+ case GDK_1:
+ switch (event->key.keyval) {
+ case GDK_plus:
+ gth_image_viewer_zoom_in (viewer);
+ break;
+ case GDK_minus:
+ gth_image_viewer_zoom_out (viewer);
+ break;
+ case GDK_1:
+ gth_image_viewer_set_zoom (viewer, 1.0);
+ break;
+ }
+
+ update_popup_geometry (nav_popup);
+ nav_popup->visible_area.x = MAX (nav_popup->visible_area.x, 0);
+ nav_popup->visible_area.x = MIN (nav_popup->visible_area.x, nav_popup->popup_width - nav_popup->visible_area.width);
+ nav_popup->visible_area.y = MAX (nav_popup->visible_area.y, 0);
+ nav_popup->visible_area.y = MIN (nav_popup->visible_area.y, nav_popup->popup_height - nav_popup->visible_area.height);
+ gtk_widget_queue_draw (widget);
+ break;
+
+ default:
+ break;
+ }
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static void
+nav_window_grab_pointer (NavigatorPopup *nav_popup)
+{
+ GdkCursor *cursor;
+
+ gtk_grab_add (nav_popup->popup_win);
+
+ cursor = gdk_cursor_new (GDK_FLEUR);
+ gdk_pointer_grab (nav_popup->popup_win->window,
+ TRUE,
+ (GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_EXTENSION_EVENTS_ALL),
+ nav_popup->preview->window,
+ cursor,
+ 0);
+ gdk_cursor_unref (cursor);
+
+ /* Capture keyboard events. */
+
+ gdk_keyboard_grab (nav_popup->popup_win->window, TRUE, GDK_CURRENT_TIME);
+ gtk_widget_grab_focus (nav_popup->popup_win);
+}
+
+
+static gboolean
+navigator_popup_expose_event_cb (GtkWidget *widget,
+ GdkEventExpose *event,
+ NavigatorPopup *nav_popup)
+{
+ cairo_t *cr;
+
+ if (nav_popup->pixbuf == NULL)
+ return FALSE;
+
+ cr = gdk_cairo_create (gtk_widget_get_window (widget));
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ gdk_cairo_set_source_pixbuf (cr, nav_popup->pixbuf, 0, 0);
+ cairo_rectangle (cr, 0, 0, nav_popup->popup_width, nav_popup->popup_height);
+ cairo_fill (cr);
+
+ if ((nav_popup->visible_area.width < nav_popup->popup_width)
+ || (nav_popup->visible_area.height < nav_popup->popup_height))
+ {
+ cairo_save (cr);
+ cairo_set_line_width (cr, VISIBLE_AREA_BORDER);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_rectangle (cr,
+ nav_popup->visible_area.x + 1.0,
+ nav_popup->visible_area.y + 1.0,
+ nav_popup->visible_area.width - VISIBLE_AREA_BORDER,
+ nav_popup->visible_area.height - VISIBLE_AREA_BORDER);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ cairo_destroy (cr);
+
+ return TRUE;
+}
+
+
+static void
+navigator_event_area_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ GthImageViewer *viewer)
+{
+ NavigatorPopup *nav_popup;
+ GtkWidget *out_frame;
+ GtkWidget *in_frame;
+
+ if (gth_image_viewer_is_void (viewer))
+ return;
+
+ nav_popup = g_new0 (NavigatorPopup, 1);
+ nav_popup->viewer = viewer;
+ nav_popup->popup_win = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_wmclass (GTK_WINDOW (nav_popup->popup_win), "", "gthumb_navigator");
+
+ out_frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (out_frame), GTK_SHADOW_OUT);
+ gtk_container_add (GTK_CONTAINER (nav_popup->popup_win), out_frame);
+
+ in_frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (in_frame), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (out_frame), in_frame);
+
+ nav_popup->preview = gtk_drawing_area_new ();
+ gtk_container_add (GTK_CONTAINER (in_frame), nav_popup->preview);
+ g_signal_connect (G_OBJECT (nav_popup->preview),
+ "expose_event",
+ G_CALLBACK (navigator_popup_expose_event_cb),
+ nav_popup);
+
+ nav_popup->x_root = event->x_root;
+ nav_popup->y_root = event->y_root;
+ nav_popup->image_width = gth_image_viewer_get_image_width (viewer);
+ nav_popup->image_height = gth_image_viewer_get_image_height (viewer);
+ update_popup_geometry (nav_popup);
+
+ g_signal_connect (G_OBJECT (nav_popup->popup_win),
+ "event",
+ G_CALLBACK (popup_window_event_cb),
+ nav_popup);
+
+ gtk_window_move (GTK_WINDOW (nav_popup->popup_win),
+ nav_popup->popup_x,
+ nav_popup->popup_y);
+
+ gtk_window_set_default_size (GTK_WINDOW (nav_popup->popup_win),
+ nav_popup->popup_width + POPUP_BORDER_2,
+ nav_popup->popup_height + POPUP_BORDER_2);
+
+ gtk_widget_show_all (nav_popup->popup_win);
+
+ nav_window_grab_pointer (nav_popup);
+}
+
+
+static gboolean
+image_viewer_size_changed_cb (GtkWidget *widget,
+ GthImageNavigator *self)
+{
+ GtkAdjustment *vadj;
+ GtkAdjustment *hadj;
+ gboolean hide_vscr;
+ gboolean hide_hscr;
+
+ gth_image_viewer_get_adjustments (self->priv->viewer, &hadj, &vadj);
+
+ g_return_val_if_fail (hadj != NULL, FALSE);
+ g_return_val_if_fail (vadj != NULL, FALSE);
+
+ hide_vscr = (vadj->page_size == 0) || (vadj->upper <= vadj->page_size);
+ hide_hscr = (hadj->page_size == 0) || (hadj->upper <= hadj->page_size);
+
+ if (! self->priv->scrollbars_visible || (hide_vscr && hide_hscr)) {
+ gtk_widget_hide (self->priv->viewer_vscr);
+ gtk_widget_hide (self->priv->viewer_hscr);
+ gtk_widget_hide (self->priv->navigator_event_area);
+ }
+ else {
+ gtk_widget_show (self->priv->viewer_vscr);
+ gtk_widget_show (self->priv->viewer_hscr);
+ gtk_widget_show (self->priv->navigator_event_area);
+ }
+
+ return TRUE;
+}
+
+
+static void
+gth_image_navigator_construct (GthImageNavigator *self,
+ GthImageViewer *viewer)
+{
+ GtkAdjustment *vadj = NULL;
+ GtkAdjustment *hadj = NULL;
+ GtkWidget *hbox;
+ GtkWidget *table;
+
+ self->priv->viewer = viewer;
+ g_signal_connect (G_OBJECT (self->priv->viewer),
+ "size_changed",
+ G_CALLBACK (image_viewer_size_changed_cb),
+ self);
+
+ gth_image_viewer_get_adjustments (self->priv->viewer, &hadj, &vadj);
+ self->priv->viewer_hscr = gtk_hscrollbar_new (hadj);
+ self->priv->viewer_vscr = gtk_vscrollbar_new (vadj);
+
+ self->priv->navigator_event_area = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (self->priv->navigator_event_area), _gtk_image_new_from_xpm_data (nav_button_xpm));
+
+ g_signal_connect (G_OBJECT (self->priv->navigator_event_area),
+ "button_press_event",
+ G_CALLBACK (navigator_event_area_button_press_event_cb),
+ self->priv->viewer);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (hbox), GTK_WIDGET (self->priv->viewer));
+
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), self->priv->viewer_vscr, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), self->priv->viewer_hscr, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_table_attach (GTK_TABLE (table), self->priv->navigator_event_area, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ gtk_widget_show_all (hbox);
+ gtk_widget_show (table);
+
+ gtk_container_add (GTK_CONTAINER (self), table);
+}
+
+
+GtkWidget *
+gth_image_navigator_new (GthImageViewer *viewer)
+{
+ GthImageNavigator *self;
+
+ g_return_val_if_fail (viewer != NULL, NULL);
+
+ self = g_object_new (GTH_TYPE_IMAGE_NAVIGATOR, NULL);
+ gth_image_navigator_construct (self, viewer);
+
+ return (GtkWidget*) self;
+}
+
+
+void
+gth_image_navigator_set_scrollbars_visible (GthImageNavigator *self,
+ gboolean visible)
+{
+ self->priv->scrollbars_visible = visible;
+ image_viewer_size_changed_cb (NULL, self);
+}
diff --git a/gthumb/gth-image-navigator.h b/gthumb/gth-image-navigator.h
new file mode 100644
index 0000000..70a79fd
--- /dev/null
+++ b/gthumb/gth-image-navigator.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2006-2009 The Free Software Foundation, Inc.
+ *
+ * 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 Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_IMAGE_NAVIGATOR_H
+#define GTH_IMAGE_NAVIGATOR_H
+
+#include <gtk/gtk.h>
+#include "gth-image-viewer.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_IMAGE_NAVIGATOR (gth_image_navigator_get_type ())
+#define GTH_IMAGE_NAVIGATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigator))
+#define GTH_IMAGE_NAVIGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorClass))
+#define GTH_IS_IMAGE_NAVIGATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE_NAVIGATOR))
+#define GTH_IS_IMAGE_NAVIGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_IMAGE_NAVIGATOR))
+#define GTH_IMAGE_NAVIGATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorClass))
+
+typedef struct _GthImageNavigator GthImageNavigator;
+typedef struct _GthImageNavigatorClass GthImageNavigatorClass;
+typedef struct _GthImageNavigatorPrivate GthImageNavigatorPrivate;
+
+struct _GthImageNavigator {
+ GtkHBox __parent;
+ GthImageNavigatorPrivate *priv;
+};
+
+struct _GthImageNavigatorClass {
+ GtkHBoxClass __parent;
+};
+
+GType gth_image_navigator_get_type (void);
+GtkWidget * gth_image_navigator_new (GthImageViewer *viewer);
+void gth_image_navigator_set_scrollbars_visible (GthImageNavigator *window,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_NAVIGATOR_H */
diff --git a/gthumb/gth-image-selector.c b/gthumb/gth-image-selector.c
index 17ab49e..91bc706 100644
--- a/gthumb/gth-image-selector.c
+++ b/gthumb/gth-image-selector.c
@@ -35,6 +35,7 @@
#define STEP_INCREMENT 20.0 /* scroll increment. */
#define SCROLL_TIMEOUT 30 /* autoscroll timeout in milliseconds */
#define GOLDEN_RATIO 1.6180339887
+#define GOLDER_RATIO_FACTOR (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO))
typedef struct {
@@ -206,7 +207,6 @@ struct _GthImageSelectorPrivate {
gboolean active;
GdkRectangle drag_start_selection_area;
- GdkGC *selection_gc;
GdkRectangle selection_area;
GdkRectangle selection;
@@ -512,15 +512,6 @@ gth_image_selector_realize (GthImageViewerTool *base)
widget = (GtkWidget *) self->priv->viewer;
- self->priv->selection_gc = gdk_gc_new (widget->window);
- gdk_gc_copy (self->priv->selection_gc, widget->style->white_gc);
- gdk_gc_set_line_attributes (self->priv->selection_gc,
- 1,
- GDK_LINE_SOLID,
- GDK_CAP_BUTT,
- GDK_JOIN_MITER);
- gdk_gc_set_function (self->priv->selection_gc, GDK_INVERT);
-
if (self->priv->type == GTH_SELECTOR_TYPE_REGION)
self->priv->default_cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_CROSSHAIR /*GDK_LEFT_PTR*/);
else if (self->priv->type == GTH_SELECTOR_TYPE_POINT)
@@ -552,11 +543,6 @@ gth_image_selector_unrealize (GthImageViewerTool *base)
self->priv->default_cursor = NULL;
}
- if (self->priv->selection_gc != NULL) {
- g_object_unref (self->priv->selection_gc);
- self->priv->selection_gc = NULL;
- }
-
free_event_area_list (self);
}
@@ -588,9 +574,11 @@ gth_image_selector_unmap (GthImageViewerTool *base)
static void
paint_background (GthImageSelector *self,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
gth_image_viewer_paint_region (self->priv->viewer,
+ cr,
self->priv->background,
self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -602,19 +590,17 @@ paint_background (GthImageSelector *self,
static void
paint_selection (GthImageSelector *self,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
GdkRectangle selection_area;
- GdkRectangle paint_area;
selection_area = self->priv->selection_area;
selection_area.x += self->priv->viewer->image_area.x - self->priv->viewer->x_offset;
selection_area.y += self->priv->viewer->image_area.y - self->priv->viewer->y_offset;
- if (! gdk_rectangle_intersect (&selection_area, &event->area, &paint_area))
- return;
-
gth_image_viewer_paint_region (self->priv->viewer,
+ cr,
self->priv->pixbuf,
self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -622,26 +608,37 @@ paint_selection (GthImageSelector *self,
event->region,
GDK_INTERP_TILES);
- gdk_gc_set_clip_region (self->priv->selection_gc, event->region);
+ cairo_save (cr);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2)
+ cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+#else
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+#endif
+
+
+ gdk_cairo_region (cr, event->region);
+ gdk_cairo_rectangle (cr, &selection_area);
+ cairo_clip (cr);
if (self->priv->grid_type != GTH_GRID_NONE) {
int grid_x0, grid_x1, grid_x2, grid_x3;
int grid_y0, grid_y1, grid_y2, grid_y3;
int x_delta, y_delta;
- grid_x0 = paint_area.x;
- grid_x3 = paint_area.x + paint_area.width;
+ grid_x0 = selection_area.x;
+ grid_x3 = selection_area.x + selection_area.width;
- grid_y0 = paint_area.y;
- grid_y3 = paint_area.y + paint_area.height;
+ grid_y0 = selection_area.y;
+ grid_y3 = selection_area.y + selection_area.height;
if (self->priv->grid_type == GTH_GRID_THIRDS) {
- x_delta = paint_area.width / 3;
- y_delta = paint_area.height /3;
+ x_delta = selection_area.width / 3;
+ y_delta = selection_area.height /3;
}
else if (self->priv->grid_type == GTH_GRID_GOLDEN) {
- x_delta = paint_area.width * (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO));
- y_delta = paint_area.height * (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO));
+ x_delta = selection_area.width * GOLDER_RATIO_FACTOR;
+ y_delta = selection_area.height * GOLDER_RATIO_FACTOR;
}
grid_x1 = grid_x0 + x_delta;
@@ -649,39 +646,37 @@ paint_selection (GthImageSelector *self,
grid_y1 = grid_y0 + y_delta;
grid_y2 = grid_y3 - y_delta;
- gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
- self->priv->selection_gc,
- grid_x1, grid_y0,
- grid_x1, grid_y3);
- gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
- self->priv->selection_gc,
- grid_x2, grid_y0,
- grid_x2, grid_y3);
- gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
- self->priv->selection_gc,
- grid_x0, grid_y1,
- grid_x3, grid_y1);
- gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
- self->priv->selection_gc,
- grid_x0, grid_y2,
- grid_x3, grid_y2);
+ cairo_move_to (cr, grid_x1 + 0.5, grid_y0 + 0.5);
+ cairo_line_to (cr, grid_x1 + 0.5, grid_y3 + 0.5);
+
+ cairo_move_to (cr, grid_x2 + 0.5, grid_y0 + 0.5);
+ cairo_line_to (cr, grid_x2 + 0.5, grid_y3 + 0.5);
+
+ cairo_move_to (cr, grid_x0 + 0.5, grid_y1 + 0.5);
+ cairo_line_to (cr, grid_x3 + 0.5, grid_y1 + 0.5);
+
+ cairo_move_to (cr, grid_x0 + 0.5, grid_y2 + 0.5);
+ cairo_line_to (cr, grid_x3 + 0.5, grid_y2 + 0.5);
}
- gdk_draw_rectangle (GTK_WIDGET (self->priv->viewer)->window,
- self->priv->selection_gc,
- FALSE,
- selection_area.x,
- selection_area.y,
- selection_area.width,
- selection_area.height);
+ cairo_rectangle (cr,
+ selection_area.x + 0.5,
+ selection_area.y + 0.5,
+ selection_area.width,
+ selection_area.height);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
}
static void
paint_image (GthImageSelector *self,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
gth_image_viewer_paint_region (self->priv->viewer,
+ cr,
self->priv->pixbuf,
self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -693,7 +688,8 @@ paint_image (GthImageSelector *self,
static void
gth_image_selector_expose (GthImageViewerTool *base,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
@@ -701,11 +697,11 @@ gth_image_selector_expose (GthImageViewerTool *base,
return;
if (self->priv->mask_visible) {
- paint_background (self, event);
- paint_selection (self, event);
+ paint_background (self, event, cr);
+ paint_selection (self, event, cr);
}
else
- paint_image (self, event);
+ paint_image (self, event, cr);
}
diff --git a/gthumb/gth-image-viewer-tool.c b/gthumb/gth-image-viewer-tool.c
index be6c7f1..e41e437 100644
--- a/gthumb/gth-image-viewer-tool.c
+++ b/gthumb/gth-image-viewer-tool.c
@@ -88,9 +88,10 @@ gth_image_viewer_tool_size_allocate (GthImageViewerTool *self,
void
gth_image_viewer_tool_expose (GthImageViewerTool *self,
- GdkEventExpose *event)
+ GdkEventExpose *event,
+ cairo_t *cr)
{
- GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->expose (self, event);
+ GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->expose (self, event, cr);
}
diff --git a/gthumb/gth-image-viewer-tool.h b/gthumb/gth-image-viewer-tool.h
index c69cfcf..8a3374d 100644
--- a/gthumb/gth-image-viewer-tool.h
+++ b/gthumb/gth-image-viewer-tool.h
@@ -45,7 +45,8 @@ struct _GthImageViewerToolIface {
void (*size_allocate) (GthImageViewerTool *self,
GtkAllocation *allocation);
void (*expose) (GthImageViewerTool *self,
- GdkEventExpose *event);
+ GdkEventExpose *event,
+ cairo_t *cr);
gboolean (*button_press) (GthImageViewerTool *self,
GdkEventButton *event);
gboolean (*button_release) (GthImageViewerTool *self,
@@ -64,7 +65,8 @@ void gth_image_viewer_tool_unrealize (GthImageViewerTool *self);
void gth_image_viewer_tool_size_allocate (GthImageViewerTool *self,
GtkAllocation *allocation);
void gth_image_viewer_tool_expose (GthImageViewerTool *self,
- GdkEventExpose *event);
+ GdkEventExpose *event,
+ cairo_t *cr);
gboolean gth_image_viewer_tool_button_press (GthImageViewerTool *self,
GdkEventButton *event);
gboolean gth_image_viewer_tool_button_release (GthImageViewerTool *self,
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index 553d548..f9aa6fe 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -717,13 +717,24 @@ gth_image_viewer_expose (GtkWidget *widget,
GdkEventExpose *event)
{
GthImageViewer *viewer;
+ cairo_t *cr;
+ GtkStyle *style;
int gdk_width;
int gdk_height;
viewer = GTH_IMAGE_VIEWER (widget);
+ cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ cairo_set_line_width (cr, 0.5);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
/* Draw the background. */
+ style = gtk_widget_get_style (widget);
gdk_width = widget->allocation.width - viewer->priv->frame_border2;
gdk_height = widget->allocation.height - viewer->priv->frame_border2;
@@ -732,74 +743,62 @@ gth_image_viewer_expose (GtkWidget *widget,
|| (viewer->image_area.width < gdk_width)
|| (viewer->image_area.height < gdk_height))
{
- int rx, ry, rw, rh;
- GdkGC *gc;
+ int rx, ry, rw, rh;
if (viewer->priv->black_bg)
- gc = widget->style->black_gc;
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
else
- gc = widget->style->bg_gc[GTK_STATE_NORMAL];
+ gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
if (gth_image_viewer_get_current_pixbuf (viewer) == NULL) {
- gdk_draw_rectangle (widget->window,
- gc,
- TRUE,
- 0, 0,
- widget->allocation.width,
- widget->allocation.height);
+ cairo_rectangle (cr,
+ 0 + 0.5,
+ 0 + 0.5,
+ widget->allocation.width + 0.5,
+ widget->allocation.height + 0.5);
}
else {
/* If an image is present draw in four phases to avoid
* flickering. */
/* Top rectangle. */
+
rx = 0;
ry = 0;
rw = widget->allocation.width;
rh = viewer->image_area.y;
if ((rw > 0) && (rh > 0))
- gdk_draw_rectangle (widget->window,
- gc,
- TRUE,
- rx, ry,
- rw, rh);
+ cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
/* Bottom rectangle. */
+
rx = 0;
ry = viewer->image_area.y + viewer->image_area.height;
rw = widget->allocation.width;
rh = widget->allocation.height - viewer->image_area.y - viewer->image_area.height;
if ((rw > 0) && (rh > 0))
- gdk_draw_rectangle (widget->window,
- gc,
- TRUE,
- rx, ry,
- rw, rh);
+ cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
/* Left rectangle. */
+
rx = 0;
ry = viewer->image_area.y - 1;
rw = viewer->image_area.x;
rh = viewer->image_area.height + 2;
if ((rw > 0) && (rh > 0))
- gdk_draw_rectangle (widget->window,
- gc,
- TRUE,
- rx, ry,
- rw, rh);
+ cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
/* Right rectangle. */
+
rx = viewer->image_area.x + viewer->image_area.width;
ry = viewer->image_area.y - 1;
rw = widget->allocation.width - viewer->image_area.x - viewer->image_area.width;
rh = viewer->image_area.height + 2;
if ((rw > 0) && (rh > 0))
- gdk_draw_rectangle (widget->window,
- gc,
- TRUE,
- rx, ry,
- rw, rh);
+ cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
}
+
+ cairo_fill (cr);
}
/* Draw the frame. */
@@ -807,58 +806,43 @@ gth_image_viewer_expose (GtkWidget *widget,
if ((viewer->priv->frame_border > 0)
&& (gth_image_viewer_get_current_pixbuf (viewer) != NULL))
{
- int x1, y1, x2, y2;
- GdkGC *gc;
- if (viewer->priv->black_bg)
- gc = widget->style->black_gc;
- else
- gc = widget->style->light_gc[GTK_STATE_NORMAL];
- /*gc = widget->style->dark_gc[GTK_STATE_NORMAL];*/
-
- x1 = viewer->image_area.x + viewer->image_area.width;
- y1 = viewer->image_area.y - 1;
- x2 = viewer->image_area.x + viewer->image_area.width;
- y2 = viewer->image_area.y + viewer->image_area.height;
- gdk_draw_line (widget->window,
- gc,
- x1, y1,
- x2, y2);
-
- x1 = viewer->image_area.x - 1;
- y1 = viewer->image_area.y + viewer->image_area.height;
- x2 = viewer->image_area.x + viewer->image_area.width;
- y2 = viewer->image_area.y + viewer->image_area.height;
- gdk_draw_line (widget->window,
- gc,
- x1, y1,
- x2, y2);
+ /* bottom and right side */
if (viewer->priv->black_bg)
- gc = widget->style->black_gc;
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
else
- gc = widget->style->dark_gc[GTK_STATE_NORMAL];
-
- x1 = viewer->image_area.x - 1;
- y1 = viewer->image_area.y - 1;
- x2 = viewer->image_area.x - 1;
- y2 = viewer->image_area.y + viewer->image_area.height;
- gdk_draw_line (widget->window,
- gc,
- x1, y1,
- x2, y2);
-
- x1 = viewer->image_area.x - 1;
- y1 = viewer->image_area.y - 1;
- x2 = viewer->image_area.x + viewer->image_area.width;
- y2 = viewer->image_area.y - 1;
- gdk_draw_line (widget->window,
- gc,
- x1, y1,
- x2, y2);
+ gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_NORMAL]);
+
+ cairo_move_to (cr,
+ viewer->image_area.x + viewer->image_area.width + 0.5,
+ viewer->image_area.y - 1 + 0.5);
+ cairo_line_to (cr,
+ viewer->image_area.x + viewer->image_area.width + 0.5,
+ viewer->image_area.y + viewer->image_area.height + 0.5);
+ cairo_line_to (cr,
+ viewer->image_area.x - 1 + 0.5,
+ viewer->image_area.y + viewer->image_area.height + 0.5);
+ cairo_stroke (cr);
+
+ /* top and left side */
+
+ if (! viewer->priv->black_bg)
+ gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
+
+ cairo_move_to (cr,
+ viewer->image_area.x - 1 + 0.5,
+ viewer->image_area.y + viewer->image_area.height + 0.5);
+ cairo_line_to (cr,
+ viewer->image_area.x - 1 + 0.5,
+ viewer->image_area.y - 1 + 0.5);
+ cairo_line_to (cr,
+ viewer->image_area.x + viewer->image_area.width + 0.5,
+ viewer->image_area.y - 1 + 0.5);
+ cairo_stroke (cr);
}
- gth_image_viewer_tool_expose (viewer->priv->tool, event);
+ gth_image_viewer_tool_expose (viewer->priv->tool, event, cr);
/* Draw the focus. */
@@ -882,6 +866,8 @@ gth_image_viewer_expose (GtkWidget *widget,
queue_frame_change (viewer);
+ cairo_destroy (cr);
+
return FALSE;
}
@@ -1028,9 +1014,9 @@ scroll_to (GthImageViewer *viewer,
}
if ((delta_x != 0) || (delta_y != 0)) {
- GdkGC *gc = GTK_WIDGET (viewer)->style->black_gc;
- int src_x, dest_x;
- int src_y, dest_y;
+ int src_x, dest_x;
+ int src_y, dest_y;
+ cairo_t *cr;
if (delta_x < 0) {
src_x = 0;
@@ -1050,23 +1036,21 @@ scroll_to (GthImageViewer *viewer,
dest_y = 0;
}
- gc = gdk_gc_new (drawable);
- gdk_gc_set_exposures (gc, TRUE);
-
dest_x += viewer->priv->frame_border;
dest_y += viewer->priv->frame_border;
src_x += viewer->priv->frame_border;
src_y += viewer->priv->frame_border;
- gdk_draw_drawable (drawable,
- gc,
- drawable,
- src_x, src_y,
- dest_x, dest_y,
- gdk_width - abs (delta_x),
- gdk_height - abs (delta_y));
+ cr = gdk_cairo_create (drawable);
+ gdk_cairo_set_source_pixmap (cr, drawable, dest_x - src_x, dest_y - src_y);
+ cairo_rectangle (cr,
+ dest_x,
+ dest_y,
+ gdk_width - abs (delta_x),
+ gdk_height - abs (delta_y));
+ cairo_fill (cr);
- g_object_unref (gc);
+ cairo_destroy (cr);
}
viewer->x_offset = *x_offset;
@@ -1712,6 +1696,7 @@ gth_image_viewer_instance_init (GthImageViewer *viewer)
GTK_WIDGET_SET_FLAGS (viewer, GTK_CAN_FOCUS);
viewer->priv = GTH_IMAGE_VIEWER_GET_PRIVATE (viewer);
+ gtk_widget_set_double_buffered (GTK_WIDGET (viewer), TRUE);
/* Initialize data. */
@@ -2588,6 +2573,7 @@ gth_image_viewer_is_frame_visible (GthImageViewer *viewer)
void
gth_image_viewer_paint (GthImageViewer *viewer,
+ cairo_t *cr,
GdkPixbuf *pixbuf,
int src_x,
int src_y,
@@ -2597,11 +2583,9 @@ gth_image_viewer_paint (GthImageViewer *viewer,
int height,
int interp_type)
{
- double zoom_level;
- int bits_per_sample;
- GdkColorspace color_space;
- guchar *pixels;
- int rowstride;
+ double zoom_level;
+ int bits_per_sample;
+ GdkColorspace color_space;
zoom_level = viewer->priv->zoom_level;
@@ -2629,62 +2613,42 @@ gth_image_viewer_paint (GthImageViewer *viewer,
viewer->priv->paint_bps = bits_per_sample;
}
- if ((zoom_level == 1.0) && ! gdk_pixbuf_get_has_alpha (pixbuf) && (bits_per_sample == 8)) {
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- pixels = gdk_pixbuf_get_pixels (pixbuf) + (src_y * rowstride) + (src_x * gdk_pixbuf_get_n_channels (pixbuf));
- }
- else {
- if (gdk_pixbuf_get_has_alpha (pixbuf))
- gdk_pixbuf_composite_color (pixbuf,
- viewer->priv->paint_pixbuf,
- 0, 0,
- width, height,
- (double) -src_x,
- (double) -src_y,
- zoom_level,
- zoom_level,
- interp_type,
- 255,
- src_x, src_y,
- viewer->priv->check_size,
- viewer->priv->check_color1,
- viewer->priv->check_color2);
- else
- gdk_pixbuf_scale (pixbuf,
- viewer->priv->paint_pixbuf,
- 0, 0,
- width, height,
- (double) -src_x,
- (double) -src_y,
- zoom_level,
- zoom_level,
- interp_type);
-
- rowstride = gdk_pixbuf_get_rowstride (viewer->priv->paint_pixbuf);
- pixels = gdk_pixbuf_get_pixels (viewer->priv->paint_pixbuf);
- }
-
- gdk_draw_rgb_image_dithalign (GTK_WIDGET (viewer)->window,
- GTK_WIDGET (viewer)->style->black_gc,
- dest_x, dest_y,
- width, height,
- GDK_RGB_DITHER_MAX,
- pixels,
- rowstride,
- dest_x, dest_y);
+ if (gdk_pixbuf_get_has_alpha (pixbuf))
+ gdk_pixbuf_composite_color (pixbuf,
+ viewer->priv->paint_pixbuf,
+ 0, 0,
+ width, height,
+ (double) -src_x,
+ (double) -src_y,
+ zoom_level,
+ zoom_level,
+ interp_type,
+ 255,
+ src_x, src_y,
+ viewer->priv->check_size,
+ viewer->priv->check_color1,
+ viewer->priv->check_color2);
+ else
+ gdk_pixbuf_scale (pixbuf,
+ viewer->priv->paint_pixbuf,
+ 0, 0,
+ width, height,
+ (double) -src_x,
+ (double) -src_y,
+ zoom_level,
+ zoom_level,
+ interp_type);
-#if 0
- gdk_draw_rectangle (GTK_WIDGET (viewer)->window,
- GTK_WIDGET (viewer)->style->black_gc,
- FALSE,
- dest_x, dest_y,
- width, height);
-#endif
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ gdk_cairo_set_source_pixbuf (cr, viewer->priv->paint_pixbuf, dest_x, dest_y);
+ cairo_rectangle (cr, dest_x, dest_y, width, height);
+ cairo_fill (cr);
}
void
gth_image_viewer_paint_region (GthImageViewer *viewer,
+ cairo_t *cr,
GdkPixbuf *pixbuf,
int src_x,
int src_y,
@@ -2696,12 +2660,19 @@ gth_image_viewer_paint_region (GthImageViewer *viewer,
int n_rects;
int i;
+ cairo_save (cr);
+ gdk_cairo_region (cr, region);
+ cairo_clip (cr);
+ gdk_cairo_rectangle (cr, pixbuf_area);
+ cairo_clip (cr);
+
gdk_region_get_rectangles (region, &rects, &n_rects);
for (i = 0; i < n_rects; i++) {
GdkRectangle paint_area;
if (gdk_rectangle_intersect (pixbuf_area, &rects[i], &paint_area))
gth_image_viewer_paint (viewer,
+ cr,
pixbuf,
src_x + paint_area.x,
src_y + paint_area.y,
@@ -2712,6 +2683,8 @@ gth_image_viewer_paint_region (GthImageViewer *viewer,
interp_type);
}
+ cairo_restore (cr);
+
g_free (rects);
}
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index 5d48f67..6690176 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -266,6 +266,7 @@ gboolean gth_image_viewer_is_frame_visible (GthImageViewer *vi
/*< protected, used by the tools >*/
void gth_image_viewer_paint (GthImageViewer *viewer,
+ cairo_t *cr,
GdkPixbuf *pixbuf,
int src_x,
int src_y,
@@ -275,6 +276,7 @@ void gth_image_viewer_paint (GthImageViewer *vi
int height,
int interp_type);
void gth_image_viewer_paint_region (GthImageViewer *viewer,
+ cairo_t *cr,
GdkPixbuf *pixbuf,
int src_x,
int src_y,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1da6a5c..3655100 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -639,6 +639,8 @@ gthumb/gth-image-history.c
gthumb/gth-image-history.h
gthumb/gth-image-loader.c
gthumb/gth-image-loader.h
+gthumb/gth-image-navigator.c
+gthumb/gth-image-navigator.h
gthumb/gth-image-preloader.c
gthumb/gth-image-preloader.h
gthumb/gth-image-selector.c
@@ -670,8 +672,6 @@ gthumb/gth-monitor.c
gthumb/gth-monitor.h
gthumb/gth-multipage.c
gthumb/gth-multipage.h
-gthumb/gth-nav-window.c
-gthumb/gth-nav-window.h
gthumb/gth-overwrite-dialog.c
gthumb/gth-overwrite-dialog.h
gthumb/gth-pixbuf-list-task.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]