[gnome-photos] Prepare the zoom-* GActions for touch gestures
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos] Prepare the zoom-* GActions for touch gestures
- Date: Tue, 17 Oct 2017 08:55:30 +0000 (UTC)
commit de6a45480949d2ed66b51b799f814ca325afc150
Author: Debarshi Ray <debarshir gnome org>
Date: Sat Oct 14 08:59:31 2017 +0200
Prepare the zoom-* GActions for touch gestures
So far the zooming interface provided by the zoom-in/out GActions was
based on the notion of incremental steps. Each step represents one
press/release of an accelerator key or mouse button, or one notch on
the mouse's scroll wheel. A new zoom value is calculated for each step.
However, touch gestures are different.
Once the touch points start moving, the changing distance between them
is indicated as a ratio to the initial distance when the gesture was
initiated. This makes it necessary to keep track of the initial
distance. A pair of zoom-begin and zoom-end GActions were added for
this.
With touch, the content needs to stick to the touch points while the
gesture is active. This means that the ratio of the new and initial
zoom values should track the ratio of the distance between the touch
touch points and their initial distance. Moreover, touch events have a
finer granularity than keyboard accelerators, mouse buttons or the
scroll wheel. Therefore, changes in zoom levels are not animated when
reacting to touch.
https://bugzilla.gnome.org/show_bug.cgi?id=783922
src/photos-application.c | 12 +++++
src/photos-preview-view.c | 105 ++++++++++++++++++++++++++++++++++++++++++--
src/photos-utils.h | 3 +-
3 files changed, 114 insertions(+), 6 deletions(-)
---
diff --git a/src/photos-application.c b/src/photos-application.c
index 4957d98..4fe57c6 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -111,7 +111,9 @@ struct _PhotosApplication
GSimpleAction *set_ss_action;
GSimpleAction *share_action;
GSimpleAction *sharpen_action;
+ GSimpleAction *zoom_begin_action;
GSimpleAction *zoom_best_fit_action;
+ GSimpleAction *zoom_end_action;
GSimpleAction *zoom_in_action;
GSimpleAction *zoom_out_action;
GtkWidget *main_window;
@@ -375,6 +377,7 @@ photos_application_actions_update (PhotosApplication *self)
selection_mode = photos_utils_get_selection_mode ();
g_simple_action_set_enabled (self->zoom_best_fit_action, FALSE);
+ g_simple_action_set_enabled (self->zoom_end_action, FALSE);
g_simple_action_set_enabled (self->zoom_out_action, FALSE);
enable = (mode == PHOTOS_WINDOW_MODE_EDIT);
@@ -419,6 +422,7 @@ photos_application_actions_update (PhotosApplication *self)
g_simple_action_set_enabled (self->gear_action, enable);
g_simple_action_set_enabled (self->set_bg_action, enable);
g_simple_action_set_enabled (self->set_ss_action, enable);
+ g_simple_action_set_enabled (self->zoom_begin_action, enable);
g_simple_action_set_enabled (self->zoom_in_action, enable);
enable = ((load_state == PHOTOS_LOAD_STATE_FINISHED && mode == PHOTOS_WINDOW_MODE_PREVIEW)
@@ -2060,9 +2064,15 @@ photos_application_startup (GApplication *application)
self->sharpen_action = g_simple_action_new ("sharpen-current", G_VARIANT_TYPE_DOUBLE);
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (self->sharpen_action));
+ self->zoom_begin_action = g_simple_action_new ("zoom-begin", G_VARIANT_TYPE_VARDICT);
+ g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (self->zoom_begin_action));
+
self->zoom_best_fit_action = g_simple_action_new ("zoom-best-fit", NULL);
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (self->zoom_best_fit_action));
+ self->zoom_end_action = g_simple_action_new ("zoom-end", G_VARIANT_TYPE_VARDICT);
+ g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (self->zoom_end_action));
+
self->zoom_in_action = g_simple_action_new ("zoom-in", G_VARIANT_TYPE_VARDICT);
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (self->zoom_in_action));
@@ -2182,7 +2192,9 @@ photos_application_dispose (GObject *object)
g_clear_object (&self->set_ss_action);
g_clear_object (&self->share_action);
g_clear_object (&self->sharpen_action);
+ g_clear_object (&self->zoom_begin_action);
g_clear_object (&self->zoom_best_fit_action);
+ g_clear_object (&self->zoom_end_action);
g_clear_object (&self->zoom_in_action);
g_clear_object (&self->zoom_out_action);
g_clear_object (&self->shr_pnt_mngr);
diff --git a/src/photos-preview-view.c b/src/photos-preview-view.c
index e354854..c8a99e1 100644
--- a/src/photos-preview-view.c
+++ b/src/photos-preview-view.c
@@ -47,7 +47,9 @@
struct _PhotosPreviewView
{
GtkBin parent_instance;
+ GAction *zoom_begin_action;
GAction *zoom_best_fit_action;
+ GAction *zoom_end_action;
GAction *zoom_in_action;
GAction *zoom_out_action;
GCancellable *cancellable;
@@ -63,6 +65,7 @@ struct _PhotosPreviewView
gboolean grabbed;
gdouble event_x_last;
gdouble event_y_last;
+ gdouble zoom_begin;
gdouble zoom_best_fit;
};
@@ -76,6 +79,7 @@ enum
G_DEFINE_TYPE (PhotosPreviewView, photos_preview_view, GTK_TYPE_BIN);
+static const gdouble ZOOM_BEST_FIT_FACTOR_TOUCH = 0.6;
static const gdouble ZOOM_FACTOR_1 = 2.8561;
static const gdouble ZOOM_FACTOR_2 = 1.69;
static const gdouble ZOOM_FACTOR_3 = 1.3;
@@ -836,6 +840,29 @@ photos_preview_view_window_mode_changed (PhotosPreviewView *self, PhotosWindowMo
static void
+photos_preview_view_zoom_begin (PhotosPreviewView *self, GVariant *parameter)
+{
+ GtkWidget *view;
+ GtkWidget *view_container;
+ PhotosZoomEvent event;
+
+ event = photos_utils_get_zoom_event (parameter);
+ g_return_if_fail (event == PHOTOS_ZOOM_EVENT_TOUCH);
+
+ view_container = gtk_stack_get_visible_child (GTK_STACK (self->stack));
+ view = photos_preview_view_get_view_from_view_container (view_container);
+ self->zoom_begin = photos_image_view_get_zoom (PHOTOS_IMAGE_VIEW (view));
+
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_begin_action), FALSE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_best_fit_action), TRUE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_end_action), TRUE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_out_action), TRUE);
+ photos_preview_nav_buttons_set_auto_hide (self->nav_buttons, FALSE);
+ photos_preview_nav_buttons_set_show_navigation (self->nav_buttons, FALSE);
+}
+
+
+static void
photos_preview_view_zoom_best_fit (PhotosPreviewView *self)
{
GtkWidget *view;
@@ -851,6 +878,37 @@ photos_preview_view_zoom_best_fit (PhotosPreviewView *self)
}
+static void
+photos_preview_view_zoom_end (PhotosPreviewView *self, GVariant *parameter)
+{
+ GtkWidget *view;
+ GtkWidget *view_container;
+ PhotosZoomEvent event;
+ gdouble zoom;
+
+ event = photos_utils_get_zoom_event (parameter);
+ g_return_if_fail (event == PHOTOS_ZOOM_EVENT_TOUCH);
+
+ view_container = gtk_stack_get_visible_child (GTK_STACK (self->stack));
+ view = photos_preview_view_get_view_from_view_container (view_container);
+ zoom = photos_image_view_get_zoom (PHOTOS_IMAGE_VIEW (view));
+
+ if (zoom < self->zoom_best_fit || photos_utils_equal_double (self->zoom_best_fit, zoom))
+ {
+ photos_image_view_set_best_fit (PHOTOS_IMAGE_VIEW (view), TRUE, TRUE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_best_fit_action), FALSE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_out_action), FALSE);
+ }
+
+ self->zoom_begin = 0.0;
+
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_begin_action), TRUE);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_end_action), FALSE);
+ photos_preview_nav_buttons_set_auto_hide (self->nav_buttons, TRUE);
+ photos_preview_nav_buttons_set_show_navigation (self->nav_buttons, TRUE);
+}
+
+
static gdouble
photos_preview_view_calculate_zoom_for_non_touch (PhotosPreviewView *self,
gdouble delta,
@@ -865,6 +923,7 @@ photos_preview_view_calculate_zoom_for_non_touch (PhotosPreviewView *self,
gdouble zoom_factor_for_delta;
g_return_val_if_fail (event != PHOTOS_ZOOM_EVENT_NONE, 0.0);
+ g_return_val_if_fail (event != PHOTOS_ZOOM_EVENT_TOUCH, 0.0);
g_return_val_if_fail ((event == PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR && photos_utils_equal_double
(delta, 1.0))
|| (event == PHOTOS_ZOOM_EVENT_MOUSE_CLICK && photos_utils_equal_double (delta, 1.0))
|| (event == PHOTOS_ZOOM_EVENT_SCROLL && delta >= 0.0),
@@ -887,6 +946,7 @@ photos_preview_view_calculate_zoom_for_non_touch (PhotosPreviewView *self,
break;
case PHOTOS_ZOOM_EVENT_NONE:
+ case PHOTOS_ZOOM_EVENT_TOUCH:
default:
g_assert_not_reached ();
break;
@@ -910,6 +970,7 @@ photos_preview_view_zoom_in (PhotosPreviewView *self, GVariant *parameter)
GtkWidget *view;
GtkWidget *view_container;
PhotosZoomEvent event;
+ gboolean enable_animation;
gdouble delta;
gdouble zoom;
@@ -921,16 +982,23 @@ photos_preview_view_zoom_in (PhotosPreviewView *self, GVariant *parameter)
delta = photos_utils_get_zoom_delta (parameter);
g_return_if_fail ((event == PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR && photos_utils_equal_double (delta,
1.0))
|| (event == PHOTOS_ZOOM_EVENT_MOUSE_CLICK && photos_utils_equal_double (delta, 1.0))
- || (event == PHOTOS_ZOOM_EVENT_SCROLL && delta >= 0.0));
+ || (event == PHOTOS_ZOOM_EVENT_SCROLL && delta >= 0.0)
+ || (event == PHOTOS_ZOOM_EVENT_TOUCH && delta >= 0.0 && self->zoom_begin > 0.0));
switch (event)
{
case PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR:
case PHOTOS_ZOOM_EVENT_MOUSE_CLICK:
case PHOTOS_ZOOM_EVENT_SCROLL:
+ enable_animation = TRUE;
zoom = photos_preview_view_calculate_zoom_for_non_touch (self, delta, event, TRUE);
break;
+ case PHOTOS_ZOOM_EVENT_TOUCH:
+ enable_animation = FALSE;
+ zoom = self->zoom_begin * delta;
+ break;
+
case PHOTOS_ZOOM_EVENT_NONE:
default:
g_assert_not_reached ();
@@ -939,7 +1007,7 @@ photos_preview_view_zoom_in (PhotosPreviewView *self, GVariant *parameter)
view_container = gtk_stack_get_visible_child (GTK_STACK (self->stack));
view = photos_preview_view_get_view_from_view_container (view_container);
- photos_image_view_set_zoom (PHOTOS_IMAGE_VIEW (view), zoom, TRUE);
+ photos_image_view_set_zoom (PHOTOS_IMAGE_VIEW (view), zoom, enable_animation);
g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_best_fit_action), TRUE);
g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_out_action), TRUE);
@@ -954,8 +1022,11 @@ photos_preview_view_zoom_out (PhotosPreviewView *self, GVariant *parameter)
GtkWidget *view;
GtkWidget *view_container;
PhotosZoomEvent event;
+ gboolean enable_animation;
gdouble delta;
gdouble zoom;
+ gdouble zoom_best_fit;
+ gdouble zoom_best_fit_factor;
g_return_if_fail (self->zoom_best_fit > 0.0);
@@ -965,14 +1036,23 @@ photos_preview_view_zoom_out (PhotosPreviewView *self, GVariant *parameter)
delta = photos_utils_get_zoom_delta (parameter);
g_return_if_fail ((event == PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR && photos_utils_equal_double (delta,
1.0))
|| (event == PHOTOS_ZOOM_EVENT_MOUSE_CLICK && photos_utils_equal_double (delta, 1.0))
- || (event == PHOTOS_ZOOM_EVENT_SCROLL && delta >= 0.0));
+ || (event == PHOTOS_ZOOM_EVENT_SCROLL && delta >= 0.0)
+ || (event == PHOTOS_ZOOM_EVENT_TOUCH && delta >= 0.0 && self->zoom_begin > 0.0));
switch (event)
{
case PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR:
case PHOTOS_ZOOM_EVENT_MOUSE_CLICK:
case PHOTOS_ZOOM_EVENT_SCROLL:
+ enable_animation = TRUE;
zoom = photos_preview_view_calculate_zoom_for_non_touch (self, delta, event, FALSE);
+ zoom_best_fit_factor = 1.0;
+ break;
+
+ case PHOTOS_ZOOM_EVENT_TOUCH:
+ enable_animation = FALSE;
+ zoom = self->zoom_begin * delta;
+ zoom_best_fit_factor = ZOOM_BEST_FIT_FACTOR_TOUCH;
break;
case PHOTOS_ZOOM_EVENT_NONE:
@@ -984,7 +1064,8 @@ photos_preview_view_zoom_out (PhotosPreviewView *self, GVariant *parameter)
view_container = gtk_stack_get_visible_child (GTK_STACK (self->stack));
view = photos_preview_view_get_view_from_view_container (view_container);
- if (zoom < self->zoom_best_fit || photos_utils_equal_double (self->zoom_best_fit, zoom))
+ zoom_best_fit = self->zoom_best_fit * zoom_best_fit_factor;
+ if (zoom < zoom_best_fit || photos_utils_equal_double (zoom_best_fit, zoom))
{
photos_image_view_set_best_fit (PHOTOS_IMAGE_VIEW (view), TRUE, TRUE);
g_simple_action_set_enabled (G_SIMPLE_ACTION (self->zoom_best_fit_action), FALSE);
@@ -994,7 +1075,7 @@ photos_preview_view_zoom_out (PhotosPreviewView *self, GVariant *parameter)
}
else
{
- photos_image_view_set_zoom (PHOTOS_IMAGE_VIEW (view), zoom, TRUE);
+ photos_image_view_set_zoom (PHOTOS_IMAGE_VIEW (view), zoom, enable_animation);
}
}
@@ -1156,6 +1237,13 @@ photos_preview_view_init (PhotosPreviewView *self)
action = g_action_map_lookup_action (G_ACTION_MAP (app), "sharpen-current");
g_signal_connect_object (action, "activate", G_CALLBACK (photos_preview_view_sharpen), self,
G_CONNECT_SWAPPED);
+ self->zoom_begin_action = g_action_map_lookup_action (G_ACTION_MAP (app), "zoom-begin");
+ g_signal_connect_object (self->zoom_begin_action,
+ "activate",
+ G_CALLBACK (photos_preview_view_zoom_begin),
+ self,
+ G_CONNECT_SWAPPED);
+
self->zoom_best_fit_action = g_action_map_lookup_action (G_ACTION_MAP (app), "zoom-best-fit");
g_signal_connect_object (self->zoom_best_fit_action,
"activate",
@@ -1163,6 +1251,13 @@ photos_preview_view_init (PhotosPreviewView *self)
self,
G_CONNECT_SWAPPED);
+ self->zoom_end_action = g_action_map_lookup_action (G_ACTION_MAP (app), "zoom-end");
+ g_signal_connect_object (self->zoom_end_action,
+ "activate",
+ G_CALLBACK (photos_preview_view_zoom_end),
+ self,
+ G_CONNECT_SWAPPED);
+
self->zoom_in_action = g_action_map_lookup_action (G_ACTION_MAP (app), "zoom-in");
g_signal_connect_object (self->zoom_in_action,
"activate",
diff --git a/src/photos-utils.h b/src/photos-utils.h
index e40ef2a..0956f58 100644
--- a/src/photos-utils.h
+++ b/src/photos-utils.h
@@ -57,7 +57,8 @@ typedef enum
PHOTOS_ZOOM_EVENT_NONE,
PHOTOS_ZOOM_EVENT_KEYBOARD_ACCELERATOR,
PHOTOS_ZOOM_EVENT_MOUSE_CLICK,
- PHOTOS_ZOOM_EVENT_SCROLL
+ PHOTOS_ZOOM_EVENT_SCROLL,
+ PHOTOS_ZOOM_EVENT_TOUCH
} PhotosZoomEvent;
GdkPixbuf *photos_utils_center_pixbuf (GdkPixbuf *pixbuf, gint size);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]