[gthumb] Refactored the code of the image viewer widget
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] Refactored the code of the image viewer widget
- Date: Thu, 27 Oct 2011 13:51:24 +0000 (UTC)
commit 910274071a8c144d227b07fa701ed3cfc78cee36
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Oct 27 15:33:48 2011 +0200
Refactored the code of the image viewer widget
Removed useless functions and signals. The image navigator is now a
custom container that hides or shows the scrollbars during the size_allocate
function. Added some local utility functions and renamed some variables
to make the code clearer.
extensions/image_viewer/gth-image-viewer-page.c | 40 +-
gthumb/gth-image-dragger.c | 4 +-
gthumb/gth-image-navigator.c | 422 ++++++++++-----
gthumb/gth-image-navigator.h | 12 +-
gthumb/gth-image-viewer.c | 692 +++++++++++------------
gthumb/gth-image-viewer.h | 13 +-
6 files changed, 637 insertions(+), 546 deletions(-)
---
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index eafd5fa..af6eb05 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -469,10 +469,9 @@ pref_zoom_quality_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_zoom_quality (image_viewer, eel_gconf_get_enum (PREF_ZOOM_QUALITY, GTH_TYPE_ZOOM_QUALITY, GTH_ZOOM_QUALITY_HIGH));
- gth_image_viewer_update_view (image_viewer);
+ gth_image_viewer_set_zoom_quality (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_enum (PREF_ZOOM_QUALITY, GTH_TYPE_ZOOM_QUALITY, GTH_ZOOM_QUALITY_HIGH));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -483,10 +482,9 @@ pref_zoom_change_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_zoom_change (image_viewer, eel_gconf_get_enum (PREF_ZOOM_CHANGE, GTH_TYPE_ZOOM_CHANGE, GTH_ZOOM_CHANGE_FIT_SIZE_IF_LARGER));
- gth_image_viewer_update_view (image_viewer);
+ gth_image_viewer_set_zoom_change (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_enum (PREF_ZOOM_CHANGE, GTH_TYPE_ZOOM_CHANGE, GTH_ZOOM_CHANGE_FIT_SIZE_IF_LARGER));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -497,10 +495,9 @@ pref_transp_type_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_transp_type (image_viewer, eel_gconf_get_enum (PREF_TRANSP_TYPE, GTH_TYPE_TRANSP_TYPE, GTH_TRANSP_TYPE_NONE));
- gth_image_viewer_update_view (image_viewer);
+ gth_image_viewer_set_transp_type (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_enum (PREF_TRANSP_TYPE, GTH_TYPE_TRANSP_TYPE, GTH_TRANSP_TYPE_NONE));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -511,10 +508,9 @@ pref_check_type_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_check_type (image_viewer, eel_gconf_get_enum (PREF_CHECK_TYPE, GTH_TYPE_CHECK_TYPE, GTH_CHECK_TYPE_MIDTONE));
- gth_image_viewer_update_view (image_viewer);
+ gth_image_viewer_set_check_type (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_enum (PREF_CHECK_TYPE, GTH_TYPE_CHECK_TYPE, GTH_CHECK_TYPE_MIDTONE));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -525,10 +521,9 @@ pref_check_size_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_check_size (image_viewer, eel_gconf_get_enum (PREF_CHECK_SIZE, GTH_TYPE_CHECK_SIZE, GTH_CHECK_SIZE_MEDIUM));
- gth_image_viewer_update_view (image_viewer);
+ gth_image_viewer_set_check_size (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_enum (PREF_CHECK_SIZE, GTH_TYPE_CHECK_SIZE, GTH_CHECK_SIZE_MEDIUM));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -539,9 +534,9 @@ pref_black_background_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_black_background (image_viewer, eel_gconf_get_boolean (PREF_BLACK_BACKGROUND, FALSE));
+ gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_boolean (PREF_BLACK_BACKGROUND, FALSE));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -552,9 +547,8 @@ pref_reset_scrollbars_changed (GConfClient *client,
gpointer user_data)
{
GthImageViewerPage *self = user_data;
- GthImageViewer *image_viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
- gth_image_viewer_set_reset_scrollbars (image_viewer, eel_gconf_get_boolean (PREF_RESET_SCROLLBARS, TRUE));
+ gth_image_viewer_set_reset_scrollbars (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_boolean (PREF_RESET_SCROLLBARS, TRUE));
}
@@ -1029,11 +1023,11 @@ gth_image_viewer_page_real_fullscreen (GthViewerPage *base,
self = (GthImageViewerPage *) base;
if (active) {
- gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), FALSE);
+ gth_image_navigator_set_automatic_scrollbars (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), FALSE);
gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), TRUE);
}
else {
- gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), TRUE);
+ gth_image_navigator_set_automatic_scrollbars (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));
}
}
@@ -1351,7 +1345,7 @@ gth_image_viewer_page_real_update_info (GthViewerPage *base,
if (self->priv->viewer == NULL)
return;
- gth_image_viewer_update_view (GTH_IMAGE_VIEWER (self->priv->viewer));
+ gtk_widget_queue_draw (self->priv->viewer);
}
@@ -1367,7 +1361,7 @@ gth_image_viewer_page_real_show_properties (GthViewerPage *base,
gth_image_viewer_add_painter (GTH_IMAGE_VIEWER (self->priv->viewer), paint_comment_over_image_func, self);
else
gth_image_viewer_remove_painter (GTH_IMAGE_VIEWER (self->priv->viewer), paint_comment_over_image_func, self);
- gth_image_viewer_update_view (GTH_IMAGE_VIEWER (self->priv->viewer));
+ gtk_widget_queue_draw (self->priv->viewer);
}
diff --git a/gthumb/gth-image-dragger.c b/gthumb/gth-image-dragger.c
index f281884..60064d3 100644
--- a/gthumb/gth-image-dragger.c
+++ b/gthumb/gth-image-dragger.c
@@ -261,8 +261,8 @@ gth_image_dragger_motion_notify (GthImageViewerTool *self,
return FALSE;
gth_image_viewer_scroll_to (viewer,
- viewer->x_offset + viewer->event_x_prev - event->x,
- viewer->y_offset + viewer->event_y_prev - event->y);
+ viewer->drag_x_start - event->x,
+ viewer->drag_y_start - event->y);
return TRUE;
}
diff --git a/gthumb/gth-image-navigator.c b/gthumb/gth-image-navigator.c
index 635a81a..bfa24b0 100644
--- a/gthumb/gth-image-navigator.c
+++ b/gthumb/gth-image-navigator.c
@@ -36,59 +36,273 @@
#define POPUP_MAX_HEIGHT 112
+/* Properties */
+enum {
+ PROP_0,
+ PROP_VIEWER
+};
+
+
struct _GthImageNavigatorPrivate {
- GthImageViewer *viewer;
- GtkWidget *viewer_vscr;
- GtkWidget *viewer_hscr;
- GtkWidget *navigator_event_area;
- gboolean scrollbars_visible;
+ GtkWidget *viewer;
+ GtkWidget *vscrollbar;
+ GtkWidget *hscrollbar;
+ GtkWidget *navigator_event_area;
+ gboolean automatic_scrollbars;
+ gboolean scrollbars_visible;
};
-static GtkHBoxClass *parent_class = NULL;
+static gpointer parent_class = NULL;
static void
-gth_image_navigator_class_init (GthImageNavigatorClass *class)
+_gth_image_navigator_set_viewer (GthImageNavigator *self,
+ GtkWidget *viewer)
{
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (GthImageNavigatorPrivate));
+ if (self->priv->viewer == viewer)
+ return;
+
+ if (self->priv->viewer != NULL)
+ gtk_container_remove (GTK_CONTAINER (self), self->priv->viewer);
+
+ if (viewer == NULL)
+ return;
+
+ gtk_container_add (GTK_CONTAINER (self), viewer);
+ gtk_range_set_adjustment (GTK_RANGE (self->priv->hscrollbar), gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewer)));
+ gtk_range_set_adjustment (GTK_RANGE (self->priv->vscrollbar), gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewer)));
+
+ g_object_notify (G_OBJECT (self), "viewer");
}
static void
-gth_image_navigator_init (GthImageNavigator *self)
+gth_image_navigator_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorPrivate);
- self->priv->scrollbars_visible = TRUE;
+ GthImageNavigator *self = GTH_IMAGE_NAVIGATOR (object);
+
+ switch (property_id) {
+ case PROP_VIEWER:
+ _gth_image_navigator_set_viewer (self, g_value_get_object (value));
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void
+gth_image_navigator_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GthImageNavigator *self = GTH_IMAGE_NAVIGATOR (object);
+
+ switch (property_id) {
+ case PROP_VIEWER:
+ g_value_set_object (value, self->priv->viewer);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+gth_image_navigator_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GthImageNavigator *self = (GthImageNavigator *) widget;
+ gboolean needs_scrollbars;
+ GtkAllocation viewer_allocation;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ needs_scrollbars = self->priv->automatic_scrollbars && gth_image_viewer_needs_scrollbars (GTH_IMAGE_VIEWER (self->priv->viewer), allocation);
+ if (self->priv->scrollbars_visible != needs_scrollbars) {
+ self->priv->scrollbars_visible = needs_scrollbars;
+ gtk_widget_set_child_visible (self->priv->vscrollbar, self->priv->scrollbars_visible);
+ gtk_widget_set_child_visible (self->priv->hscrollbar, self->priv->scrollbars_visible);
+ gtk_widget_set_child_visible (self->priv->navigator_event_area, self->priv->scrollbars_visible);
+ }
+
+ viewer_allocation = *allocation;
+ if (self->priv->scrollbars_visible) {
+ GtkRequisition vscrollbar_requisition;
+ GtkRequisition hscrollbar_requisition;
+ GtkAllocation child_allocation;
+
+ gtk_widget_get_preferred_size (self->priv->vscrollbar, &vscrollbar_requisition, NULL);
+ gtk_widget_get_preferred_size (self->priv->hscrollbar, &hscrollbar_requisition, NULL);
+
+ viewer_allocation.width -= vscrollbar_requisition.width;
+ viewer_allocation.height -= hscrollbar_requisition.height;
+
+ /* vertical scrollbar */
+
+ child_allocation.x = allocation->x + allocation->width - vscrollbar_requisition.width;
+ child_allocation.y = allocation->y;
+ child_allocation.width = vscrollbar_requisition.width;
+ child_allocation.height = allocation->height - hscrollbar_requisition.height;
+ gtk_widget_size_allocate (self->priv->vscrollbar, &child_allocation);
+
+ /* horizontal scrollbar */
+
+ child_allocation.x = allocation->x;
+ child_allocation.y = allocation->y + allocation->height - hscrollbar_requisition.height;
+ child_allocation.width = allocation->width - vscrollbar_requisition.width;
+ child_allocation.height = hscrollbar_requisition.height;
+ gtk_widget_size_allocate (self->priv->hscrollbar, &child_allocation);
+
+ /* event area */
+
+ child_allocation.x = allocation->x + allocation->width - vscrollbar_requisition.width;
+ child_allocation.y = allocation->y + allocation->height - hscrollbar_requisition.height;
+ child_allocation.width = vscrollbar_requisition.width;
+ child_allocation.height = hscrollbar_requisition.height;
+ gtk_widget_size_allocate (self->priv->navigator_event_area, &child_allocation);
+ }
+ gtk_widget_size_allocate (self->priv->viewer, &viewer_allocation);
+}
+
+
+typedef struct {
+ GtkWidget *container;
+ cairo_t *cr;
+} DrawData;
+
+
+
+static void
+gth_image_navigator_draw_child (GtkWidget *child,
+ gpointer user_data)
+{
+ DrawData *data = user_data;
+
+ if (gtk_widget_get_child_visible (child))
+ gtk_container_propagate_draw (GTK_CONTAINER (data->container),
+ child,
+ data->cr);
+}
+
+
+static gboolean
+gth_image_navigator_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ DrawData data;
+
+ data.container = widget;
+ data.cr = cr;
+ gtk_container_forall (GTK_CONTAINER (widget),
+ gth_image_navigator_draw_child,
+ &data);
+
+ return FALSE;
}
-GType
-gth_image_navigator_get_type (void)
+static void
+gth_image_navigator_add (GtkContainer *container,
+ GtkWidget *widget)
{
- 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;
+ GthImageNavigator *self = GTH_IMAGE_NAVIGATOR (container);
+
+ if (self->priv->viewer != NULL) {
+ g_warning ("Attempt to add a second widget to a GthImageNavigator");
+ return;
+ }
+
+ gtk_widget_set_parent (widget, GTK_WIDGET (container));
+ self->priv->viewer = widget;
+}
+
+
+static void
+gth_image_navigator_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GthImageNavigator *self = GTH_IMAGE_NAVIGATOR (container);
+ gboolean widget_was_visible;
+
+ g_return_if_fail (self->priv->viewer == widget);
+
+ widget_was_visible = gtk_widget_get_visible (widget);
+ gtk_widget_unparent (widget);
+ self->priv->viewer = NULL;
+
+ if (widget_was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+}
+
+
+static void
+gth_image_navigator_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GthImageNavigator *self = GTH_IMAGE_NAVIGATOR (container);
+
+ (* callback) (GTK_WIDGET (self->priv->viewer), callback_data);
+ if (include_internals) {
+ (* callback) (self->priv->hscrollbar, callback_data);
+ (* callback) (self->priv->vscrollbar, callback_data);
+ (* callback) (self->priv->navigator_event_area, callback_data);
+ }
+}
+
+
+static GType
+gth_image_navigator_child_type (GtkContainer *container)
+{
+ return GTK_TYPE_WIDGET;
+}
+
+
+static void
+gth_image_navigator_class_init (GthImageNavigatorClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthImageNavigatorPrivate));
+
+ object_class = (GObjectClass *) klass;
+ object_class->set_property = gth_image_navigator_set_property;
+ object_class->get_property = gth_image_navigator_get_property;
+
+ widget_class = (GtkWidgetClass *) klass;
+ widget_class->size_allocate = gth_image_navigator_size_allocate;
+ widget_class->draw = gth_image_navigator_draw;
+
+ container_class = (GtkContainerClass *) klass;
+ container_class->add = gth_image_navigator_add;
+ container_class->remove = gth_image_navigator_remove;
+ container_class->forall = gth_image_navigator_forall;
+ container_class->child_type = gth_image_navigator_child_type;
+ gtk_container_class_handle_border_width (container_class);
+
+ /* properties */
+
+ g_object_class_install_property (object_class,
+ PROP_VIEWER,
+ g_param_spec_object ("viewer",
+ "Viewer",
+ "The image viewer to use",
+ GTH_TYPE_IMAGE_VIEWER,
+ G_PARAM_READWRITE));
}
@@ -353,17 +567,18 @@ navigator_popup_draw_cb (GtkWidget *widget,
static void
navigator_event_area_button_press_event_cb (GtkWidget *widget,
GdkEventButton *event,
- GthImageViewer *viewer)
+ gpointer user_data)
{
- NavigatorPopup *nav_popup;
- GtkWidget *out_frame;
- GtkWidget *in_frame;
+ GthImageNavigator *self = user_data;
+ NavigatorPopup *nav_popup;
+ GtkWidget *out_frame;
+ GtkWidget *in_frame;
- if (gth_image_viewer_is_void (viewer))
+ if ((self->priv->viewer == NULL) || gth_image_viewer_is_void (GTH_IMAGE_VIEWER (self->priv->viewer)))
return;
nav_popup = g_new0 (NavigatorPopup, 1);
- nav_popup->viewer = viewer;
+ nav_popup->viewer = GTH_IMAGE_VIEWER (self->priv->viewer);
nav_popup->popup_win = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_wmclass (GTK_WINDOW (nav_popup->popup_win), "", "gthumb_navigator");
@@ -384,8 +599,8 @@ navigator_event_area_button_press_event_cb (GtkWidget *widget,
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);
+ nav_popup->image_width = gth_image_viewer_get_image_width (GTH_IMAGE_VIEWER (self->priv->viewer));
+ nav_popup->image_height = gth_image_viewer_get_image_height (GTH_IMAGE_VIEWER (self->priv->viewer));
update_popup_geometry (nav_popup);
g_signal_connect (G_OBJECT (nav_popup->popup_win),
@@ -407,114 +622,61 @@ navigator_event_area_button_press_event_cb (GtkWidget *widget,
}
-static gboolean
-image_viewer_size_changed_cb (GtkWidget *widget,
- GthImageNavigator *self)
+static void
+gth_image_navigator_init (GthImageNavigator *self)
{
- GtkAdjustment *vadj;
- GtkAdjustment *hadj;
- double h_page_size;
- double v_page_size;
- double h_upper;
- double v_upper;
- 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);
-
- h_page_size = gtk_adjustment_get_page_size (hadj);
- v_page_size = gtk_adjustment_get_page_size (vadj);
- h_upper = gtk_adjustment_get_upper (hadj);
- v_upper = gtk_adjustment_get_upper (vadj);
- hide_vscr = (v_page_size == 0) || (v_upper <= v_page_size);
- hide_hscr = (h_page_size == 0) || (h_upper <= h_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);
- }
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorPrivate);
- return TRUE;
-}
+ gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
+ gtk_container_set_reallocate_redraws (GTK_CONTAINER (self), TRUE);
+ gtk_widget_set_hexpand (GTK_WIDGET (self), TRUE);
+ gtk_widget_set_vexpand (GTK_WIDGET (self), TRUE);
+ self->priv->automatic_scrollbars = TRUE;
+ self->priv->scrollbars_visible = FALSE;
-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);
+ /* horizonal scrollbar */
+
+ self->priv->hscrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, NULL);
+ gtk_widget_set_parent (self->priv->hscrollbar, GTK_WIDGET (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);
+ /* vertical scrollbar */
+
+ self->priv->vscrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, NULL);
+ gtk_widget_set_parent (self->priv->vscrollbar, GTK_WIDGET (self));
+
+ /* navigator event area */
self->priv->navigator_event_area = gtk_event_box_new ();
+ gtk_widget_set_parent (GTK_WIDGET (self->priv->navigator_event_area), GTK_WIDGET (self));
gtk_container_add (GTK_CONTAINER (self->priv->navigator_event_area),
gtk_image_new_from_icon_name ("image-navigator", GTK_ICON_SIZE_MENU));
-
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 (table);
-
- gtk_container_add (GTK_CONTAINER (self), table);
+ self);
+
+ gtk_widget_show (self->priv->hscrollbar);
+ gtk_widget_show (self->priv->vscrollbar);
+ gtk_widget_show (self->priv->navigator_event_area);
}
+G_DEFINE_TYPE(GthImageNavigator, gth_image_navigator, GTK_TYPE_CONTAINER)
+
+
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;
+ return (GtkWidget *) g_object_new (GTH_TYPE_IMAGE_NAVIGATOR, "viewer", viewer, NULL);
}
void
-gth_image_navigator_set_scrollbars_visible (GthImageNavigator *self,
- gboolean visible)
+gth_image_navigator_set_automatic_scrollbars (GthImageNavigator *self,
+ gboolean automatic)
{
- self->priv->scrollbars_visible = visible;
- image_viewer_size_changed_cb (NULL, self);
+ self->priv->automatic_scrollbars = automatic;
+ gtk_widget_queue_resize (self->priv->viewer);
}
diff --git a/gthumb/gth-image-navigator.h b/gthumb/gth-image-navigator.h
index 8245214..efb5fbf 100644
--- a/gthumb/gth-image-navigator.h
+++ b/gthumb/gth-image-navigator.h
@@ -39,18 +39,18 @@ typedef struct _GthImageNavigatorClass GthImageNavigatorClass;
typedef struct _GthImageNavigatorPrivate GthImageNavigatorPrivate;
struct _GthImageNavigator {
- GtkHBox __parent;
+ GtkContainer __parent;
GthImageNavigatorPrivate *priv;
};
struct _GthImageNavigatorClass {
- GtkHBoxClass __parent;
+ GtkContainerClass __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);
+GType gth_image_navigator_get_type (void);
+GtkWidget * gth_image_navigator_new (GthImageViewer *viewer);
+void gth_image_navigator_set_automatic_scrollbars (GthImageNavigator *window,
+ gboolean automatic);
G_END_DECLS
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index bf45291..44740c1 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -50,11 +50,11 @@
enum {
- PROP_0,
- PROP_HADJUSTMENT,
- PROP_VADJUSTMENT,
- PROP_HSCROLL_POLICY,
- PROP_VSCROLL_POLICY
+ PROP_0,
+ PROP_HADJUSTMENT,
+ PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY
};
@@ -65,7 +65,6 @@ enum {
SET_ZOOM,
SET_FIT_MODE,
ZOOM_CHANGED,
- SIZE_CHANGED,
SCROLL,
LAST_SIGNAL
};
@@ -116,17 +115,11 @@ struct _GthImageViewerPrivate {
gboolean is_void; /* If TRUE do not show anything.
* It is reset to FALSE we an
* image is loaded. */
-
gboolean double_click;
gboolean just_focused;
-
gboolean black_bg;
-
gboolean skip_zoom_change;
- gboolean skip_size_change;
-
gboolean reset_scrollbars;
- guint update_adjustment_values;
GList *painters;
};
@@ -225,43 +218,75 @@ get_prev_zoom (double zoom)
static void
-_gth_image_viewer_get_zoomed_size (GthImageViewer *self,
- int *width,
- int *height)
+_gth_image_viewer_get_zoomed_size_for_zoom (GthImageViewer *self,
+ int *width,
+ int *height,
+ double zoom_level)
{
if (gth_image_viewer_get_current_image (self) == NULL) {
- *width = 0;
- *height = 0;
+ if (width != NULL) *width = 0;
+ if (height != NULL) *height = 0;
}
else {
- *width = (int) floor ((double) self->priv->original_width * self->priv->zoom_level);
- *height = (int) floor ((double) self->priv->original_height * self->priv->zoom_level);
+ if (width != NULL) *width = (int) floor ((double) self->priv->original_width * zoom_level);
+ if (height != NULL) *height = (int) floor ((double) self->priv->original_height * zoom_level);
}
}
static void
-_gth_image_viewer_update_image_area (GthImageViewer *self)
+_gth_image_viewer_get_zoomed_size (GthImageViewer *self,
+ int *width,
+ int *height)
{
- GtkWidget *widget;
- int zoomed_width;
- int zoomed_height;
- GtkAllocation allocation;
- int gdk_width;
- int gdk_height;
+ _gth_image_viewer_get_zoomed_size_for_zoom (self, width, height, self->priv->zoom_level);
+}
- widget = GTK_WIDGET (self);
- gtk_widget_get_allocation (widget, &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
- gdk_height = allocation.height - self->priv->frame_border2;
+static void
+_gth_image_viewer_get_visible_area_size_for_allocation (GthImageViewer *self,
+ int *width,
+ int *height,
+ GtkAllocation *allocation)
+{
+ GtkAllocation local_allocation;
+
+ if (allocation != NULL)
+ local_allocation = *allocation;
+ else
+ gtk_widget_get_allocation (GTK_WIDGET (self), &local_allocation);
+
+ if (width != NULL)
+ *width = local_allocation.width - self->priv->frame_border2;
+ if (height != NULL)
+ *height = local_allocation.height - self->priv->frame_border2;
+}
+
+static void
+_gth_image_viewer_get_visible_area_size (GthImageViewer *self,
+ int *width,
+ int *height)
+{
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, width, height, NULL);
+}
+
+
+static void
+_gth_image_viewer_update_image_area (GthImageViewer *self)
+{
+ int zoomed_width;
+ int zoomed_height;
+ int visible_width;
+ int visible_height;
+
+ _gth_image_viewer_get_visible_area_size (self, &visible_width, &visible_height);
_gth_image_viewer_get_zoomed_size (self, &zoomed_width, &zoomed_height);
- self->image_area.x = MAX (self->priv->frame_border, (gdk_width - zoomed_width) / 2);
- self->image_area.y = MAX (self->priv->frame_border, (gdk_height - zoomed_height) / 2);
- self->image_area.width = MIN (zoomed_width, gdk_width);
- self->image_area.height = MIN (zoomed_height, gdk_height);
+ self->image_area.x = MAX (self->priv->frame_border, (visible_width - zoomed_width) / 2);
+ self->image_area.y = MAX (self->priv->frame_border, (visible_height - zoomed_height) / 2);
+ self->image_area.width = MIN (zoomed_width, visible_width);
+ self->image_area.height = MIN (zoomed_height, visible_height);
}
@@ -271,38 +296,23 @@ set_zoom (GthImageViewer *self,
int center_x,
int center_y)
{
- GtkWidget *widget = (GtkWidget*) self;
- GtkAllocation allocation;
- gdouble zoom_ratio;
- int gdk_width, gdk_height;
+ int visible_width;
+ int visible_height;
+ gdouble zoom_ratio;
g_return_if_fail (self != NULL);
- gtk_widget_get_allocation (widget, &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
- gdk_height = allocation.height - self->priv->frame_border2;
-
/* try to keep the center of the view visible. */
-
+ _gth_image_viewer_get_visible_area_size (self, &visible_width, &visible_height);
zoom_ratio = zoom_level / self->priv->zoom_level;
- self->x_offset = ((self->x_offset + center_x) * zoom_ratio - gdk_width / 2);
- self->y_offset = ((self->y_offset + center_y) * zoom_ratio - gdk_height / 2);
-
- /* reset zoom_fit unless we are performing a zoom to fit. */
-
- if (! self->priv->doing_zoom_fit)
- self->priv->fit = GTH_FIT_NONE;
+ self->x_offset = ((self->x_offset + center_x) * zoom_ratio - visible_width / 2);
+ self->y_offset = ((self->y_offset + center_y) * zoom_ratio - visible_height / 2);
self->priv->zoom_level = zoom_level;
_gth_image_viewer_update_image_area (self);
gth_image_viewer_tool_zoom_changed (self->priv->tool);
- if (! self->priv->doing_zoom_fit) {
- gtk_widget_queue_resize (GTK_WIDGET (self));
- gtk_widget_queue_draw (GTK_WIDGET (self));
- }
-
if (! self->priv->skip_zoom_change)
g_signal_emit (G_OBJECT (self),
gth_image_viewer_signals[ZOOM_CHANGED],
@@ -312,6 +322,24 @@ set_zoom (GthImageViewer *self,
}
+static void
+set_zoom_centered (GthImageViewer *self,
+ gdouble zoom_level,
+ gboolean zoom_to_fit,
+ GtkAllocation *allocation)
+{
+ int visible_width;
+ int visible_height;
+
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, allocation);
+ set_zoom (self, zoom_level, visible_width / 2, visible_height / 2);
+
+ /* reset zoom_fit unless we are performing a zoom to fit. */
+ if (! zoom_to_fit)
+ self->priv->fit = GTH_FIT_NONE;
+}
+
+
static int
to_255 (int v)
{
@@ -406,11 +434,6 @@ gth_image_viewer_unrealize (GtkWidget *widget)
self->priv->cursor_void = NULL;
}
- if (self->priv->update_adjustment_values != 0) {
- g_source_remove (self->priv->update_adjustment_values);
- self->priv->update_adjustment_values = 0;
- }
-
gth_image_viewer_tool_unrealize (self->priv->tool);
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
@@ -446,196 +469,176 @@ gth_image_viewer_unmap (GtkWidget *widget)
static void
-zoom_to_fit (GthImageViewer *self)
+_gth_image_viewer_configure_hadjustment (GthImageViewer *self)
{
- GtkAllocation allocation;
- int gdk_width;
- int gdk_height;
- int original_width;
- int original_height;
- double x_level;
- double y_level;
- double new_zoom_level;
+ int zoomed_width;
+ int visible_width;
- gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
- gdk_height = allocation.height - self->priv->frame_border2;
-
- gth_image_viewer_get_original_size (self, &original_width, &original_height);
-
- x_level = (double) gdk_width / original_width;
- y_level = (double) gdk_height / original_height;
+ _gth_image_viewer_get_zoomed_size (self, &zoomed_width, NULL);
+ _gth_image_viewer_get_visible_area_size (self, &visible_width, NULL);
- new_zoom_level = (x_level < y_level) ? x_level : y_level;
- if (new_zoom_level > 0.0) {
- self->priv->doing_zoom_fit = TRUE;
- gth_image_viewer_set_zoom (self, new_zoom_level);
- self->priv->doing_zoom_fit = FALSE;
- }
+ gtk_adjustment_configure (self->hadj,
+ self->x_offset,
+ 0.0,
+ zoomed_width,
+ STEP_INCREMENT,
+ visible_width / 2,
+ visible_width);
}
static void
-zoom_to_fit_width (GthImageViewer *self)
+_gth_image_viewer_configure_vadjustment (GthImageViewer *self)
{
- GtkAllocation allocation;
- int gdk_width;
- int original_width;
- double new_zoom_level;
+ int zoomed_height;
+ int visible_height;
- gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
+ _gth_image_viewer_get_zoomed_size (self, NULL, &zoomed_height);
+ _gth_image_viewer_get_visible_area_size (self, NULL, &visible_height);
- gth_image_viewer_get_original_size (self, &original_width, NULL);
+ gtk_adjustment_configure (self->vadj,
+ self->y_offset,
+ 0.0,
+ zoomed_height,
+ STEP_INCREMENT,
+ visible_height / 2,
+ visible_height);
+}
- new_zoom_level = (double) gdk_width / original_width;
- if (new_zoom_level > 0.0) {
- self->priv->doing_zoom_fit = TRUE;
- gth_image_viewer_set_zoom (self, new_zoom_level);
- self->priv->doing_zoom_fit = FALSE;
- }
+static GtkSizeRequestMode
+gth_image_viewer_get_request_mode (GtkWidget *widget)
+{
+ return GTK_SIZE_REQUEST_CONSTANT_SIZE;
}
static void
-gth_image_viewer_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
+gth_image_viewer_get_preferred_width (GtkWidget *widget,
+ int *minimum_width,
+ int *natural_width)
{
- GthImageViewer *self;
- int gdk_width;
- int gdk_height;
- int original_width;
- int original_height;
- cairo_surface_t *current_image;
+ GthImageViewer *self = GTH_IMAGE_VIEWER (widget);
+ int zoomed_width;
- self = GTH_IMAGE_VIEWER (widget);
+ _gth_image_viewer_get_zoomed_size (self, &zoomed_width, NULL);
+ *minimum_width = 0;
+ *natural_width = zoomed_width;
+}
- gtk_widget_set_allocation (widget, allocation);
- gdk_width = allocation->width - self->priv->frame_border2;
- gdk_height = allocation->height - self->priv->frame_border2;
+static void
+gth_image_viewer_get_preferred_height (GtkWidget *widget,
+ int *minimum_height,
+ int *natural_height)
+{
+ GthImageViewer *self = GTH_IMAGE_VIEWER (widget);
+ int zoomed_height;
- if ((gdk_width < 0) || (gdk_height < 0))
- return;
+ _gth_image_viewer_get_zoomed_size (self, NULL, &zoomed_height);
+ *minimum_height = 0;
+ *natural_height = zoomed_height;
+}
- current_image = gth_image_viewer_get_current_image (self);
+static double
+get_zoom_to_fit (GthImageViewer *self,
+ GtkAllocation *allocation)
+{
+ int visible_width;
+ int visible_height;
+ int original_width;
+ int original_height;
+ double x_level;
+ double y_level;
+
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, allocation);
gth_image_viewer_get_original_size (self, &original_width, &original_height);
- /* If a fit type is active update the zoom level. */
+ x_level = (double) visible_width / original_width;
+ y_level = (double) visible_height / original_height;
- if (! self->priv->is_void && (current_image != NULL)) {
- switch (self->priv->fit) {
- case GTH_FIT_SIZE:
- zoom_to_fit (self);
- break;
+ return (x_level < y_level) ? x_level : y_level;
+}
- case GTH_FIT_SIZE_IF_LARGER:
- if ((gdk_width < original_width) || (gdk_height < original_height)) {
- zoom_to_fit (self);
- }
- else {
- self->priv->doing_zoom_fit = TRUE;
- gth_image_viewer_set_zoom (self, 1.0);
- self->priv->doing_zoom_fit = FALSE;
- }
- break;
- case GTH_FIT_WIDTH:
- zoom_to_fit_width (self);
- break;
+static double
+get_zoom_to_fit_width (GthImageViewer *self,
+ GtkAllocation *allocation)
+{
+ int visible_width;
+ int original_width;
- case GTH_FIT_WIDTH_IF_LARGER:
- if (gdk_width < original_width) {
- zoom_to_fit_width (self);
- }
- else {
- self->priv->doing_zoom_fit = TRUE;
- gth_image_viewer_set_zoom (self, 1.0);
- self->priv->doing_zoom_fit = FALSE;
- }
- break;
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, NULL, allocation);
+ gth_image_viewer_get_original_size (self, &original_width, NULL);
- default:
- break;
- }
- }
+ return (double) visible_width / original_width;
+}
- /* Check whether the offset is still valid. */
- if (current_image != NULL) {
- int width;
- int height;
+static double
+get_zoom_level_for_allocation (GthImageViewer *self,
+ GtkAllocation *allocation)
+{
+ double zoom_level;
+ cairo_surface_t *current_image;
+ int original_width;
+ int original_height;
+ int visible_width;
+ int visible_height;
- _gth_image_viewer_get_zoomed_size (self, &width, &height);
+ zoom_level = self->priv->zoom_level;
+ current_image = gth_image_viewer_get_current_image (self);
+ if (self->priv->is_void || (current_image == NULL))
+ return zoom_level;
- if (width > gdk_width)
- self->x_offset = CLAMP (self->x_offset,
- 0,
- width - gdk_width);
+ gth_image_viewer_get_original_size (self, &original_width, &original_height);
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, allocation);
+
+ switch (self->priv->fit) {
+ case GTH_FIT_SIZE:
+ zoom_level = get_zoom_to_fit (self, allocation);
+ break;
+
+ case GTH_FIT_SIZE_IF_LARGER:
+ if ((visible_width < original_width) || (visible_height < original_height))
+ zoom_level = get_zoom_to_fit (self, allocation);
else
- self->x_offset = 0;
+ zoom_level = 1.0;
+ break;
+
+ case GTH_FIT_WIDTH:
+ zoom_level = get_zoom_to_fit_width (self, allocation);
+ break;
- if (height > gdk_height)
- self->y_offset = CLAMP (self->y_offset,
- 0,
- height - gdk_height);
+ case GTH_FIT_WIDTH_IF_LARGER:
+ if (visible_width < original_width)
+ zoom_level = get_zoom_to_fit_width (self, allocation);
else
- self->y_offset = 0;
-
- if ((width != gtk_adjustment_get_upper (self->hadj)) || (height != gtk_adjustment_get_upper (self->vadj)))
- g_signal_emit (G_OBJECT (self),
- gth_image_viewer_signals[SIZE_CHANGED],
- 0);
-
- /* Change adjustment values. */
-
- gtk_adjustment_configure (self->hadj,
- self->x_offset,
- 0.0,
- width,
- STEP_INCREMENT,
- gdk_width / 2,
- gdk_width);
- gtk_adjustment_configure (self->vadj,
- self->y_offset,
- 0.0,
- height,
- STEP_INCREMENT,
- gdk_height / 2,
- gdk_height);
- }
- else {
- gtk_adjustment_configure (self->hadj,
- 0.0,
- 0.0,
- 1.0,
- 0.1,
- 1.0,
- 1.0);
- gtk_adjustment_configure (self->vadj,
- 0.0,
- 0.0,
- 1.0,
- 0.1,
- 1.0,
- 1.0);
+ zoom_level = 1.0;
+ break;
+
+ default:
+ break;
}
- _gth_image_viewer_update_image_area (self);
+ return zoom_level;
+}
- /* FIXME
- g_signal_handlers_block_by_data (G_OBJECT (self->hadj), self);
- g_signal_handlers_block_by_data (G_OBJECT (self->vadj), self);
- gtk_adjustment_changed (self->hadj);
- gtk_adjustment_changed (self->vadj);
- g_signal_handlers_unblock_by_data (G_OBJECT (self->hadj), self);
- g_signal_handlers_unblock_by_data (G_OBJECT (self->vadj), self);
- */
- /**/
+static void
+gth_image_viewer_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GthImageViewer *self = GTH_IMAGE_VIEWER (widget);
+ double zoom_level;
+ int visible_width;
+ int visible_height;
+ int zoomed_width;
+ int zoomed_height;
+ cairo_surface_t *current_image;
+ gtk_widget_set_allocation (widget, allocation);
if (gtk_widget_get_realized (widget))
gdk_window_move_resize (gtk_widget_get_window (widget),
allocation->x,
@@ -643,14 +646,25 @@ gth_image_viewer_size_allocate (GtkWidget *widget,
allocation->width,
allocation->height);
- gth_image_viewer_tool_size_allocate (self->priv->tool, allocation);
- if (! self->priv->skip_size_change)
- g_signal_emit (G_OBJECT (self),
- gth_image_viewer_signals[SIZE_CHANGED],
- 0);
- else
- self->priv->skip_size_change = FALSE;
+ /* update the zoom level if the automatic fit mode is active */
+
+ zoom_level = get_zoom_level_for_allocation (self, allocation);
+ if (self->priv->fit != GTH_FIT_NONE)
+ set_zoom_centered (self, zoom_level, TRUE, allocation);
+
+ /* Keep the scrollbars offset in a valid range */
+
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, allocation);
+ _gth_image_viewer_get_zoomed_size (self, &zoomed_width, &zoomed_height);
+ current_image = gth_image_viewer_get_current_image (self);
+ self->x_offset = (current_image == NULL || zoomed_width <= visible_width) ? 0 : CLAMP (self->x_offset, 0, zoomed_width - visible_width);
+ self->y_offset = (current_image == NULL || zoomed_height <= visible_height) ? 0 : CLAMP (self->y_offset, 0, zoomed_height - visible_height);
+
+ _gth_image_viewer_configure_hadjustment (self);
+ _gth_image_viewer_configure_vadjustment (self);
+ _gth_image_viewer_update_image_area (self);
+ gth_image_viewer_tool_size_allocate (self->priv->tool, allocation);
}
@@ -714,8 +728,7 @@ change_animation_frame (gpointer data)
_cairo_clear_surface (&self->priv->iter_surface);
self->priv->skip_zoom_change = TRUE;
- self->priv->skip_size_change = TRUE;
- gth_image_viewer_update_view (self);
+ gtk_widget_queue_resize (GTK_WIDGET (self));
return FALSE;
}
@@ -773,14 +786,7 @@ gth_image_viewer_button_press (GtkWidget *widget,
if (self->dragging)
return FALSE;
- if ((event->type == GDK_2BUTTON_PRESS)
- || (event->type == GDK_3BUTTON_PRESS))
- {
- self->priv->double_click = TRUE;
- /*return FALSE;*/
- }
- else
- self->priv->double_click = FALSE;
+ self->priv->double_click = ((event->type == GDK_2BUTTON_PRESS) || (event->type == GDK_3BUTTON_PRESS));
retval = gth_image_viewer_tool_button_press (self->priv->tool, event);
@@ -823,45 +829,44 @@ gth_image_viewer_button_release (GtkWidget *widget,
static void
scroll_to (GthImageViewer *self,
- int *x_offset,
- int *y_offset)
+ int x_offset,
+ int y_offset)
{
- GdkWindow *window;
GtkAllocation allocation;
- int width, height;
+ int zoomed_width, zoomed_height;
int delta_x, delta_y;
- int gdk_width, gdk_height;
+ int visible_width, visible_height;
+ GdkWindow *window;
g_return_if_fail (self != NULL);
if (gth_image_viewer_get_current_image (self) == NULL)
return;
- _gth_image_viewer_get_zoomed_size (self, &width, &height);
-
- window = gtk_widget_get_window (GTK_WIDGET (self));
+ _gth_image_viewer_get_zoomed_size (self, &zoomed_width, &zoomed_height);
gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
- gdk_height = allocation.height - self->priv->frame_border2;
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, &allocation);
- if (width > gdk_width)
- *x_offset = CLAMP (*x_offset, 0, width - gdk_width);
+ if (zoomed_width > visible_width)
+ x_offset = CLAMP (x_offset, 0, zoomed_width - visible_width);
else
- *x_offset = self->x_offset;
+ x_offset = self->x_offset;
- if (height > gdk_height)
- *y_offset = CLAMP (*y_offset, 0, height - gdk_height);
+ if (zoomed_height > visible_height)
+ y_offset = CLAMP (y_offset, 0, zoomed_height - visible_height);
else
- *y_offset = self->y_offset;
+ y_offset = self->y_offset;
- if ((*x_offset == self->x_offset) && (*y_offset == self->y_offset))
+ if ((x_offset == self->x_offset) && (y_offset == self->y_offset))
return;
- delta_x = *x_offset - self->x_offset;
- delta_y = *y_offset - self->y_offset;
+ delta_x = x_offset - self->x_offset;
+ delta_y = y_offset - self->y_offset;
+
+ self->x_offset = x_offset;
+ self->y_offset = y_offset;
- self->x_offset = *x_offset;
- self->y_offset = *y_offset;
+ window = gtk_widget_get_window (GTK_WIDGET (self));
if (self->priv->painters != NULL) {
cairo_rectangle_int_t area;
@@ -884,8 +889,8 @@ scroll_to (GthImageViewer *self,
area.x = (delta_x < 0) ? self->priv->frame_border : self->priv->frame_border + delta_x;
area.y = (delta_y < 0) ? self->priv->frame_border : self->priv->frame_border + delta_y;
- area.width = gdk_width - abs (delta_x);
- area.height = gdk_height - abs (delta_y);
+ area.width = visible_width - abs (delta_x);
+ area.height = visible_height - abs (delta_y);
region = cairo_region_create_rectangle (&area);
gdk_window_move_region (window, region, -delta_x, -delta_y);
@@ -901,15 +906,15 @@ scroll_to (GthImageViewer *self,
region = cairo_region_create ();
area.x = self->priv->frame_border;
- area.y = (delta_y < 0) ? self->priv->frame_border : self->priv->frame_border + gdk_height - delta_y;
- area.width = gdk_width;
+ area.y = (delta_y < 0) ? self->priv->frame_border : self->priv->frame_border + visible_height - delta_y;
+ area.width = visible_width;
area.height = abs (delta_y);
cairo_region_union_rectangle (region, &area);
- area.x = (delta_x < 0) ? self->priv->frame_border : self->priv->frame_border + gdk_width - delta_x;
+ area.x = (delta_x < 0) ? self->priv->frame_border : self->priv->frame_border + visible_width - delta_x;
area.y = self->priv->frame_border;
area.width = abs (delta_x);
- area.height = gdk_height;
+ area.height = visible_height;
cairo_region_union_rectangle (region, &area);
gdk_window_invalidate_region (window, region, TRUE);
@@ -1076,12 +1081,7 @@ static gboolean
hadj_value_changed (GtkAdjustment *adj,
GthImageViewer *self)
{
- int x_ofs, y_ofs;
-
- x_ofs = (int) gtk_adjustment_get_value (adj);
- y_ofs = self->y_offset;
- scroll_to (self, &x_ofs, &y_ofs);
-
+ scroll_to (self, (int) gtk_adjustment_get_value (adj), self->y_offset);
return FALSE;
}
@@ -1090,12 +1090,7 @@ static gboolean
vadj_value_changed (GtkAdjustment *adj,
GthImageViewer *self)
{
- int x_ofs, y_ofs;
-
- x_ofs = self->x_offset;
- y_ofs = (int) gtk_adjustment_get_value (adj);
- scroll_to (self, &x_ofs, &y_ofs);
-
+ scroll_to (self, self->x_offset, (int) gtk_adjustment_get_value (adj));
return FALSE;
}
@@ -1107,7 +1102,7 @@ _gth_image_viewer_set_hadjustment (GthImageViewer *self,
if (hadj != NULL)
g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
else
- hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+ hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
if ((self->hadj != NULL) && (self->hadj != hadj)) {
g_signal_handlers_disconnect_by_data (G_OBJECT (self->hadj), self);
@@ -1120,8 +1115,10 @@ _gth_image_viewer_set_hadjustment (GthImageViewer *self,
g_object_ref (self->hadj);
g_object_ref_sink (self->hadj);
+ _gth_image_viewer_configure_hadjustment (self);
+
g_signal_connect (G_OBJECT (self->hadj),
- "value_changed",
+ "value-changed",
G_CALLBACK (hadj_value_changed),
self);
}
@@ -1135,7 +1132,7 @@ _gth_image_viewer_set_vadjustment (GthImageViewer *self,
if (vadj != NULL)
g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
else
- vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+ vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
if ((self->vadj != NULL) && (self->vadj != vadj)) {
g_signal_handlers_disconnect_by_data (G_OBJECT (self->vadj), self);
@@ -1148,8 +1145,10 @@ _gth_image_viewer_set_vadjustment (GthImageViewer *self,
g_object_ref (self->vadj);
g_object_ref_sink (self->vadj);
+ _gth_image_viewer_configure_vadjustment (self);
+
g_signal_connect (G_OBJECT (self->vadj),
- "value_changed",
+ "value-changed",
G_CALLBACK (vadj_value_changed),
self);
}
@@ -1234,11 +1233,9 @@ gth_image_viewer_set_property (GObject *object,
break;
case PROP_HSCROLL_POLICY:
self->priv->hscroll_policy = g_value_get_enum (value);
- gtk_widget_queue_resize (GTK_WIDGET (self));
break;
case PROP_VSCROLL_POLICY:
self->priv->vscroll_policy = g_value_get_enum (value);
- gtk_widget_queue_resize (GTK_WIDGET (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1315,15 +1312,6 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
- gth_image_viewer_signals[SIZE_CHANGED] =
- g_signal_new ("size_changed",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GthImageViewerClass, size_changed),
- 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),
@@ -1348,6 +1336,9 @@ gth_image_viewer_class_init (GthImageViewerClass *class)
widget_class->unrealize = gth_image_viewer_unrealize;
widget_class->map = gth_image_viewer_map;
widget_class->unmap = gth_image_viewer_unmap;
+ widget_class->get_request_mode = gth_image_viewer_get_request_mode;
+ widget_class->get_preferred_width = gth_image_viewer_get_preferred_width;
+ widget_class->get_preferred_height = gth_image_viewer_get_preferred_height;
widget_class->size_allocate = gth_image_viewer_size_allocate;
widget_class->focus_in_event = gth_image_viewer_focus_in;
widget_class->focus_out_event = gth_image_viewer_focus_out;
@@ -1525,7 +1516,6 @@ gth_image_viewer_init (GthImageViewer *self)
self->priv->doing_zoom_fit = FALSE;
self->priv->skip_zoom_change = FALSE;
- self->priv->skip_size_change = FALSE;
self->priv->is_void = TRUE;
self->x_offset = 0;
@@ -1540,7 +1530,6 @@ gth_image_viewer_init (GthImageViewer *self)
self->priv->cursor_void = NULL;
self->priv->reset_scrollbars = TRUE;
- self->priv->update_adjustment_values = 0;
gth_image_viewer_set_tool (self, NULL);
@@ -1622,7 +1611,7 @@ _gth_image_viewer_content_changed (GthImageViewer *self,
break;
case GTH_ZOOM_CHANGE_KEEP_PREV:
- gth_image_viewer_update_view (self);
+ gtk_widget_queue_resize (GTK_WIDGET (self));
break;
case GTH_ZOOM_CHANGE_FIT_SIZE:
@@ -1809,18 +1798,6 @@ gth_image_viewer_is_void (GthImageViewer *self)
void
-gth_image_viewer_update_view (GthImageViewer *self)
-{
- g_return_if_fail (self != NULL);
-
- if (self->priv->fit == GTH_FIT_NONE)
- gth_image_viewer_set_zoom (self, self->priv->zoom_level);
- else
- gth_image_viewer_set_fit_mode (self, self->priv->fit);
-}
-
-
-void
gth_image_viewer_add_painter (GthImageViewer *self,
GthImageViewerPaintFunc func,
gpointer user_data)
@@ -1972,7 +1949,7 @@ gth_image_viewer_start_animation (GthImageViewer *self)
g_return_if_fail (self != NULL);
self->priv->play_animation = TRUE;
- gth_image_viewer_update_view (self);
+ gtk_widget_queue_resize (GTK_WIDGET (self));
}
@@ -2022,16 +1999,11 @@ void
gth_image_viewer_set_zoom (GthImageViewer *self,
gdouble zoom_level)
{
- GtkAllocation allocation;
-
- if (! self->priv->zoom_enabled && ! self->priv->doing_zoom_fit)
+ if (! self->priv->zoom_enabled)
return;
- gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
- set_zoom (self,
- zoom_level,
- (allocation.width - self->priv->frame_border2) / 2,
- (allocation.height - self->priv->frame_border2) / 2);
+ set_zoom_centered (self, zoom_level, FALSE, NULL);
+ gtk_widget_queue_resize (GTK_WIDGET (self));
}
@@ -2092,18 +2064,16 @@ gth_image_viewer_get_zoom_change (GthImageViewer *self)
void
gth_image_viewer_zoom_in (GthImageViewer *self)
{
- if (gth_image_viewer_get_current_image (self) == NULL)
- return;
- gth_image_viewer_set_zoom (self, get_next_zoom (self->priv->zoom_level));
+ if (! self->priv->is_void)
+ gth_image_viewer_set_zoom (self, get_next_zoom (self->priv->zoom_level));
}
void
gth_image_viewer_zoom_out (GthImageViewer *self)
{
- if (gth_image_viewer_get_current_image (self) == NULL)
- return;
- gth_image_viewer_set_zoom (self, get_prev_zoom (self->priv->zoom_level));
+ if (! self->priv->is_void)
+ gth_image_viewer_set_zoom (self, get_prev_zoom (self->priv->zoom_level));
}
@@ -2115,9 +2085,8 @@ gth_image_viewer_set_fit_mode (GthImageViewer *self,
return;
self->priv->fit = fit_mode;
- if (self->priv->is_void)
- return;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ if (! self->priv->is_void)
+ gtk_widget_queue_resize (GTK_WIDGET (self));
}
@@ -2253,21 +2222,6 @@ gth_image_viewer_clicked (GthImageViewer *self)
void
-gth_image_viewer_set_size_request (GthImageViewer *self,
- int width,
- int height)
-{
- GtkRequisition requisition;
-
- requisition.width = width;
- requisition.height = height;
- gtk_widget_get_preferred_size (GTK_WIDGET (self), &requisition, NULL);
-
- gtk_widget_queue_resize (GTK_WIDGET (self));
-}
-
-
-void
gth_image_viewer_set_black_background (GthImageViewer *self,
gboolean set_black)
{
@@ -2288,18 +2242,6 @@ gth_image_viewer_is_black_background (GthImageViewer *self)
void
-gth_image_viewer_get_adjustments (GthImageViewer *self,
- GtkAdjustment **hadj,
- GtkAdjustment **vadj)
-{
- if (hadj != NULL)
- *hadj = self->hadj;
- if (vadj != NULL)
- *vadj = self->vadj;
-}
-
-
-void
gth_image_viewer_set_tool (GthImageViewer *self,
GthImageViewerTool *tool)
{
@@ -2316,26 +2258,6 @@ gth_image_viewer_set_tool (GthImageViewer *self,
gth_image_viewer_tool_realize (self->priv->tool);
gth_image_viewer_tool_image_changed (self->priv->tool);
gtk_widget_queue_resize (GTK_WIDGET (self));
- gtk_widget_queue_draw (GTK_WIDGET (self));
-}
-
-
-static gboolean
-update_adjustment_values_cb (gpointer user_data)
-{
- GthImageViewer *self = user_data;
-
- g_source_remove (self->priv->update_adjustment_values);
- self->priv->update_adjustment_values = 0;
-
- g_signal_handlers_block_by_data (G_OBJECT (self->hadj), self);
- g_signal_handlers_block_by_data (G_OBJECT (self->vadj), self);
- gtk_adjustment_set_value (self->hadj, self->x_offset);
- gtk_adjustment_set_value (self->vadj, self->y_offset);
- g_signal_handlers_unblock_by_data (G_OBJECT (self->hadj), self);
- g_signal_handlers_unblock_by_data (G_OBJECT (self->vadj), self);
-
- return FALSE;
}
@@ -2349,11 +2271,16 @@ gth_image_viewer_scroll_to (GthImageViewer *self,
if (gth_image_viewer_get_current_image (self) == NULL)
return;
- scroll_to (self, &x_offset, &y_offset);
+ scroll_to (self, x_offset, y_offset);
- if (self->priv->update_adjustment_values != 0)
- g_source_remove (self->priv->update_adjustment_values);
- self->priv->update_adjustment_values = g_timeout_add (10, update_adjustment_values_cb, self);
+ /* update the adjustments value */
+
+ g_signal_handlers_block_by_data (G_OBJECT (self->hadj), self);
+ g_signal_handlers_block_by_data (G_OBJECT (self->vadj), self);
+ gtk_adjustment_set_value (self->hadj, self->x_offset);
+ gtk_adjustment_set_value (self->vadj, self->y_offset);
+ g_signal_handlers_unblock_by_data (G_OBJECT (self->hadj), self);
+ g_signal_handlers_unblock_by_data (G_OBJECT (self->vadj), self);
}
@@ -2422,6 +2349,24 @@ gth_image_viewer_get_reset_scrollbars (GthImageViewer *self)
}
+gboolean
+gth_image_viewer_needs_scrollbars (GthImageViewer *self,
+ GtkAllocation *allocation)
+{
+ int visible_width;
+ int visible_height;
+ double zoom_level;
+ int zoomed_width;
+ int zoomed_height;
+
+ zoom_level = get_zoom_level_for_allocation (self, allocation);
+ _gth_image_viewer_get_zoomed_size_for_zoom (self, &zoomed_width, &zoomed_height, zoom_level);
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, allocation);
+
+ return ((zoomed_width > visible_width) || (zoomed_height > visible_height));
+}
+
+
void
gth_image_viewer_show_cursor (GthImageViewer *self)
{
@@ -2585,19 +2530,18 @@ gth_image_viewer_paint_background (GthImageViewer *self,
cairo_t *cr)
{
GtkAllocation allocation;
- int gdk_width;
- int gdk_height;
+ int visible_width;
+ int visible_height;
GtkStyleContext *style_context;
gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
- gdk_width = allocation.width - self->priv->frame_border2;
- gdk_height = allocation.height - self->priv->frame_border2;
+ _gth_image_viewer_get_visible_area_size_for_allocation (self, &visible_width, &visible_height, &allocation);
style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
if ((self->image_area.x > self->priv->frame_border)
|| (self->image_area.y > self->priv->frame_border)
- || (self->image_area.width < gdk_width)
- || (self->image_area.height < gdk_height))
+ || (self->image_area.width < visible_width)
+ || (self->image_area.height < visible_height))
{
int rx, ry, rw, rh;
@@ -2766,10 +2710,10 @@ void
gth_image_viewer_crop_area (GthImageViewer *self,
cairo_rectangle_int_t *area)
{
- GtkWidget *widget = GTK_WIDGET (self);
- GtkAllocation allocation;
+ int visible_width;
+ int visible_height;
- gtk_widget_get_allocation (widget, &allocation);
- area->width = MIN (area->width, allocation.width - self->priv->frame_border2);
- area->width = MIN (area->height, allocation.height - self->priv->frame_border2);
+ _gth_image_viewer_get_visible_area_size (self, &visible_width, &visible_height);
+ area->width = MIN (area->width, visible_width);
+ area->width = MIN (area->height, visible_height);
}
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index 918bf6d..bd459db 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -132,10 +132,6 @@ struct _GthImageViewerClass
void (* clicked) (GthImageViewer *viewer);
void (* zoom_changed) (GthImageViewer *viewer);
- void (* size_changed) (GthImageViewer *viewer);
- void (* set_scroll_adjustments) (GtkWidget *widget,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj);
/* -- Key binding signals -- */
@@ -178,7 +174,6 @@ void gth_image_viewer_set_better_quality (GthImageViewer
int original_height);
void gth_image_viewer_set_void (GthImageViewer *viewer);
gboolean gth_image_viewer_is_void (GthImageViewer *viewer);
-void gth_image_viewer_update_view (GthImageViewer *viewer);
void gth_image_viewer_add_painter (GthImageViewer *viewer,
GthImageViewerPaintFunc
func,
@@ -246,15 +241,9 @@ GthCheckSize gth_image_viewer_get_check_size (GthImageViewer
/* misc. */
void gth_image_viewer_clicked (GthImageViewer *viewer);
-void gth_image_viewer_set_size_request (GthImageViewer *viewer,
- int width,
- int height);
void gth_image_viewer_set_black_background (GthImageViewer *viewer,
gboolean set_black);
gboolean gth_image_viewer_is_black_background (GthImageViewer *viewer);
-void gth_image_viewer_get_adjustments (GthImageViewer *self,
- GtkAdjustment **hadj,
- GtkAdjustment **vadj);
void gth_image_viewer_set_tool (GthImageViewer *viewer,
GthImageViewerTool *tool);
@@ -277,6 +266,8 @@ void gth_image_viewer_get_scroll_offset (GthImageViewer
void gth_image_viewer_set_reset_scrollbars (GthImageViewer *viewer,
gboolean reset);
gboolean gth_image_viewer_get_reset_scrollbars (GthImageViewer *viewer);
+gboolean gth_image_viewer_needs_scrollbars (GthImageViewer *viewer,
+ GtkAllocation *allocation);
/* Cursor. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]