[gthumb] image overview: fixed the proportions of the visible area
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] image overview: fixed the proportions of the visible area
- Date: Sat, 9 Nov 2013 20:09:56 +0000 (UTC)
commit 4fe30a9f460d832fc45be42152207df48d4fe932
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Nov 3 18:26:33 2013 +0100
image overview: fixed the proportions of the visible area
gthumb/gth-image-overview.c | 246 +++++++++++++++++++++++--------------------
gthumb/gth-image-viewer.c | 40 ++++---
gthumb/gth-image-viewer.h | 1 +
3 files changed, 158 insertions(+), 129 deletions(-)
---
diff --git a/gthumb/gth-image-overview.c b/gthumb/gth-image-overview.c
index ab565b2..b27d968 100644
--- a/gthumb/gth-image-overview.c
+++ b/gthumb/gth-image-overview.c
@@ -45,20 +45,20 @@ struct _GthImageOverviewPrivate {
GthImageViewer *viewer;
cairo_surface_t *preview;
int preview_width;
- double preview_frame_border;
- int preview_image_width;
- int preview_image_height;
int preview_height;
+ cairo_rectangle_int_t preview_area;
cairo_rectangle_int_t visible_area;
double zoom_factor;
- double quality_zoom;
+ double quality_zoom;
gulong zoom_changed_id;
+ gulong better_quality_id;
gulong image_changed_id;
gulong vadj_vchanged_id;
gulong hadj_vchanged_id;
gulong vadj_changed_id;
gulong hadj_changed_id;
gboolean scrolling_active;
+ gboolean update_preview;
};
@@ -82,31 +82,21 @@ gth_image_overview_finalize (GObject *object)
static void
-_gth_image_overview_update_preview (GthImageOverview *self)
+_gth_image_overview_update_zoom_info (GthImageOverview *self)
{
- cairo_surface_t *image;
- int width, height;
- int frame_border;
- double zoom_factor;
-
- cairo_surface_destroy (self->priv->preview);
- self->priv->preview = NULL;
+ cairo_surface_t *image;
+ int width, height;
+ double zoom;
image = gth_image_viewer_get_current_image (self->priv->viewer);
- if (image == NULL) {
- self->priv->preview_width = 0;
- self->priv->preview_height = 0;
- self->priv->visible_area.width = 0;
- self->priv->visible_area.height = 0;
- gtk_widget_queue_draw (GTK_WIDGET (self));
-
+ if (image == NULL)
return;
- }
gth_image_viewer_get_original_size (self->priv->viewer, &width, &height);
- frame_border = gth_image_viewer_get_frame_border (self->priv->viewer);
- width += (frame_border * 2);
- height += (frame_border * 2);
+ self->priv->quality_zoom = (double) width / cairo_image_surface_get_width (image);
+ zoom = gth_image_viewer_get_zoom (self->priv->viewer);
+ width = width * zoom;
+ height = height * zoom;
self->priv->preview_width = width;
self->priv->preview_height = height;
@@ -114,62 +104,71 @@ _gth_image_overview_update_preview (GthImageOverview *self)
&self->priv->preview_height,
MAX_IMAGE_SIZE,
MAX_IMAGE_SIZE,
- FALSE);
+ TRUE);
- zoom_factor = MIN ((double) (self->priv->preview_width) / width,
- (double) (self->priv->preview_height) / height);
- self->priv->preview_frame_border = frame_border * zoom_factor;
- self->priv->preview_image_width = self->priv->preview_width - (self->priv->preview_frame_border * 2);
- self->priv->preview_image_height = self->priv->preview_height - (self->priv->preview_frame_border *
2);
+ self->priv->zoom_factor = MIN ((double) (self->priv->preview_width) / width,
+ (double) (self->priv->preview_height) / height);
- self->priv->preview = _cairo_image_surface_scale_bilinear (image,
- self->priv->preview_image_width,
- self->priv->preview_image_height);
+ self->priv->preview_area.x = IMAGE_BORDER;
+ self->priv->preview_area.y = IMAGE_BORDER;
+ self->priv->preview_area.width = self->priv->preview_width;
+ self->priv->preview_area.height = self->priv->preview_height;
}
static void
-_gth_image_overview_update_zoom_info (GthImageOverview *self)
+_gth_image_overview_update_preview (GthImageOverview *self)
{
- cairo_surface_t *image;
- int width, height;
- double zoom;
- int frame_border;
+ cairo_surface_t *image;
- if (self->priv->preview == NULL)
+ if (self->priv->viewer == NULL)
return;
- image = gth_image_viewer_get_current_image (self->priv->viewer);
- if (image == NULL)
+ if (! self->priv->update_preview)
return;
- gth_image_viewer_get_original_size (self->priv->viewer, &width, &height);
- self->priv->quality_zoom = (double) width / cairo_image_surface_get_width (image);
+ self->priv->update_preview = FALSE;
- zoom = gth_image_viewer_get_zoom (self->priv->viewer);
- frame_border = gth_image_viewer_get_frame_border (self->priv->viewer);
- width = width * zoom + (frame_border * 2);
- height = height * zoom + (frame_border * 2);
+ cairo_surface_destroy (self->priv->preview);
+ self->priv->preview = NULL;
- self->priv->zoom_factor = MIN ((double) (self->priv->preview_width) / width,
- (double) (self->priv->preview_height) / height);
+ image = gth_image_viewer_get_current_image (self->priv->viewer);
+ if (image == NULL) {
+ self->priv->preview_width = 0;
+ self->priv->preview_height = 0;
+ self->priv->visible_area.width = 0;
+ self->priv->visible_area.height = 0;
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+
+ return;
+ }
+
+ _gth_image_overview_update_zoom_info (self);
+ self->priv->preview = _cairo_image_surface_scale_bilinear (image,
+ self->priv->preview_area.width,
+ self->priv->preview_area.height);
}
static void
_gth_image_overview_update_visible_area (GthImageOverview *self)
{
+ int frame_border;
+
+ if (self->priv->viewer == NULL)
+ return;
+
+ frame_border = gth_image_viewer_get_frame_border (self->priv->viewer);
+
/* visible area size */
self->priv->visible_area.width = self->priv->viewer->visible_area.width * self->priv->zoom_factor;
- self->priv->visible_area.width = MIN (self->priv->visible_area.width, self->priv->preview_width);
self->priv->visible_area.height = self->priv->viewer->visible_area.height * self->priv->zoom_factor;
- self->priv->visible_area.height = MIN (self->priv->visible_area.height, self->priv->preview_height);
/* visible area position */
- self->priv->visible_area.x = self->priv->viewer->visible_area.x * self->priv->zoom_factor;
- self->priv->visible_area.y = self->priv->viewer->visible_area.y * self->priv->zoom_factor;
+ self->priv->visible_area.x = (self->priv->viewer->visible_area.x - frame_border) *
self->priv->zoom_factor + IMAGE_BORDER;
+ self->priv->visible_area.y = (self->priv->viewer->visible_area.y - frame_border) *
self->priv->zoom_factor + IMAGE_BORDER;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
@@ -181,6 +180,9 @@ viewer_zoom_changed_cb (GthImageViewer *viewer,
{
GthImageOverview *self = GTH_IMAGE_OVERVIEW (user_data);
+ if (! gtk_widget_get_visible (GTK_WIDGET (self)))
+ return;
+
_gth_image_overview_update_zoom_info (self);
_gth_image_overview_update_visible_area (self);
}
@@ -192,8 +194,12 @@ viewer_image_changed_cb (GthImageViewer *viewer,
{
GthImageOverview *self = GTH_IMAGE_OVERVIEW (user_data);
+ self->priv->update_preview = TRUE;
+
+ if (! gtk_widget_get_visible (GTK_WIDGET (self)))
+ return;
+
_gth_image_overview_update_preview (self);
- _gth_image_overview_update_zoom_info (self);
_gth_image_overview_update_visible_area (self);
gtk_widget_queue_resize (GTK_WIDGET (user_data));
@@ -204,7 +210,11 @@ static void
viewer_adj_value_changed_cb (GtkAdjustment *adjustment,
gpointer user_data)
{
- _gth_image_overview_update_visible_area (GTH_IMAGE_OVERVIEW (user_data));
+ GthImageOverview *self = GTH_IMAGE_OVERVIEW (user_data);
+
+ if (! gtk_widget_get_visible (GTK_WIDGET (self)))
+ return;
+ _gth_image_overview_update_visible_area (self);
}
@@ -225,6 +235,11 @@ _gth_image_overview_set_viewer (GthImageOverview *self,
g_signal_handler_disconnect (self->priv->viewer, self->priv->image_changed_id);
self->priv->image_changed_id = 0;
}
+ if (self->priv->better_quality_id > 0) {
+ if (self->priv->viewer != NULL)
+ g_signal_handler_disconnect (self->priv->viewer, self->priv->better_quality_id);
+ self->priv->better_quality_id = 0;
+ }
if (self->priv->vadj_vchanged_id > 0) {
if (self->priv->viewer != NULL)
g_signal_handler_disconnect (self->priv->viewer->vadj, self->priv->vadj_vchanged_id);
@@ -256,6 +271,10 @@ _gth_image_overview_set_viewer (GthImageOverview *self,
"zoom-changed",
G_CALLBACK (viewer_zoom_changed_cb),
self);
+ self->priv->better_quality_id = g_signal_connect (self->priv->viewer,
+ "better-quality",
+ G_CALLBACK (viewer_zoom_changed_cb),
+ self);
self->priv->image_changed_id = g_signal_connect (self->priv->viewer,
"image-changed",
G_CALLBACK (viewer_image_changed_cb),
@@ -375,8 +394,10 @@ static gboolean
gth_image_overview_draw (GtkWidget *widget,
cairo_t *cr)
{
- GthImageOverview *self;
- GtkAllocation allocation;
+ GthImageOverview *self;
+ GtkAllocation allocation;
+ cairo_region_t *region;
+ cairo_rectangle_int_t visible_area;
self = GTH_IMAGE_OVERVIEW (widget);
@@ -385,6 +406,8 @@ gth_image_overview_draw (GtkWidget *widget,
gtk_widget_get_allocation (widget, &allocation);
+ /* frame */
+
cairo_save (cr);
cairo_rectangle (cr, 0.5, 0.5, allocation.width - 1, allocation.height - 1);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
@@ -393,66 +416,44 @@ gth_image_overview_draw (GtkWidget *widget,
cairo_fill (cr);
cairo_restore (cr);
+ /* image */
+
cairo_save (cr);
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
cairo_set_source_surface (cr, self->priv->preview,
- IMAGE_BORDER + self->priv->preview_frame_border,
- IMAGE_BORDER + self->priv->preview_frame_border);
+ IMAGE_BORDER,
+ IMAGE_BORDER);
cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_FAST);
cairo_rectangle (cr,
- IMAGE_BORDER + self->priv->preview_frame_border,
- IMAGE_BORDER + self->priv->preview_frame_border,
- self->priv->preview_image_width,
- self->priv->preview_image_height);
+ self->priv->preview_area.x,
+ self->priv->preview_area.y,
+ self->priv->preview_area.width,
+ self->priv->preview_area.height);
cairo_fill_preserve (cr);
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_stroke (cr);
cairo_restore (cr);
- if ((self->priv->visible_area.width < self->priv->preview_width)
- || (self->priv->visible_area.height < self->priv->preview_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,
- self->priv->visible_area.x + IMAGE_BORDER,
- self->priv->visible_area.y + IMAGE_BORDER,
- self->priv->visible_area.width,
- self->priv->visible_area.height);
- cairo_stroke (cr);
- cairo_restore (cr);
- }
-
- return TRUE;
-}
+ /* visible area */
+ region = cairo_region_create_rectangle (&self->priv->preview_area);
+ cairo_region_intersect_rectangle (region, &self->priv->visible_area);
+ cairo_region_get_extents (region, &visible_area);
+ cairo_region_destroy (region);
-static void
-get_visible_area_origin_as_double (GthImageOverview *self,
- int mx,
- int my,
- double *x,
- double *y)
-{
- *x = MIN (mx, self->priv->preview_width);
- *y = MIN (my, self->priv->preview_height);
-
- if (*x - self->priv->visible_area.width / 2.0 < 0.0)
- *x = self->priv->visible_area.width / 2.0;
-
- if (*y - self->priv->visible_area.height / 2.0 < 0.0)
- *y = self->priv->visible_area.height / 2.0;
-
- if (*x + self->priv->visible_area.width / 2.0 > self->priv->preview_width - 0)
- *x = self->priv->preview_width - 0 - self->priv->visible_area.width / 2.0;
-
- if (*y + self->priv->visible_area.height / 2.0 > self->priv->preview_height - 0)
- *y = self->priv->preview_height - 0 - self->priv->visible_area.height / 2.0;
+ 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,
+ visible_area.x,
+ visible_area.y,
+ visible_area.width,
+ visible_area.height);
+ cairo_stroke (cr);
+ cairo_restore (cr);
- *x = *x - self->priv->visible_area.width / 2.0;
- *y = *y - self->priv->visible_area.height / 2.0;
+ return TRUE;
}
@@ -460,8 +461,7 @@ static void
update_offset (GthImageOverview *self,
GdkEvent *event)
{
- int mx, my;
- double x, y;
+ int mx, my;
gdk_window_get_device_position (gtk_widget_get_window (GTK_WIDGET (self)),
gdk_event_get_device (event),
@@ -469,10 +469,11 @@ update_offset (GthImageOverview *self,
&my,
NULL);
- get_visible_area_origin_as_double (self, mx, my, &x, &y);
+ mx = mx - self->priv->visible_area.width / 2.0;
+ my = my - self->priv->visible_area.height / 2.0;
+ mx = mx / (self->priv->quality_zoom * self->priv->zoom_factor);
+ my = my / (self->priv->quality_zoom * self->priv->zoom_factor);
- mx = (int) (x / (self->priv->quality_zoom * self->priv->zoom_factor));
- my = (int) (y / (self->priv->quality_zoom * self->priv->zoom_factor));
gth_image_viewer_set_scroll_offset (self->priv->viewer, mx, my);
}
@@ -487,7 +488,7 @@ gth_image_overview_button_press_event (GtkWidget *widget,
gth_image_overview_activate_scrolling (GTH_IMAGE_OVERVIEW (widget), TRUE, event);
update_offset (GTH_IMAGE_OVERVIEW (widget), (GdkEvent*) event);
- return TRUE;
+ return FALSE;
}
@@ -496,7 +497,7 @@ gth_image_overview_button_release_event (GtkWidget *widget,
GdkEventButton *event)
{
gth_image_overview_activate_scrolling (GTH_IMAGE_OVERVIEW (widget), FALSE, event);
- return TRUE;
+ return FALSE;
}
@@ -619,6 +620,21 @@ gth_image_overview_class_init (GthImageOverviewClass *klass)
static void
+notify_visible_cb (GObject *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GthImageOverview *self = GTH_IMAGE_OVERVIEW (gobject);
+
+ if (self->priv->viewer == NULL)
+ return;
+
+ _gth_image_overview_update_preview (self);
+ _gth_image_overview_update_visible_area (self);
+}
+
+
+static void
gth_image_overview_init (GthImageOverview *self)
{
self->priv = gth_image_overview_get_instance_private (self);
@@ -628,12 +644,16 @@ gth_image_overview_init (GthImageOverview *self)
self->priv->visible_area.height = 0;
self->priv->zoom_factor = 1.0;
self->priv->zoom_changed_id = 0;
+ self->priv->better_quality_id = 0;
self->priv->image_changed_id = 0;
self->priv->vadj_vchanged_id = 0;
self->priv->hadj_vchanged_id = 0;
self->priv->vadj_changed_id = 0;
self->priv->hadj_changed_id = 0;
self->priv->scrolling_active = FALSE;
+ self->priv->update_preview = TRUE;
+
+ g_signal_connect (self, "notify::visible", G_CALLBACK (notify_visible_cb), NULL);
/* do not use the rgba visual on the drawing area */
{
@@ -648,7 +668,6 @@ gth_image_overview_init (GthImageOverview *self)
GtkWidget *
gth_image_overview_new (GthImageViewer *viewer)
{
- g_return_val_if_fail (viewer != NULL, NULL);
return (GtkWidget *) g_object_new (GTH_TYPE_IMAGE_OVERVIEW, "viewer", viewer, NULL);
}
@@ -658,6 +677,9 @@ gth_image_overview_get_size (GthImageOverview *self,
int *width,
int *height)
{
+ _gth_image_overview_update_preview (self);
+ _gth_image_overview_update_visible_area (self);
+
if (width != NULL) *width = self->priv->preview_width;
if (height != NULL) *height = self->priv->preview_height;
}
@@ -670,8 +692,8 @@ gth_image_overview_get_visible_area (GthImageOverview *self,
int *width,
int *height)
{
- if (x != NULL) *x = self->priv->visible_area.x;
- if (y != NULL) *y = self->priv->visible_area.y;
+ if (x != NULL) *x = self->priv->visible_area.x - IMAGE_BORDER;
+ if (y != NULL) *y = self->priv->visible_area.y - IMAGE_BORDER;
if (width != NULL) *width = self->priv->visible_area.width;
if (height != NULL) *height = self->priv->visible_area.height;
}
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index ae70bba..8bb8c18 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -66,6 +66,7 @@ enum {
SET_FIT_MODE,
IMAGE_CHANGED,
ZOOM_CHANGED,
+ BETTER_QUALITY,
SCROLL,
LAST_SIGNAL
};
@@ -300,15 +301,6 @@ _gth_image_viewer_update_image_area (GthImageViewer *self)
}
-static void
-_gth_image_viewer_image_changed (GthImageViewer *self)
-{
- if (self->priv->tool != NULL)
- gth_image_viewer_tool_image_changed (self->priv->tool);
- g_signal_emit (G_OBJECT (self), gth_image_viewer_signals[IMAGE_CHANGED], 0);
-}
-
-
static void _set_surface (GthImageViewer *self,
cairo_surface_t *surface,
int original_width,
@@ -377,7 +369,7 @@ set_zoom (GthImageViewer *self,
_gth_image_viewer_update_image_area (self);
if (self->priv->update_image_after_zoom) {
- _gth_image_viewer_image_changed (self);
+ gth_image_viewer_tool_image_changed (self->priv->tool);
self->priv->update_image_after_zoom = FALSE;
}
else
@@ -1273,7 +1265,7 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
G_TYPE_NONE,
0);
gth_image_viewer_signals[SET_ZOOM] =
- g_signal_new ("set_zoom",
+ g_signal_new ("set-zoom",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GthImageViewerClass, set_zoom),
@@ -1283,7 +1275,7 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
1,
G_TYPE_DOUBLE);
gth_image_viewer_signals[SET_FIT_MODE] =
- g_signal_new ("set_fit_mode",
+ g_signal_new ("set-fit-mode",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GthImageViewerClass, set_fit_mode),
@@ -1293,7 +1285,7 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
1,
GTH_TYPE_FIT);
gth_image_viewer_signals[IMAGE_CHANGED] =
- g_signal_new ("image_changed",
+ g_signal_new ("image-changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GthImageViewerClass, image_changed),
@@ -1302,7 +1294,7 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
G_TYPE_NONE,
0);
gth_image_viewer_signals[ZOOM_CHANGED] =
- g_signal_new ("zoom_changed",
+ g_signal_new ("zoom-changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GthImageViewerClass, zoom_changed),
@@ -1310,6 +1302,15 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+ gth_image_viewer_signals[BETTER_QUALITY] =
+ g_signal_new ("better-quality",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthImageViewerClass, better_quality),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
gth_image_viewer_signals[SCROLL] =
g_signal_new ("scroll",
G_TYPE_FROM_CLASS (class),
@@ -1601,13 +1602,18 @@ _gth_image_viewer_content_changed (GthImageViewer *self,
{
halt_animation (self);
+ if (better_quality)
+ g_signal_emit (G_OBJECT (self), gth_image_viewer_signals[BETTER_QUALITY], 0);
+ else
+ g_signal_emit (G_OBJECT (self), gth_image_viewer_signals[IMAGE_CHANGED], 0);
+
if (! better_quality && self->priv->reset_scrollbars) {
self->visible_area.x = 0;
self->visible_area.y = 0;
}
if (better_quality || ! self->priv->zoom_enabled) {
- _gth_image_viewer_image_changed (self);
+ gth_image_viewer_tool_image_changed (self->priv->tool);
return;
}
@@ -1620,7 +1626,7 @@ _gth_image_viewer_content_changed (GthImageViewer *self,
break;
case GTH_ZOOM_CHANGE_KEEP_PREV:
- _gth_image_viewer_image_changed (self);
+ gth_image_viewer_tool_image_changed (self->priv->tool);
gtk_widget_queue_resize (GTK_WIDGET (self));
break;
@@ -2194,7 +2200,7 @@ gth_image_viewer_set_tool (GthImageViewer *self,
gth_image_viewer_tool_set_viewer (self->priv->tool, self);
if (gtk_widget_get_realized (GTK_WIDGET (self)))
gth_image_viewer_tool_realize (self->priv->tool);
- _gth_image_viewer_image_changed (self);
+ gth_image_viewer_tool_image_changed (self->priv->tool);
gtk_widget_queue_resize (GTK_WIDGET (self));
}
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index ead7d5e..694e4ed 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -114,6 +114,7 @@ struct _GthImageViewerClass
void (* clicked) (GthImageViewer *viewer);
void (* image_changed) (GthImageViewer *viewer);
void (* zoom_changed) (GthImageViewer *viewer);
+ void (* better_quality) (GthImageViewer *viewer);
/* -- Key binding signals -- */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]