[gnome-builder/wip/chergert/three-finger-swipe] layout: stub out three-finger-swipe
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/three-finger-swipe] layout: stub out three-finger-swipe
- Date: Fri, 13 Oct 2017 10:02:41 +0000 (UTC)
commit a71b530f4d1a168beab574a7928b5cf9c01affd8
Author: Christian Hergert <chergert redhat com>
Date: Fri Oct 13 01:15:24 2017 -0700
layout: stub out three-finger-swipe
This starts on plumbing to use three-finger-swipe to move
IdeLayoutView left/right.
Nothing reacts to the move yet, but it's sort of fun to play
around with.
src/libide/layout/ide-layout-stack.c | 186 ++++++++++++++++++++++++++++-
src/libide/layout/ide-layout-stack.ui | 211 +++++++++++++++++----------------
2 files changed, 287 insertions(+), 110 deletions(-)
---
diff --git a/src/libide/layout/ide-layout-stack.c b/src/libide/layout/ide-layout-stack.c
index 75b2193..c5622fe 100644
--- a/src/libide/layout/ide-layout-stack.c
+++ b/src/libide/layout/ide-layout-stack.c
@@ -54,12 +54,26 @@ typedef struct
GPtrArray *in_transition;
PeasExtensionSet *addins;
+ /*
+ * Our gestures are used to do interactive moves when the user
+ * does a three finger swipe. We create the dummy gesture to
+ * ensure things work, because it for some reason does not without
+ * the dummy gesture set.
+ *
+ * https://bugzilla.gnome.org/show_bug.cgi?id=788914
+ */
+ GtkGesture *dummy;
+ GtkGesture *pan;
+ DzlBoxTheatric *pan_theatric;
+ IdeLayoutView *pan_view;
+
/* Template references */
DzlBox *empty_state;
DzlEmptyState *failed_state;
IdeLayoutStackHeader *header;
GtkStack *stack;
GtkStack *top_stack;
+ GtkEventBox *event_box;
} IdeLayoutStackPrivate;
typedef struct
@@ -91,6 +105,13 @@ G_DEFINE_TYPE_WITH_CODE (IdeLayoutStack, ide_layout_stack, GTK_TYPE_BOX,
static GParamSpec *properties [N_PROPS];
static guint signals [N_SIGNALS];
+static inline gboolean
+is_uninitialized (GtkAllocation *alloc)
+{
+ return (alloc->x == -1 && alloc->y == -1 &&
+ alloc->width == 1 && alloc->height == 1);
+}
+
static void
ide_layout_stack_view_failed (IdeLayoutStack *self,
GParamSpec *pspec,
@@ -388,6 +409,130 @@ ide_layout_stack_addin_removed (PeasExtensionSet *set,
ide_layout_stack_addin_unload (addin, self);
}
+static gboolean
+ide_layout_stack_pan_begin (IdeLayoutStack *self,
+ GdkEventSequence *sequence,
+ GtkGesturePan *gesture)
+{
+ IdeLayoutStackPrivate *priv = ide_layout_stack_get_instance_private (self);
+ GtkAllocation alloc;
+ cairo_surface_t *surface = NULL;
+ IdeLayoutView *view;
+ GdkWindow *window;
+ GtkWidget *grid;
+ cairo_t *cr;
+ gdouble x, y;
+ gboolean enable_animations;
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_assert (GTK_IS_GESTURE_PAN (gesture));
+ g_assert (priv->pan_theatric == NULL);
+
+ view = ide_layout_stack_get_visible_child (self);
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &alloc);
+
+ g_object_get (gtk_settings_get_default (),
+ "gtk-enable-animations", &enable_animations,
+ NULL);
+
+ if (sequence != NULL ||
+ view == NULL ||
+ !enable_animations ||
+ is_uninitialized (&alloc) ||
+ NULL == (window = gtk_widget_get_window (GTK_WIDGET (view))) ||
+ NULL == (surface = gdk_window_create_similar_surface (window,
+ CAIRO_CONTENT_COLOR,
+ alloc.width,
+ alloc.height)))
+ {
+ if (sequence != NULL)
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+ return FALSE;
+ }
+
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y);
+
+ cr = cairo_create (surface);
+ gtk_widget_draw (GTK_WIDGET (view), cr);
+ cairo_destroy (cr);
+
+ grid = gtk_widget_get_ancestor (GTK_WIDGET (self), IDE_TYPE_LAYOUT_GRID_COLUMN);
+ gtk_widget_translate_coordinates (GTK_WIDGET (priv->stack), grid, 0, 0,
+ &alloc.x, &alloc.y);
+
+ priv->pan_view = g_object_ref (view);
+ priv->pan_theatric = g_object_new (DZL_TYPE_BOX_THEATRIC,
+ "surface", surface,
+ "height", alloc.height,
+ "target", grid,
+ "width", alloc.width,
+ "x", (gint)(alloc.x + x),
+ "y", alloc.y,
+ NULL);
+
+ g_clear_pointer (&surface, cairo_surface_destroy);
+
+ /* Hide the view while we begin the possible transition to another
+ * layout stack.
+ */
+ gtk_widget_hide (GTK_WIDGET (priv->pan_view));
+
+ return TRUE;
+}
+
+static void
+ide_layout_stack_pan_update (IdeLayoutStack *self,
+ GdkEventSequence *sequence,
+ GtkGestureSwipe *gesture)
+{
+ IdeLayoutStackPrivate *priv = ide_layout_stack_get_instance_private (self);
+ GtkAllocation alloc;
+ gdouble x, y;
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_assert (GTK_IS_GESTURE_PAN (gesture));
+ g_assert (priv->pan_theatric != NULL);
+
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y);
+
+ gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+ g_object_set (priv->pan_theatric,
+ "x", (gint)(alloc.x + x),
+ NULL);
+}
+
+static void
+ide_layout_stack_pan_end (IdeLayoutStack *self,
+ GdkEventSequence *sequence,
+ GtkGesturePan *gesture)
+{
+ IdeLayoutStackPrivate *priv = ide_layout_stack_get_instance_private (self);
+ GtkAllocation alloc;
+ gdouble x, y;
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_assert (GTK_IS_GESTURE_PAN (gesture));
+
+ gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (gesture), &x, &y);
+
+ if (x > (alloc.width / 3))
+ g_print ("Move right\n");
+ else if (x < -(alloc.width / 3))
+ g_print ("Move left\n");
+
+
+ gtk_widget_show (GTK_WIDGET (priv->pan_view));
+
+ g_clear_object (&priv->pan_theatric);
+ g_clear_object (&priv->pan_view);
+
+ gtk_widget_queue_draw (gtk_widget_get_toplevel (GTK_WIDGET (self)));
+}
+
static void
ide_layout_stack_constructed (GObject *object)
{
@@ -415,6 +560,37 @@ ide_layout_stack_constructed (GObject *object)
peas_extension_set_foreach (priv->addins,
ide_layout_stack_addin_added,
self);
+
+ gtk_widget_add_events (GTK_WIDGET (priv->event_box), GDK_TOUCH_MASK);
+ priv->pan = g_object_new (GTK_TYPE_GESTURE_PAN,
+ "widget", priv->event_box,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "n-points", 3,
+ NULL);
+ g_signal_connect_swapped (priv->pan,
+ "begin",
+ G_CALLBACK (ide_layout_stack_pan_begin),
+ self);
+ g_signal_connect_swapped (priv->pan,
+ "update",
+ G_CALLBACK (ide_layout_stack_pan_update),
+ self);
+ g_signal_connect_swapped (priv->pan,
+ "end",
+ G_CALLBACK (ide_layout_stack_pan_end),
+ self);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->pan),
+ GTK_PHASE_BUBBLE);
+
+ /*
+ * FIXME: Our priv->pan gesture does not activate unless we add another
+ * dummy gesture. I currently have no idea why that is.
+ *
+ * https://bugzilla.gnome.org/show_bug.cgi?id=788914
+ */
+ priv->dummy = gtk_gesture_rotate_new (GTK_WIDGET (priv->event_box));
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->dummy),
+ GTK_PHASE_BUBBLE);
}
static void
@@ -463,6 +639,8 @@ ide_layout_stack_destroy (GtkWidget *widget)
g_clear_object (&priv->signals);
}
+ g_clear_object (&priv->pan);
+
GTK_WIDGET_CLASS (ide_layout_stack_parent_class)->destroy (widget);
}
@@ -557,6 +735,7 @@ ide_layout_stack_class_init (IdeLayoutStackClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, IdeLayoutStack, header);
gtk_widget_class_bind_template_child_private (widget_class, IdeLayoutStack, stack);
gtk_widget_class_bind_template_child_private (widget_class, IdeLayoutStack, top_stack);
+ gtk_widget_class_bind_template_child_private (widget_class, IdeLayoutStack, event_box);
g_type_ensure (IDE_TYPE_LAYOUT_STACK_HEADER);
g_type_ensure (IDE_TYPE_SHORTCUT_LABEL);
@@ -880,13 +1059,6 @@ animation_state_complete (gpointer data)
g_slice_free (AnimationState, state);
}
-static inline gboolean
-is_uninitialized (GtkAllocation *alloc)
-{
- return (alloc->x == -1 && alloc->y == -1 &&
- alloc->width == 1 && alloc->height == 1);
-}
-
void
_ide_layout_stack_transfer (IdeLayoutStack *self,
IdeLayoutStack *dest,
diff --git a/src/libide/layout/ide-layout-stack.ui b/src/libide/layout/ide-layout-stack.ui
index cf15da7..be87e44 100644
--- a/src/libide/layout/ide-layout-stack.ui
+++ b/src/libide/layout/ide-layout-stack.ui
@@ -10,125 +10,130 @@
</object>
</child>
<child>
- <object class="GtkStack" id="top_stack">
- <property name="expand">true</property>
- <property name="homogeneous">false</property>
- <property name="interpolate-size">false</property>
+ <object class="GtkEventBox" id="event_box">
<property name="visible">true</property>
<child>
- <object class="DzlBox" id="empty_state">
- <property name="expand">false</property>
- <property name="halign">center</property>
- <property name="orientation">vertical</property>
- <property name="valign">center</property>
- <property name="max-width-request">275</property>
- <property name="margin">32</property>
- <property name="spacing">6</property>
+ <object class="GtkStack" id="top_stack">
+ <property name="expand">true</property>
+ <property name="homogeneous">false</property>
+ <property name="interpolate-size">false</property>
<property name="visible">true</property>
<child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Open a File or Terminal</property>
- <property name="margin-bottom">6</property>
- <property name="visible">true</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="weight" value="bold"/>
- <attribute name="scale" value="1.2"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Use the page switcher above or use one of the
following:</property>
- <property name="justify">center</property>
- <property name="margin-bottom">18</property>
- <property name="visible">true</property>
- <property name="wrap">true</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="scale" value=".909"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="IdeShortcutLabel">
- <property name="title" translatable="yes">Search</property>
- <property name="action">win.global-search</property>
- <property name="visible">true</property>
- <!-- Remove after auto accel tracking -->
- <property name="accel">Ctrl+.</property>
- </object>
- </child>
- <child>
- <object class="IdeShortcutLabel">
- <property name="title" translatable="yes">Project sidebar</property>
- <property name="action">editor.sidebar</property>
- <property name="visible">true</property>
- <!-- Remove after auto accel tracking -->
- <property name="accel">F9</property>
- </object>
- </child>
- <child>
- <object class="IdeShortcutLabel">
- <property name="title" translatable="yes">File chooser</property>
- <property name="action">editor.open-file</property>
- <property name="visible">true</property>
- <!-- Remove after auto accel tracking -->
- <property name="accel">Ctrl+O</property>
- </object>
- </child>
- <child>
- <object class="IdeShortcutLabel">
- <property name="title" translatable="yes">New terminal</property>
- <property name="action">win.new-terminal</property>
- <property name="visible">true</property>
- <!-- Remove after auto accel tracking -->
- <property name="accel">Ctrl+Shift+T</property>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="homogeneous">true</property>
- <property name="margin-top">18</property>
+ <object class="DzlBox" id="empty_state">
+ <property name="expand">false</property>
+ <property name="halign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="valign">center</property>
+ <property name="max-width-request">275</property>
+ <property name="margin">32</property>
<property name="spacing">6</property>
<property name="visible">true</property>
<child>
- <object class="GtkButton">
- <property name="action-name">editor.open-file</property>
- <property name="label" translatable="yes">Open File…</property>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Open a File or Terminal</property>
+ <property name="margin-bottom">6</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.2"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Use the page switcher above or use one of the
following:</property>
+ <property name="justify">center</property>
+ <property name="margin-bottom">18</property>
+ <property name="visible">true</property>
+ <property name="wrap">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ <attributes>
+ <attribute name="scale" value=".909"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="IdeShortcutLabel">
+ <property name="title" translatable="yes">Search</property>
+ <property name="action">win.global-search</property>
<property name="visible">true</property>
+ <!-- Remove after auto accel tracking -->
+ <property name="accel">Ctrl+.</property>
</object>
</child>
<child>
- <object class="GtkButton">
- <property name="action-name">win.new-terminal</property>
- <property name="label" translatable="yes">New Terminal</property>
+ <object class="IdeShortcutLabel">
+ <property name="title" translatable="yes">Project sidebar</property>
+ <property name="action">editor.sidebar</property>
<property name="visible">true</property>
+ <!-- Remove after auto accel tracking -->
+ <property name="accel">F9</property>
+ </object>
+ </child>
+ <child>
+ <object class="IdeShortcutLabel">
+ <property name="title" translatable="yes">File chooser</property>
+ <property name="action">editor.open-file</property>
+ <property name="visible">true</property>
+ <!-- Remove after auto accel tracking -->
+ <property name="accel">Ctrl+O</property>
+ </object>
+ </child>
+ <child>
+ <object class="IdeShortcutLabel">
+ <property name="title" translatable="yes">New terminal</property>
+ <property name="action">win.new-terminal</property>
+ <property name="visible">true</property>
+ <!-- Remove after auto accel tracking -->
+ <property name="accel">Ctrl+Shift+T</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="homogeneous">true</property>
+ <property name="margin-top">18</property>
+ <property name="spacing">6</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">editor.open-file</property>
+ <property name="label" translatable="yes">Open File…</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">win.new-terminal</property>
+ <property name="label" translatable="yes">New Terminal</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
</object>
</child>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="DzlEmptyState" id="failed_state">
- <property name="icon-name">computer-fail-symbolic</property>
- <property name="pixel-size">160</property>
- <property name="title" translatable="yes">Uh oh, something went wrong</property>
- <property name="subtitle" translatable="yes">There was a failure while trying to perform the
operation.</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkStack" id="stack">
- <property name="expand">true</property>
- <property name="homogeneous">false</property>
- <property name="interpolate-size">false</property>
- <property name="visible">true</property>
+ <child>
+ <object class="DzlEmptyState" id="failed_state">
+ <property name="icon-name">computer-fail-symbolic</property>
+ <property name="pixel-size">160</property>
+ <property name="title" translatable="yes">Uh oh, something went wrong</property>
+ <property name="subtitle" translatable="yes">There was a failure while trying to perform the
operation.</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="expand">true</property>
+ <property name="homogeneous">false</property>
+ <property name="interpolate-size">false</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]