[libhandy/wip/haecker-felix/flap-widget] Add window, bin -> container



commit 73ed1bf09c1f44b67986c67a45980facd0060afc
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Tue Nov 17 17:17:35 2020 +0500

    Add window, bin -> container
    
    Swipes should now work from anywhere

 src/hdy-flap.c | 122 +++++++++++++++++++++++++++++++++++++++++++++------------
 src/hdy-flap.h |   2 +-
 2 files changed, 97 insertions(+), 27 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 00309ec4..25f66bc5 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -24,9 +24,11 @@
 
 struct _HdyFlap
 {
-  GtkBin parent_instance;
+  GtkContainer parent_instance;
 
+  GtkWidget *content;
   GtkWidget *flap;
+
   HdyFlapFoldPolicy fold_policy;
   GtkPackType flap_position;
   gboolean reveal_flap;
@@ -49,7 +51,7 @@ struct _HdyFlap
 
 static void hdy_flap_swipeable_init (HdySwipeableInterface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (HdyFlap, hdy_flap, GTK_TYPE_BIN,
+G_DEFINE_TYPE_WITH_CODE (HdyFlap, hdy_flap, GTK_TYPE_CONTAINER,
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
                          G_IMPLEMENT_INTERFACE (HDY_TYPE_SWIPEABLE, hdy_flap_swipeable_init))
 
@@ -280,18 +282,18 @@ allocate_flap (HdyFlap       *self,
   GtkTextDirection direction = gtk_widget_get_direction (GTK_WIDGET (self));
   gboolean is_rtl = direction == GTK_TEXT_DIR_RTL;
   GtkPackType start_or_end = is_rtl ? GTK_PACK_END : GTK_PACK_START;
-  gint flap_x = widget_alloc->x;
-  gint flap_y = widget_alloc->y;
+  gint flap_x = 0;
+  gint flap_y = 0;
   gint flap_size = get_flap_size (self, widget_alloc, self->orientation);
 
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
     if (self->flap_position == start_or_end)
-      flap_x -= (gint) round (flap_size * (1 - self->reveal_progress));
+      flap_x = (gint) round (flap_size * (self->reveal_progress - 1));
     else
       flap_x = widget_alloc->width - (gint) round (flap_size * self->reveal_progress);
   } else {
     if (self->flap_position == GTK_PACK_START)
-      flap_y -= (gint) round (flap_size * (1 - self->reveal_progress));
+      flap_y = (gint) round (flap_size * (self->reveal_progress - 1));
     else
       flap_y = widget_alloc->height - (gint) round (flap_size * self->reveal_progress);
   }
@@ -314,7 +316,6 @@ static void
 allocate_content (HdyFlap       *self,
                   GtkAllocation *alloc)
 {
-  GtkWidget *content = gtk_bin_get_child (GTK_BIN (self));
   GtkTextDirection direction = gtk_widget_get_direction (GTK_WIDGET (self));
   gboolean is_rtl = direction == GTK_TEXT_DIR_RTL;
   GtkPackType start_or_end = is_rtl ? GTK_PACK_END : GTK_PACK_START;
@@ -330,10 +331,10 @@ allocate_content (HdyFlap       *self,
     flap_min.width = 0;
   }
 
-  gtk_widget_get_preferred_size (content, &content_min, &content_nat);
+  gtk_widget_get_preferred_size (self->content, &content_min, &content_nat);
 
-  content_x = alloc->x;
-  content_y = alloc->y;
+  content_x = 0;
+  content_y = 0;
 
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
     gint min = content_min.width + flap_min.width;
@@ -358,7 +359,7 @@ allocate_content (HdyFlap       *self,
   child_alloc.width = get_content_size (self, alloc, GTK_ORIENTATION_HORIZONTAL);
   child_alloc.height = get_content_size (self, alloc, GTK_ORIENTATION_VERTICAL);
 
-  gtk_widget_size_allocate (content, &child_alloc);
+  gtk_widget_size_allocate (self->content, &child_alloc);
 }
 
 static void
@@ -366,14 +367,17 @@ hdy_flap_size_allocate (GtkWidget     *widget,
                         GtkAllocation *alloc)
 {
   HdyFlap *self = HDY_FLAP (widget);
-  GtkWidget *content = gtk_bin_get_child (GTK_BIN (self));
 
   gtk_widget_set_allocation (widget, alloc);
 
+  if (gtk_widget_get_realized (widget))
+    gdk_window_move_resize (gtk_widget_get_window (widget),
+                            alloc->x, alloc->y, alloc->width, alloc->height);
+
   if (self->flap)
     allocate_flap (self, alloc);
 
-  if (content)
+  if (self->content)
     allocate_content (self, alloc);
 
   gtk_widget_set_clip (widget, alloc);
@@ -392,7 +396,6 @@ hdy_flap_measure (GtkWidget      *widget,
                   gint           *natural_baseline)
 {
   HdyFlap *self = HDY_FLAP (widget);
-  GtkWidget *content = gtk_bin_get_child (GTK_BIN (self));
 
   gint content_min = 0, content_nat = 0;
   gint flap_min = 0, flap_nat = 0;
@@ -407,8 +410,8 @@ hdy_flap_measure (GtkWidget      *widget,
     *natural_baseline = -1;
 
   if (orientation == GTK_ORIENTATION_VERTICAL) {
-    if (content)
-      gtk_widget_get_preferred_height (content, &content_min, &content_nat);
+    if (self->content)
+      gtk_widget_get_preferred_height (self->content, &content_min, &content_nat);
 
     if (self->flap)
       gtk_widget_get_preferred_height (self->flap, &flap_min, &flap_nat);
@@ -424,8 +427,8 @@ hdy_flap_measure (GtkWidget      *widget,
       return;
     }
   } else {
-    if (content)
-      gtk_widget_get_preferred_width (content, &content_min, &content_nat);
+    if (self->content)
+      gtk_widget_get_preferred_width (self->content, &content_min, &content_nat);
 
     if (self->flap)
       gtk_widget_get_preferred_width (self->flap, &flap_min, &flap_nat);
@@ -524,7 +527,7 @@ hdy_flap_draw (GtkWidget *widget,
   }
 
   gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                gtk_bin_get_child (GTK_BIN (self)),
+                                self->content,
                                 cr);
 
   gtk_container_propagate_draw (GTK_CONTAINER (self),
@@ -542,6 +545,41 @@ hdy_flap_draw (GtkWidget *widget,
   return GDK_EVENT_PROPAGATE;
 }
 
+static void
+hdy_flap_realize (GtkWidget *widget)
+{
+  HdyFlap *self = HDY_FLAP (widget);
+  GtkAllocation allocation;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+  GdkWindow *window;
+
+  gtk_widget_get_allocation (widget, &allocation);
+  gtk_widget_set_realized (widget, TRUE);
+
+  attributes.x = allocation.x;
+  attributes.y = allocation.y;
+  attributes.width = allocation.width;
+  attributes.height = allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+
+  window = gdk_window_new (gtk_widget_get_parent_window (widget),
+                           &attributes,
+                           attributes_mask);
+  gtk_widget_set_window (widget, window);
+  gtk_widget_register_window (widget, window);
+
+  if (self->content)
+    gtk_widget_set_parent_window (self->content, window);
+
+  if (self->flap)
+    gtk_widget_set_parent_window (self->flap, window);
+}
+
 static void
 hdy_flap_direction_changed (GtkWidget        *widget,
                             GtkTextDirection  previous_direction)
@@ -558,16 +596,40 @@ static void
 hdy_flap_forall (GtkContainer *container,
                  gboolean      include_internals,
                  GtkCallback   callback,
-                 gpointer      callback_target)
+                 gpointer      callback_data)
 {
   HdyFlap *self = HDY_FLAP (container);
-  GtkWidget *content = gtk_bin_get_child (GTK_BIN (self));
 
-  if (content)
-    callback (content, callback_target);
+  if (self->content)
+    callback (self->content, callback_data);
 
   if (self->flap)
-    callback (self->flap, callback_target);
+    callback (self->flap, callback_data);
+}
+
+static void
+hdy_flap_add (GtkContainer *container,
+              GtkWidget    *widget)
+{
+  HdyFlap *self = HDY_FLAP (container);
+
+  if (self->content) {
+    g_warning ("Attempting to add a widget with type %s to a %s, "
+               "but %s can only contain one widget at a time; "
+               "it already contains a widget of type %s",
+               g_type_name (G_OBJECT_TYPE (widget)),
+               g_type_name (G_OBJECT_TYPE (self)),
+               g_type_name (G_OBJECT_TYPE (self)),
+               g_type_name (G_OBJECT_TYPE (self->content)));
+
+    return;
+  }
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (self));
+  self->content = widget;
+
+  if (gtk_widget_get_realized (GTK_WIDGET (self)))
+    gtk_widget_set_parent_window (self->content, gtk_widget_get_window (GTK_WIDGET (self)));
 }
 
 static void
@@ -578,8 +640,10 @@ hdy_flap_remove (GtkContainer *container,
 
   if (widget == self->flap)
     hdy_flap_set_flap (self, NULL);
+  else if (widget == self->content)
+    g_clear_pointer (&self->content, gtk_widget_unparent);
   else
-    GTK_CONTAINER_CLASS (hdy_flap_parent_class)->remove (container, widget);
+    g_return_if_reached ();
 }
 
 static void
@@ -689,9 +753,11 @@ 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->realize = hdy_flap_realize;
   widget_class->direction_changed = hdy_flap_direction_changed;
 
   container_class->remove = hdy_flap_remove;
+  container_class->add = hdy_flap_add;
   container_class->forall = hdy_flap_forall;
 
   /**
@@ -966,9 +1032,13 @@ hdy_flap_set_flap (HdyFlap   *self,
 
   self->flap = flap;
 
-  if (self->flap)
+  if (self->flap) {
     gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
 
+    if (gtk_widget_get_realized (GTK_WIDGET (self)))
+      gtk_widget_set_parent_window (self->flap, gtk_widget_get_window (GTK_WIDGET (self)));
+  }
+
   hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
diff --git a/src/hdy-flap.h b/src/hdy-flap.h
index ed61089e..1a3109c1 100644
--- a/src/hdy-flap.h
+++ b/src/hdy-flap.h
@@ -20,7 +20,7 @@ G_BEGIN_DECLS
 #define HDY_TYPE_FLAP (hdy_flap_get_type ())
 
 HDY_AVAILABLE_IN_1_1
-G_DECLARE_FINAL_TYPE (HdyFlap, hdy_flap, HDY, FLAP, GtkBin)
+G_DECLARE_FINAL_TYPE (HdyFlap, hdy_flap, HDY, FLAP, GtkContainer)
 
 typedef enum {
   HDY_FLAP_FOLD_POLICY_NEVER,


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