[libadwaita/wip/exalm/browsing-view: 4/5] header-bar: Magic back buttons




commit 165f76aafb5a5ac2f4a854e2d6cdc4deca2180f7
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Sun Oct 9 02:15:31 2022 +0400

    header-bar: Magic back buttons

 src/adw-header-bar.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 3 deletions(-)
---
diff --git a/src/adw-header-bar.c b/src/adw-header-bar.c
index fb28d2ce..1547596f 100644
--- a/src/adw-header-bar.c
+++ b/src/adw-header-bar.c
@@ -151,6 +151,7 @@ struct _AdwHeaderBar {
 
   GtkWidget *start_window_controls;
   GtkWidget *end_window_controls;
+  GtkWidget *back_button;
 
   char *decoration_layout;
 
@@ -163,6 +164,7 @@ struct _AdwHeaderBar {
 
   GtkSizeGroup *size_group;
 
+  GtkWidget *browsing_view;
   GtkWidget *browsing_view_child;
 };
 
@@ -213,6 +215,50 @@ create_end_window_controls (AdwHeaderBar *self)
   self->end_window_controls = controls;
 }
 
+static void
+update_back_button (AdwHeaderBar *self)
+{
+  gboolean has_back_button = FALSE;
+  const char *tooltip = NULL;
+
+  if (self->browsing_view && self->browsing_view_child) {
+    AdwBrowsingViewChild *prev_child;
+
+    // TODO: if there's a way to edit hsitory at some point, this will need to
+    // be updated too
+    // TODO: ditto for merging views
+    // TODO: need to check can-go-back once it's implemented
+    // TODO: track title changes
+    prev_child = adw_browsing_view_get_previous_child (ADW_BROWSING_VIEW (self->browsing_view),
+                                                       ADW_BROWSING_VIEW_CHILD (self->browsing_view_child));
+
+
+    has_back_button = !!prev_child;
+
+    if (prev_child)
+      tooltip = adw_browsing_view_child_get_title (prev_child);
+  }
+
+  if (has_back_button) {
+    if (!self->back_button) {
+      self->back_button = gtk_button_new_from_icon_name ("go-previous-symbolic");
+
+      gtk_actionable_set_action_name (GTK_ACTIONABLE (self->back_button), "browsing.pop");
+
+      gtk_box_insert_child_after (GTK_BOX (self->start_box),
+                                  self->back_button,
+                                  self->start_window_controls);
+    }
+
+    gtk_widget_set_tooltip_text (self->back_button, tooltip);
+  } else {
+    if (self->back_button)
+      gtk_box_remove (GTK_BOX (self->start_box), self->back_button);
+
+    self->back_button = NULL;
+  }
+}
+
 static void
 update_title (AdwHeaderBar *self)
 {
@@ -262,19 +308,42 @@ construct_title_label (AdwHeaderBar *self)
   update_title (self);
 }
 
+static void
+browsing_view_visible_child_cb (AdwHeaderBar *self)
+{
+  AdwBrowsingViewChild *visible_child;
+
+  g_assert (self->browsing_view);
+  g_assert (self->browsing_view_child);
+
+  visible_child = adw_browsing_view_get_visible_child (ADW_BROWSING_VIEW (self->browsing_view));
+
+  if (visible_child == ADW_BROWSING_VIEW_CHILD (self->browsing_view_child))
+    update_back_button (self);
+}
+
 static void
 adw_header_bar_root (GtkWidget *widget)
 {
   AdwHeaderBar *self = ADW_HEADER_BAR (widget);
-  GtkWidget *browsing_view_child;
+  GtkWidget *browsing_view = NULL, *browsing_view_child;
 
   GTK_WIDGET_CLASS (adw_header_bar_parent_class)->root (widget);
 
   browsing_view_child = gtk_widget_get_ancestor (widget, ADW_TYPE_BROWSING_VIEW_CHILD);
 
-  if (browsing_view_child) {
+  if (browsing_view_child)
+    browsing_view = gtk_widget_get_parent (browsing_view_child);
+
+  if (!ADW_IS_BROWSING_VIEW (browsing_view))
+    browsing_view = NULL;
+
+  if (browsing_view && browsing_view_child) {
+    self->browsing_view = browsing_view;
     self->browsing_view_child = browsing_view_child;
 
+    g_signal_connect_swapped (browsing_view, "notify::visible-child",
+                              G_CALLBACK (browsing_view_visible_child_cb), widget);
     g_signal_connect_swapped (browsing_view_child, "notify::title",
                               G_CALLBACK (update_title), widget);
   } else {
@@ -286,6 +355,7 @@ adw_header_bar_root (GtkWidget *widget)
   }
 
   update_title (ADW_HEADER_BAR (widget));
+  update_back_button (ADW_HEADER_BAR (widget));
 }
 
 static void
@@ -293,10 +363,13 @@ adw_header_bar_unroot (GtkWidget *widget)
 {
   AdwHeaderBar *self = ADW_HEADER_BAR (widget);
 
-  if (self->browsing_view_child) {
+  if (self->browsing_view && self->browsing_view_child) {
+    g_signal_handlers_disconnect_by_func (self->browsing_view,
+                                          browsing_view_visible_child_cb, widget);
     g_signal_handlers_disconnect_by_func (self->browsing_view_child,
                                           update_title, widget);
 
+    self->browsing_view = NULL;
     self->browsing_view_child = NULL;
   } else {
     g_signal_handlers_disconnect_by_func (gtk_widget_get_root (widget),


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