[libhandy/wip/haecker-felix/flap-widget] Separators



commit 437c97b0be44128552598ff10f6cb2ac3fa7576d
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Sat Nov 21 00:22:47 2020 +0500

    Separators
    
    Wow this took a while

 src/hdy-flap.c | 435 ++++++++++++++++++++++++++++++++++++++++-----------------
 src/hdy-flap.h |   6 +
 2 files changed, 310 insertions(+), 131 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 96e27261..b89a7b83 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -53,12 +53,15 @@ struct _HdyFlap
 
   GtkWidget *content;
   GtkWidget *flap;
+  GtkWidget *separator;
 
   GdkWindow *content_window;
+  GdkWindow *separator_window;
   GdkWindow *flap_window;
 
   GtkAllocation flap_allocation;
   GtkAllocation content_allocation;
+  GtkAllocation separator_allocation;
 
   HdyFlapFoldPolicy fold_policy;
   HdyFlapTransitionType transition_type;
@@ -96,6 +99,7 @@ G_DEFINE_TYPE_WITH_CODE (HdyFlap, hdy_flap, GTK_TYPE_CONTAINER,
 enum {
   PROP_0,
   PROP_FLAP,
+  PROP_SEPARATOR,
   PROP_FOLD_POLICY,
   PROP_FLAP_POSITION,
   PROP_REVEAL_FLAP,
@@ -280,15 +284,6 @@ set_folded (HdyFlap  *self,
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FOLDED]);
 }
 
-static gint
-adjust_for_overlay (HdyFlap *self,
-                    gint     value)
-{
-  gdouble progress = MIN (1 - self->fold_progress, self->reveal_progress);
-
-  return (gint) round (value * progress);
-}
-
 static void
 begin_swipe_cb (HdySwipeTracker        *tracker,
                 HdyNavigationDirection  direction,
@@ -371,9 +366,9 @@ 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_SLIDE:
   case HDY_FLAP_TRANSITION_TYPE_UNDER:
     return TRUE;
 
@@ -419,14 +414,24 @@ restack_windows (HdyFlap *self)
 {
   gboolean content_above_flap = transition_is_content_above_flap (self);
 
-  if (self->content_window && !content_above_flap)
-    gdk_window_raise (self->content_window);
+  if (!content_above_flap) {
+    if (self->content_window)
+      gdk_window_raise (self->content_window);
+
+    if (self->separator_window)
+      gdk_window_raise (self->separator_window);
+  }
 
   if (self->flap_window)
     gdk_window_raise (self->flap_window);
 
-  if (self->content_window && content_above_flap)
-    gdk_window_raise (self->content_window);
+  if (content_above_flap) {
+    if (self->separator_window)
+      gdk_window_raise (self->separator_window);
+
+    if (self->content_window)
+      gdk_window_raise (self->content_window);
+  }
 }
 
 static inline GtkPackType
@@ -434,8 +439,9 @@ get_start_or_end (HdyFlap *self)
 {
   GtkTextDirection direction = gtk_widget_get_direction (GTK_WIDGET (self));
   gboolean is_rtl = direction == GTK_TEXT_DIR_RTL;
+  gboolean is_horiz = self->orientation == GTK_ORIENTATION_HORIZONTAL;
 
-  return is_rtl ? GTK_PACK_END : GTK_PACK_START;
+  return (is_rtl && !is_horiz) ? GTK_PACK_END : GTK_PACK_START;
 }
 
 static inline void
@@ -456,7 +462,8 @@ compute_sizes (HdyFlap       *self,
                gboolean       folded,
                gboolean       revealed,
                gint          *flap_size,
-               gint          *content_size)
+               gint          *content_size,
+               gint          *separator_size)
 {
   gboolean flap_expand, content_expand;
   gint total, extra;
@@ -465,6 +472,11 @@ compute_sizes (HdyFlap       *self,
   if (!self->flap && !self->content)
     return;
 
+  if (self->separator)
+    get_preferred_size (self->separator, self->orientation, separator_size, NULL);
+  else
+    *separator_size = 0;
+
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
     total = alloc->width;
   else
@@ -503,6 +515,9 @@ compute_sizes (HdyFlap       *self,
     return;
   }
 
+  if (revealed)
+    total -= *separator_size;
+
   if (flap_expand && content_expand) {
     *flap_size = MAX (total / 2, *flap_size);
 
@@ -557,18 +572,19 @@ interpolate_reveal (HdyFlap       *self,
                     GtkAllocation *alloc,
                     gboolean       folded,
                     gint          *flap_size,
-                    gint          *content_size)
+                    gint          *content_size,
+                    gint          *separator_size)
 {
   if (self->reveal_progress <= 0) {
-    compute_sizes (self, alloc, folded, FALSE, flap_size, content_size);
+    compute_sizes (self, alloc, folded, FALSE, flap_size, content_size, separator_size);
   } else if (self->reveal_progress >= 1) {
-    compute_sizes (self, alloc, folded, TRUE, flap_size, content_size);
+    compute_sizes (self, alloc, folded, TRUE, flap_size, content_size, separator_size);
   } else {
-    gint flap_revealed, content_revealed;
-    gint flap_hidden, content_hidden;
+    gint flap_revealed, content_revealed, separator_revealed;
+    gint flap_hidden, content_hidden, separator_hidden;
 
-    compute_sizes (self, alloc, folded, TRUE, &flap_revealed, &content_revealed);
-    compute_sizes (self, alloc, folded, FALSE, &flap_hidden, &content_hidden);
+    compute_sizes (self, alloc, folded, TRUE, &flap_revealed, &content_revealed, &separator_revealed);
+    compute_sizes (self, alloc, folded, FALSE, &flap_hidden, &content_hidden, &separator_hidden);
 
     *flap_size =
       (gint) round (hdy_lerp (flap_hidden, flap_revealed,
@@ -576,6 +592,9 @@ interpolate_reveal (HdyFlap       *self,
     *content_size =
       (gint) round (hdy_lerp (content_hidden, content_revealed,
                               self->reveal_progress));
+    *separator_size =
+      (gint) round (hdy_lerp (separator_hidden, separator_revealed,
+                              self->reveal_progress));
   }
 }
 
@@ -583,18 +602,19 @@ static inline void
 interpolate_fold (HdyFlap       *self,
                   GtkAllocation *alloc,
                   gint          *flap_size,
-                  gint          *content_size)
+                  gint          *content_size,
+                  gint          *separator_size)
 {
   if (self->fold_progress <= 0) {
-    interpolate_reveal (self, alloc, FALSE, flap_size, content_size);
+    interpolate_reveal (self, alloc, FALSE, flap_size, content_size, separator_size);
   } else if (self->fold_progress >= 1) {
-    interpolate_reveal (self, alloc, TRUE, flap_size, content_size);
+    interpolate_reveal (self, alloc, TRUE, flap_size, content_size, separator_size);
   } else {
-    gint flap_folded, content_folded;
-    gint flap_unfolded, content_unfolded;
+    gint flap_folded, content_folded, separator_folded;
+    gint flap_unfolded, content_unfolded, separator_unfolded;
 
-    interpolate_reveal (self, alloc, TRUE, &flap_folded, &content_folded);
-    interpolate_reveal (self, alloc, FALSE, &flap_unfolded, &content_unfolded);
+    interpolate_reveal (self, alloc, TRUE, &flap_folded, &content_folded, &separator_folded);
+    interpolate_reveal (self, alloc, FALSE, &flap_unfolded, &content_unfolded, &separator_unfolded);
 
     *flap_size =
       (gint) round (hdy_lerp (flap_unfolded, flap_folded,
@@ -602,6 +622,9 @@ interpolate_fold (HdyFlap       *self,
     *content_size =
       (gint) round (hdy_lerp (content_unfolded, content_folded,
                               self->fold_progress));
+    *separator_size =
+      (gint) round (hdy_lerp (separator_unfolded, separator_folded,
+                              self->fold_progress));
   }
 }
 
@@ -609,52 +632,108 @@ static void
 compute_allocation (HdyFlap       *self,
                     GtkAllocation *alloc,
                     GtkAllocation *flap_alloc,
-                    GtkAllocation *content_alloc)
+                    GtkAllocation *content_alloc,
+                    GtkAllocation *separator_alloc)
 {
-  gint content_offset, flap_offset;
+  gdouble distance;
+  gint content_size, flap_size, separator_size;
+  gint total, content_pos, flap_pos, separator_pos;
+  gboolean content_above_flap = transition_is_content_above_flap (self);
 
-  if (!self->flap && !self->content)
+  if (!self->flap && !self->content && !self->separator)
     return;
 
   content_alloc->x = 0;
   content_alloc->y = 0;
   flap_alloc->x = 0;
   flap_alloc->y = 0;
+  separator_alloc->x = 0;
+  separator_alloc->y = 0;
+
+  interpolate_fold (self, alloc, &flap_size, &content_size, &separator_size);
 
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
-    interpolate_fold (self, alloc, &flap_alloc->width, &content_alloc->width);
-    flap_alloc->height = content_alloc->height = alloc->height;
+    flap_alloc->width = flap_size;
+    content_alloc->width = content_size;
+    separator_alloc->width = separator_size;
+    flap_alloc->height = content_alloc->height = separator_alloc->height = alloc->height;
+    total = alloc->width;
   } else {
-    interpolate_fold (self, alloc, &flap_alloc->height, &content_alloc->height);
-    flap_alloc->width = content_alloc->width = alloc->width;
+    flap_alloc->height = flap_size;
+    content_alloc->height = content_size;
+    separator_alloc->height = separator_size;
+    flap_alloc->width = content_alloc->width = separator_alloc->width = alloc->width;
+    total = alloc->height;
   }
 
   if (!self->flap)
     return;
 
-  if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
-    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 (content_above_flap)
+    distance = flap_size + separator_size;
+  else
+    distance = flap_size + separator_size * (1 - self->fold_progress);
 
-    if (self->flap_position == get_start_or_end (self)) {
-      content_alloc->x = alloc->width - content_alloc->width + content_offset;
-      flap_alloc->x = flap_offset;
-    } else {
-      content_alloc->x = -content_offset;
-      flap_alloc->x = alloc->width - flap_alloc->width - flap_offset;
-    }
+  flap_pos = -(gint) round ((1 - self->reveal_progress) * transition_get_flap_motion_factor (self) * 
distance);
+
+  if (content_above_flap) {
+    content_pos = (gint) round (self->reveal_progress * transition_get_content_motion_factor (self) * 
distance);
+    separator_pos = flap_pos + flap_size;
+  } else {
+    content_pos = total - content_size + (gint) round (self->reveal_progress * self->fold_progress * 
transition_get_content_motion_factor (self) * distance);
+    separator_pos = content_pos - separator_size;
+  }
+
+  if (self->flap_position != get_start_or_end (self)) {
+    flap_pos = total - flap_pos - flap_size;
+    separator_pos = total - separator_pos - separator_size;
+    content_pos = total - content_pos - content_size;
+  }
+
+  if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
+    content_alloc->x = content_pos;
+    flap_alloc->x = flap_pos;
+    separator_alloc->x = separator_pos;
   } else {
-    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);
+    content_alloc->y = content_pos;
+    flap_alloc->y = flap_pos;
+    separator_alloc->y = separator_pos;
+  }
+}
+
+static inline void
+allocate_child (HdyFlap       *self,
+                GtkWidget     *widget,
+                GdkWindow     *window,
+                GtkAllocation *allocation,
+                gboolean       visible)
+{
+  GtkAllocation child_alloc;
 
-    if (self->flap_position == GTK_PACK_START) {
-      content_alloc->y = alloc->height - content_alloc->height + content_offset;
-      flap_alloc->y = flap_offset;
+  if (!widget)
+    return;
+
+  gtk_widget_set_child_visible (widget, visible);
+
+  if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+    if (visible) {
+      gdk_window_show_unraised (window);
+      gdk_window_move_resize (window, allocation->x, allocation->y,
+                              allocation->width, allocation->height);
     } else {
-      content_alloc->y = -content_offset;
-      flap_alloc->y = alloc->height - flap_alloc->height - flap_offset;
+      gdk_window_hide (window);
     }
   }
+
+  if (!visible)
+    return;
+
+  child_alloc.x = 0;
+  child_alloc.y = 0;
+  child_alloc.width = allocation->width;
+  child_alloc.height = allocation->height;
+
+  gtk_widget_size_allocate (widget, &child_alloc);
 }
 
 static void
@@ -662,7 +741,6 @@ hdy_flap_size_allocate (GtkWidget     *widget,
                         GtkAllocation *alloc)
 {
   HdyFlap *self = HDY_FLAP (widget);
-  GtkAllocation child_alloc;
 
   gtk_widget_set_allocation (widget, alloc);
 
@@ -671,59 +749,41 @@ hdy_flap_size_allocate (GtkWidget     *widget,
                             alloc->x, alloc->y, alloc->width, alloc->height);
 
   if (self->fold_policy == HDY_FLAP_FOLD_POLICY_AUTO) {
-    GtkRequisition flap_min, content_min;
+    GtkRequisition flap_min, content_min, separator_min;
 
     gtk_widget_get_preferred_size (self->flap, &flap_min, NULL);
     gtk_widget_get_preferred_size (self->content, &content_min, NULL);
+    gtk_widget_get_preferred_size (self->separator, &separator_min, NULL);
 
     if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
-      set_folded (self, alloc->width < content_min.width + flap_min.width);
+      set_folded (self, alloc->width < content_min.width + flap_min.width + separator_min.width);
     else
-      set_folded (self, alloc->height < content_min.height + flap_min.height);
-  }
-
-  compute_allocation (self, alloc, &self->flap_allocation, &self->content_allocation);
-
-  child_alloc.x = 0;
-  child_alloc.y = 0;
-
-  if (self->content) {
-    if (gtk_widget_get_realized (widget))
-      gdk_window_move_resize (self->content_window,
-                              self->content_allocation.x,
-                              self->content_allocation.y,
-                              self->content_allocation.width,
-                              self->content_allocation.height);
-
-    child_alloc.width = self->content_allocation.width;
-    child_alloc.height = self->content_allocation.height;
-
-    gtk_widget_size_allocate (self->content, &child_alloc);
+      set_folded (self, alloc->height < content_min.height + flap_min.height + separator_min.height);
   }
 
-  if (self->flap) {
-    gtk_widget_set_child_visible (self->flap, self->reveal_progress > 0);
-
-    if (gtk_widget_get_realized (widget)) {
-      if (self->reveal_progress > 0) {
-        gdk_window_show_unraised (self->flap_window);
-        gdk_window_move_resize (self->flap_window,
-                                self->flap_allocation.x,
-                                self->flap_allocation.y,
-                                self->flap_allocation.width,
-                                self->flap_allocation.height);
-      } else {
-        gdk_window_hide (self->flap_window);
-      }
-    }
-
-    if (self->reveal_progress > 0) {
-      child_alloc.width = self->flap_allocation.width;
-      child_alloc.height = self->flap_allocation.height;
-
-      gtk_widget_size_allocate (self->flap, &child_alloc);
-    }
-  }
+  compute_allocation (self,
+                      alloc,
+                      &self->flap_allocation,
+                      &self->content_allocation,
+                      &self->separator_allocation);
+
+  allocate_child (self,
+                  self->content,
+                  self->content_window,
+                  &self->content_allocation,
+                  TRUE);
+
+  allocate_child (self,
+                  self->separator,
+                  self->separator_window,
+                  &self->separator_allocation,
+                  self->reveal_progress > 0);
+
+  allocate_child (self,
+                  self->flap,
+                  self->flap_window,
+                  &self->flap_allocation,
+                  self->reveal_progress > 0);
 
   gtk_widget_set_clip (widget, alloc);
 }
@@ -744,29 +804,27 @@ hdy_flap_measure (GtkWidget      *widget,
 
   gint content_min = 0, content_nat = 0;
   gint flap_min = 0, flap_nat = 0;
+  gint separator_min = 0, separator_nat = 0;
   gint min, nat;
 
-  if (self->content) {
-    if (orientation == GTK_ORIENTATION_VERTICAL)
-      gtk_widget_get_preferred_height (self->content, &content_min, &content_nat);
-    else
-      gtk_widget_get_preferred_width (self->content, &content_min, &content_nat);
-  }
+  if (self->content)
+    get_preferred_size (self->content, orientation, &content_min, &content_nat);
 
-  if (self->flap) {
-    if (orientation == GTK_ORIENTATION_VERTICAL)
-      gtk_widget_get_preferred_height (self->flap, &flap_min, &flap_nat);
-    else
-      gtk_widget_get_preferred_width (self->flap, &flap_min, &flap_nat);
-  }
+  if (self->flap)
+    get_preferred_size (self->flap, orientation, &flap_min, &flap_nat);
+
+  if (self->separator)
+    get_preferred_size (self->separator, orientation, &separator_min, &separator_nat);
 
   if (self->orientation == orientation &&
       self->fold_policy != HDY_FLAP_FOLD_POLICY_AUTO) {
-    min = MAX (content_min + adjust_for_overlay (self, flap_min), flap_min);
-    nat = MAX (content_nat + adjust_for_overlay (self, flap_nat), flap_nat);
+    gdouble progress = (1 - self->fold_progress) * self->reveal_progress;
+
+    min = MAX (content_min + (gint) round ((flap_min + separator_min) * progress), flap_min);
+    nat = MAX (content_nat + (gint) round ((flap_nat + separator_nat) * progress), flap_nat);
   } else {
-    min = MAX (content_min, flap_min);
-    nat = MAX (content_nat, flap_nat);
+    min = MAX (MAX (content_min, flap_min), separator_min);
+    nat = MAX (MAX (content_nat, flap_nat), separator_nat);
   }
 
   if (minimum)
@@ -830,20 +888,34 @@ hdy_flap_draw (GtkWidget *widget,
   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 (!content_above_flap) {
+    if (self->content)
+      gtk_container_propagate_draw (GTK_CONTAINER (self),
+                                    self->content,
+                                    cr);
+
+    if (self->separator)
+      gtk_container_propagate_draw (GTK_CONTAINER (self),
+                                    self->separator,
+                                    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 (content_above_flap) {
+    if (self->separator)
+      gtk_container_propagate_draw (GTK_CONTAINER (self),
+                                    self->separator,
+                                    cr);
+
+    if (self->content)
+      gtk_container_propagate_draw (GTK_CONTAINER (self),
+                                    self->content,
+                                    cr);
+  }
 
   if (!self->flap)
     return GDK_EVENT_PROPAGATE;
@@ -930,6 +1002,9 @@ hdy_flap_realize (GtkWidget *widget)
   if (self->content)
     register_window (self, self->content, &self->content_allocation, &self->content_window);
 
+  if (self->separator)
+    register_window (self, self->separator, &self->separator_allocation, &self->separator_window);
+
   if (self->flap)
     register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
 
@@ -942,6 +1017,7 @@ hdy_flap_unrealize (GtkWidget *widget)
   HdyFlap *self = HDY_FLAP (widget);
 
   unregister_window (self, &self->content_window);
+  unregister_window (self, &self->separator_window);
   unregister_window (self, &self->flap_window);
 
   GTK_WIDGET_CLASS (hdy_flap_parent_class)->unrealize (widget);
@@ -970,6 +1046,9 @@ hdy_flap_forall (GtkContainer *container,
   if (self->content)
     callback (self->content, callback_data);
 
+  if (self->separator)
+    callback (self->separator, callback_data);
+
   if (self->flap)
     callback (self->flap, callback_data);
 }
@@ -1013,6 +1092,12 @@ hdy_flap_remove (GtkContainer *container,
     return;
   }
 
+  if (widget == self->separator) {
+    hdy_flap_set_separator (self, NULL);
+
+    return;
+  }
+
   if (widget == self->content) {
     if (gtk_widget_get_realized (GTK_WIDGET (self)))
       unregister_window (self, &self->content_window);
@@ -1037,6 +1122,9 @@ hdy_flap_get_property (GObject    *object,
   case PROP_FLAP:
     g_value_set_object (value, hdy_flap_get_flap (self));
     break;
+  case PROP_SEPARATOR:
+    g_value_set_object (value, hdy_flap_get_separator (self));
+    break;
   case PROP_FOLD_POLICY:
     g_value_set_enum (value, hdy_flap_get_fold_policy (self));
     break;
@@ -1081,6 +1169,9 @@ hdy_flap_set_property (GObject      *object,
   case PROP_FLAP:
     hdy_flap_set_flap (self, g_value_get_object (value));
     break;
+  case PROP_SEPARATOR:
+    hdy_flap_set_separator (self, g_value_get_object (value));
+    break;
   case PROP_FOLD_POLICY:
     hdy_flap_set_fold_policy (self, g_value_get_enum (value));
     break;
@@ -1158,6 +1249,18 @@ hdy_flap_class_init (HdyFlapClass *klass)
                          GTK_TYPE_WIDGET,
                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * HdyFlap:separator:
+   *
+   * Since: 1.1
+   */
+  props[PROP_SEPARATOR] =
+    g_param_spec_object ("separator",
+                         _("Separator widget"),
+                         _("Separator Widget"),
+                         GTK_TYPE_WIDGET,
+                         G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
   /**
    * HdyFlap:fold-policy:
    *
@@ -1300,10 +1403,12 @@ hdy_flap_add_child (GtkBuildable *buildable,
                     GObject      *child,
                     const gchar  *type)
 {
-  if (type && !g_strcmp0 (type, "flap"))
-    hdy_flap_set_flap (HDY_FLAP (buildable), GTK_WIDGET (child));
-  else if (!type)
+  if (!type)
     gtk_container_add (GTK_CONTAINER (buildable), GTK_WIDGET (child));
+  else if (!g_strcmp0 (type, "flap"))
+    hdy_flap_set_flap (HDY_FLAP (buildable), GTK_WIDGET (child));
+  else if (!g_strcmp0 (type, "separator"))
+    hdy_flap_set_separator (HDY_FLAP (buildable), GTK_WIDGET (child));
   else
     GTK_BUILDER_WARN_INVALID_CHILD_TYPE (HDY_FLAP (buildable), type);
 }
@@ -1336,14 +1441,23 @@ static gdouble
 hdy_flap_get_distance (HdySwipeable *swipeable)
 {
   HdyFlap *self = HDY_FLAP (swipeable);
+  gint flap, separator;
 
   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));
+  if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
+    flap = self->flap_allocation.width;
+    separator = self->separator_allocation.width;
+  } else {
+    flap = self->flap_allocation.height;
+    separator = self->separator_allocation.height;
+  }
+
+  if (transition_is_content_above_flap (self))
+    return flap + separator;
+
+  return flap + separator * (1 - self->fold_progress);
 }
 
 static gdouble *
@@ -1529,6 +1643,65 @@ hdy_flap_set_flap (HdyFlap   *self,
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
 }
 
+/**
+ * hdy_flap_get_separator:
+ * @self: a #HdyFlap
+ *
+ * Returns: (transfer none) (nullable): Flap child.
+ *
+ * Since: 1.1
+ */
+GtkWidget *
+hdy_flap_get_separator (HdyFlap *self)
+{
+  g_return_val_if_fail (HDY_IS_FLAP (self), NULL);
+
+  return self->separator;
+}
+
+/**
+ * hdy_flap_set_seoarator:
+ * @self: a #HdyFlap
+ * @separator: (nullable): flap widget
+ *
+ * Since: 1.1
+ */
+void
+hdy_flap_set_separator (HdyFlap   *self,
+                        GtkWidget *separator)
+{
+  g_return_if_fail (HDY_IS_FLAP (self));
+  g_return_if_fail (GTK_IS_WIDGET (separator) || separator == NULL);
+
+  if (self->separator == separator)
+    return;
+
+  if (self->separator) {
+    if (gtk_widget_get_realized (GTK_WIDGET (self)))
+      unregister_window (self, &self->separator_window);
+
+    gtk_widget_unparent (self->separator);
+  }
+
+  self->separator = separator;
+
+  if (self->separator) {
+    if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+      register_window (self, self->separator, &self->separator_allocation, &self->separator_window);
+      restack_windows (self);
+    }
+
+    gtk_widget_set_parent (self->separator, GTK_WIDGET (self));
+
+    if (gtk_widget_get_realized (GTK_WIDGET (self)))
+      gtk_widget_set_parent_window (self->separator, gtk_widget_get_window (GTK_WIDGET (self)));
+  }
+
+  hdy_swipe_tracker_set_enabled (self->tracker, self->separator != NULL);
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SEPARATOR]);
+}
+
 /**
  * hdy_flap_get_fold_policy:
  * @self: a #HdyFlap
diff --git a/src/hdy-flap.h b/src/hdy-flap.h
index 9d16c11a..ca9a078b 100644
--- a/src/hdy-flap.h
+++ b/src/hdy-flap.h
@@ -43,6 +43,12 @@ HDY_AVAILABLE_IN_1_1
 void       hdy_flap_set_flap (HdyFlap   *self,
                               GtkWidget *flap);
 
+HDY_AVAILABLE_IN_1_1
+GtkWidget *hdy_flap_get_separator (HdyFlap   *self);
+HDY_AVAILABLE_IN_1_1
+void       hdy_flap_set_separator (HdyFlap   *self,
+                                   GtkWidget *separator);
+
 HDY_AVAILABLE_IN_1_1
 HdyFlapFoldPolicy hdy_flap_get_fold_policy (HdyFlap           *self);
 HDY_AVAILABLE_IN_1_1


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