From bd2e929b77b4bbf9eae7b96986fa441380140d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Sun, 17 Jul 2022 12:37:32 +0200 Subject: [PATCH] Add ability to keep zoom/position when browsing --- README.adoc | 2 + fiv-view.c | 29 +++++- fiv-view.h | 3 +- fiv.c | 6 +- resources/pin2-symbolic.svg | 152 ++++++++++++++++++++++++++++++ resources/resources.gresource.xml | 1 + 6 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 resources/pin2-symbolic.svg diff --git a/README.adoc b/README.adoc index d245a0f..965cb62 100644 --- a/README.adoc +++ b/README.adoc @@ -14,6 +14,8 @@ Features - Employs high-performance file format libraries: Wuffs and libjpeg-turbo. - Makes use of 30-bit X.org visuals, whenever it's possible and appropriate. - Has a notion of pages, and tries to load all included content within files. + - Can keep the zoom and position when browsing, to help with comparing + zoomed-in images. Explicit non-goals ------------------ diff --git a/fiv-view.c b/fiv-view.c index 01bedc8..8a42d04 100644 --- a/fiv-view.c +++ b/fiv-view.c @@ -67,6 +67,7 @@ struct _FivView { bool checkerboard : 1; ///< Show checkerboard background bool enhance : 1; ///< Try to enhance picture data bool scale_to_fit : 1; ///< Image no larger than the allocation + bool fixate : 1; ///< Keep zoom and position double scale; ///< Scaling factor double drag_start[2]; ///< Adjustment values for drag origin @@ -125,6 +126,7 @@ enum { PROP_MESSAGES = 1, PROP_SCALE, PROP_SCALE_TO_FIT, + PROP_FIXATE, PROP_ENABLE_CMS, PROP_FILTER, PROP_CHECKERBOARD, @@ -254,6 +256,9 @@ fiv_view_get_property( case PROP_SCALE_TO_FIT: g_value_set_boolean(value, self->scale_to_fit); break; + case PROP_FIXATE: + g_value_set_boolean(value, self->fixate); + break; case PROP_ENABLE_CMS: g_value_set_boolean(value, self->enable_cms); break; @@ -311,6 +316,10 @@ fiv_view_set_property( if (self->scale_to_fit != g_value_get_boolean(value)) fiv_view_command(self, FIV_VIEW_COMMAND_TOGGLE_SCALE_TO_FIT); break; + case PROP_FIXATE: + if (self->fixate != g_value_get_boolean(value)) + fiv_view_command(self, FIV_VIEW_COMMAND_TOGGLE_FIXATE); + break; case PROP_ENABLE_CMS: if (self->enable_cms != g_value_get_boolean(value)) fiv_view_command(self, FIV_VIEW_COMMAND_TOGGLE_CMS); @@ -636,7 +645,12 @@ static gboolean set_scale_to_fit(FivView *self, bool scale_to_fit) { if (self->scale_to_fit != scale_to_fit) { - self->scale_to_fit = scale_to_fit; + if ((self->scale_to_fit = scale_to_fit)) { + self->fixate = false; + g_object_notify_by_pspec( + G_OBJECT(self), view_properties[PROP_FIXATE]); + } + g_object_notify_by_pspec( G_OBJECT(self), view_properties[PROP_SCALE_TO_FIT]); gtk_widget_queue_resize(GTK_WIDGET(self)); @@ -1270,6 +1284,9 @@ fiv_view_class_init(FivViewClass *klass) view_properties[PROP_SCALE_TO_FIT] = g_param_spec_boolean( "scale-to-fit", "Scale to fit", "Scale images down to fit the window", TRUE, G_PARAM_READWRITE); + view_properties[PROP_FIXATE] = g_param_spec_boolean( + "fixate", "Fixate", "Keep zoom and position", + FALSE, G_PARAM_READWRITE); view_properties[PROP_ENABLE_CMS] = g_param_spec_boolean( "enable-cms", "Enable CMS", "Enable color management", TRUE, G_PARAM_READWRITE); @@ -1443,7 +1460,10 @@ fiv_view_set_uri(FivView *self, const char *uri) self->frame = self->page = NULL; self->image = surface; switch_page(self, self->image); - set_scale_to_fit(self, true); + + // Otherwise, adjustment values and zoom are retained implicitly. + if (!self->fixate) + set_scale_to_fit(self, true); g_free(self->uri); self->uri = g_strdup(uri); @@ -1592,5 +1612,10 @@ fiv_view_command(FivView *self, FivViewCommand command) set_scale_to_fit_height(self); break; case FIV_VIEW_COMMAND_TOGGLE_SCALE_TO_FIT: set_scale_to_fit(self, !self->scale_to_fit); + break; case FIV_VIEW_COMMAND_TOGGLE_FIXATE: + if ((self->fixate = !self->fixate)) + set_scale_to_fit(self, false); + g_object_notify_by_pspec( + G_OBJECT(self), view_properties[PROP_FIXATE]); } } diff --git a/fiv-view.h b/fiv-view.h index c2d8b8b..7f4e3a3 100644 --- a/fiv-view.h +++ b/fiv-view.h @@ -60,7 +60,8 @@ typedef enum _FivViewCommand { XX(FIV_VIEW_COMMAND_ZOOM_1, "zoom-1") \ XX(FIV_VIEW_COMMAND_FIT_WIDTH, "fit-width") \ XX(FIV_VIEW_COMMAND_FIT_HEIGHT, "fit-height") \ - XX(FIV_VIEW_COMMAND_TOGGLE_SCALE_TO_FIT, "toggle-scale-to-fit") + XX(FIV_VIEW_COMMAND_TOGGLE_SCALE_TO_FIT, "toggle-scale-to-fit") \ + XX(FIV_VIEW_COMMAND_TOGGLE_FIXATE, "toggle-fixate") #define XX(constant, name) constant, FIV_VIEW_COMMANDS(XX) #undef XX diff --git a/fiv.c b/fiv.c index dccc85f..73a996b 100644 --- a/fiv.c +++ b/fiv.c @@ -497,13 +497,13 @@ show_about_dialog(GtkWidget *parent) XX(PLAY_PAUSE, B("media-playback-start-symbolic", "Pause")) \ XX(SEEK_FORWARD, B("media-seek-forward-symbolic", "Next frame")) \ XX(S3, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL)) \ + XX(FIXATE, T("pin2-symbolic", "Keep zoom and position")) \ XX(MINUS, B("zoom-out-symbolic", "Zoom out")) \ XX(SCALE, gtk_label_new("")) \ XX(PLUS, B("zoom-in-symbolic", "Zoom in")) \ XX(ONE, B("zoom-original-symbolic", "Original size")) \ XX(FIT, T("zoom-fit-best-symbolic", "Scale to fit")) \ XX(S4, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL)) \ - /* XX(PIN, B("view-pin-symbolic", "Keep view configuration")) */ \ /* Or perhaps "blur-symbolic", also in the extended set. */ \ XX(COLOR, T("preferences-color-symbolic", "Color management")) \ XX(SMOOTH, T("blend-tool-symbolic", "Smooth scaling")) \ @@ -1523,6 +1523,7 @@ make_view_toolbar(void) toolbar_command(TOOLBAR_PLUS, FIV_VIEW_COMMAND_ZOOM_IN); toolbar_command(TOOLBAR_ONE, FIV_VIEW_COMMAND_ZOOM_1); toolbar_toggler(TOOLBAR_FIT, "scale-to-fit"); + toolbar_toggler(TOOLBAR_FIXATE, "fixate"); toolbar_toggler(TOOLBAR_COLOR, "enable-cms"); toolbar_toggler(TOOLBAR_SMOOTH, "filter"); toolbar_toggler(TOOLBAR_CHECKERBOARD, "checkerboard"); @@ -1541,6 +1542,8 @@ make_view_toolbar(void) G_CALLBACK(on_notify_view_playing), NULL); g_signal_connect(g.view, "notify::scale-to-fit", G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_FIT]); + g_signal_connect(g.view, "notify::fixate", + G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_FIXATE]); g_signal_connect(g.view, "notify::enable-cms", G_CALLBACK(on_notify_view_boolean), g.toolbar[TOOLBAR_COLOR]); g_signal_connect(g.view, "notify::filter", @@ -1553,6 +1556,7 @@ make_view_toolbar(void) g_object_notify(G_OBJECT(g.view), "scale"); g_object_notify(G_OBJECT(g.view), "playing"); g_object_notify(G_OBJECT(g.view), "scale-to-fit"); + g_object_notify(G_OBJECT(g.view), "fixate"); g_object_notify(G_OBJECT(g.view), "enable-cms"); g_object_notify(G_OBJECT(g.view), "filter"); g_object_notify(G_OBJECT(g.view), "checkerboard"); diff --git a/resources/pin2-symbolic.svg b/resources/pin2-symbolic.svg new file mode 100644 index 0000000..5b5fdab --- /dev/null +++ b/resources/pin2-symbolic.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources.gresource.xml b/resources/resources.gresource.xml index 092aed1..f52bb76 100644 --- a/resources/resources.gresource.xml +++ b/resources/resources.gresource.xml @@ -10,5 +10,6 @@ checkerboard-symbolic.svg heal-symbolic.svg info-symbolic.svg + pin2-symbolic.svg