[libhandy/wip/haecker-felix/flap-widget] Transition types
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy/wip/haecker-felix/flap-widget] Transition types
- Date: Thu, 19 Nov 2020 12:43:56 +0000 (UTC)
commit af5dbfd9c39b34f0e53bb56a302bb0777bc708e0
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Thu Nov 19 17:21:59 2020 +0500
Transition types
debian/libhandy-1-0.symbols | 2 +
src/hdy-flap.c | 258 ++++++++++++++++++++++++++++++++++++--------
src/hdy-flap.h | 12 +++
3 files changed, 229 insertions(+), 43 deletions(-)
---
diff --git a/debian/libhandy-1-0.symbols b/debian/libhandy-1-0.symbols
index 719ab553..db0ba268 100644
--- a/debian/libhandy-1-0.symbols
+++ b/debian/libhandy-1-0.symbols
@@ -129,6 +129,7 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
hdy_flap_get_locked@LIBHANDY_1_0 1.1.0
hdy_flap_get_reveal_duration@LIBHANDY_1_0 1.1.0
hdy_flap_get_reveal_flap@LIBHANDY_1_0 1.1.0
+ hdy_flap_get_transition_type@LIBHANDY_1_0 1.1.0
hdy_flap_get_type@LIBHANDY_1_0 1.1.0
hdy_flap_new@LIBHANDY_1_0 1.1.0
hdy_flap_set_flap@LIBHANDY_1_0 1.1.0
@@ -138,6 +139,7 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
hdy_flap_set_locked@LIBHANDY_1_0 1.1.0
hdy_flap_set_reveal_duration@LIBHANDY_1_0 1.1.0
hdy_flap_set_reveal_flap@LIBHANDY_1_0 1.1.0
+ hdy_flap_set_transition_type@LIBHANDY_1_0 1.1.0
hdy_get_enable_animations@LIBHANDY_1_0 0.0.11
hdy_header_bar_get_centering_policy@LIBHANDY_1_0 0.0.10
hdy_header_bar_get_custom_title@LIBHANDY_1_0 0.0.10
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 246b1c49..c16b91a2 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -33,9 +33,19 @@
* in a #HdyFlap widget.
*/
+/**
+ * HdyFlapTransitionType:
+ * @HDY_FLAP_TRANSITION_TYPE_OVER: No transition
+ * @HDY_FLAP_TRANSITION_TYPE_UNDER: A cross-fade
+ * @HDY_FLAP_TRANSITION_TYPE_SLIDE: TBD
+ *
+ * These enumeration values describe the possible transitions between children
+ * in a #HdyFlap widget.
+ *
+ * New values may be added to this enum over time.
+ */
+
#define HDY_SWIPE_BORDER 16
-#define FLAP_MOTION_FACTOR 1.0
-#define CONTENT_MOTION_FACTOR 0.0
struct _HdyFlap
{
@@ -51,6 +61,7 @@ struct _HdyFlap
GtkAllocation content_allocation;
HdyFlapFoldPolicy fold_policy;
+ HdyFlapTransitionType transition_type;
GtkPackType flap_position;
gboolean reveal_flap;
gboolean locked;
@@ -84,7 +95,6 @@ G_DEFINE_TYPE_WITH_CODE (HdyFlap, hdy_flap, GTK_TYPE_CONTAINER,
enum {
PROP_0,
-
PROP_FLAP,
PROP_FOLD_POLICY,
PROP_FLAP_POSITION,
@@ -93,11 +103,12 @@ enum {
PROP_FOLDED,
PROP_FOLD_DURATION,
PROP_REVEAL_DURATION,
+ PROP_TRANSITION_TYPE,
/* Overridden properties */
PROP_ORIENTATION,
- LAST_PROP = PROP_REVEAL_DURATION + 1,
+ LAST_PROP = PROP_ORIENTATION,
};
static GParamSpec *props[LAST_PROP];
@@ -355,14 +366,67 @@ unregister_window (HdyFlap *self,
*window = NULL;
}
+static gboolean
+transition_is_content_above_flap (HdyFlap *self)
+{
+ switch (self->transition_type) {
+ case HDY_FLAP_TRANSITION_TYPE_OVER:
+ case HDY_FLAP_TRANSITION_TYPE_SLIDE:
+ return FALSE;
+
+ case HDY_FLAP_TRANSITION_TYPE_UNDER:
+ return TRUE;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gdouble
+transition_get_content_motion_factor (HdyFlap *self)
+{
+ switch (self->transition_type) {
+ case HDY_FLAP_TRANSITION_TYPE_OVER:
+ return 0;
+
+ case HDY_FLAP_TRANSITION_TYPE_SLIDE:
+ case HDY_FLAP_TRANSITION_TYPE_UNDER:
+ return 1;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gdouble
+transition_get_flap_motion_factor (HdyFlap *self)
+{
+ switch (self->transition_type) {
+ case HDY_FLAP_TRANSITION_TYPE_OVER:
+ case HDY_FLAP_TRANSITION_TYPE_SLIDE:
+ return 1;
+
+ case HDY_FLAP_TRANSITION_TYPE_UNDER:
+ return 0;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
static void
restack_windows (HdyFlap *self)
{
- if (self->content_window)
+ gboolean content_above_flap = transition_is_content_above_flap (self);
+
+ if (self->content_window && !content_above_flap)
gdk_window_raise (self->content_window);
if (self->flap_window)
gdk_window_raise (self->flap_window);
+
+ if (self->content_window && content_above_flap)
+ gdk_window_raise (self->content_window);
}
static inline GtkPackType
@@ -569,8 +633,8 @@ compute_allocation (HdyFlap *self,
return;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
- content_offset = (gint) round (MIN (self->fold_progress, self->reveal_progress) * CONTENT_MOTION_FACTOR
* flap_alloc->width);
- flap_offset = (gint) round ((self->reveal_progress - 1) * FLAP_MOTION_FACTOR * flap_alloc->width);
+ content_offset = (gint) round (MIN (self->fold_progress, self->reveal_progress) *
transition_get_content_motion_factor (self) * flap_alloc->width);
+ flap_offset = (gint) round ((self->reveal_progress - 1) * transition_get_flap_motion_factor (self) *
flap_alloc->width);
if (self->flap_position == get_start_or_end (self)) {
content_alloc->x = alloc->width - content_alloc->width + content_offset;
@@ -580,8 +644,8 @@ compute_allocation (HdyFlap *self,
flap_alloc->x = alloc->width - flap_alloc->width - flap_offset;
}
} else {
- content_offset = (gint) round (MIN (self->fold_progress, self->reveal_progress) * CONTENT_MOTION_FACTOR
* flap_alloc->height);
- flap_offset = (gint) round ((self->reveal_progress - 1) * FLAP_MOTION_FACTOR * flap_alloc->height);
+ content_offset = (gint) round (MIN (self->fold_progress, self->reveal_progress) *
transition_get_content_motion_factor (self) * flap_alloc->height);
+ flap_offset = (gint) round ((self->reveal_progress - 1) * transition_get_flap_motion_factor (self) *
flap_alloc->height);
if (self->flap_position == GTK_PACK_START) {
content_alloc->y = alloc->height - content_alloc->height + content_offset;
@@ -763,39 +827,68 @@ hdy_flap_draw (GtkWidget *widget,
gint shadow_x = 0, shadow_y = 0;
gdouble progress;
GtkPanDirection shadow_direction;
+ gboolean content_above_flap = transition_is_content_above_flap (self);
+ GtkAllocation *shadow_alloc;
+
+ if (self->content && !content_above_flap)
+ gtk_container_propagate_draw (GTK_CONTAINER (self),
+ self->content,
+ cr);
+
+ if (self->flap)
+ gtk_container_propagate_draw (GTK_CONTAINER (self),
+ self->flap,
+ cr);
+
+ if (self->content && content_above_flap)
+ gtk_container_propagate_draw (GTK_CONTAINER (self),
+ self->content,
+ cr);
+
+ if (!self->flap)
+ return GDK_EVENT_PROPAGATE;
+
+ shadow_alloc = content_above_flap ? &self->content_allocation : &self->flap_allocation;
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
if (self->orientation == GTK_ORIENTATION_VERTICAL) {
- if (self->flap_position == GTK_PACK_START) {
+ if ((self->flap_position == GTK_PACK_START) != content_above_flap) {
shadow_direction = GTK_PAN_DIRECTION_UP;
- shadow_y = self->flap_allocation.y + self->flap_allocation.height;
+ shadow_y = shadow_alloc->y + shadow_alloc->height;
} else {
shadow_direction = GTK_PAN_DIRECTION_DOWN;
- shadow_y = self->flap_allocation.y - height;
+ shadow_y = shadow_alloc->y - height;
}
} else {
- if (self->flap_position == get_start_or_end (self)) {
+ if ((self->flap_position == get_start_or_end (self)) != content_above_flap) {
shadow_direction = GTK_PAN_DIRECTION_LEFT;
- shadow_x = self->flap_allocation.x + self->flap_allocation.width;
+ shadow_x = shadow_alloc->x + shadow_alloc->width;
} else {
shadow_direction = GTK_PAN_DIRECTION_RIGHT;
- shadow_x = self->flap_allocation.x - width;
+ shadow_x = shadow_alloc->x - width;
}
}
- gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->content,
- cr);
+ switch (self->transition_type) {
+ case HDY_FLAP_TRANSITION_TYPE_OVER:
+ progress = 1 - MIN (self->reveal_progress, self->fold_progress);
+ break;
+
+ case HDY_FLAP_TRANSITION_TYPE_UNDER:
+ progress = self->reveal_progress;
+ break;
- gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->flap,
- cr);
+ case HDY_FLAP_TRANSITION_TYPE_SLIDE:
+ progress = 1;
+ break;
- progress = 1 - MIN (self->reveal_progress, self->fold_progress);
+ default:
+ g_assert_not_reached ();
+ }
- if (progress < 1) {
+ if (progress < 1 && gtk_widget_get_mapped (self->flap)) {
cairo_save (cr);
cairo_translate (cr, shadow_x, shadow_y);
hdy_shadow_helper_draw_shadow (self->shadow_helper, cr, width, height,
@@ -965,6 +1058,9 @@ hdy_flap_get_property (GObject *object,
case PROP_REVEAL_DURATION:
g_value_set_uint (value, hdy_flap_get_reveal_duration (self));
break;
+ case PROP_TRANSITION_TYPE:
+ g_value_set_enum (value, hdy_flap_get_transition_type (self));
+ break;
case PROP_ORIENTATION:
g_value_set_enum (value, self->orientation);
break;
@@ -1003,6 +1099,9 @@ hdy_flap_set_property (GObject *object,
case PROP_REVEAL_DURATION:
hdy_flap_set_reveal_duration (self, g_value_get_uint (value));
break;
+ case PROP_TRANSITION_TYPE:
+ hdy_flap_set_transition_type (self, g_value_get_enum (value));
+ break;
case PROP_ORIENTATION:
set_orientation (self, g_value_get_enum (value));
break;
@@ -1147,6 +1246,19 @@ hdy_flap_class_init (HdyFlapClass *klass)
250,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * HdyFlap:transition-type:
+ *
+ * Since: 1.1
+ */
+ props[PROP_TRANSITION_TYPE] =
+ g_param_spec_enum ("transition-type",
+ _("Transition Type"),
+ _("Transition Type"),
+ HDY_TYPE_FLAP_TRANSITION_TYPE,
+ HDY_FLAP_TRANSITION_TYPE_OVER,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
g_object_class_override_property (object_class,
@@ -1162,6 +1274,7 @@ hdy_flap_init (HdyFlap *self)
self->orientation = GTK_ORIENTATION_HORIZONTAL;
self->flap_position = GTK_PACK_START;
self->fold_policy = HDY_FLAP_FOLD_POLICY_AUTO;
+ self->transition_type = HDY_FLAP_TRANSITION_TYPE_OVER;
self->reveal_flap = TRUE;
self->locked = FALSE;
self->reveal_progress = 1;
@@ -1271,7 +1384,7 @@ hdy_flap_get_swipe_area (HdySwipeable *swipeable,
GdkRectangle *rect)
{
HdyFlap *self = HDY_FLAP (swipeable);
- GtkAllocation alloc;
+ GtkAllocation *alloc;
gint width, height;
if (!self->flap) {
@@ -1286,30 +1399,47 @@ hdy_flap_get_swipe_area (HdySwipeable *swipeable,
width = gtk_widget_get_allocated_width (GTK_WIDGET (self));
height = gtk_widget_get_allocated_height (GTK_WIDGET (self));
- alloc = self->flap_allocation;
+ if (transition_get_flap_motion_factor (self) >=1 &&
+ transition_get_content_motion_factor (self) >= 1) {
+ rect->x = 0;
+ rect->y = 0;
+ rect->width = width;
+ rect->height = height;
+
+ return;
+ }
+
+ alloc = transition_is_content_above_flap (self)
+ ? &self->content_allocation
+ : &self->flap_allocation;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
- if (self->flap_position == get_start_or_end (self)) {
- rect->x = 0;
- rect->width = MAX (alloc.x + alloc.width, HDY_SWIPE_BORDER);
- } else {
- rect->x = MIN (alloc.x, width - HDY_SWIPE_BORDER);
- rect->width = width - rect->x;
- }
+ if (alloc->x <= 0) {
+ rect->x = 0;
+ rect->width = MAX (alloc->width + alloc->x, HDY_SWIPE_BORDER);
+ } else if (alloc->x + alloc->width >= width) {
+ rect->width = MAX (width - alloc->x, HDY_SWIPE_BORDER);
+ rect->x = width - rect->width;
+ } else {
+ g_assert_not_reached ();
+ }
- rect->y = alloc.y;
- rect->height = alloc.height;
+ rect->y = alloc->y;
+ rect->height = alloc->height;
} else {
- if (self->flap_position == GTK_PACK_START) {
- rect->y = 0;
- rect->height = MAX (alloc.y + alloc.height, HDY_SWIPE_BORDER);
- } else {
- rect->y = MIN (alloc.y, height - HDY_SWIPE_BORDER);
- rect->height = height - rect->y;
- }
+ if (alloc->y <= 0) {
+ rect->y = 0;
+ rect->height = MAX (alloc->height + alloc->y, HDY_SWIPE_BORDER);
+ } else if (alloc->y + alloc->height >= height) {
+ rect->height = MAX (height - alloc->y, HDY_SWIPE_BORDER);
+ rect->y = height - rect->height;
+ } else {
+ g_assert_not_reached ();
+ }
+
- rect->x = alloc.x;
- rect->width = alloc.width;
+ rect->x = alloc->x;
+ rect->width = alloc->width;
}
}
@@ -1643,3 +1773,45 @@ hdy_flap_set_reveal_duration (HdyFlap *self,
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_REVEAL_DURATION]);
}
+
+/**
+ * hdy_flap_get_transition_type:
+ * @self: a #HdyFlap
+ *
+ * Returns: current transition type.
+ *
+ * Since: 1.1
+ */
+HdyFlapTransitionType
+hdy_flap_get_transition_type (HdyFlap *self)
+{
+ g_return_val_if_fail (HDY_IS_FLAP (self), HDY_FLAP_TRANSITION_TYPE_OVER);
+
+ return self->transition_type;
+}
+
+/**
+ * hdy_flap_set_transition_type:
+ * @self: a #HdyFlap
+ * @transition_type: Duration for reveal animation
+ *
+ * Since: 1.1
+ */
+void
+hdy_flap_set_transition_type (HdyFlap *self,
+ HdyFlapTransitionType transition_type)
+{
+ g_return_if_fail (HDY_IS_FLAP (self));
+
+ if (self->transition_type == transition_type)
+ return;
+
+ self->transition_type = transition_type;
+
+ restack_windows (self);
+
+ if (self->reveal_progress > 0 || (self->fold_progress > 0 && self->fold_progress < 1))
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TRANSITION_TYPE]);
+}
diff --git a/src/hdy-flap.h b/src/hdy-flap.h
index f5f3eb7b..9d16c11a 100644
--- a/src/hdy-flap.h
+++ b/src/hdy-flap.h
@@ -28,6 +28,12 @@ typedef enum {
HDY_FLAP_FOLD_POLICY_AUTO,
} HdyFlapFoldPolicy;
+typedef enum {
+ HDY_FLAP_TRANSITION_TYPE_OVER,
+ HDY_FLAP_TRANSITION_TYPE_UNDER,
+ HDY_FLAP_TRANSITION_TYPE_SLIDE,
+} HdyFlapTransitionType;
+
HDY_AVAILABLE_IN_1_1
GtkWidget *hdy_flap_new (void);
@@ -76,4 +82,10 @@ HDY_AVAILABLE_IN_1_1
void hdy_flap_set_reveal_duration (HdyFlap *self,
guint duration);
+HDY_AVAILABLE_IN_1_1
+HdyFlapTransitionType hdy_flap_get_transition_type (HdyFlap *self);
+HDY_AVAILABLE_IN_1_1
+void hdy_flap_set_transition_type (HdyFlap *self,
+ HdyFlapTransitionType transition_type);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]