[libhandy/wip/haecker-felix/flap-widget: 138/138] WIP swipes




commit 7a2a1e390c41cc722984fb6a2b333434164bfffc
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Mon Aug 3 21:27:35 2020 +0500

    WIP swipes

 src/hdy-flap.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/hdy-flap.h |  19 ++++++
 2 files changed, 197 insertions(+), 11 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index b90ea69f..b47d7818 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -12,6 +12,8 @@
 
 #include "hdy-animation-private.h"
 #include "hdy-shadow-helper-private.h"
+#include "hdy-swipeable.h"
+#include "hdy-swipe-tracker.h"
 
 /**
  * SECTION:hdy-flap
@@ -40,14 +42,21 @@ struct _HdyFlap
   gint64 reveal_start_time;
   guint reveal_tick_cb_id;
   gdouble reveal_progress;
+  gdouble reveal_start_progress;
+  gdouble reveal_end_progress;
+  gint64 reveal_current_duration;
 
   GtkOrientation orientation;
 
   HdyShadowHelper *shadow_helper;
+  HdySwipeTracker *tracker;
 };
 
+static void hdy_flap_swipeable_init (HdySwipeableInterface *iface);
+
 G_DEFINE_TYPE_WITH_CODE (HdyFlap, hdy_flap, GTK_TYPE_BIN,
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
+                         G_IMPLEMENT_INTERFACE (HDY_TYPE_SWIPEABLE, hdy_flap_swipeable_init))
 
 enum {
   PROP_0,
@@ -70,6 +79,19 @@ enum {
 
 static GParamSpec *props[LAST_PROP];
 
+static void
+update_swipe_tracker (HdyFlap *self)
+{
+  gboolean reverse = self->flap_position == GTK_PACK_START;
+
+  if (self->orientation == GTK_ORIENTATION_HORIZONTAL &&
+      gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
+    reverse = !reverse;
+
+  hdy_swipe_tracker_set_reversed (self->tracker, reverse);
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (self->tracker), self->orientation);
+}
+
 static void
 set_orientation (HdyFlap        *self,
                  GtkOrientation  orientation)
@@ -78,7 +100,10 @@ set_orientation (HdyFlap        *self,
     return;
 
   self->orientation = orientation;
+
   gtk_widget_queue_resize (GTK_WIDGET (self));
+  update_swipe_tracker (self);
+
   g_object_notify (G_OBJECT (self), "orientation");
 }
 
@@ -177,6 +202,7 @@ hdy_flap_finalize (GObject *object)
   }
 
   g_clear_object (&self->shadow_helper);
+  g_clear_object (&self->tracker);
 
   G_OBJECT_CLASS (hdy_flap_parent_class)->finalize (object);
 }
@@ -193,10 +219,10 @@ reveal_tick_cb (HdyFlap       *self,
                 GdkFrameClock *frame_clock)
 {
   guint64 frame_time = gdk_frame_clock_get_frame_time (frame_clock) / 1000;
-  gdouble t = (gdouble) (frame_time - self->reveal_start_time) / self->reveal_duration;
+  gdouble t = (gdouble) (frame_time - self->reveal_start_time) / self->reveal_current_duration;
 
   if (t >= 1) {
-    self->reveal_progress = self->reveal_flap ? 1 : 0;
+    self->reveal_progress = self->reveal_end_progress;
     self->reveal_tick_cb_id = 0;
 
     gtk_widget_queue_resize (GTK_WIDGET (self));
@@ -204,10 +230,9 @@ reveal_tick_cb (HdyFlap       *self,
     return FALSE;
   }
 
-  self->reveal_progress = hdy_ease_out_cubic (t);
-
-  if (!self->reveal_flap)
-    self->reveal_progress = 1 - self->reveal_progress;
+  self->reveal_progress = hdy_lerp (self->reveal_start_progress,
+                                    self->reveal_end_progress,
+                                    hdy_ease_out_cubic (t));
 
   gtk_widget_queue_resize (GTK_WIDGET (self));
 
@@ -263,10 +288,12 @@ animate_overlay (HdyFlap *self)
 }
 
 static void
-animate_reveal (HdyFlap *self)
+animate_reveal (HdyFlap *self,
+                gdouble  to,
+                gint64   duration)
 {
   if (!hdy_get_enable_animations (GTK_WIDGET (self)) || !gtk_widget_get_mapped (GTK_WIDGET (self))) {
-    self->reveal_progress = self->reveal_flap ? 1 : 0;
+    self->reveal_progress = to;
     gtk_widget_queue_resize (GTK_WIDGET (self));
     return;
   }
@@ -277,7 +304,9 @@ animate_reveal (HdyFlap *self)
   }
 
   self->reveal_start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (GTK_WIDGET (self))) 
/ 1000;
-  self->reveal_progress = self->reveal_flap ? 0 : 1;
+  self->reveal_start_progress = self->reveal_progress;
+  self->reveal_end_progress = to;
+  self->reveal_current_duration = duration;
   self->reveal_tick_cb_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), (GtkTickCallback) 
reveal_tick_cb, NULL, NULL);
 }
 
@@ -303,6 +332,36 @@ adjust_for_text_direction (HdyFlap     *self,
   return pack_type;
 }
 
+static void
+begin_swipe_cb (HdySwipeTracker        *tracker,
+                HdyNavigationDirection  direction,
+                gboolean                direct,
+                HdyFlap                *self)
+{
+  if (self->reveal_tick_cb_id != 0) {
+    gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->reveal_tick_cb_id);
+    self->overlay_tick_cb_id = 0;
+  }
+}
+
+static void
+update_swipe_cb (HdySwipeTracker *tracker,
+                 gdouble          progress,
+                 HdyFlap         *self)
+{
+  self->reveal_progress = progress;
+  gtk_widget_queue_allocate (GTK_WIDGET (self));
+}
+
+static void
+end_swipe_cb (HdySwipeTracker *tracker,
+              gint64           duration,
+              gdouble          to,
+              HdyFlap         *self)
+{
+  animate_reveal (self, to, duration);
+}
+
 static void
 set_folded (HdyFlap  *self,
                       gboolean  folded)
@@ -620,6 +679,16 @@ hdy_flap_draw (GtkWidget *widget,
   return GDK_EVENT_PROPAGATE;
 }
 
+static void
+hdy_flap_direction_changed (GtkWidget        *widget,
+                            GtkTextDirection  previous_direction)
+{
+  update_swipe_tracker (HDY_FLAP (widget));
+
+  GTK_WIDGET_CLASS (hdy_flap_parent_class)->direction_changed (widget,
+                                                               previous_direction);
+}
+
 static void
 hdy_flap_forall (GtkContainer *container,
                  gboolean      include_internals,
@@ -656,6 +725,79 @@ hdy_flap_remove (GtkContainer *base,
   }
 }
 
+static HdySwipeTracker *
+hdy_flap_get_swipe_tracker (HdySwipeable *swipeable)
+{
+  HdyFlap *self = HDY_FLAP (swipeable);
+
+  return self->tracker;
+}
+
+static gdouble
+hdy_flap_get_distance (HdySwipeable *swipeable)
+{
+  HdyFlap *self = HDY_FLAP (swipeable);
+
+  if (!self->flap)
+    return 0;
+
+  if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
+    return gtk_widget_get_allocated_width (GTK_WIDGET (self->flap));
+  else
+    return gtk_widget_get_allocated_height (GTK_WIDGET (self->flap));
+}
+
+static gdouble *
+hdy_flap_get_snap_points (HdySwipeable *swipeable,
+                          gint         *n_snap_points)
+{
+  gdouble *points = g_new0 (gdouble, 2);
+
+  if (n_snap_points)
+    *n_snap_points = 2;
+
+  points[0] = 0;
+  points[1] = 1;
+
+  return points;
+}
+
+static gdouble
+hdy_flap_get_progress (HdySwipeable *swipeable)
+{
+  HdyFlap *self = HDY_FLAP (swipeable);
+
+  return self->reveal_progress;
+}
+
+static gdouble
+hdy_flap_get_cancel_progress (HdySwipeable *swipeable)
+{
+  HdyFlap *self = HDY_FLAP (swipeable);
+
+  return round (self->reveal_progress);
+}
+
+static void
+hdy_flap_get_swipe_area (HdySwipeable           *swipeable,
+                         HdyNavigationDirection  navigation_direction,
+                         gboolean                is_drag,
+                         GdkRectangle           *rect)
+{
+  HdyFlap *self = HDY_FLAP (swipeable);
+  gint width, height;
+
+  if (!self->flap) {
+    rect->x = 0;
+    rect->y = 0;
+    rect->width = 0;
+    rect->height = 0;
+  }
+
+  width = gtk_widget_get_allocated_width (self->flap);
+  height = gtk_widget_get_allocated_height (self->flap);
+}
+
 static void
 hdy_flap_class_init (HdyFlapClass *klass)
 {
@@ -673,6 +815,7 @@ hdy_flap_class_init (HdyFlapClass *klass)
   widget_class->get_preferred_height_for_width = hdy_flap_get_preferred_height_for_width;
   widget_class->size_allocate = hdy_flap_size_allocate;
   widget_class->draw = hdy_flap_draw;
+  widget_class->direction_changed = hdy_flap_direction_changed;
 
   container_class->remove = hdy_flap_remove;
   container_class->forall = hdy_flap_forall;
@@ -802,6 +945,26 @@ hdy_flap_init (HdyFlap *self)
   self->reveal_duration = 250;
 
   self->shadow_helper = hdy_shadow_helper_new (GTK_WIDGET (self));
+  self->tracker = hdy_swipe_tracker_new (HDY_SWIPEABLE (self));
+  hdy_swipe_tracker_set_enabled (self->tracker, FALSE);
+
+  g_signal_connect_object (self->tracker, "begin-swipe", G_CALLBACK (begin_swipe_cb), self, 0);
+  g_signal_connect_object (self->tracker, "update-swipe", G_CALLBACK (update_swipe_cb), self, 0);
+  g_signal_connect_object (self->tracker, "end-swipe", G_CALLBACK (end_swipe_cb), self, 0);
+
+  update_swipe_tracker (self);
+}
+
+static void
+hdy_flap_swipeable_init (HdySwipeableInterface *iface)
+{
+//  iface->switch_child = hdy_leaflet_switch_child;
+  iface->get_swipe_tracker = hdy_flap_get_swipe_tracker;
+  iface->get_distance = hdy_flap_get_distance;
+  iface->get_snap_points = hdy_flap_get_snap_points;
+  iface->get_progress = hdy_flap_get_progress;
+  iface->get_cancel_progress = hdy_flap_get_cancel_progress;
+//  iface->get_swipe_area = hdy_flap_get_swipe_area;
 }
 
 /**
@@ -859,6 +1022,8 @@ hdy_flap_set_flap (HdyFlap *self,
   if (self->flap)
     gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
 
+  hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
+
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
 }
 
@@ -932,6 +1097,7 @@ void
 hdy_flap_set_flap_position  (HdyFlap     *self,
                              GtkPackType  flap_position)
 {
+
   g_return_if_fail (HDY_IS_FLAP (self));
 
   if (self->flap_position == flap_position)
@@ -941,6 +1107,7 @@ hdy_flap_set_flap_position  (HdyFlap     *self,
 
   gtk_widget_queue_allocate (GTK_WIDGET (self));
   hdy_shadow_helper_clear_cache (self->shadow_helper);
+  update_swipe_tracker (self);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP_POSITION]);
 }
@@ -979,7 +1146,7 @@ hdy_flap_set_reveal_flap (HdyFlap  *self,
     return;
 
   self->reveal_flap = reveal_flap;
-  animate_reveal(self);
+  animate_reveal (self, reveal_flap ? 1 : 0, self->reveal_duration);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_REVEAL_FLAP]);
 }
diff --git a/src/hdy-flap.h b/src/hdy-flap.h
index 71b6a545..90bc546a 100644
--- a/src/hdy-flap.h
+++ b/src/hdy-flap.h
@@ -10,6 +10,8 @@
 #error "Only <handy.h> can be included directly."
 #endif
 
+#include "hdy-version.h"
+
 #include <gtk/gtk.h>
 #include "hdy-enums.h"
 
@@ -17,6 +19,7 @@ G_BEGIN_DECLS
 
 #define HDY_TYPE_FLAP (hdy_flap_get_type())
 
+HDY_AVAILABLE_IN_ALL
 G_DECLARE_FINAL_TYPE (HdyFlap, hdy_flap, HDY, FLAP, GtkBin)
 
 typedef enum {
@@ -26,28 +29,44 @@ typedef enum {
 } HdyFlapFoldPolicy;
 
 
+HDY_AVAILABLE_IN_ALL
 GtkWidget *hdy_flap_new (void);
 
+HDY_AVAILABLE_IN_ALL
 GtkWidget *hdy_flap_get_flap (HdyFlap   *self);
+HDY_AVAILABLE_IN_ALL
 void       hdy_flap_set_flap (HdyFlap   *self,
                               GtkWidget *flap);
+HDY_AVAILABLE_IN_ALL
 HdyFlapFoldPolicy hdy_flap_get_flap_fold_policy (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void        hdy_flap_set_flap_fold_policy (HdyFlap *self,
                                     HdyFlapFoldPolicy flap_mode);
+HDY_AVAILABLE_IN_ALL
 GtkPackType hdy_flap_get_flap_position (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void        hdy_flap_set_flap_position (HdyFlap *self,
                                         GtkPackType flap_position);
+HDY_AVAILABLE_IN_ALL
 gboolean hdy_flap_get_reveal_flap (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void     hdy_flap_set_reveal_flap (HdyFlap *self,
                                    gboolean reveal_flap);
+HDY_AVAILABLE_IN_ALL
 gboolean hdy_flap_get_locked (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void     hdy_flap_set_locked (HdyFlap *self,
                               gboolean locked);
+HDY_AVAILABLE_IN_ALL
 gboolean hdy_flap_get_folded (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 gint     hdy_flap_get_overlay_duration (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void     hdy_flap_set_overlay_duration (HdyFlap *self,
                                         gint overlay_duration);
+HDY_AVAILABLE_IN_ALL
 gint hdy_flap_get_reveal_duration (HdyFlap *self);
+HDY_AVAILABLE_IN_ALL
 void hdy_flap_set_reveal_duration (HdyFlap *self,
                                    gint reveal_duration);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]