[libhandy/wip/haecker-felix/flap-widget: 98/98] WIP swipes
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy/wip/haecker-felix/flap-widget: 98/98] WIP swipes
- Date: Mon, 3 Aug 2020 16:27:57 +0000 (UTC)
commit 75a5abda5d91fb08a8324a4413a1244b760ac2e2
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]