[libhandy/wip/haecker-felix/flap-widget] Add window, bin -> container
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy/wip/haecker-felix/flap-widget] Add window, bin -> container
- Date: Tue, 17 Nov 2020 12:19:12 +0000 (UTC)
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]