diff options
author | Felix Riemann <friemann@gnome.org> | 2017-02-12 20:39:20 +0100 |
---|---|---|
committer | Felix Riemann <friemann@gnome.org> | 2017-02-12 20:39:20 +0100 |
commit | b5d37f3916f7611082d1b20598f2e703d4f0fecb (patch) | |
tree | bfc7db7c67e57db4681066144a1728b2c372f460 | |
parent | 277309100cb94526c3f439ac0d6eb9aa4076688d (diff) | |
download | eog-b5d37f3916f7611082d1b20598f2e703d4f0fecb.tar.gz |
EogZoomEntry: Replace zoom GtkRange
This replaces the zoom GtkRange with a combined GtkEntry with buttons
and menu. This allows more control than the GtkRange-based solution
which wasn't even able to use the full zoom range.
EogZoomEntry is based on Evince's EvZoomAction.
-rw-r--r-- | data/popup-menus.ui | 11 | ||||
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/eog-scroll-view.c | 674 | ||||
-rw-r--r-- | src/eog-scroll-view.h | 3 | ||||
-rw-r--r-- | src/eog-window.c | 115 | ||||
-rw-r--r-- | src/eog-zoom-entry.c | 335 | ||||
-rw-r--r-- | src/eog-zoom-entry.h | 41 | ||||
-rw-r--r-- | src/eog.gresource.xml | 1 |
8 files changed, 746 insertions, 450 deletions
diff --git a/data/popup-menus.ui b/data/popup-menus.ui index 846ec177..aae780c0 100644 --- a/data/popup-menus.ui +++ b/data/popup-menus.ui @@ -51,4 +51,15 @@ </item> </section> </menu> + <menu id="zoom-menu"> + <section> + <item> + <attribute name="label" translatable="yes">_Best fit</attribute> + <attribute name="action">win.toggle-zoom-fit</attribute> + </item> + </section> + <section> + </section> + </menu> + </interface> diff --git a/src/Makefile.am b/src/Makefile.am index 1d1ae988..735dbd46 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,14 +25,15 @@ NOINST_H_FILES = \ eog-metadata-reader-jpg.h \ eog-metadata-reader-png.h \ eog-pixbuf-util.h \ - eog-plugin-engine.h \ + eog-plugin-engine.h \ eog-preferences-dialog.h \ eog-print.h \ - eog-print-image-setup.h \ - eog-print-preview.h \ + eog-print-image-setup.h \ + eog-print-preview.h \ eog-save-as-dialog-helper.h \ eog-session.h \ eog-util.h \ + eog-zoom-entry.h \ zoom.h INST_H_FILES = \ @@ -63,7 +64,7 @@ libeog_c_files = \ eog-application.c \ eog-application-activatable.c \ eog-clipboard-handler.c \ - eog-close-confirmation-dialog.c \ + eog-close-confirmation-dialog.c \ eog-debug.c \ eog-error-message-area.c \ eog-file-chooser.c \ @@ -78,11 +79,11 @@ libeog_c_files = \ eog-metadata-reader-jpg.c \ eog-metadata-reader-png.c \ eog-pixbuf-util.c \ - eog-plugin-engine.c \ + eog-plugin-engine.c \ eog-preferences-dialog.c \ eog-print.c \ - eog-print-image-setup.c \ - eog-print-preview.c \ + eog-print-image-setup.c \ + eog-print-preview.c \ eog-properties-dialog.c \ eog-save-as-dialog-helper.c \ eog-scroll-view.c \ @@ -97,6 +98,7 @@ libeog_c_files = \ eog-util.c \ eog-window-activatable.c \ eog-window.c \ + eog-zoom-entry.c \ zoom.c libeog_la_SOURCES = \ diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c index 53fea06e..8c1bf008 100644 --- a/src/eog-scroll-view.c +++ b/src/eog-scroll-view.c @@ -19,8 +19,8 @@ #include "zoom.h" /* Maximum zoom factor */ -#define MAX_ZOOM_FACTOR 20 -#define MIN_ZOOM_FACTOR 0.02 +#define MAX_ZOOM_FACTOR EOG_SCROLL_VIEW_MAX_ZOOM_FACTOR +#define MIN_ZOOM_FACTOR EOG_SCROLL_VIEW_MIN_ZOOM_FACTOR /* Default increment for zooming. The current zoom factor is multiplied or * divided by this amount on every zooming step. For consistency, you should @@ -77,7 +77,7 @@ typedef enum { /* Drag 'n Drop */ static GtkTargetEntry target_table[] = { - { "text/uri-list", 0, 0}, + { "text/uri-list", 0, 0}, }; enum { @@ -182,11 +182,11 @@ static void set_zoom_fit (EogScrollView *view); /* static void request_paint_area (EogScrollView *view, GdkRectangle *area); */ static void set_minimum_zoom_factor (EogScrollView *view); static void view_on_drag_begin_cb (GtkWidget *widget, GdkDragContext *context, - gpointer user_data); + gpointer user_data); static void view_on_drag_data_get_cb (GtkWidget *widget, - GdkDragContext*drag_context, - GtkSelectionData *data, guint info, - guint time, gpointer user_data); + GdkDragContext*drag_context, + GtkSelectionData *data, guint info, + guint time, gpointer user_data); static void _set_zoom_mode_internal (EogScrollView *view, EogZoomMode mode); static gboolean eog_scroll_view_get_image_coords (EogScrollView *view, gint *x, gint *y, gint *width, @@ -198,7 +198,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (EogScrollView, eog_scroll_view, GTK_TYPE_GRID) /*=================================== widget size changing handler & - util functions + util functions ---------------------------------*/ static cairo_surface_t * @@ -208,9 +208,9 @@ create_surface_from_pixbuf (EogScrollView *view, GdkPixbuf *pixbuf) cairo_t *cr; surface = gdk_window_create_similar_surface (gtk_widget_get_window (view->priv->display), - CAIRO_CONTENT_COLOR | CAIRO_CONTENT_ALPHA, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); + CAIRO_CONTENT_COLOR | CAIRO_CONTENT_ALPHA, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); cr = cairo_create (surface); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); @@ -273,10 +273,10 @@ compute_scaled_size (EogScrollView *view, double zoom, int *width, int *height) */ static void compute_center_zoom_offsets (EogScrollView *view, - double old_zoom, double new_zoom, - int width, int height, - double zoom_x_anchor, double zoom_y_anchor, - int *xofs, int *yofs) + double old_zoom, double new_zoom, + int width, int height, + double zoom_x_anchor, double zoom_y_anchor, + int *xofs, int *yofs) { EogScrollViewPrivate *priv; int old_scaled_width, old_scaled_height; @@ -286,7 +286,7 @@ compute_center_zoom_offsets (EogScrollView *view, priv = view->priv; compute_scaled_size (view, old_zoom, - &old_scaled_width, &old_scaled_height); + &old_scaled_width, &old_scaled_height); if (old_scaled_width < width) view_cx = (zoom_x_anchor * old_scaled_width) / old_zoom; @@ -299,7 +299,7 @@ compute_center_zoom_offsets (EogScrollView *view, view_cy = (priv->yofs + zoom_y_anchor * height) / old_zoom; compute_scaled_size (view, new_zoom, - &new_scaled_width, &new_scaled_height); + &new_scaled_width, &new_scaled_height); if (new_scaled_width < width) *xofs = 0; @@ -349,16 +349,16 @@ update_scrollbar_values (EogScrollView *view) priv->xofs = CLAMP (priv->xofs, 0, upper - page_size); g_signal_handlers_block_matched ( - priv->hadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->hadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); gtk_adjustment_configure (priv->hadj, priv->xofs, lower, - upper, step_increment, - page_increment, page_size); + upper, step_increment, + page_increment, page_size); g_signal_handlers_unblock_matched ( - priv->hadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->hadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); } if (gtk_widget_get_visible (GTK_WIDGET (priv->vbar))) { @@ -371,16 +371,16 @@ update_scrollbar_values (EogScrollView *view) priv->yofs = CLAMP (priv->yofs, 0, upper - page_size); g_signal_handlers_block_matched ( - priv->vadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->vadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); gtk_adjustment_configure (priv->vadj, priv->yofs, lower, - upper, step_increment, - page_increment, page_size); + upper, step_increment, + page_increment, page_size); g_signal_handlers_unblock_matched ( - priv->vadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->vadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); } } @@ -400,15 +400,15 @@ eog_scroll_view_set_cursor (EogScrollView *view, EogScrollViewCursor new_cursor) view->priv->cursor = new_cursor; switch (new_cursor) { - case EOG_SCROLL_VIEW_CURSOR_NORMAL: - gdk_window_set_cursor (gtk_widget_get_window (widget), NULL); - break; - case EOG_SCROLL_VIEW_CURSOR_HIDDEN: - cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR); - break; - case EOG_SCROLL_VIEW_CURSOR_DRAG: - cursor = gdk_cursor_new_for_display (display, GDK_FLEUR); - break; + case EOG_SCROLL_VIEW_CURSOR_NORMAL: + gdk_window_set_cursor (gtk_widget_get_window (widget), NULL); + break; + case EOG_SCROLL_VIEW_CURSOR_HIDDEN: + cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR); + break; + case EOG_SCROLL_VIEW_CURSOR_DRAG: + cursor = gdk_cursor_new_for_display (display, GDK_FLEUR); + break; } if (cursor) { @@ -455,7 +455,7 @@ check_scrollbar_visibility (EogScrollView *view, GtkAllocation *alloc) bar_width = req.width; eog_debug_message (DEBUG_WINDOW, "Widget Size allocate: %i, %i Bar: %i, %i\n", - width, height, bar_width, bar_height); + width, height, bar_width, bar_height); hbar_visible = vbar_visible = FALSE; if (priv->zoom_mode == EOG_ZOOM_MODE_SHRINK_TO_FIT) @@ -471,7 +471,7 @@ check_scrollbar_visibility (EogScrollView *view, GtkAllocation *alloc) else vbar_visible = TRUE; } - else if (img_height > height) { + else if (img_height > height) { vbar_visible = TRUE; if (img_width <= (width - bar_width)) hbar_visible = FALSE; @@ -524,7 +524,7 @@ is_image_movable (EogScrollView *view) } /*=================================== - drawing core + drawing core ---------------------------------*/ static void @@ -570,8 +570,8 @@ create_background_surface (EogScrollView *view) get_transparency_params (view, &check_size, &check_1, &check_2); surface = gdk_window_create_similar_surface (gtk_widget_get_window (view->priv->display), - CAIRO_CONTENT_COLOR_ALPHA, - check_size * 2, check_size * 2); + CAIRO_CONTENT_COLOR_ALPHA, + check_size * 2, check_size * 2); cairo_t* cr = cairo_create (surface); /* Use source operator to make fully transparent work */ @@ -617,14 +617,14 @@ scroll_to (EogScrollView *view, int x, int y, gboolean change_adjustments) /* Check bounds & Compute offsets */ if (gtk_widget_get_visible (priv->hbar)) { x = CLAMP (x, 0, gtk_adjustment_get_upper (priv->hadj) - - gtk_adjustment_get_page_size (priv->hadj)); + - gtk_adjustment_get_page_size (priv->hadj)); xofs = x - priv->xofs; } else xofs = 0; if (gtk_widget_get_visible (priv->vbar)) { y = CLAMP (y, 0, gtk_adjustment_get_upper (priv->vadj) - - gtk_adjustment_get_page_size (priv->vadj)); + - gtk_adjustment_get_page_size (priv->vadj)); yofs = y - priv->yofs; } else yofs = 0; @@ -659,21 +659,21 @@ scroll_to (EogScrollView *view, int x, int y, gboolean change_adjustments) return; g_signal_handlers_block_matched ( - priv->hadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->hadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); g_signal_handlers_block_matched ( - priv->vadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->vadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); gtk_adjustment_set_value (priv->hadj, x); gtk_adjustment_set_value (priv->vadj, y); g_signal_handlers_unblock_matched ( - priv->hadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->hadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); g_signal_handlers_unblock_matched ( - priv->vadj, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, view); + priv->vadj, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, view); } /* Scrolls the image view by the specified offsets. Notifies the adjustments @@ -701,7 +701,7 @@ adjustment_changed_cb (GtkAdjustment *adj, gpointer data) priv = view->priv; scroll_to (view, gtk_adjustment_get_value (priv->hadj), - gtk_adjustment_get_value (priv->vadj), FALSE); + gtk_adjustment_get_value (priv->vadj), FALSE); } @@ -729,8 +729,8 @@ set_minimum_zoom_factor (EogScrollView *view) g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); view->priv->min_zoom = MAX (1.0 / gdk_pixbuf_get_width (view->priv->pixbuf), - MAX(1.0 / gdk_pixbuf_get_height (view->priv->pixbuf), - MIN_ZOOM_FACTOR) ); + MAX(1.0 / gdk_pixbuf_get_height (view->priv->pixbuf), + MIN_ZOOM_FACTOR) ); return; } @@ -751,7 +751,7 @@ set_minimum_zoom_factor (EogScrollView *view) **/ static void set_zoom (EogScrollView *view, double zoom, - gboolean have_anchor, int anchorx, int anchory) + gboolean have_anchor, int anchorx, int anchory) { EogScrollViewPrivate *priv; GtkAllocation allocation; @@ -787,9 +787,9 @@ set_zoom (EogScrollView *view, double zoom, } compute_center_zoom_offsets (view, priv->zoom, zoom, - allocation.width, allocation.height, - x_rel, y_rel, - &xofs, &yofs); + allocation.width, allocation.height, + x_rel, y_rel, + &xofs, &yofs); /* set new values */ priv->xofs = xofs; /* (img_width * x_rel * zoom) - anchorx; */ @@ -840,9 +840,9 @@ set_zoom_fit (EogScrollView *view) gtk_widget_get_allocation (GTK_WIDGET(priv->display), &allocation); new_zoom = zoom_fit_scale (allocation.width, allocation.height, - gdk_pixbuf_get_width (priv->pixbuf), - gdk_pixbuf_get_height (priv->pixbuf), - priv->upscale); + gdk_pixbuf_get_width (priv->pixbuf), + gdk_pixbuf_get_height (priv->pixbuf), + priv->upscale); if (new_zoom > MAX_ZOOM_FACTOR) new_zoom = MAX_ZOOM_FACTOR; @@ -1014,9 +1014,9 @@ eog_scroll_view_button_press_event (GtkWidget *widget, GdkEventButton *event, gp return FALSE; switch (event->button) { - case 1: - case 2: - if (event->button == 1 && !priv->scroll_wheel_zoom && + case 1: + case 2: + if (event->button == 1 && !priv->scroll_wheel_zoom && !(event->state & GDK_CONTROL_MASK)) break; @@ -1032,8 +1032,8 @@ eog_scroll_view_button_press_event (GtkWidget *widget, GdkEventButton *event, gp return TRUE; } - default: - break; + default: + break; } return FALSE; @@ -1053,16 +1053,16 @@ eog_scroll_view_button_release_event (GtkWidget *widget, GdkEventButton *event, return FALSE; switch (event->button) { - case 1: - case 2: - drag_to (view, event->x, event->y); + case 1: + case 2: + drag_to (view, event->x, event->y); priv->dragging = FALSE; eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL); - break; + break; - default: - break; + default: + break; } return TRUE; @@ -1119,23 +1119,23 @@ eog_scroll_view_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer return FALSE; } - if (priv->scroll_wheel_zoom) { + if (priv->scroll_wheel_zoom) { if (event->state & GDK_SHIFT_MASK) scroll_by (view, yofs, xofs); else if (event->state & GDK_CONTROL_MASK) scroll_by (view, xofs, yofs); else set_zoom (view, priv->zoom * zoom_factor, - TRUE, event->x, event->y); + TRUE, event->x, event->y); } else { if (event->state & GDK_SHIFT_MASK) scroll_by (view, yofs, xofs); else if (event->state & GDK_CONTROL_MASK) set_zoom (view, priv->zoom * zoom_factor, - TRUE, event->x, event->y); + TRUE, event->x, event->y); else scroll_by (view, xofs, yofs); - } + } return TRUE; } @@ -1194,7 +1194,7 @@ eog_scroll_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc) check_scrollbar_visibility (view, alloc); GTK_WIDGET_CLASS (eog_scroll_view_parent_class)->size_allocate (widget - ,alloc); + ,alloc); } static void @@ -1237,8 +1237,8 @@ display_size_change (GtkWidget *widget, GdkEventConfigure *event, gpointer data) static gboolean eog_scroll_view_focus_in_event (GtkWidget *widget, - GdkEventFocus *event, - gpointer data) + GdkEventFocus *event, + gpointer data) { g_signal_stop_emission_by_name (G_OBJECT (widget), "focus_in_event"); return FALSE; @@ -1246,8 +1246,8 @@ eog_scroll_view_focus_in_event (GtkWidget *widget, static gboolean eog_scroll_view_focus_out_event (GtkWidget *widget, - GdkEventFocus *event, - gpointer data) + GdkEventFocus *event, + gpointer data) { g_signal_stop_emission_by_name (G_OBJECT (widget), "focus_out_event"); return FALSE; @@ -1316,24 +1316,24 @@ display_draw (GtkWidget *widget, cairo_t *cr, gpointer data) &scaled_width, &scaled_height); eog_debug_message (DEBUG_WINDOW, "zoom %.2f, xofs: %i, yofs: %i scaled w: %i h: %i\n", - priv->zoom, xofs, yofs, scaled_width, scaled_height); + priv->zoom, xofs, yofs, scaled_width, scaled_height); /* Paint the background */ gtk_widget_get_allocation (GTK_WIDGET (priv->display), &allocation); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); if (priv->transp_style != EOG_TRANSP_BACKGROUND) cairo_rectangle (cr, MAX (0, xofs), MAX (0, yofs), - scaled_width, scaled_height); + scaled_width, scaled_height); if (priv->override_bg_color != NULL) background_color = priv->override_bg_color; else if (priv->use_bg_color) background_color = priv->background_color; if (background_color != NULL) cairo_set_source_rgba (cr, - background_color->red, - background_color->green, - background_color->blue, - background_color->alpha); + background_color->red, + background_color->green, + background_color->blue, + background_color->alpha); else cairo_set_source (cr, gdk_window_get_background_pattern (gtk_widget_get_window (priv->display))); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); @@ -1435,8 +1435,8 @@ display_draw (GtkWidget *widget, cairo_t *cr, gpointer data) static void zoom_gesture_begin_cb (GtkGestureZoom *gesture, - GdkEventSequence *sequence, - EogScrollView *view) + GdkEventSequence *sequence, + EogScrollView *view) { gdouble center_x, center_y; EogScrollViewPrivate *priv; @@ -1445,7 +1445,7 @@ zoom_gesture_begin_cb (GtkGestureZoom *gesture, /* Displace dragging point to gesture center */ gtk_gesture_get_bounding_box_center (GTK_GESTURE (gesture), - ¢er_x, ¢er_y); + ¢er_x, ¢er_y); priv->drag_anchor_x = center_x; priv->drag_anchor_y = center_y; priv->drag_ofs_x = priv->xofs; @@ -1453,13 +1453,13 @@ zoom_gesture_begin_cb (GtkGestureZoom *gesture, priv->dragging = TRUE; priv->initial_zoom = priv->zoom; - gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); + gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); } static void zoom_gesture_update_cb (GtkGestureZoom *gesture, - GdkEventSequence *sequence, - EogScrollView *view) + GdkEventSequence *sequence, + EogScrollView *view) { gdouble center_x, center_y, scale; EogScrollViewPrivate *priv; @@ -1467,29 +1467,29 @@ zoom_gesture_update_cb (GtkGestureZoom *gesture, priv = view->priv; scale = gtk_gesture_zoom_get_scale_delta (gesture); gtk_gesture_get_bounding_box_center (GTK_GESTURE (gesture), - ¢er_x, ¢er_y); + ¢er_x, ¢er_y); drag_to (view, center_x, center_y); set_zoom (view, priv->initial_zoom * scale, TRUE, - center_x, center_y); + center_x, center_y); } static void zoom_gesture_end_cb (GtkGestureZoom *gesture, - GdkEventSequence *sequence, - EogScrollView *view) + GdkEventSequence *sequence, + EogScrollView *view) { EogScrollViewPrivate *priv; priv = view->priv; priv->dragging = FALSE; - eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL); + eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL); } static void rotate_gesture_begin_cb (GtkGesture *gesture, - GdkEventSequence *sequence, - EogScrollView *view) + GdkEventSequence *sequence, + EogScrollView *view) { EogScrollViewPrivate *priv; @@ -1499,15 +1499,15 @@ rotate_gesture_begin_cb (GtkGesture *gesture, static void pan_gesture_pan_cb (GtkGesturePan *gesture, - GtkPanDirection direction, - gdouble offset, - EogScrollView *view) + GtkPanDirection direction, + gdouble offset, + EogScrollView *view) { EogScrollViewPrivate *priv; if (eog_scroll_view_scrollbars_visible (view)) { gtk_gesture_set_state (GTK_GESTURE (gesture), - GTK_EVENT_SEQUENCE_DENIED); + GTK_EVENT_SEQUENCE_DENIED); return; } @@ -1529,8 +1529,8 @@ pan_gesture_pan_cb (GtkGesturePan *gesture, static void pan_gesture_end_cb (GtkGesture *gesture, - GdkEventSequence *sequence, - EogScrollView *view) + GdkEventSequence *sequence, + EogScrollView *view) { EogScrollViewPrivate *priv; @@ -1549,22 +1549,22 @@ pan_gesture_end_cb (GtkGesture *gesture, static gboolean scroll_view_check_angle (gdouble angle, - gdouble min, - gdouble max, - gdouble threshold) + gdouble min, + gdouble max, + gdouble threshold) { if (min < max) { return (angle > min - threshold && - angle < max + threshold); + angle < max + threshold); } else { return (angle < max + threshold || - angle > min - threshold); + angle > min - threshold); } } static EogRotationState scroll_view_get_rotate_state (EogScrollView *view, - gdouble delta) + gdouble delta) { EogScrollViewPrivate *priv; @@ -1574,22 +1574,22 @@ scroll_view_get_rotate_state (EogScrollView *view, switch (priv->rotate_state) { case EOG_ROTATION_0: if (scroll_view_check_angle (delta, G_PI * 7 / 4, - G_PI / 4, THRESHOLD)) + G_PI / 4, THRESHOLD)) return priv->rotate_state; break; case EOG_ROTATION_90: if (scroll_view_check_angle (delta, G_PI / 4, - G_PI * 3 / 4, THRESHOLD)) + G_PI * 3 / 4, THRESHOLD)) return priv->rotate_state; break; case EOG_ROTATION_180: if (scroll_view_check_angle (delta, G_PI * 3 / 4, - G_PI * 5 / 4, THRESHOLD)) + G_PI * 5 / 4, THRESHOLD)) return priv->rotate_state; break; case EOG_ROTATION_270: if (scroll_view_check_angle (delta, G_PI * 5 / 4, - G_PI * 7 / 4, THRESHOLD)) + G_PI * 7 / 4, THRESHOLD)) return priv->rotate_state; break; default: @@ -1610,17 +1610,17 @@ scroll_view_get_rotate_state (EogScrollView *view, static void rotate_gesture_angle_changed_cb (GtkGestureRotate *rotate, - gdouble angle, - gdouble delta, - EogScrollView *view) + gdouble angle, + gdouble delta, + EogScrollView *view) { EogRotationState rotate_state; EogScrollViewPrivate *priv; gint angle_diffs [N_EOG_ROTATIONS][N_EOG_ROTATIONS] = { - { 0, 90, 180, 270 }, - { 270, 0, 90, 180 }, - { 180, 270, 0, 90 }, - { 90, 180, 270, 0 } + { 0, 90, 180, 270 }, + { 270, 0, 90, 180 }, + { 180, 270, 0, 90 }, + { 90, 180, 270, 0 } }; gint rotate_angle; @@ -1669,11 +1669,11 @@ image_changed_cb (EogImage *img, gpointer data) update_pixbuf (EOG_SCROLL_VIEW (data), eog_image_get_pixbuf (img)); _set_zoom_mode_internal (EOG_SCROLL_VIEW (data), - EOG_ZOOM_MODE_SHRINK_TO_FIT); + EOG_ZOOM_MODE_SHRINK_TO_FIT); } /*=================================== - public API + public API ---------------------------------*/ void @@ -1782,12 +1782,12 @@ eog_scroll_view_set_transparency_color (EogScrollView *view, GdkRGBA *color) void eog_scroll_view_set_transparency (EogScrollView *view, - EogTransparencyStyle style) + EogTransparencyStyle style) { EogScrollViewPrivate *priv; g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); - + priv = view->priv; if (priv->transp_style != style) { @@ -1800,9 +1800,9 @@ eog_scroll_view_set_transparency (EogScrollView *view, /* zoom api */ static double preferred_zoom_levels[] = { - 1.0 / 100, 1.0 / 50, 1.0 / 20, - 1.0 / 10.0, 1.0 / 5.0, 1.0 / 3.0, 1.0 / 2.0, 1.0 / 1.5, - 1.0, 1 / 0.75, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, + 1.0 / 100, 1.0 / 50, 1.0 / 20, + 1.0 / 10.0, 1.0 / 5.0, 1.0 / 3.0, 1.0 / 2.0, 1.0 / 1.5, + 1.0, 1 / 0.75, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0 }; static const gint n_zoom_levels = (sizeof (preferred_zoom_levels) / sizeof (double)); @@ -1826,7 +1826,7 @@ eog_scroll_view_zoom_in (EogScrollView *view, gboolean smooth) for (i = 0; i < n_zoom_levels; i++) { if (preferred_zoom_levels [i] - priv->zoom - > DOUBLE_EQUAL_MAX_DIFF) { + > DOUBLE_EQUAL_MAX_DIFF) { index = i; break; } @@ -1862,7 +1862,7 @@ eog_scroll_view_zoom_out (EogScrollView *view, gboolean smooth) for (i = n_zoom_levels - 1; i >= 0; i--) { if (priv->zoom - preferred_zoom_levels [i] - > DOUBLE_EQUAL_MAX_DIFF) { + > DOUBLE_EQUAL_MAX_DIFF) { index = i; break; } @@ -1925,7 +1925,7 @@ eog_scroll_view_get_zoom_is_max (EogScrollView *view) static void display_next_frame_cb (EogImage *image, gint delay, gpointer data) { - EogScrollViewPrivate *priv; + EogScrollViewPrivate *priv; EogScrollView *view; if (!EOG_IS_SCROLL_VIEW (data)) @@ -1936,7 +1936,7 @@ display_next_frame_cb (EogImage *image, gint delay, gpointer data) update_pixbuf (view, eog_image_get_pixbuf (image)); - gtk_widget_queue_draw (GTK_WIDGET (priv->display)); + gtk_widget_queue_draw (GTK_WIDGET (priv->display)); } void @@ -1966,12 +1966,12 @@ eog_scroll_view_set_image (EogScrollView *view, EogImage *image) update_pixbuf (view, eog_image_get_pixbuf (image)); /* priv->progressive_state = PROGRESSIVE_NONE; */ _set_zoom_mode_internal (view, - EOG_ZOOM_MODE_SHRINK_TO_FIT); + EOG_ZOOM_MODE_SHRINK_TO_FIT); } #if 0 else if ((is_zoomed_in (view) && priv->interp_type_in != CAIRO_FILTER_NEAREST) || - (is_zoomed_out (view) && priv->interp_type_out != CAIRO_FILTER_NEAREST)) + (is_zoomed_out (view) && priv->interp_type_out != CAIRO_FILTER_NEAREST)) { /* paint antialiased image version */ priv->progressive_state = PROGRESSIVE_POLISHING; @@ -1980,11 +1980,11 @@ eog_scroll_view_set_image (EogScrollView *view, EogImage *image) #endif priv->image_changed_id = g_signal_connect (image, "changed", - (GCallback) image_changed_cb, view); + (GCallback) image_changed_cb, view); if (eog_image_is_animation (image) == TRUE ) { eog_image_start_animation (image); - priv->frame_changed_id = g_signal_connect (image, "next-frame", - (GCallback) display_next_frame_cb, view); + priv->frame_changed_id = g_signal_connect (image, "next-frame", + (GCallback) display_next_frame_cb, view); } } else { gtk_widget_queue_draw (GTK_WIDGET (priv->display)); @@ -2034,8 +2034,8 @@ eog_scroll_view_scrollbars_visible (EogScrollView *view) static gboolean sv_string_to_rgba_mapping (GValue *value, - GVariant *variant, - gpointer user_data) + GVariant *variant, + gpointer user_data) { GdkRGBA color; @@ -2051,8 +2051,8 @@ sv_string_to_rgba_mapping (GValue *value, static GVariant* sv_rgba_to_string_mapping (const GValue *value, - const GVariantType *expected_type, - gpointer user_data) + const GVariantType *expected_type, + gpointer user_data) { GVariant *variant = NULL; GdkRGBA *color; @@ -2112,8 +2112,8 @@ _set_overlay_timeout (EogScrollView *view) static gboolean _enter_overlay_event_cb (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) + GdkEvent *event, + gpointer user_data) { EogScrollView *view = EOG_SCROLL_VIEW (user_data); @@ -2174,14 +2174,14 @@ eog_scroll_view_init (EogScrollView *view) priv->hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 100, 0, 10, 10, 100)); g_signal_connect (priv->hadj, "value_changed", - G_CALLBACK (adjustment_changed_cb), - view); + G_CALLBACK (adjustment_changed_cb), + view); priv->hbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, priv->hadj); priv->vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 100, 0, 10, 10, 100)); g_signal_connect (priv->vadj, "value_changed", - G_CALLBACK (adjustment_changed_cb), - view); + G_CALLBACK (adjustment_changed_cb), + view); priv->vbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, priv->vadj); @@ -2189,219 +2189,219 @@ eog_scroll_view_init (EogScrollView *view) gtk_grid_attach (GTK_GRID (view), priv->overlay, 0, 0, 1, 1); priv->display = g_object_new (GTK_TYPE_DRAWING_AREA, - "can-focus", TRUE, - NULL); + "can-focus", TRUE, + NULL); gtk_widget_add_events (GTK_WIDGET (priv->display), - GDK_EXPOSURE_MASK - | GDK_TOUCHPAD_GESTURE_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_TOUCH_MASK - | GDK_SCROLL_MASK - | GDK_KEY_PRESS_MASK); + GDK_EXPOSURE_MASK + | GDK_TOUCHPAD_GESTURE_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_TOUCH_MASK + | GDK_SCROLL_MASK + | GDK_KEY_PRESS_MASK); g_signal_connect (G_OBJECT (priv->display), "configure_event", - G_CALLBACK (display_size_change), view); + G_CALLBACK (display_size_change), view); g_signal_connect (G_OBJECT (priv->display), "draw", - G_CALLBACK (display_draw), view); + G_CALLBACK (display_draw), view); g_signal_connect (G_OBJECT (priv->display), "map_event", - G_CALLBACK (display_map_event), view); + G_CALLBACK (display_map_event), view); g_signal_connect (G_OBJECT (priv->display), "button_press_event", - G_CALLBACK (eog_scroll_view_button_press_event), - view); + G_CALLBACK (eog_scroll_view_button_press_event), + view); g_signal_connect (G_OBJECT (priv->display), "motion_notify_event", - G_CALLBACK (eog_scroll_view_motion_event), view); + G_CALLBACK (eog_scroll_view_motion_event), view); g_signal_connect (G_OBJECT (priv->display), "button_release_event", - G_CALLBACK (eog_scroll_view_button_release_event), - view); + G_CALLBACK (eog_scroll_view_button_release_event), + view); g_signal_connect (G_OBJECT (priv->display), "scroll_event", - G_CALLBACK (eog_scroll_view_scroll_event), view); + G_CALLBACK (eog_scroll_view_scroll_event), view); g_signal_connect (G_OBJECT (priv->display), "focus_in_event", - G_CALLBACK (eog_scroll_view_focus_in_event), NULL); + G_CALLBACK (eog_scroll_view_focus_in_event), NULL); g_signal_connect (G_OBJECT (priv->display), "focus_out_event", - G_CALLBACK (eog_scroll_view_focus_out_event), NULL); + G_CALLBACK (eog_scroll_view_focus_out_event), NULL); g_signal_connect (G_OBJECT (view), "key_press_event", - G_CALLBACK (display_key_press_event), view); + G_CALLBACK (display_key_press_event), view); gtk_drag_source_set (priv->display, GDK_BUTTON1_MASK, - target_table, G_N_ELEMENTS (target_table), - GDK_ACTION_COPY | GDK_ACTION_MOVE | - GDK_ACTION_LINK | GDK_ACTION_ASK); + target_table, G_N_ELEMENTS (target_table), + GDK_ACTION_COPY | GDK_ACTION_MOVE | + GDK_ACTION_LINK | GDK_ACTION_ASK); g_signal_connect (G_OBJECT (priv->display), "drag-data-get", - G_CALLBACK (view_on_drag_data_get_cb), view); + G_CALLBACK (view_on_drag_data_get_cb), view); g_signal_connect (G_OBJECT (priv->display), "drag-begin", - G_CALLBACK (view_on_drag_begin_cb), view); + G_CALLBACK (view_on_drag_begin_cb), view); gtk_container_add (GTK_CONTAINER (priv->overlay), priv->display); gtk_widget_set_hexpand (priv->display, TRUE); gtk_widget_set_vexpand (priv->display, TRUE); gtk_grid_attach (GTK_GRID (view), priv->hbar, - 0, 1, 1, 1); + 0, 1, 1, 1); gtk_widget_set_hexpand (priv->hbar, TRUE); gtk_grid_attach (GTK_GRID (view), priv->vbar, - 1, 0, 1, 1); + 1, 0, 1, 1); gtk_widget_set_vexpand (priv->vbar, TRUE); g_settings_bind (settings, EOG_CONF_VIEW_USE_BG_COLOR, view, - "use-background-color", G_SETTINGS_BIND_DEFAULT); + "use-background-color", G_SETTINGS_BIND_DEFAULT); g_settings_bind_with_mapping (settings, EOG_CONF_VIEW_BACKGROUND_COLOR, - view, "background-color", - G_SETTINGS_BIND_DEFAULT, - sv_string_to_rgba_mapping, - sv_rgba_to_string_mapping, NULL, NULL); + view, "background-color", + G_SETTINGS_BIND_DEFAULT, + sv_string_to_rgba_mapping, + sv_rgba_to_string_mapping, NULL, NULL); g_settings_bind_with_mapping (settings, EOG_CONF_VIEW_TRANS_COLOR, - view, "transparency-color", - G_SETTINGS_BIND_GET, - sv_string_to_rgba_mapping, - sv_rgba_to_string_mapping, NULL, NULL); + view, "transparency-color", + G_SETTINGS_BIND_GET, + sv_string_to_rgba_mapping, + sv_rgba_to_string_mapping, NULL, NULL); g_settings_bind (settings, EOG_CONF_VIEW_TRANSPARENCY, view, - "transparency-style", G_SETTINGS_BIND_GET); + "transparency-style", G_SETTINGS_BIND_GET); g_settings_bind (settings, EOG_CONF_VIEW_EXTRAPOLATE, view, - "antialiasing-in", G_SETTINGS_BIND_GET); + "antialiasing-in", G_SETTINGS_BIND_GET); g_settings_bind (settings, EOG_CONF_VIEW_INTERPOLATE, view, - "antialiasing-out", G_SETTINGS_BIND_GET); + "antialiasing-out", G_SETTINGS_BIND_GET); g_object_unref (settings); priv->zoom_gesture = gtk_gesture_zoom_new (GTK_WIDGET (view)); g_signal_connect (priv->zoom_gesture, "begin", - G_CALLBACK (zoom_gesture_begin_cb), view); + G_CALLBACK (zoom_gesture_begin_cb), view); g_signal_connect (priv->zoom_gesture, "update", - G_CALLBACK (zoom_gesture_update_cb), view); + G_CALLBACK (zoom_gesture_update_cb), view); g_signal_connect (priv->zoom_gesture, "end", - G_CALLBACK (zoom_gesture_end_cb), view); + G_CALLBACK (zoom_gesture_end_cb), view); g_signal_connect (priv->zoom_gesture, "cancel", - G_CALLBACK (zoom_gesture_end_cb), view); + G_CALLBACK (zoom_gesture_end_cb), view); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->zoom_gesture), - GTK_PHASE_CAPTURE); + GTK_PHASE_CAPTURE); priv->rotate_gesture = gtk_gesture_rotate_new (GTK_WIDGET (view)); gtk_gesture_group (priv->rotate_gesture, priv->zoom_gesture); g_signal_connect (priv->rotate_gesture, "angle-changed", - G_CALLBACK (rotate_gesture_angle_changed_cb), view); + G_CALLBACK (rotate_gesture_angle_changed_cb), view); g_signal_connect (priv->rotate_gesture, "begin", - G_CALLBACK (rotate_gesture_begin_cb), view); + G_CALLBACK (rotate_gesture_begin_cb), view); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->rotate_gesture), - GTK_PHASE_CAPTURE); + GTK_PHASE_CAPTURE); priv->pan_gesture = gtk_gesture_pan_new (GTK_WIDGET (view), - GTK_ORIENTATION_HORIZONTAL); + GTK_ORIENTATION_HORIZONTAL); g_signal_connect (priv->pan_gesture, "pan", - G_CALLBACK (pan_gesture_pan_cb), view); + G_CALLBACK (pan_gesture_pan_cb), view); g_signal_connect (priv->pan_gesture, "end", - G_CALLBACK (pan_gesture_end_cb), view); - gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->pan_gesture), - TRUE); + G_CALLBACK (pan_gesture_end_cb), view); + gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->pan_gesture), + TRUE); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->pan_gesture), - GTK_PHASE_CAPTURE); + GTK_PHASE_CAPTURE); /* left revealer */ priv->left_revealer = gtk_revealer_new (); gtk_revealer_set_transition_type (GTK_REVEALER (priv->left_revealer), - GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); + GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); gtk_revealer_set_transition_duration (GTK_REVEALER (priv->left_revealer), - OVERLAY_REVEAL_ANIM_TIME); + OVERLAY_REVEAL_ANIM_TIME); gtk_widget_set_halign (priv->left_revealer, GTK_ALIGN_START); gtk_widget_set_valign (priv->left_revealer, GTK_ALIGN_CENTER); gtk_widget_set_margin_start(priv->left_revealer, 12); gtk_widget_set_margin_end(priv->left_revealer, 12); gtk_overlay_add_overlay (GTK_OVERLAY (priv->overlay), - priv->left_revealer); + priv->left_revealer); /* right revealer */ priv->right_revealer = gtk_revealer_new (); gtk_revealer_set_transition_type (GTK_REVEALER (priv->right_revealer), - GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); + GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); gtk_revealer_set_transition_duration (GTK_REVEALER (priv->right_revealer), - OVERLAY_REVEAL_ANIM_TIME); + OVERLAY_REVEAL_ANIM_TIME); gtk_widget_set_halign (priv->right_revealer, GTK_ALIGN_END); gtk_widget_set_valign (priv->right_revealer, GTK_ALIGN_CENTER); gtk_widget_set_margin_start (priv->right_revealer, 12); gtk_widget_set_margin_end (priv->right_revealer, 12); gtk_overlay_add_overlay(GTK_OVERLAY (priv->overlay), - priv->right_revealer); + priv->right_revealer); /* bottom revealer */ priv->bottom_revealer = gtk_revealer_new (); gtk_revealer_set_transition_type (GTK_REVEALER (priv->bottom_revealer), - GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); + GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); gtk_revealer_set_transition_duration (GTK_REVEALER (priv->bottom_revealer), - OVERLAY_REVEAL_ANIM_TIME); + OVERLAY_REVEAL_ANIM_TIME); gtk_widget_set_halign (priv->bottom_revealer, GTK_ALIGN_CENTER); gtk_widget_set_valign (priv->bottom_revealer, GTK_ALIGN_END); gtk_widget_set_margin_bottom (priv->bottom_revealer, 12); gtk_overlay_add_overlay (GTK_OVERLAY (priv->overlay), - priv->bottom_revealer); + priv->bottom_revealer); /* overlaid buttons */ GtkWidget *button = gtk_button_new_from_icon_name ("go-next-symbolic", - GTK_ICON_SIZE_BUTTON); + GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER (priv->right_revealer), button); gtk_actionable_set_action_name(GTK_ACTIONABLE (button), "win.go-next"); gtk_widget_set_tooltip_text (button, - _("Go to the next image of the gallery")); + _("Go to the next image of the gallery")); gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_OSD); + GTK_STYLE_CLASS_OSD); button = gtk_button_new_from_icon_name("go-previous-symbolic", - GTK_ICON_SIZE_BUTTON); + GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER (priv->left_revealer), button); gtk_actionable_set_action_name (GTK_ACTIONABLE(button), - "win.go-previous"); + "win.go-previous"); gtk_widget_set_tooltip_text (button, - _("Go to the previous image of the gallery")); + _("Go to the previous image of the gallery")); gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_OSD); + GTK_STYLE_CLASS_OSD); /* group rotate buttons into a box */ GtkWidget* bottomBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_style_context_add_class (gtk_widget_get_style_context (bottomBox), - GTK_STYLE_CLASS_LINKED); + GTK_STYLE_CLASS_LINKED); button = gtk_button_new_from_icon_name ("object-rotate-left-symbolic", - GTK_ICON_SIZE_BUTTON); + GTK_ICON_SIZE_BUTTON); gtk_actionable_set_action_name (GTK_ACTIONABLE (button), - "win.rotate-270"); + "win.rotate-270"); gtk_widget_set_tooltip_text (button, - _("Rotate the image 90 degrees to the left")); + _("Rotate the image 90 degrees to the left")); gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_OSD); + GTK_STYLE_CLASS_OSD); gtk_container_add (GTK_CONTAINER (bottomBox), button); button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic", - GTK_ICON_SIZE_BUTTON); + GTK_ICON_SIZE_BUTTON); gtk_actionable_set_action_name (GTK_ACTIONABLE (button), - "win.rotate-90"); + "win.rotate-90"); gtk_widget_set_tooltip_text (button, - _("Rotate the image 90 degrees to the right")); + _("Rotate the image 90 degrees to the right")); gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_OSD); + GTK_STYLE_CLASS_OSD); gtk_container_add (GTK_CONTAINER (bottomBox), button); gtk_container_add (GTK_CONTAINER (priv->bottom_revealer), bottomBox); /* Display overlay buttons on mouse movement */ g_signal_connect (priv->display, - "motion-notify-event", - G_CALLBACK (_motion_notify_cb), - view); + "motion-notify-event", + G_CALLBACK (_motion_notify_cb), + view); /* Don't hide overlay buttons when above */ gtk_widget_add_events (GTK_WIDGET (priv->overlay), - GDK_ENTER_NOTIFY_MASK); + GDK_ENTER_NOTIFY_MASK); g_signal_connect (priv->overlay, - "enter-notify-event", - G_CALLBACK (_enter_overlay_event_cb), - view); + "enter-notify-event", + G_CALLBACK (_enter_overlay_event_cb), + view); } static void @@ -2460,7 +2460,7 @@ eog_scroll_view_dispose (GObject *object) static void eog_scroll_view_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { EogScrollView *view; EogScrollViewPrivate *priv; @@ -2512,7 +2512,7 @@ eog_scroll_view_get_property (GObject *object, guint property_id, static void eog_scroll_view_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { EogScrollView *view; @@ -2570,8 +2570,8 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) widget_class = (GtkWidgetClass*) klass; gobject_class->dispose = eog_scroll_view_dispose; - gobject_class->set_property = eog_scroll_view_set_property; - gobject_class->get_property = eog_scroll_view_get_property; + gobject_class->set_property = eog_scroll_view_set_property; + gobject_class->get_property = eog_scroll_view_get_property; /** * EogScrollView:antialiasing-in: @@ -2580,9 +2580,9 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * while being zoomed in. */ g_object_class_install_property ( - gobject_class, PROP_ANTIALIAS_IN, - g_param_spec_boolean ("antialiasing-in", NULL, NULL, TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_ANTIALIAS_IN, + g_param_spec_boolean ("antialiasing-in", NULL, NULL, TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:antialiasing-out: * @@ -2590,9 +2590,9 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * while being zoomed out. */ g_object_class_install_property ( - gobject_class, PROP_ANTIALIAS_OUT, - g_param_spec_boolean ("antialiasing-out", NULL, NULL, TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_ANTIALIAS_OUT, + g_param_spec_boolean ("antialiasing-out", NULL, NULL, TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:background-color: @@ -2602,15 +2602,15 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * active GTK theme. */ g_object_class_install_property ( - gobject_class, PROP_BACKGROUND_COLOR, - g_param_spec_boxed ("background-color", NULL, NULL, - GDK_TYPE_RGBA, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_BACKGROUND_COLOR, + g_param_spec_boxed ("background-color", NULL, NULL, + GDK_TYPE_RGBA, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); g_object_class_install_property ( - gobject_class, PROP_USE_BG_COLOR, - g_param_spec_boolean ("use-background-color", NULL, NULL, FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_USE_BG_COLOR, + g_param_spec_boolean ("use-background-color", NULL, NULL, FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:zoom-multiplier: @@ -2619,10 +2619,10 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * scrolling with the scrollwheel to determine the next zoom factor. */ g_object_class_install_property ( - gobject_class, PROP_ZOOM_MULTIPLIER, - g_param_spec_double ("zoom-multiplier", NULL, NULL, - -G_MAXDOUBLE, G_MAXDOUBLE - 1.0, 0.05, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_ZOOM_MULTIPLIER, + g_param_spec_double ("zoom-multiplier", NULL, NULL, + -G_MAXDOUBLE, G_MAXDOUBLE - 1.0, 0.05, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:scrollwheel-zoom: @@ -2631,9 +2631,9 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * used for scrolling a zoomed image. */ g_object_class_install_property ( - gobject_class, PROP_SCROLLWHEEL_ZOOM, - g_param_spec_boolean ("scrollwheel-zoom", NULL, NULL, TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_SCROLLWHEEL_ZOOM, + g_param_spec_boolean ("scrollwheel-zoom", NULL, NULL, TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:image: @@ -2641,9 +2641,9 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * This is the currently display #EogImage. */ g_object_class_install_property ( - gobject_class, PROP_IMAGE, - g_param_spec_object ("image", NULL, NULL, EOG_TYPE_IMAGE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_IMAGE, + g_param_spec_object ("image", NULL, NULL, EOG_TYPE_IMAGE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); /** * EogScrollView:transparency-color: @@ -2652,73 +2652,73 @@ eog_scroll_view_class_init (EogScrollViewClass *klass) * if #EogScrollView:transparency-style is set to %EOG_TRANSP_COLOR. */ g_object_class_install_property ( - gobject_class, PROP_TRANSP_COLOR, - g_param_spec_boxed ("transparency-color", NULL, NULL, - GDK_TYPE_RGBA, - G_PARAM_WRITABLE | G_PARAM_STATIC_NAME)); - + gobject_class, PROP_TRANSP_COLOR, + g_param_spec_boxed ("transparency-color", NULL, NULL, + GDK_TYPE_RGBA, + G_PARAM_WRITABLE | G_PARAM_STATIC_NAME)); + /** * EogScrollView:transparency-style: * * Determines how to fill the shown image's transparent areas. */ g_object_class_install_property ( - gobject_class, PROP_TRANSPARENCY_STYLE, - g_param_spec_enum ("transparency-style", NULL, NULL, - EOG_TYPE_TRANSPARENCY_STYLE, - EOG_TRANSP_CHECKED, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_TRANSPARENCY_STYLE, + g_param_spec_enum ("transparency-style", NULL, NULL, + EOG_TYPE_TRANSPARENCY_STYLE, + EOG_TRANSP_CHECKED, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); g_object_class_install_property ( - gobject_class, PROP_ZOOM_MODE, - g_param_spec_enum ("zoom-mode", NULL, NULL, - EOG_TYPE_ZOOM_MODE, - EOG_ZOOM_MODE_SHRINK_TO_FIT, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); + gobject_class, PROP_ZOOM_MODE, + g_param_spec_enum ("zoom-mode", NULL, NULL, + EOG_TYPE_ZOOM_MODE, + EOG_ZOOM_MODE_SHRINK_TO_FIT, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME)); view_signals [SIGNAL_ZOOM_CHANGED] = - g_signal_new ("zoom_changed", - EOG_TYPE_SCROLL_VIEW, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EogScrollViewClass, zoom_changed), - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, - G_TYPE_DOUBLE); + g_signal_new ("zoom_changed", + EOG_TYPE_SCROLL_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EogScrollViewClass, zoom_changed), + NULL, NULL, + g_cclosure_marshal_VOID__DOUBLE, + G_TYPE_NONE, 1, + G_TYPE_DOUBLE); view_signals [SIGNAL_ROTATION_CHANGED] = - g_signal_new ("rotation-changed", - EOG_TYPE_SCROLL_VIEW, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EogScrollViewClass, rotation_changed), - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, - G_TYPE_DOUBLE); + g_signal_new ("rotation-changed", + EOG_TYPE_SCROLL_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EogScrollViewClass, rotation_changed), + NULL, NULL, + g_cclosure_marshal_VOID__DOUBLE, + G_TYPE_NONE, 1, + G_TYPE_DOUBLE); view_signals [SIGNAL_NEXT_IMAGE] = - g_signal_new ("next-image", - EOG_TYPE_SCROLL_VIEW, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EogScrollViewClass, next_image), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_signal_new ("next-image", + EOG_TYPE_SCROLL_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EogScrollViewClass, next_image), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); view_signals [SIGNAL_PREVIOUS_IMAGE] = - g_signal_new ("previous-image", - EOG_TYPE_SCROLL_VIEW, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EogScrollViewClass, previous_image), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_signal_new ("previous-image", + EOG_TYPE_SCROLL_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EogScrollViewClass, previous_image), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); widget_class->size_allocate = eog_scroll_view_size_allocate; } static void view_on_drag_begin_cb (GtkWidget *widget, - GdkDragContext *context, - gpointer user_data) + GdkDragContext *context, + gpointer user_data) { EogScrollView *view; EogImage *image; @@ -2740,11 +2740,11 @@ view_on_drag_begin_cb (GtkWidget *widget, static void view_on_drag_data_get_cb (GtkWidget *widget, - GdkDragContext *drag_context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data) + GdkDragContext *drag_context, + GtkSelectionData *data, + guint info, + guint time, + gpointer user_data) { EogScrollView *view; EogImage *image; @@ -2771,10 +2771,10 @@ eog_scroll_view_new (void) GtkWidget *widget; widget = g_object_new (EOG_TYPE_SCROLL_VIEW, - "can-focus", TRUE, - "row-homogeneous", FALSE, - "column-homogeneous", FALSE, - NULL); + "can-focus", TRUE, + "row-homogeneous", FALSE, + "column-homogeneous", FALSE, + NULL); return widget; } @@ -2788,7 +2788,7 @@ eog_scroll_view_popup_menu (EogScrollView *view, GdkEventButton *event) static gboolean view_on_button_press_event_cb (GtkWidget *view, GdkEventButton *event, - gpointer user_data) + gpointer user_data) { /* Ignore double-clicks and triple-clicks */ if (gdk_event_triggers_context_menu ((const GdkEvent*) event) @@ -2811,7 +2811,7 @@ eog_scroll_view_popup_menu_handler (GtkWidget *widget, gpointer user_data) void eog_scroll_view_set_popup (EogScrollView *view, - GtkMenu *menu) + GtkMenu *menu) { g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); g_return_if_fail (view->priv->menu == NULL); @@ -2819,13 +2819,13 @@ eog_scroll_view_set_popup (EogScrollView *view, view->priv->menu = g_object_ref (menu); gtk_menu_attach_to_widget (GTK_MENU (view->priv->menu), - GTK_WIDGET (view), - NULL); + GTK_WIDGET (view), + NULL); g_signal_connect (G_OBJECT (view), "button_press_event", - G_CALLBACK (view_on_button_press_event_cb), NULL); + G_CALLBACK (view_on_button_press_event_cb), NULL); g_signal_connect (G_OBJECT (view), "popup-menu", - G_CALLBACK (eog_scroll_view_popup_menu_handler), NULL); + G_CALLBACK (eog_scroll_view_popup_menu_handler), NULL); } static gboolean @@ -2871,7 +2871,7 @@ _eog_scroll_view_update_bg_color (EogScrollView *view) void eog_scroll_view_set_background_color (EogScrollView *view, - const GdkRGBA *color) + const GdkRGBA *color) { g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); @@ -2881,7 +2881,7 @@ eog_scroll_view_set_background_color (EogScrollView *view, void eog_scroll_view_override_bg_color (EogScrollView *view, - const GdkRGBA *color) + const GdkRGBA *color) { g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); @@ -2909,23 +2909,23 @@ eog_scroll_view_set_use_bg_color (EogScrollView *view, gboolean use) void eog_scroll_view_set_scroll_wheel_zoom (EogScrollView *view, - gboolean scroll_wheel_zoom) + gboolean scroll_wheel_zoom) { g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); if (view->priv->scroll_wheel_zoom != scroll_wheel_zoom) { - view->priv->scroll_wheel_zoom = scroll_wheel_zoom; + view->priv->scroll_wheel_zoom = scroll_wheel_zoom; g_object_notify (G_OBJECT (view), "scrollwheel-zoom"); } } void eog_scroll_view_set_zoom_multiplier (EogScrollView *view, - gdouble zoom_multiplier) + gdouble zoom_multiplier) { g_return_if_fail (EOG_IS_SCROLL_VIEW (view)); - view->priv->zoom_multiplier = 1.0 + zoom_multiplier; + view->priv->zoom_multiplier = 1.0 + zoom_multiplier; g_object_notify (G_OBJECT (view), "zoom-multiplier"); } @@ -2941,7 +2941,7 @@ _set_zoom_mode_internal (EogScrollView *view, EogZoomMode mode) eog_scroll_view_zoom_fit (view); else view->priv->zoom_mode = mode; - + if (notify) g_object_notify (G_OBJECT (view), "zoom-mode"); } @@ -2962,7 +2962,7 @@ EogZoomMode eog_scroll_view_get_zoom_mode (EogScrollView *view) { g_return_val_if_fail (EOG_IS_SCROLL_VIEW (view), - EOG_ZOOM_MODE_SHRINK_TO_FIT); + EOG_ZOOM_MODE_SHRINK_TO_FIT); return view->priv->zoom_mode; } @@ -3036,7 +3036,7 @@ eog_scroll_view_event_is_over_image (EogScrollView *view, const GdkEvent *ev) priv = view->priv; window = gtk_widget_get_window (GTK_WIDGET (priv->display)); - if (G_UNLIKELY (priv->pixbuf == NULL + if (G_UNLIKELY (priv->pixbuf == NULL || window != ((GdkEventAny*) ev)->window)) return FALSE; diff --git a/src/eog-scroll-view.h b/src/eog-scroll-view.h index 2b3c1da6..063ce813 100644 --- a/src/eog-scroll-view.h +++ b/src/eog-scroll-view.h @@ -62,6 +62,9 @@ typedef enum { EOG_ZOOM_MODE_SHRINK_TO_FIT } EogZoomMode; +#define EOG_SCROLL_VIEW_MAX_ZOOM_FACTOR (20) +#define EOG_SCROLL_VIEW_MIN_ZOOM_FACTOR (0.02) + GType eog_scroll_view_get_type (void) G_GNUC_CONST; GtkWidget* eog_scroll_view_new (void); diff --git a/src/eog-window.c b/src/eog-window.c index ae9d7ca9..81eff177 100644 --- a/src/eog-window.c +++ b/src/eog-window.c @@ -56,6 +56,7 @@ #include "eog-clipboard-handler.h" #include "eog-window-activatable.h" #include "eog-metadata-sidebar.h" +#include "eog-zoom-entry.h" #include "eog-enum-types.h" @@ -131,8 +132,6 @@ struct _EogWindowPrivate { GtkWidget *statusbar; GtkWidget *nav; GtkWidget *message_area; - GtkWidget *zoom_revealer; - GtkWidget *zoom_scale; GtkWidget *properties_dlg; GMenu *open_with_menu; @@ -204,8 +203,6 @@ static void eog_window_list_store_image_removed (GtkTreeModel *tree_model, static void eog_window_set_wallpaper (EogWindow *window, const gchar *filename, const gchar *visible_filename); static gboolean eog_window_save_images (EogWindow *window, GList *images); static void eog_window_finish_saving (EogWindow *window); -static void eog_window_zoom_scale_value_changed_cb (GtkRange *range, - gpointer user_data); static void eog_window_error_message_area_response (GtkInfoBar *message_area, gint response_id, EogWindow *window); @@ -234,21 +231,6 @@ _eog_zoom_shrink_to_boolean (GBinding *binding, const GValue *source, return TRUE; } -static gboolean -_eog_zoom_button_variant_to_boolean (GBinding *binding, const GValue *source, - GValue *target, gpointer user_data) -{ - GVariant *variant = g_value_get_variant (source); - g_return_val_if_fail(g_variant_is_of_type (variant, - G_VARIANT_TYPE_BOOLEAN), - FALSE); - - // Use inverted logic, as the button behaves inverted as well - g_value_set_boolean(target, !g_variant_get_boolean(variant)); - - return TRUE; -} - static void eog_window_set_gallery_mode (EogWindow *window, EogWindowGalleryPos position, @@ -496,19 +478,6 @@ eog_window_get_display_profile (GtkWidget *window) #endif static void -update_zoom_scale (EogWindow *window) -{ - EogWindowPrivate *priv; - gdouble zoom; - - g_return_if_fail (EOG_IS_WINDOW (window)); - - priv = window->priv; - zoom = eog_scroll_view_get_zoom (EOG_SCROLL_VIEW (priv->view)); - gtk_range_set_value (GTK_RANGE (priv->zoom_scale), zoom); -} - -static void update_image_pos (EogWindow *window) { EogWindowPrivate *priv; @@ -1633,19 +1602,6 @@ view_zoom_changed_cb (GtkWidget *widget, double zoom, gpointer user_data) update_status_bar (window); - /* Block signal handler to avoid setting the zoom again. - * Although the ScrollView will usually ignore it, it won't - * do so when the zoom scale clamps the zoom factor to its - * own allowed range. (#747410) - */ - g_signal_handlers_block_by_func (window->priv->zoom_scale, - eog_window_zoom_scale_value_changed_cb, - window); - update_zoom_scale (window); - g_signal_handlers_unblock_by_func (window->priv->zoom_scale, - eog_window_zoom_scale_value_changed_cb, - window); - action_zoom_in = g_action_map_lookup_action (G_ACTION_MAP (window), "zoom-in"); @@ -4214,60 +4170,6 @@ eog_window_view_previous_image_cb (EogScrollView *view, } static void -eog_window_zoom_scale_value_changed_cb (GtkRange *range, gpointer user_data) -{ - EogWindow *window; - EogWindowPrivate *priv; - - g_return_if_fail (EOG_IS_WINDOW (user_data)); - window = EOG_WINDOW (user_data); - priv = window->priv; - - if (priv->view) { - gdouble value; - - value = gtk_range_get_value (range); - eog_scroll_view_set_zoom (EOG_SCROLL_VIEW (priv->view), value); - } -} - -static void -eog_window_zoom_button_toggled_cb (GtkToggleButton *button, gpointer user_data) -{ - EogWindow *window; - EogWindowPrivate *priv; - GtkWidget *zoom_image; - gboolean toggled; - - g_return_if_fail (EOG_IS_WINDOW (user_data)); - window = EOG_WINDOW (user_data); - priv = window->priv; - - if (!priv->view) { - return; - } - - toggled = gtk_toggle_button_get_active (button); - if (toggled) { - zoom_image = gtk_image_new_from_icon_name ("zoom-out-symbolic", - GTK_ICON_SIZE_BUTTON); - gtk_widget_set_tooltip_text (GTK_WIDGET (button), - _("Fit the image to the window")); - eog_scroll_view_zoom_in (EOG_SCROLL_VIEW (priv->view), FALSE); - } else { - zoom_image = gtk_image_new_from_icon_name ("zoom-in-symbolic", - GTK_ICON_SIZE_BUTTON); - eog_scroll_view_set_zoom_mode (EOG_SCROLL_VIEW (priv->view), - EOG_ZOOM_MODE_SHRINK_TO_FIT); - gtk_widget_set_tooltip_text (GTK_WIDGET (button), - _("Shrink or enlarge the current image")); - } - - gtk_revealer_set_reveal_child (GTK_REVEALER (priv->zoom_revealer), toggled); - gtk_button_set_image (GTK_BUTTON (button), zoom_image); -} - -static void eog_window_construct_ui (EogWindow *window) { EogWindowPrivate *priv; @@ -4279,8 +4181,7 @@ eog_window_construct_ui (EogWindow *window) GtkWidget *popup_menu; GtkWidget *hpaned; GtkWidget *headerbar; - GtkWidget *zoom_button; - GtkWidget *zoom_image; + GtkWidget *zoom_entry; GtkWidget *menu_button; GtkWidget *menu_image; GtkWidget *fullscreen_button; @@ -4300,6 +4201,7 @@ eog_window_construct_ui (EogWindow *window) gtk_window_set_titlebar (GTK_WINDOW (window), headerbar); gtk_widget_show (headerbar); +#if 0 zoom_button = gtk_toggle_button_new (); zoom_image = gtk_image_new_from_icon_name ("zoom-in-symbolic", GTK_ICON_SIZE_BUTTON); @@ -4339,6 +4241,7 @@ eog_window_construct_ui (EogWindow *window) gtk_container_add (GTK_CONTAINER (priv->zoom_revealer), priv->zoom_scale); gtk_widget_show (priv->zoom_scale); +#endif menu_button = gtk_menu_button_new (); menu_image = gtk_image_new_from_icon_name ("open-menu-symbolic", @@ -4457,11 +4360,6 @@ eog_window_construct_ui (EogWindow *window) G_BINDING_SYNC_CREATE, _eog_zoom_shrink_to_boolean, NULL, NULL, NULL); - g_object_bind_property_full (action, "state", - zoom_button, "active", - G_BINDING_SYNC_CREATE, - _eog_zoom_button_variant_to_boolean, - NULL, NULL, NULL); } g_settings_bind (priv->view_settings, EOG_CONF_VIEW_SCROLL_WHEEL_ZOOM, priv->view, "scrollwheel-zoom", G_SETTINGS_BIND_GET); @@ -4492,6 +4390,11 @@ eog_window_construct_ui (EogWindow *window) gtk_widget_show_all (hpaned); + zoom_entry = eog_zoom_entry_new (EOG_SCROLL_VIEW (priv->view), + G_MENU (gtk_builder_get_object (builder, + "zoom-menu"))); + gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), zoom_entry); + priv->thumbview = g_object_ref (eog_thumb_view_new ()); /* giving shape to the view */ diff --git a/src/eog-zoom-entry.c b/src/eog-zoom-entry.c new file mode 100644 index 00000000..908f4ef3 --- /dev/null +++ b/src/eog-zoom-entry.c @@ -0,0 +1,335 @@ +/* + * eog-zoom-entry.c + * This file is part of eog + * + * Author: Felix Riemann <friemann@gnome.org> + * + * Copyright (C) 2017 GNOME Foundation + * + * Based on code (ev-zoom-action.c) by: + * - Carlos Garcia Campos <carlosgc@gnome.org> + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "eog-zoom-entry.h" +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <math.h> + +enum { + PROP_0, + PROP_SCROLL_VIEW, + PROP_MENU +}; + +typedef struct _EogZoomEntryPrivate { + GtkWidget *btn_zoom_in; + GtkWidget *btn_zoom_out; + GtkWidget *value_entry; + + EogScrollView *view; + + GMenu *menu; + GMenuModel *zoom_free_section; + GtkWidget *popup; + gboolean popup_shown; +} EogZoomEntryPrivate; + +struct _EogZoomEntry { + GtkBox box; + + EogZoomEntryPrivate *priv; +}; + +static const struct { + const gchar *name; + const double level; +} zoom_levels[] = { + { N_("33%"), (1.0/3.0) }, + { N_("50%"), (1.0/2.0) }, + { N_("100%"), 1.0 }, + { N_("133%"), (1.0/0.75) }, + { N_("200%"), 2.0 }, + { N_("500%"), 5.0 }, + { N_("1000%"), 10.0 }, + { N_("1500%"), 15.0 }, + { N_("2000%"), 20.0 } +}; + +G_DEFINE_TYPE_WITH_PRIVATE (EogZoomEntry, eog_zoom_entry, GTK_TYPE_BOX); + +//static guint signals[LAST_SIGNAL] = { 0 }; + +static void eog_zoom_entry_reset_zoom_level (EogZoomEntry *entry); +static void eog_zoom_entry_set_zoom_level (EogZoomEntry *entry, gdouble zoom); + + +static void +eog_zoom_entry_populate_free_zoom_section (EogZoomEntry *zoom_entry) +{ + guint i; + gint width = 0; + + for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) { + GMenuItem *item; + gint length; + + if (zoom_levels[i].level > EOG_SCROLL_VIEW_MAX_ZOOM_FACTOR) + break; + + length = g_utf8_strlen (zoom_levels[i].name, -1); + if (length > width) + width = length; + + item = g_menu_item_new (zoom_levels[i].name, NULL); + g_menu_item_set_action_and_target (item, "win.zoom-set", + "d", zoom_levels[i].level); + g_menu_append_item (G_MENU (zoom_entry->priv->zoom_free_section), item); + g_object_unref (item); + } +} + +static void +eog_zoom_entry_activate_cb (GtkEntry *gtk_entry, EogZoomEntry *entry) +{ + const gchar *text = gtk_entry_get_text (gtk_entry); + gchar *end_ptr = NULL; + double zoom_perc; + + if (!text || text[0] == '\0') { + eog_zoom_entry_reset_zoom_level (entry); + return; + } + + zoom_perc = g_strtod (text, &end_ptr); + if (end_ptr && end_ptr[0] != '\0' && end_ptr[0] != '%') { + eog_zoom_entry_reset_zoom_level (entry); + return; + } + + eog_scroll_view_set_zoom (entry->priv->view, zoom_perc / 100.0); +} + +static gboolean +focus_out_cb (EogZoomEntry *zoom_entry) +{ + eog_zoom_entry_reset_zoom_level (zoom_entry); + + return FALSE; +} + +static void +popup_menu_closed (GtkWidget *popup, + EogZoomEntry *zoom_entry) +{ + if (zoom_entry->priv->popup != popup) + return; + + zoom_entry->priv->popup_shown = FALSE; + zoom_entry->priv->popup = NULL; +} + +static GtkWidget* +get_popup (EogZoomEntry *zoom_entry) +{ + GdkRectangle rect; + + if (zoom_entry->priv->popup) + return zoom_entry->priv->popup; + + zoom_entry->priv->popup = gtk_popover_new_from_model (GTK_WIDGET (zoom_entry), + G_MENU_MODEL (zoom_entry->priv->menu)); + g_signal_connect (zoom_entry->priv->popup, "closed", + G_CALLBACK (popup_menu_closed), + zoom_entry); + gtk_entry_get_icon_area (GTK_ENTRY (zoom_entry->priv->value_entry), + GTK_ENTRY_ICON_SECONDARY, &rect); + gtk_popover_set_pointing_to (GTK_POPOVER (zoom_entry->priv->popup), &rect); + gtk_popover_set_position (GTK_POPOVER (zoom_entry->priv->popup), GTK_POS_BOTTOM); + + return zoom_entry->priv->popup; +} + +static void +eog_zoom_entry_icon_press_cb (GtkEntry *entry, GtkEntryIconPosition icon_pos, + GdkEvent *event, gpointer data) +{ + EogZoomEntry *zoom_entry; + guint button; + + g_return_if_fail (EOG_IS_ZOOM_ENTRY (data)); + g_return_if_fail (icon_pos == GTK_ENTRY_ICON_SECONDARY); + + if (!gdk_event_get_button (event, &button) || button != GDK_BUTTON_PRIMARY) + return; + + zoom_entry = EOG_ZOOM_ENTRY (data); + + gtk_widget_show (get_popup (zoom_entry)); + zoom_entry->priv->popup_shown = TRUE; +} + +static void +eog_zoom_entry_view_zoom_changed_cb (EogScrollView *view, gdouble zoom, + gpointer data) +{ + EogZoomEntry *zoom_entry = EOG_ZOOM_ENTRY (data); + + eog_zoom_entry_set_zoom_level (zoom_entry, zoom); +} + +static void +eog_zoom_entry_constructed (GObject *object) +{ + EogZoomEntry *zoom_entry = EOG_ZOOM_ENTRY (object); + + G_OBJECT_CLASS (eog_zoom_entry_parent_class)->constructed (object); + + g_signal_connect (zoom_entry->priv->view, + "zoom-changed", + G_CALLBACK (eog_zoom_entry_view_zoom_changed_cb), + zoom_entry); + + zoom_entry->priv->zoom_free_section = + g_menu_model_get_item_link (G_MENU_MODEL (zoom_entry->priv->menu), + 1, G_MENU_LINK_SECTION); + eog_zoom_entry_populate_free_zoom_section (zoom_entry); +} + +static void +eog_zoom_entry_finalize (GObject *object) +{ + EogZoomEntry *zoom_entry = EOG_ZOOM_ENTRY (object); + + g_clear_object (&zoom_entry->priv->menu); + g_clear_object (&zoom_entry->priv->zoom_free_section); + g_clear_object (&zoom_entry->priv->view); + + G_OBJECT_CLASS (eog_zoom_entry_parent_class)->finalize (object); +} + +static void +eog_zoom_entry_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EogZoomEntry *zoom_entry = EOG_ZOOM_ENTRY (object); + + switch (prop_id) { + case PROP_SCROLL_VIEW: + zoom_entry->priv->view = g_value_dup_object (value); + break; + case PROP_MENU: + zoom_entry->priv->menu = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +eog_zoom_entry_set_zoom_level (EogZoomEntry *entry, gdouble zoom) +{ + gchar *zoom_str; + gdouble zoom_percent; + + /* Mimic the zoom calculation from EogWindow to get matching displays */ + zoom = CLAMP (zoom, EOG_SCROLL_VIEW_MIN_ZOOM_FACTOR, + EOG_SCROLL_VIEW_MAX_ZOOM_FACTOR); + zoom_percent = floor (zoom * 100. + 0.5); + zoom_str = g_strdup_printf ("%d%%", (gint) zoom_percent); + gtk_entry_set_text (GTK_ENTRY (entry->priv->value_entry), zoom_str); + g_free (zoom_str); +} + +static void +eog_zoom_entry_reset_zoom_level (EogZoomEntry *entry) +{ + const gdouble zoom = eog_scroll_view_get_zoom (entry->priv->view); + eog_zoom_entry_set_zoom_level (entry, zoom); +} + +static void +eog_zoom_entry_class_init (EogZoomEntryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *wklass = GTK_WIDGET_CLASS (klass); + + object_class->constructed = eog_zoom_entry_constructed; + object_class->set_property = eog_zoom_entry_set_property; + object_class->finalize = eog_zoom_entry_finalize; + + gtk_widget_class_set_template_from_resource (wklass, + "/org/gnome/eog/ui/eog-zoom-entry.ui"); + gtk_widget_class_bind_template_child_private (wklass, + EogZoomEntry, + btn_zoom_in); + gtk_widget_class_bind_template_child_private (wklass, + EogZoomEntry, + btn_zoom_out); + gtk_widget_class_bind_template_child_private (wklass, + EogZoomEntry, + value_entry); + + gtk_widget_class_bind_template_callback (wklass, + eog_zoom_entry_activate_cb); + gtk_widget_class_bind_template_callback (wklass, + eog_zoom_entry_icon_press_cb); + + g_object_class_install_property (object_class, PROP_SCROLL_VIEW, + g_param_spec_object ("scroll-view", + "EogScrollView", + "The EogScrollView to work with", + EOG_TYPE_SCROLL_VIEW, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_MENU, + g_param_spec_object ("menu", + "Menu", + "The zoom popup menu", + G_TYPE_MENU, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +eog_zoom_entry_init (EogZoomEntry *entry) +{ + entry->priv = eog_zoom_entry_get_instance_private (entry); + gtk_widget_init_template (GTK_WIDGET (entry)); + + g_signal_connect_swapped (entry->priv->value_entry, "focus-out-event", + G_CALLBACK (focus_out_cb), + entry); +} + +GtkWidget* eog_zoom_entry_new(EogScrollView *view, GMenu *menu) +{ + g_return_val_if_fail (EOG_IS_SCROLL_VIEW (view), NULL); + g_return_val_if_fail (G_IS_MENU (menu), NULL); + + return g_object_new (EOG_TYPE_ZOOM_ENTRY, + "scroll-view", view, + "menu", menu, + NULL); +} diff --git a/src/eog-zoom-entry.h b/src/eog-zoom-entry.h new file mode 100644 index 00000000..a4ff7169 --- /dev/null +++ b/src/eog-zoom-entry.h @@ -0,0 +1,41 @@ +/* + * eog-zoom-entry.h + * This file is part of eog + * + * Author: Felix Riemann <friemann@gnome.org> + * + * Copyright (C) 2017 GNOME Foundation + * + * Based on code (ev-zoom-action.c) by: + * - Carlos Garcia Campos <carlosgc@gnome.org> + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef EOG_ZOOM_ENTRY_H +#define EOG_ZOOM_ENTRY_H + +#include <glib.h> +#include <glib-object.h> +#include <gtk/gtk.h> + +#include "eog-scroll-view.h" + +#define EOG_TYPE_ZOOM_ENTRY (eog_zoom_entry_get_type()) + +G_DECLARE_FINAL_TYPE(EogZoomEntry, eog_zoom_entry, EOG, ZOOM_ENTRY, GtkBox); + +GtkWidget* eog_zoom_entry_new (EogScrollView *view, GMenu *menu); + +#endif /* EOG_ZOOM_ENTRY_H */ diff --git a/src/eog.gresource.xml b/src/eog.gresource.xml index a8194457..79f80716 100644 --- a/src/eog.gresource.xml +++ b/src/eog.gresource.xml @@ -8,6 +8,7 @@ <file compressed="true" preprocess="xml-stripblanks">eog-preferences-dialog.ui</file> <file compressed="true" preprocess="xml-stripblanks">fullscreen-toolbar.ui</file> <file compressed="true" preprocess="xml-stripblanks">metadata-sidebar.ui</file> + <file compressed="true" preprocess="xml-stripblanks">eog-zoom-entry.ui</file> <file>pixmaps/thumbnail-frame.png</file> <file compressed="true" preprocess="xml-stripblanks">popup-menus.ui</file> </gresource> |