[libadwaita/wip/exalm/browsing-view] browsing view
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/browsing-view] browsing view
- Date: Thu, 13 Oct 2022 23:33:18 +0000 (UTC)
commit 821a426d1b55006652c8761d3eabca56d538854e
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Fri Oct 14 00:22:44 2022 +0400
browsing view
src/adw-browsing-view.c | 145 +++++++++++++++++++++++++++++++++++++-----------
src/adw-browsing-view.h | 14 +++--
2 files changed, 122 insertions(+), 37 deletions(-)
---
diff --git a/src/adw-browsing-view.c b/src/adw-browsing-view.c
index 8c363e7e..c7dd4203 100644
--- a/src/adw-browsing-view.c
+++ b/src/adw-browsing-view.c
@@ -84,6 +84,7 @@ struct _AdwBrowsingView
AdwBrowsingView *previous_view;
AdwBrowsingView *next_view;
+ gboolean inside_set_previous_next_child;
};
static void adw_browsing_view_buildable_init (GtkBuildableIface *iface);
@@ -94,6 +95,8 @@ G_DEFINE_FINAL_TYPE_WITH_CODE (AdwBrowsingView, adw_browsing_view, GTK_TYPE_WIDG
enum {
PROP_0,
PROP_VISIBLE_CHILD,
+ PROP_PREVIOUS_VIEW,
+ PROP_NEXT_VIEW,
LAST_PROP
};
@@ -403,7 +406,8 @@ switch_child (AdwBrowsingView *self,
static void
push_to_stack (AdwBrowsingView *self,
AdwBrowsingViewChild *child,
- gboolean animate)
+ gboolean animate,
+ gboolean emit_signal)
{
AdwBrowsingViewChild *previous_child = adw_browsing_view_get_visible_child (self);
@@ -842,6 +846,12 @@ adw_browsing_view_get_property (GObject *object,
case PROP_VISIBLE_CHILD:
g_value_set_object (value, adw_browsing_view_get_visible_child (self));
break;
+ case PROP_PREVIOUS_VIEW:
+ g_value_set_object (value, adw_browsing_view_get_previous_view (self));
+ break;
+ case PROP_NEXT_VIEW:
+ g_value_set_object (value, adw_browsing_view_get_next_view (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -903,6 +913,30 @@ adw_browsing_view_class_init (AdwBrowsingViewClass *klass)
ADW_TYPE_BROWSING_VIEW_CHILD,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ /**
+ * AdwBrowsingView:previous-view: (attributes
org.gtk.Property.get=adw_browsing_view_child_get_previous_view
org.gtk.Property.set=adw_browsing_view_child_set_previous_view)
+ *
+ * TODO
+ *
+ * Since: 1.3
+ */
+ props[PROP_PREVIOUS_VIEW] =
+ g_param_spec_object ("previous-view", NULL, NULL,
+ ADW_TYPE_BROWSING_VIEW,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * AdwBrowsingView:next-view: (attributes org.gtk.Property.get=adw_browsing_view_child_get_next_view
org.gtk.Property.set=adw_browsing_view_child_set_next_view)
+ *
+ * TODO
+ *
+ * Since: 1.3
+ */
+ props[PROP_NEXT_VIEW] =
+ g_param_spec_object ("next-view", NULL, NULL,
+ ADW_TYPE_BROWSING_VIEW,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, props);
/**
@@ -1245,7 +1279,7 @@ adw_browsing_view_add (AdwBrowsingView *self,
if (self->navigation_stack)
gtk_widget_set_child_visible (GTK_WIDGET (child), FALSE);
else
- push_to_stack (self, child, FALSE);
+ push_to_stack (self, child, FALSE, TRUE);
}
/**
@@ -1278,7 +1312,7 @@ adw_browsing_view_add_with_title (AdwBrowsingView *self,
if (self->navigation_stack)
gtk_widget_set_child_visible (wrapper, FALSE);
else
- push_to_stack (self, ADW_BROWSING_VIEW_CHILD (wrapper), FALSE);
+ push_to_stack (self, ADW_BROWSING_VIEW_CHILD (wrapper), FALSE, TRUE);
}
/**
@@ -1387,7 +1421,7 @@ adw_browsing_view_push (AdwBrowsingView *self,
return;
}
- push_to_stack (self, wrapper, animate);
+ push_to_stack (self, wrapper, animate, TRUE);
}
/**
@@ -1419,7 +1453,7 @@ adw_browsing_view_push_by_name (AdwBrowsingView *self,
return;
}
- push_to_stack (self, wrapper, animate);
+ push_to_stack (self, wrapper, animate, TRUE);
}
/**
@@ -1507,46 +1541,91 @@ adw_browsing_view_get_previous_child (AdwBrowsingView *self,
return NULL;
}
-void
-adw_browsing_view_merge (AdwBrowsingView *self,
- AdwBrowsingView *next)
+AdwBrowsingView *
+adw_browsing_view_get_previous_view (AdwBrowsingView *self)
{
- g_return_if_fail (ADW_IS_BROWSING_VIEW (self));
- g_return_if_fail (ADW_IS_BROWSING_VIEW (next));
+ g_return_val_if_fail (ADW_IS_BROWSING_VIEW (self), NULL);
- if (self->next_view == next && next->previous_view == self)
- return;
+ return self->previous_view;
+}
- self->next_view = next;
- next->previous_view = self;
+AdwBrowsingView *
+adw_browsing_view_get_next_view (AdwBrowsingView *self)
+{
+ g_return_val_if_fail (ADW_IS_BROWSING_VIEW (self), NULL);
- // TODO weak refs
- // TODO notify
- g_signal_emit (self, signals[SIGNAL_PUSHED], 0); // FIXME this is wrong
- g_signal_emit (next, signals[SIGNAL_PUSHED], 0); // FIXME this is wrong
+ return self->next_view;
+}
+
+static void
+set_next_view (AdwBrowsingView *self,
+ AdwBrowsingView *next_view)
+{
+ AdwBrowsingView *old_next = self->next_view;
+ AdwBrowsingView *old_next_prev = next_view ? next_view->previous_view : NULL;
+ gboolean pushed = FALSE;
+
+ // TODO: weak refs
+
+ if (old_next_prev)
+ old_next_prev->next_view = NULL;
+
+ if (old_next) {
+ old_next->previous_view = NULL;
+
+ if (!adw_browsing_view_get_visible_child (old_next) && old_next->last_child) {
+ g_object_freeze_notify (G_OBJECT (old_next));
+ pushed = TRUE;
+ push_to_stack (old_next, old_next->last_child, FALSE, FALSE);
+ old_next->last_child = NULL;
+ }
+ }
+
+ self->next_view = next_view;
+
+ if (next_view)
+ next_view->previous_view = self;
+
+ if (old_next_prev)
+ g_object_notify_by_pspec (G_OBJECT (old_next_prev), props[PROP_NEXT_VIEW]);
+ if (old_next)
+ g_object_notify_by_pspec (G_OBJECT (old_next), props[PROP_PREVIOUS_VIEW]);
+ if (next_view)
+ g_object_notify_by_pspec (G_OBJECT (next_view), props[PROP_PREVIOUS_VIEW]);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NEXT_VIEW]);
+
+ if (pushed) {
+ g_object_thaw_notify (G_OBJECT (old_next));
+ g_signal_emit (self, signals[SIGNAL_PUSHED], 0);
+ }
}
void
-adw_browsing_view_unmerge (AdwBrowsingView *self,
- AdwBrowsingView *next)
+adw_browsing_view_connect (AdwBrowsingView *self,
+ AdwBrowsingView *next_view)
{
g_return_if_fail (ADW_IS_BROWSING_VIEW (self));
- g_return_if_fail (ADW_IS_BROWSING_VIEW (next));
+ g_return_if_fail (ADW_IS_BROWSING_VIEW (next_view));
+ g_return_if_fail (self != next_view);
- if (self->next_view != next || next->previous_view != self)
+ if (self->next_view == next_view)
return;
- if (!adw_browsing_view_get_visible_child (next) && next->last_child) {
- push_to_stack (next, next->last_child, FALSE);
- next->last_child = NULL;
- }
+ set_next_view (self, next_view);
+}
- self->next_view = NULL;
- next->previous_view = NULL;
+void
+adw_browsing_view_disconnect (AdwBrowsingView *self,
+ AdwBrowsingView *other_view)
+{
+ g_return_if_fail (ADW_IS_BROWSING_VIEW (self));
+ g_return_if_fail (ADW_IS_BROWSING_VIEW (other_view));
+ g_return_if_fail (self != other_view);
- // TODO weak refs
- // TODO notify
- g_signal_emit (self, signals[SIGNAL_PUSHED], 0); // FIXME this is wrong
- g_signal_emit (next, signals[SIGNAL_PUSHED], 0); // FIXME this is wrong
- // probably should be properties
+ if (self->next_view == other_view)
+ set_next_view (self, NULL);
+ else if (other_view->next_view == self)
+ set_next_view (other_view, NULL);
+ else
+ g_critical ("Can't disconnect AdwBrowsingView %p and %p as they haven't connected'", self, other_view);
}
diff --git a/src/adw-browsing-view.h b/src/adw-browsing-view.h
index a8936a16..5df3b8d3 100644
--- a/src/adw-browsing-view.h
+++ b/src/adw-browsing-view.h
@@ -105,10 +105,16 @@ AdwBrowsingViewChild *adw_browsing_view_get_previous_child (AdwBrowsingView
AdwBrowsingViewChild *child);
ADW_AVAILABLE_IN_1_3
-void adw_browsing_view_merge (AdwBrowsingView *self,
- AdwBrowsingView *next);
+AdwBrowsingView *adw_browsing_view_get_previous_view (AdwBrowsingView *self);
ADW_AVAILABLE_IN_1_3
-void adw_browsing_view_unmerge (AdwBrowsingView *self,
- AdwBrowsingView *next);
+AdwBrowsingView *adw_browsing_view_get_next_view (AdwBrowsingView *self);
+
+ADW_AVAILABLE_IN_1_3
+void adw_browsing_view_connect (AdwBrowsingView *self,
+ AdwBrowsingView *next_view);
+
+ADW_AVAILABLE_IN_1_3
+void adw_browsing_view_disconnect (AdwBrowsingView *self,
+ AdwBrowsingView *other_view);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]