[nautilus/wip/antoniof/gtk4-preparation-step-container-api: 1/5] toolbar: Use list box for operations list




commit afed9950fbff79e2cc9172a55f82068a81744717
Author: António Fernandes <antoniof gnome org>
Date:   Thu Nov 25 16:42:07 2021 +0000

    toolbar: Use list box for operations list
    
    Using a GtkBox to display a dynamic list requires us to manually add
    and remove children, relying on the GtkContainer API, gone in GTK4.
    
    Instead, we should use GtkListBox, which we can pass a model and let
    it take care of creating and disposing of children for us.

 src/nautilus-toolbar.c               | 36 +++++++++++++++++++++++++-----------
 src/resources/css/Adwaita.css        |  5 +++++
 src/resources/ui/nautilus-toolbar.ui | 22 +++++++++++-----------
 3 files changed, 41 insertions(+), 22 deletions(-)
---
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index cd0cb368e..0addb85a6 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -90,7 +90,8 @@ struct _NautilusToolbar
     GtkWidget *app_menu;
 
     GtkWidget *operations_popover;
-    GtkWidget *operations_container;
+    GtkWidget *operations_list;
+    GListStore *progress_infos_model;
     GtkWidget *operations_revealer;
     GtkWidget *operations_icon;
 
@@ -516,14 +517,10 @@ update_operations (NautilusToolbar *self)
 {
     GList *progress_infos;
     GList *l;
-    GtkWidget *progress;
     gboolean should_show_progress_button = FALSE;
 
-    gtk_container_foreach (GTK_CONTAINER (self->operations_container),
-                           (GtkCallback) gtk_widget_destroy,
-                           NULL);
-
     disconnect_progress_infos (self);
+    g_list_store_remove_all (self->progress_infos_model);
 
     progress_infos = get_filtered_progress_infos (self);
     for (l = progress_infos; l != NULL; l = l->next)
@@ -537,10 +534,7 @@ update_operations (NautilusToolbar *self)
                                   G_CALLBACK (on_progress_info_cancelled), self);
         g_signal_connect_swapped (l->data, "progress-changed",
                                   G_CALLBACK (on_progress_info_progress_changed), self);
-        progress = nautilus_progress_info_widget_new (l->data);
-        gtk_box_pack_start (GTK_BOX (self->operations_container),
-                            progress,
-                            FALSE, FALSE, 0);
+        g_list_store_append (self->progress_infos_model, l->data);
     }
 
     g_list_free (progress_infos);
@@ -887,6 +881,19 @@ on_location_entry_focus_changed (GObject    *object,
     }
 }
 
+static GtkWidget *
+operations_list_create_widget (GObject  *item,
+                               gpointer  user_data)
+{
+    NautilusProgressInfo *info = NAUTILUS_PROGRESS_INFO (item);
+    GtkWidget *widget;
+
+    widget = nautilus_progress_info_widget_new (info);
+    gtk_widget_show_all (widget);
+
+    return widget;
+}
+
 static void
 nautilus_toolbar_constructed (GObject *object)
 {
@@ -912,6 +919,12 @@ nautilus_toolbar_constructed (GObject *object)
     g_signal_connect (self->progress_manager, "has-viewers-changed",
                       G_CALLBACK (on_progress_has_viewers_changed), self);
 
+    self->progress_infos_model = g_list_store_new (NAUTILUS_TYPE_PROGRESS_INFO);
+    gtk_list_box_bind_model (GTK_LIST_BOX (self->operations_list),
+                             G_LIST_MODEL (self->progress_infos_model),
+                             (GtkListBoxCreateWidgetFunc) operations_list_create_widget,
+                             NULL,
+                             NULL);
     update_operations (self);
 
     self->back_button_longpress_gesture = gtk_gesture_long_press_new (self->back_button);
@@ -1149,6 +1162,7 @@ nautilus_toolbar_finalize (GObject *obj)
     unschedule_operations_start (self);
     unschedule_operations_button_attention_style (self);
 
+    g_clear_object (&self->progress_infos_model);
     g_signal_handlers_disconnect_by_data (self->progress_manager, self);
     g_clear_object (&self->progress_manager);
 
@@ -1212,7 +1226,7 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_icon);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_popover);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_container);
+    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_list);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_revealer);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_toggle_button);
diff --git a/src/resources/css/Adwaita.css b/src/resources/css/Adwaita.css
index 68c3e424c..4b84e2d9a 100644
--- a/src/resources/css/Adwaita.css
+++ b/src/resources/css/Adwaita.css
@@ -42,6 +42,11 @@
   animation-iteration-count: 3;
 }
 
+/* Remove white background which GTK adds by default */
+.operations-list {
+  background: none;
+}
+
 .disclosure-button {
   padding-left: 4px;
   padding-right: 4px;
diff --git a/src/resources/ui/nautilus-toolbar.ui b/src/resources/ui/nautilus-toolbar.ui
index a1e6fccec..47d35a16d 100644
--- a/src/resources/ui/nautilus-toolbar.ui
+++ b/src/resources/ui/nautilus-toolbar.ui
@@ -405,22 +405,22 @@
         <property name="max_content_height">270</property>
         <property name="propagate_natural_height">True</property>
         <child>
-          <object class="GtkViewport">
+          <object class="GtkBox">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="margin_start">12</property>
+            <property name="margin_end">12</property>
+            <property name="margin_top">12</property>
+            <property name="margin_bottom">12</property>
             <child>
-              <object class="GtkBox" id="operations_container">
+              <object class="GtkListBox" id="operations_list">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="margin_start">12</property>
-                <property name="margin_end">12</property>
-                <property name="margin_top">12</property>
-                <property name="margin_bottom">12</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">10</property>
-                <child>
-                  <placeholder/>
-                </child>
+                <property name="selection-mode">none</property>
+                <property name="activate-on-single-click">False</property>
+                <style>
+                  <class name="operations-list"/>
+                </style>
               </object>
             </child>
           </object>


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