[libhandy] Add reordering API to HdyDeck and HdyLeaflet



commit d39d9bf10c5074a46c4e15233a76e6863f638ac8
Author: Yetizone <andreii lisita gmail com>
Date:   Mon Oct 19 22:14:27 2020 +0300

    Add reordering API to HdyDeck and HdyLeaflet
    
    Fixes https://gitlab.gnome.org/GNOME/libhandy/-/issues/338
    Fixes https://gitlab.gnome.org/GNOME/libhandy/-/issues/169

 debian/libhandy-1-0.symbols     |   6 ++
 src/hdy-deck.c                  |  75 +++++++++++++++++++
 src/hdy-deck.h                  |  12 +++
 src/hdy-leaflet.c               |  75 +++++++++++++++++++
 src/hdy-leaflet.h               |  12 +++
 src/hdy-stackable-box-private.h |   8 ++
 src/hdy-stackable-box.c         | 160 +++++++++++++++++++++++++++++++++-------
 tests/test-deck.c               | 105 ++++++++++++++++++++++++++
 tests/test-leaflet.c            |  81 ++++++++++++++++++++
 9 files changed, 506 insertions(+), 28 deletions(-)
---
diff --git a/debian/libhandy-1-0.symbols b/debian/libhandy-1-0.symbols
index 75901fae..c5b725da 100644
--- a/debian/libhandy-1-0.symbols
+++ b/debian/libhandy-1-0.symbols
@@ -86,8 +86,11 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
  hdy_deck_get_type@LIBHANDY_1_0 0.80.0
  hdy_deck_get_visible_child@LIBHANDY_1_0 0.80.0
  hdy_deck_get_visible_child_name@LIBHANDY_1_0 0.80.0
+ hdy_deck_insert_child_after@LIBHANDY_1_0 1.1.0
  hdy_deck_navigate@LIBHANDY_1_0 0.80.0
  hdy_deck_new@LIBHANDY_1_0 0.80.0
+ hdy_deck_prepend@LIBHANDY_1_0 1.1.0
+ hdy_deck_reorder_child_after@LIBHANDY_1_0 1.1.0
  hdy_deck_set_can_swipe_back@LIBHANDY_1_0 0.80.0
  hdy_deck_set_can_swipe_forward@LIBHANDY_1_0 0.80.0
  hdy_deck_set_homogeneous@LIBHANDY_1_0 0.80.0
@@ -193,8 +196,11 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
  hdy_leaflet_get_type@LIBHANDY_1_0 0.0~git20180429
  hdy_leaflet_get_visible_child@LIBHANDY_1_0 0.0~git20180429
  hdy_leaflet_get_visible_child_name@LIBHANDY_1_0 0.0~git20180429
+ hdy_leaflet_insert_child_after@LIBHANDY_1_0 1.1.0
  hdy_leaflet_navigate@LIBHANDY_1_0 0.80.0
  hdy_leaflet_new@LIBHANDY_1_0 0.0~git20180429
+ hdy_leaflet_prepend@LIBHANDY_1_0 1.1.0
+ hdy_leaflet_reorder_child_after@LIBHANDY_1_0 1.1.0
  hdy_leaflet_set_can_swipe_back@LIBHANDY_1_0 0.0.12
  hdy_leaflet_set_can_swipe_forward@LIBHANDY_1_0 0.0.12
  hdy_leaflet_set_child_transition_duration@LIBHANDY_1_0 0.0~git20180429
diff --git a/src/hdy-deck.c b/src/hdy-deck.c
index 01dc45e9..0736cfb0 100644
--- a/src/hdy-deck.c
+++ b/src/hdy-deck.c
@@ -531,6 +531,81 @@ hdy_deck_get_child_by_name (HdyDeck     *self,
   return hdy_stackable_box_get_child_by_name (HDY_GET_HELPER (self), name);
 }
 
+/**
+ * hdy_deck_prepend:
+ * @self: a #HdyDeck
+ * @child: the #GtkWidget to prepend
+ *
+ * Inserts @child at the first position in @self.
+ *
+ * Since: 1.1
+ */
+void
+hdy_deck_prepend (HdyDeck   *self,
+                  GtkWidget *child)
+{
+  g_return_if_fail (HDY_IS_DECK (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+
+  hdy_stackable_box_prepend (HDY_GET_HELPER (self), child);
+}
+
+/**
+ * hdy_deck_insert_child_after:
+ * @self: a #HdyDeck
+ * @child: the #GtkWidget to insert
+ * @sibling: (nullable): the sibling to insert @child after, or %NULL
+ *
+ * Inserts @child in the position after @sibling in the list of children.
+ * If @sibling is %NULL, insert @child at the first position.
+ *
+ * Since: 1.1
+ */
+void
+hdy_deck_insert_child_after (HdyDeck   *self,
+                             GtkWidget *child,
+                             GtkWidget *sibling)
+{
+  g_return_if_fail (HDY_IS_DECK (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self));
+
+  hdy_stackable_box_insert_child_after (HDY_GET_HELPER (self), child, sibling);
+}
+
+/**
+ * hdy_deck_reorder_child_after:
+ * @self: a #HdyDeck
+ * @child: the #GtkWidget to move, must be a child of @self
+ * @sibling: (nullable): the sibling to move @child after, or %NULL
+ *
+ * Moves @child to the position after @sibling in the list of children.
+ * If @sibling is %NULL, move @child to the first position.
+ *
+ * Since: 1.1
+ */
+void
+hdy_deck_reorder_child_after (HdyDeck   *self,
+                              GtkWidget *child,
+                              GtkWidget *sibling)
+{
+  g_return_if_fail (HDY_IS_DECK (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (self));
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self));
+
+  if (child == sibling)
+    return;
+
+  hdy_stackable_box_reorder_child_after (HDY_GET_HELPER (self), child, sibling);
+}
+
 /* This private method is prefixed by the call name because it will be a virtual
  * method in GTK 4.
  */
diff --git a/src/hdy-deck.h b/src/hdy-deck.h
index 3c7da182..377990f2 100644
--- a/src/hdy-deck.h
+++ b/src/hdy-deck.h
@@ -99,4 +99,16 @@ HDY_AVAILABLE_IN_ALL
 GtkWidget       *hdy_deck_get_child_by_name (HdyDeck     *self,
                                              const gchar *name);
 
+HDY_AVAILABLE_IN_1_1
+void             hdy_deck_prepend (HdyDeck   *self,
+                                   GtkWidget *child);
+HDY_AVAILABLE_IN_1_1
+void             hdy_deck_insert_child_after (HdyDeck   *self,
+                                              GtkWidget *child,
+                                              GtkWidget *sibling);
+HDY_AVAILABLE_IN_1_1
+void             hdy_deck_reorder_child_after (HdyDeck   *self,
+                                               GtkWidget *child,
+                                               GtkWidget *sibling);
+
 G_END_DECLS
diff --git a/src/hdy-leaflet.c b/src/hdy-leaflet.c
index 8c1ba2ad..01d2fa34 100644
--- a/src/hdy-leaflet.c
+++ b/src/hdy-leaflet.c
@@ -575,6 +575,81 @@ hdy_leaflet_get_child_by_name (HdyLeaflet  *self,
   return hdy_stackable_box_get_child_by_name (HDY_GET_HELPER (self), name);
 }
 
+/**
+ * hdy_leaflet_prepend:
+ * @self: a #HdyLeaflet
+ * @child: the #GtkWidget to prepend
+ *
+ * Inserts @child at the first position in @self.
+ *
+ * Since: 1.1
+ */
+void
+hdy_leaflet_prepend (HdyLeaflet *self,
+                     GtkWidget  *child)
+{
+  g_return_if_fail (HDY_IS_LEAFLET (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+
+  hdy_stackable_box_prepend (HDY_GET_HELPER (self), child);
+}
+
+/**
+ * hdy_leaflet_insert_child_after:
+ * @self: a #HdyLeaflet
+ * @child: the #GtkWidget to insert
+ * @sibling: (nullable): the sibling to insert @child after, or %NULL
+ *
+ * Inserts @child in the position after @sibling in the list of children.
+ * If @sibling is %NULL, insert @child at the first position.
+ *
+ * Since: 1.1
+ */
+void
+hdy_leaflet_insert_child_after (HdyLeaflet *self,
+                                GtkWidget  *child,
+                                GtkWidget  *sibling)
+{
+  g_return_if_fail (HDY_IS_LEAFLET (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self));
+
+  hdy_stackable_box_insert_child_after (HDY_GET_HELPER (self), child, sibling);
+}
+
+/**
+ * hdy_leaflet_reorder_child_after:
+ * @self: a #HdyLeaflet
+ * @child: the #GtkWidget to move, must be a child of @self
+ * @sibling: (nullable): the sibling to move @child after, or %NULL
+ *
+ * Moves @child to the position after @sibling in the list of children.
+ * If @sibling is %NULL, move @child to the first position.
+ *
+ * Since: 1.1
+ */
+void
+hdy_leaflet_reorder_child_after (HdyLeaflet *self,
+                                 GtkWidget  *child,
+                                 GtkWidget  *sibling)
+{
+  g_return_if_fail (HDY_IS_LEAFLET (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (self));
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self));
+
+  if (child == sibling)
+    return;
+
+  hdy_stackable_box_reorder_child_after (HDY_GET_HELPER (self), child, sibling);
+}
+
 /* This private method is prefixed by the call name because it will be a virtual
  * method in GTK 4.
  */
diff --git a/src/hdy-leaflet.h b/src/hdy-leaflet.h
index 4d9324d7..5ad4d6d1 100644
--- a/src/hdy-leaflet.h
+++ b/src/hdy-leaflet.h
@@ -110,4 +110,16 @@ HDY_AVAILABLE_IN_ALL
 GtkWidget       *hdy_leaflet_get_child_by_name (HdyLeaflet  *self,
                                                 const gchar *name);
 
+HDY_AVAILABLE_IN_1_1
+void             hdy_leaflet_prepend (HdyLeaflet *self,
+                                      GtkWidget  *child);
+HDY_AVAILABLE_IN_1_1
+void             hdy_leaflet_insert_child_after (HdyLeaflet *self,
+                                                 GtkWidget  *child,
+                                                 GtkWidget  *sibling);
+HDY_AVAILABLE_IN_1_1
+void             hdy_leaflet_reorder_child_after (HdyLeaflet *self,
+                                                  GtkWidget  *child,
+                                                  GtkWidget  *sibling);
+
 G_END_DECLS
diff --git a/src/hdy-stackable-box-private.h b/src/hdy-stackable-box-private.h
index d72c75a7..9c7a5009 100644
--- a/src/hdy-stackable-box-private.h
+++ b/src/hdy-stackable-box-private.h
@@ -129,5 +129,13 @@ void             hdy_stackable_box_map (HdyStackableBox *self);
 void             hdy_stackable_box_unmap (HdyStackableBox *self);
 void             hdy_stackable_box_direction_changed (HdyStackableBox  *self,
                                                       GtkTextDirection  previous_direction);
+void             hdy_stackable_box_prepend (HdyStackableBox *self,
+                                            GtkWidget       *child);
+void             hdy_stackable_box_insert_child_after (HdyStackableBox *self,
+                                                       GtkWidget       *child,
+                                                       GtkWidget       *sibling);
+void             hdy_stackable_box_reorder_child_after (HdyStackableBox *self,
+                                                        GtkWidget       *child,
+                                                        GtkWidget       *sibling);
 
 G_END_DECLS
diff --git a/src/hdy-stackable-box.c b/src/hdy-stackable-box.c
index de3940b9..d0ea9115 100644
--- a/src/hdy-stackable-box.c
+++ b/src/hdy-stackable-box.c
@@ -13,6 +13,7 @@
 #include "hdy-enums-private.h"
 #include "hdy-stackable-box-private.h"
 #include "hdy-shadow-helper-private.h"
+#include "hdy-swipe-tracker-private.h"
 #include "hdy-swipeable.h"
 
 /**
@@ -2278,36 +2279,13 @@ void
 hdy_stackable_box_add (HdyStackableBox *self,
                        GtkWidget       *widget)
 {
-  HdyStackableBoxChildInfo *child_info;
-
-  g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
-
-  child_info = g_new0 (HdyStackableBoxChildInfo, 1);
-  child_info->widget = widget;
-  child_info->navigatable = TRUE;
-
-  self->children = g_list_append (self->children, child_info);
-  self->children_reversed = g_list_prepend (self->children_reversed, child_info);
-
-  if (gtk_widget_get_realized (GTK_WIDGET (self->container)))
-    register_window (self, child_info);
-
-  gtk_widget_set_child_visible (widget, FALSE);
-  gtk_widget_set_parent (widget, GTK_WIDGET (self->container));
-
-  g_signal_connect (widget, "notify::visible",
-                    G_CALLBACK (hdy_stackable_box_child_visibility_notify_cb), self);
+  if (self->children == NULL) {
+    hdy_stackable_box_insert_child_after (self, widget, NULL);
+  } else {
+    HdyStackableBoxChildInfo *last_child_info = g_list_last (self->children)->data;
 
-  if (hdy_stackable_box_get_visible_child (self) == NULL &&
-      gtk_widget_get_visible (widget)) {
-    set_visible_child_info (self, child_info, self->transition_type, self->child_transition.duration, FALSE);
+    hdy_stackable_box_insert_child_after (self, widget, last_child_info->widget);
   }
-
-  if (!self->folded ||
-      (self->folded && (self->homogeneous[HDY_FOLD_FOLDED][GTK_ORIENTATION_HORIZONTAL] ||
-                        self->homogeneous[HDY_FOLD_FOLDED][GTK_ORIENTATION_VERTICAL] ||
-                        self->visible_child == child_info)))
-    gtk_widget_queue_resize (GTK_WIDGET (self->container));
 }
 
 void
@@ -2917,6 +2895,132 @@ hdy_stackable_box_set_child_navigatable (HdyStackableBox *self,
     set_visible_child_info (self, NULL, self->transition_type, self->child_transition.duration, TRUE);
 }
 
+void
+hdy_stackable_box_prepend (HdyStackableBox *self,
+                           GtkWidget       *child)
+{
+  g_return_if_fail (HDY_IS_STACKABLE_BOX (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+
+  hdy_stackable_box_insert_child_after (self, child, NULL);
+}
+
+void
+hdy_stackable_box_insert_child_after (HdyStackableBox *self,
+                                      GtkWidget       *child,
+                                      GtkWidget       *sibling)
+{
+  HdyStackableBoxChildInfo *child_info;
+  gint visible_child_pos_before_insert = -1;
+  gint visible_child_pos_after_insert = -1;
+
+  g_return_if_fail (HDY_IS_STACKABLE_BOX (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == NULL);
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self->container));
+
+  child_info = g_new0 (HdyStackableBoxChildInfo, 1);
+  child_info->widget = child;
+  child_info->navigatable = TRUE;
+
+  if (self->visible_child)
+    visible_child_pos_before_insert = g_list_index (self->children, self->visible_child);
+
+  if (!sibling) {
+    self->children = g_list_prepend (self->children, child_info);
+    self->children_reversed = g_list_append (self->children_reversed, child_info);
+  } else {
+    HdyStackableBoxChildInfo *sibling_info = find_child_info_for_widget (self, sibling);
+    gint sibling_info_pos = g_list_index (self->children, sibling_info);
+
+    self->children =
+      g_list_insert (self->children, child_info,
+                     sibling_info_pos + 1);
+    self->children_reversed =
+      g_list_insert (self->children_reversed, child_info,
+                     g_list_length (self->children) - sibling_info_pos - 1);
+  }
+
+  if (self->visible_child)
+    visible_child_pos_after_insert = g_list_index (self->children, self->visible_child);
+
+  if (gtk_widget_get_realized (GTK_WIDGET (self->container)))
+    register_window (self, child_info);
+
+  gtk_widget_set_child_visible (child, FALSE);
+  gtk_widget_set_parent (child, GTK_WIDGET (self->container));
+
+  g_signal_connect (child, "notify::visible",
+                    G_CALLBACK (hdy_stackable_box_child_visibility_notify_cb), self);
+
+  if (!hdy_stackable_box_get_visible_child (self) &&
+      gtk_widget_get_visible (child))
+    set_visible_child_info (self,
+                            child_info,
+                            self->transition_type,
+                            self->child_transition.duration,
+                            FALSE);
+  else if (visible_child_pos_before_insert != visible_child_pos_after_insert)
+    hdy_swipeable_emit_child_switched (HDY_SWIPEABLE (self->container),
+                                       visible_child_pos_after_insert,
+                                       0);
+
+  if (!self->folded ||
+      (self->homogeneous[HDY_FOLD_FOLDED][GTK_ORIENTATION_HORIZONTAL] ||
+       self->homogeneous[HDY_FOLD_FOLDED][GTK_ORIENTATION_VERTICAL] ||
+       self->visible_child == child_info))
+    gtk_widget_queue_resize (GTK_WIDGET (self->container));
+}
+
+void
+hdy_stackable_box_reorder_child_after (HdyStackableBox *self,
+                                       GtkWidget       *child,
+                                       GtkWidget       *sibling)
+{
+  HdyStackableBoxChildInfo *child_info;
+  HdyStackableBoxChildInfo *sibling_info;
+  gint sibling_info_pos;
+  gint visible_child_pos_before_reorder;
+  gint visible_child_pos_after_reorder;
+
+  g_return_if_fail (HDY_IS_STACKABLE_BOX (self));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (sibling == NULL || GTK_IS_WIDGET (sibling));
+
+  g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (self->container));
+  g_return_if_fail (sibling == NULL || gtk_widget_get_parent (sibling) == GTK_WIDGET (self->container));
+
+  if (child == sibling)
+    return;
+
+  visible_child_pos_before_reorder = g_list_index (self->children, self->visible_child);
+
+  /* Cancel a gesture if there's one in progress */
+  hdy_swipe_tracker_emit_end_swipe (self->tracker, 0, 0.0);
+
+  child_info = find_child_info_for_widget (self, child);
+  self->children = g_list_remove (self->children, child_info);
+  self->children_reversed = g_list_remove (self->children_reversed, child_info);
+
+  sibling_info = find_child_info_for_widget (self, sibling);
+  sibling_info_pos = g_list_index (self->children, sibling_info);
+
+  self->children =
+    g_list_insert (self->children, child_info,
+                   sibling_info_pos + 1);
+  self->children_reversed =
+    g_list_insert (self->children_reversed, child_info,
+                   g_list_length (self->children) - sibling_info_pos - 1);
+
+  visible_child_pos_after_reorder = g_list_index (self->children, self->visible_child);
+
+  if (visible_child_pos_before_reorder != visible_child_pos_after_reorder)
+    hdy_swipeable_emit_child_switched (HDY_SWIPEABLE (self->container), visible_child_pos_after_reorder, 0);
+}
+
 static void
 hdy_stackable_box_class_init (HdyStackableBoxClass *klass)
 {
diff --git a/tests/test-deck.c b/tests/test-deck.c
index e2c56776..9a1fd920 100644
--- a/tests/test-deck.c
+++ b/tests/test-deck.c
@@ -79,6 +79,108 @@ test_hdy_deck_navigate (void)
 }
 
 
+static void
+test_hdy_deck_prepend (void)
+{
+  g_autoptr (HdyDeck) deck = NULL;
+  GtkWidget *labels[2];
+  gint i;
+  GList *children = NULL;
+
+  deck = HDY_DECK (hdy_deck_new ());
+  g_assert_nonnull (deck);
+
+  for (i = 0; i < 2; i++) {
+    labels[i] = gtk_label_new ("");
+    g_assert_nonnull (labels[i]);
+  }
+
+  hdy_deck_prepend (deck, labels[1]);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 0);
+  g_list_free (children);
+
+  hdy_deck_prepend (deck, labels[0]);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 1);
+  g_list_free (children);
+}
+
+
+static void
+test_hdy_deck_insert_child_after (void)
+{
+  g_autoptr (HdyDeck) deck = NULL;
+  GtkWidget *labels[3];
+  gint i;
+  GList *children = NULL;
+
+  deck = HDY_DECK (hdy_deck_new ());
+  g_assert_nonnull (deck);
+
+  for (i = 0; i < 3; i++) {
+    labels[i] = gtk_label_new ("");
+    g_assert_nonnull (labels[i]);
+  }
+
+  gtk_container_add (GTK_CONTAINER (deck), labels[2]);
+
+  hdy_deck_insert_child_after (deck, labels[0], NULL);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[2]), ==, 1);
+  g_list_free (children);
+
+  hdy_deck_insert_child_after (deck, labels[1], labels[0]);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 1);
+  g_assert_cmpint (g_list_index (children, labels[2]), ==, 2);
+  g_list_free (children);
+}
+
+
+static void
+test_hdy_deck_reorder_child_after (void)
+{
+  g_autoptr (HdyDeck) deck = NULL;
+  GtkWidget *labels[3];
+  gint i;
+  GList *children = NULL;
+
+  deck = HDY_DECK (hdy_deck_new ());
+  g_assert_nonnull (deck);
+
+  for (i = 0; i < 3; i++) {
+    labels[i] = gtk_label_new ("");
+    g_assert_nonnull (labels[i]);
+
+    gtk_container_add (GTK_CONTAINER (deck), labels[i]);
+  }
+
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 1);
+  g_assert_cmpint (g_list_index (children, labels[2]), ==, 2);
+  g_list_free (children);
+
+  hdy_deck_reorder_child_after (deck, labels[2], NULL);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[2]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 1);
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 2);
+  g_list_free (children);
+
+  hdy_deck_reorder_child_after (deck, labels[0], labels[1]);
+  children = gtk_container_get_children (GTK_CONTAINER (deck));
+  g_assert_cmpint (g_list_index (children, labels[2]), ==, 0);
+  g_assert_cmpint (g_list_index (children, labels[1]), ==, 1);
+  g_assert_cmpint (g_list_index (children, labels[0]), ==, 2);
+  g_list_free (children);
+}
+
+
 gint
 main (gint argc,
       gchar *argv[])
@@ -88,6 +190,9 @@ main (gint argc,
 
   g_test_add_func ("/Handy/Deck/adjacent_child", test_hdy_deck_adjacent_child);
   g_test_add_func ("/Handy/Deck/navigate", test_hdy_deck_navigate);
+  g_test_add_func ("/Handy/Deck/prepend", test_hdy_deck_prepend);
+  g_test_add_func ("/Handy/Deck/insert_child_after", test_hdy_deck_insert_child_after);
+  g_test_add_func ("/Handy/Deck/reorder_child_after", test_hdy_deck_reorder_child_after);
 
   return g_test_run ();
 }
diff --git a/tests/test-leaflet.c b/tests/test-leaflet.c
index 43afb3c1..7ea5ce63 100644
--- a/tests/test-leaflet.c
+++ b/tests/test-leaflet.c
@@ -95,6 +95,84 @@ test_hdy_leaflet_navigate (void)
 }
 
 
+static void
+test_hdy_leaflet_prepend (void)
+{
+  g_autoptr (HdyLeaflet) leaflet = NULL;
+  GtkWidget *label_A = gtk_label_new("");
+  GtkWidget *label_B = gtk_label_new("");
+  GList *children = NULL;
+
+  leaflet = HDY_LEAFLET (hdy_leaflet_new ());
+  g_assert_nonnull (leaflet);
+
+  hdy_leaflet_prepend (leaflet, label_B);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_B) == 0);
+  g_list_free (children);
+
+  hdy_leaflet_prepend (leaflet, label_A);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_A) == 0);
+  g_assert_true (g_list_index (children, label_B) == 1);
+  g_list_free (children);
+}
+
+
+static void
+test_hdy_leaflet_insert_child_after (void)
+{
+  g_autoptr (HdyLeaflet) leaflet = NULL;
+  GtkWidget *label_A = gtk_label_new("");
+  GtkWidget *label_B = gtk_label_new("");
+  GtkWidget *label_C = gtk_label_new("");
+  GList *children = NULL;
+
+  leaflet = HDY_LEAFLET (hdy_leaflet_new ());
+  g_assert_nonnull (leaflet);
+
+  gtk_container_add (GTK_CONTAINER (leaflet), label_B);
+
+  hdy_leaflet_insert_child_after (leaflet, label_A, NULL);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_A) == 0);
+  g_list_free (children);
+
+  hdy_leaflet_insert_child_after (leaflet, label_C, label_B);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_C) == 2);
+  g_list_free (children);
+}
+
+
+static void
+test_hdy_leaflet_reorder_child_after (void)
+{
+  g_autoptr (HdyLeaflet) leaflet = NULL;
+  GtkWidget *label_A = gtk_label_new("");
+  GtkWidget *label_B = gtk_label_new("");
+  GtkWidget *label_C = gtk_label_new("");
+  GList *children = NULL;
+
+  leaflet = HDY_LEAFLET (hdy_leaflet_new ());
+  g_assert_nonnull (leaflet);
+
+  gtk_container_add (GTK_CONTAINER (leaflet), label_A);
+  gtk_container_add (GTK_CONTAINER (leaflet), label_B);
+  gtk_container_add (GTK_CONTAINER (leaflet), label_C);
+
+  hdy_leaflet_reorder_child_after (leaflet, label_C, NULL);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_C) == 0);
+  g_list_free (children);
+
+  hdy_leaflet_reorder_child_after (leaflet, label_A, label_B);
+  children = gtk_container_get_children (GTK_CONTAINER (leaflet));
+  g_assert_true (g_list_index (children, label_A) == 2);
+  g_list_free (children);
+}
+
+
 gint
 main (gint argc,
       gchar *argv[])
@@ -104,6 +182,9 @@ main (gint argc,
 
   g_test_add_func ("/Handy/Leaflet/adjacent_child", test_hdy_leaflet_adjacent_child);
   g_test_add_func ("/Handy/Leaflet/navigate", test_hdy_leaflet_navigate);
+  g_test_add_func ("/Handy/Leaflet/prepend", test_hdy_leaflet_prepend);
+  g_test_add_func ("/Handy/Leaflet/insert_child_after", test_hdy_leaflet_insert_child_after);
+  g_test_add_func ("/Handy/Leaflet/reorder_child_after", test_hdy_leaflet_reorder_child_after);
 
   return g_test_run ();
 }


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