[libhandy/wip/haecker-felix/flap-widget] Child structs
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy/wip/haecker-felix/flap-widget] Child structs
- Date: Mon, 23 Nov 2020 12:13:54 +0000 (UTC)
commit b0cc4afe879ab16c31cef062210da291bb354dcb
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Mon Nov 23 17:05:18 2020 +0500
Child structs
src/hdy-flap.c | 372 +++++++++++++++++++++++++++------------------------------
1 file changed, 176 insertions(+), 196 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 440f628a..c2cfc193 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -47,21 +47,20 @@
#define HDY_SWIPE_BORDER 16
+typedef struct {
+ GtkWidget *widget;
+ GdkWindow *window;
+ GtkAllocation allocation;
+ gboolean visible;
+} ChildInfo;
+
struct _HdyFlap
{
GtkContainer parent_instance;
- GtkWidget *content;
- GtkWidget *flap;
- GtkWidget *separator;
-
- GdkWindow *content_window;
- GdkWindow *separator_window;
- GdkWindow *flap_window;
-
- GtkAllocation flap_allocation;
- GtkAllocation content_allocation;
- GtkAllocation separator_allocation;
+ ChildInfo content;
+ ChildInfo flap;
+ ChildInfo separator;
HdyFlapFoldPolicy fold_policy;
HdyFlapTransitionType transition_type;
@@ -341,10 +340,10 @@ pressed_cb (GtkGestureMultiPress *gesture,
return;
}
- if (x >= self->flap_allocation.x &&
- x <= self->flap_allocation.x + self->flap_allocation.width &&
- y >= self->flap_allocation.y &&
- y <= self->flap_allocation.y + self->flap_allocation.height) {
+ if (x >= self->flap.allocation.x &&
+ x <= self->flap.allocation.x + self->flap.allocation.width &&
+ y >= self->flap.allocation.y &&
+ y <= self->flap.allocation.y + self->flap.allocation.height) {
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
@@ -354,46 +353,47 @@ pressed_cb (GtkGestureMultiPress *gesture,
}
static void
-register_window (HdyFlap *self,
- GtkWidget *widget,
- GtkAllocation *allocation,
- GdkWindow **window)
+register_window (HdyFlap *self,
+ ChildInfo *info)
{
GdkWindowAttr attributes = { 0 };
GdkWindowAttributesType attributes_mask;
- attributes.x = allocation->x;
- attributes.y = allocation->y;
- attributes.width = allocation->width;
- attributes.height = allocation->height;
+ if (!info->widget)
+ return;
+
+ attributes.x = info->allocation.x;
+ attributes.y = info->allocation.y;
+ attributes.width = info->allocation.width;
+ attributes.height = info->allocation.height;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.event_mask = gtk_widget_get_events (widget);
+ attributes.visual = gtk_widget_get_visual (info->widget);
+ attributes.event_mask = gtk_widget_get_events (info->widget);
attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
attributes.event_mask = gtk_widget_get_events (GTK_WIDGET (self)) |
- gtk_widget_get_events (widget);
+ gtk_widget_get_events (info->widget);
- *window = gdk_window_new (gtk_widget_get_window (GTK_WIDGET (self)),
- &attributes, attributes_mask);
- gtk_widget_register_window (GTK_WIDGET (self), *window);
+ info->window = gdk_window_new (gtk_widget_get_window (GTK_WIDGET (self)),
+ &attributes, attributes_mask);
+ gtk_widget_register_window (GTK_WIDGET (self), info->window);
- gtk_widget_set_parent_window (widget, *window);
+ gtk_widget_set_parent_window (info->widget, info->window);
- gdk_window_show (*window);
+ gdk_window_show (info->window);
}
static void
-unregister_window (HdyFlap *self,
- GdkWindow **window)
+unregister_window (HdyFlap *self,
+ ChildInfo *info)
{
- if (!*window)
+ if (!info->window)
return;
- gtk_widget_unregister_window (GTK_WIDGET (self), *window);
- gdk_window_destroy (*window);
- *window = NULL;
+ gtk_widget_unregister_window (GTK_WIDGET (self), info->window);
+ gdk_window_destroy (info->window);
+ info->window = NULL;
}
static gboolean
@@ -450,22 +450,22 @@ restack_windows (HdyFlap *self)
gboolean content_above_flap = transition_is_content_above_flap (self);
if (!content_above_flap) {
- if (self->content_window)
- gdk_window_raise (self->content_window);
+ if (self->content.window)
+ gdk_window_raise (self->content.window);
- if (self->separator_window)
- gdk_window_raise (self->separator_window);
+ if (self->separator.window)
+ gdk_window_raise (self->separator.window);
}
- if (self->flap_window)
- gdk_window_raise (self->flap_window);
+ if (self->flap.window)
+ gdk_window_raise (self->flap.window);
if (content_above_flap) {
- if (self->separator_window)
- gdk_window_raise (self->separator_window);
+ if (self->separator.window)
+ gdk_window_raise (self->separator.window);
- if (self->content_window)
- gdk_window_raise (self->content_window);
+ if (self->content.window)
+ gdk_window_raise (self->content.window);
}
}
@@ -479,6 +479,32 @@ get_start_or_end (HdyFlap *self)
return (is_rtl && !is_horiz) ? GTK_PACK_END : GTK_PACK_START;
}
+static void
+add_child (HdyFlap *self,
+ ChildInfo *info)
+{
+ if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+ register_window (self, info);
+ restack_windows (self);
+ }
+
+ gtk_widget_set_parent (info->widget, GTK_WIDGET (self));
+
+ info->visible = FALSE;
+}
+
+static void
+remove_child (HdyFlap *self,
+ ChildInfo *info)
+{
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ unregister_window (self, info);
+
+ gtk_widget_unparent (info->widget);
+
+ info->visible = FALSE;
+}
+
static inline void
get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
@@ -504,11 +530,11 @@ compute_sizes (HdyFlap *self,
gint total, extra;
gint flap_nat, content_nat;
- if (!self->flap && !self->content)
+ if (!self->flap.widget && !self->content.widget)
return;
- if (self->separator)
- get_preferred_size (self->separator, self->orientation, separator_size, NULL);
+ if (self->separator.widget)
+ get_preferred_size (self->separator.widget, self->orientation, separator_size, NULL);
else
*separator_size = 0;
@@ -517,25 +543,25 @@ compute_sizes (HdyFlap *self,
else
total = alloc->height;
- if (!self->flap) {
+ if (!self->flap.widget) {
*content_size = total;
*flap_size = 0;
return;
}
- if (!self->content) {
+ if (!self->content.widget) {
*content_size = 0;
*flap_size = total;
return;
}
- get_preferred_size (self->flap, self->orientation, flap_size, &flap_nat);
- get_preferred_size (self->content, self->orientation, content_size, &content_nat);
+ get_preferred_size (self->flap.widget, self->orientation, flap_size, &flap_nat);
+ get_preferred_size (self->content.widget, self->orientation, content_size, &content_nat);
- flap_expand = gtk_widget_compute_expand (self->flap, self->orientation);
- content_expand = gtk_widget_compute_expand (self->content, self->orientation);
+ flap_expand = gtk_widget_compute_expand (self->flap.widget, self->orientation);
+ content_expand = gtk_widget_compute_expand (self->content.widget, self->orientation);
if (folded) {
*content_size = total;
@@ -543,7 +569,7 @@ compute_sizes (HdyFlap *self,
if (flap_expand) {
*flap_size = total;
} else {
- get_preferred_size (self->flap, self->orientation, NULL, flap_size);
+ get_preferred_size (self->flap.widget, self->orientation, NULL, flap_size);
*flap_size = MIN (*flap_size, total);
}
@@ -584,11 +610,11 @@ compute_sizes (HdyFlap *self,
if (extra > 0) {
GtkRequestedSize sizes[2];
- sizes[0].data = self->flap;
+ sizes[0].data = self->flap.widget;
sizes[0].minimum_size = *flap_size;
sizes[0].natural_size = flap_nat;
- sizes[1].data = self->content;
+ sizes[1].data = self->content.widget;
sizes[1].minimum_size = *content_size;
sizes[1].natural_size = content_nat;
@@ -675,7 +701,7 @@ compute_allocation (HdyFlap *self,
gint total, content_pos, flap_pos, separator_pos;
gboolean content_above_flap = transition_is_content_above_flap (self);
- if (!self->flap && !self->content && !self->separator)
+ if (!self->flap.widget && !self->content.widget && !self->separator.widget)
return;
content_alloc->x = 0;
@@ -701,7 +727,7 @@ compute_allocation (HdyFlap *self,
total = alloc->height;
}
- if (!self->flap)
+ if (!self->flap.widget)
return;
if (content_above_flap)
@@ -737,26 +763,28 @@ compute_allocation (HdyFlap *self,
}
static inline void
-allocate_child (HdyFlap *self,
- GtkWidget *widget,
- GdkWindow *window,
- GtkAllocation *allocation,
- gboolean visible)
+allocate_child (HdyFlap *self,
+ ChildInfo *info,
+ gboolean visible)
{
GtkAllocation child_alloc;
- if (!widget)
+ if (!info->widget)
return;
- gtk_widget_set_child_visible (widget, visible);
+ if (visible != info->visible) {
+ gtk_widget_set_child_visible (info->widget, visible);
+ info->visible = 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);
+ gdk_window_show (info->window);
+ gdk_window_move_resize (info->window,
+ info->allocation.x, info->allocation.y,
+ info->allocation.width, info->allocation.height);
} else {
- gdk_window_hide (window);
+ gdk_window_hide (info->window);
}
}
@@ -765,10 +793,10 @@ allocate_child (HdyFlap *self,
child_alloc.x = 0;
child_alloc.y = 0;
- child_alloc.width = allocation->width;
- child_alloc.height = allocation->height;
+ child_alloc.width = info->allocation.width;
+ child_alloc.height = info->allocation.height;
- gtk_widget_size_allocate (widget, &child_alloc);
+ gtk_widget_size_allocate (info->widget, &child_alloc);
}
static void
@@ -786,9 +814,9 @@ hdy_flap_size_allocate (GtkWidget *widget,
if (self->fold_policy == HDY_FLAP_FOLD_POLICY_AUTO) {
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);
+ gtk_widget_get_preferred_size (self->flap.widget, &flap_min, NULL);
+ gtk_widget_get_preferred_size (self->content.widget, &content_min, NULL);
+ gtk_widget_get_preferred_size (self->separator.widget, &separator_min, NULL);
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
set_folded (self, alloc->width < content_min.width + flap_min.width + separator_min.width);
@@ -798,27 +826,13 @@ hdy_flap_size_allocate (GtkWidget *widget,
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);
+ &self->flap.allocation,
+ &self->content.allocation,
+ &self->separator.allocation);
+
+ allocate_child (self, &self->content, TRUE);
+ allocate_child (self, &self->separator, self->reveal_progress > 0);
+ allocate_child (self, &self->flap, self->reveal_progress > 0);
gtk_widget_set_clip (widget, alloc);
}
@@ -842,14 +856,14 @@ hdy_flap_measure (GtkWidget *widget,
gint separator_min = 0, separator_nat = 0;
gint min, nat;
- if (self->content)
- get_preferred_size (self->content, orientation, &content_min, &content_nat);
+ if (self->content.widget)
+ get_preferred_size (self->content.widget, orientation, &content_min, &content_nat);
- if (self->flap)
- get_preferred_size (self->flap, orientation, &flap_min, &flap_nat);
+ if (self->flap.widget)
+ get_preferred_size (self->flap.widget, orientation, &flap_min, &flap_nat);
- if (self->separator)
- get_preferred_size (self->separator, orientation, &separator_min, &separator_nat);
+ if (self->separator.widget)
+ get_preferred_size (self->separator.widget, orientation, &separator_min, &separator_nat);
if (self->orientation == orientation &&
self->fold_policy != HDY_FLAP_FOLD_POLICY_AUTO) {
@@ -924,38 +938,38 @@ hdy_flap_draw (GtkWidget *widget,
GtkAllocation *shadow_alloc;
if (!content_above_flap) {
- if (self->content)
+ if (self->content.widget)
gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->content,
+ self->content.widget,
cr);
- if (self->separator)
+ if (self->separator.widget)
gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->separator,
+ self->separator.widget,
cr);
}
- if (self->flap)
+ if (self->flap.widget)
gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->flap,
+ self->flap.widget,
cr);
if (content_above_flap) {
- if (self->separator)
+ if (self->separator.widget)
gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->separator,
+ self->separator.widget,
cr);
- if (self->content)
+ if (self->content.widget)
gtk_container_propagate_draw (GTK_CONTAINER (self),
- self->content,
+ self->content.widget,
cr);
}
- if (!self->flap)
+ if (!self->flap.widget)
return GDK_EVENT_PROPAGATE;
- shadow_alloc = content_above_flap ? &self->content_allocation : &self->flap_allocation;
+ 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);
@@ -995,7 +1009,7 @@ hdy_flap_draw (GtkWidget *widget,
g_assert_not_reached ();
}
- if (progress < 1 && gtk_widget_get_mapped (self->flap)) {
+ if (progress < 1 && gtk_widget_get_mapped (self->flap.widget)) {
cairo_save (cr);
cairo_translate (cr, shadow_x, shadow_y);
hdy_shadow_helper_draw_shadow (self->shadow_helper, cr, width, height,
@@ -1034,14 +1048,9 @@ hdy_flap_realize (GtkWidget *widget)
gtk_widget_set_window (widget, window);
gtk_widget_register_window (widget, window);
- 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);
+ register_window (self, &self->content);
+ register_window (self, &self->separator);
+ register_window (self, &self->flap);
restack_windows (self);
}
@@ -1051,9 +1060,9 @@ 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);
+ unregister_window (self, &self->content);
+ unregister_window (self, &self->separator);
+ unregister_window (self, &self->flap);
GTK_WIDGET_CLASS (hdy_flap_parent_class)->unrealize (widget);
}
@@ -1078,14 +1087,14 @@ hdy_flap_forall (GtkContainer *container,
{
HdyFlap *self = HDY_FLAP (container);
- if (self->content)
- callback (self->content, callback_data);
+ if (self->content.widget)
+ callback (self->content.widget, callback_data);
- if (self->separator)
- callback (self->separator, callback_data);
+ if (self->separator.widget)
+ callback (self->separator.widget, callback_data);
- if (self->flap)
- callback (self->flap, callback_data);
+ if (self->flap.widget)
+ callback (self->flap.widget, callback_data);
}
static void
@@ -1094,25 +1103,21 @@ hdy_flap_add (GtkContainer *container,
{
HdyFlap *self = HDY_FLAP (container);
- if (self->content) {
+ if (self->content.widget) {
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)));
+ g_type_name (G_OBJECT_TYPE (self->content.widget)));
return;
}
- if (gtk_widget_get_realized (GTK_WIDGET (self))) {
- register_window (self, widget, &self->content_allocation, &self->content_window);
- restack_windows (self);
- }
+ self->content.widget = widget;
- gtk_widget_set_parent (widget, GTK_WIDGET (self));
- self->content = widget;
+ add_child (self, &self->content);
}
static void
@@ -1121,23 +1126,21 @@ hdy_flap_remove (GtkContainer *container,
{
HdyFlap *self = HDY_FLAP (container);
- if (widget == self->flap) {
+ if (widget == self->flap.widget) {
hdy_flap_set_flap (self, NULL);
return;
}
- if (widget == self->separator) {
+ if (widget == self->separator.widget) {
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);
-
- g_clear_pointer (&self->content, gtk_widget_unparent);
+ if (widget == self->content.widget) {
+ remove_child (self, &self->content);
+ self->content.widget = NULL;
return;
}
@@ -1505,15 +1508,15 @@ hdy_flap_get_distance (HdySwipeable *swipeable)
HdyFlap *self = HDY_FLAP (swipeable);
gint flap, separator;
- if (!self->flap)
+ if (!self->flap.widget)
return 0;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
- flap = self->flap_allocation.width;
- separator = self->separator_allocation.width;
+ flap = self->flap.allocation.width;
+ separator = self->separator.allocation.width;
} else {
- flap = self->flap_allocation.height;
- separator = self->separator_allocation.height;
+ flap = self->flap.allocation.height;
+ separator = self->separator.allocation.height;
}
if (transition_is_content_above_flap (self))
@@ -1565,7 +1568,7 @@ hdy_flap_get_swipe_area (HdySwipeable *swipeable,
gdouble flap_factor, content_factor;
gboolean content_above_flap;
- if (!self->flap) {
+ if (!self->flap.widget) {
rect->x = 0;
rect->y = 0;
rect->width = 0;
@@ -1593,8 +1596,8 @@ hdy_flap_get_swipe_area (HdySwipeable *swipeable,
}
alloc = content_above_flap
- ? &self->content_allocation
- : &self->flap_allocation;
+ ? &self->content.allocation
+ : &self->flap.allocation;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
if (alloc->x <= 0) {
@@ -1665,7 +1668,7 @@ hdy_flap_get_flap (HdyFlap *self)
{
g_return_val_if_fail (HDY_IS_FLAP (self), NULL);
- return self->flap;
+ return self->flap.widget;
}
/**
@@ -1682,29 +1685,19 @@ hdy_flap_set_flap (HdyFlap *self,
g_return_if_fail (HDY_IS_FLAP (self));
g_return_if_fail (GTK_IS_WIDGET (flap) || flap == NULL);
- if (self->flap == flap)
+ if (self->flap.widget == flap)
return;
- if (self->flap) {
- if (gtk_widget_get_realized (GTK_WIDGET (self)))
- unregister_window (self, &self->flap_window);
-
- gtk_widget_unparent (self->flap);
- }
-
- self->flap = flap;
+ if (self->flap.widget)
+ remove_child (self, &self->flap);
- if (self->flap) {
- if (gtk_widget_get_realized (GTK_WIDGET (self))) {
- register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
- restack_windows (self);
- }
+ self->flap.widget = flap;
- gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
- }
+ if (self->flap.widget)
+ add_child (self, &self->flap);
if (self->tracker)
- hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
+ hdy_swipe_tracker_set_enabled (self->tracker, self->flap.widget != NULL);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
}
@@ -1722,7 +1715,7 @@ hdy_flap_get_separator (HdyFlap *self)
{
g_return_val_if_fail (HDY_IS_FLAP (self), NULL);
- return self->separator;
+ return self->separator.widget;
}
/**
@@ -1739,29 +1732,16 @@ hdy_flap_set_separator (HdyFlap *self,
g_return_if_fail (HDY_IS_FLAP (self));
g_return_if_fail (GTK_IS_WIDGET (separator) || separator == NULL);
- if (self->separator == separator)
+ if (self->separator.widget == separator)
return;
- if (self->separator) {
- if (gtk_widget_get_realized (GTK_WIDGET (self)))
- unregister_window (self, &self->separator_window);
-
- gtk_widget_unparent (self->separator);
- }
+ if (self->separator.widget)
+ remove_child (self, &self->separator);
- self->separator = separator;
+ self->separator.widget = 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 (self->tracker)
- hdy_swipe_tracker_set_enabled (self->tracker, self->separator != NULL);
+ if (self->separator.widget)
+ add_child (self, &self->separator);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SEPARATOR]);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]