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




commit cfdee53695ab8c0a2ac222523f0759cea358e018
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 can use GtkListBox, which we can pass a model and let
    it take care of creating and disposing of children for us.
    
    After the GTK4 switch, we should probably replace it with GtkListView
    to avoid the default behaviors of GtkListBox which we are adding
    workarounds for.

 src/nautilus-toolbar.c                            | 36 ++++++++++++++++-------
 src/resources/css/Adwaita.css                     |  7 +++++
 src/resources/ui/nautilus-progress-info-widget.ui |  6 ++--
 src/resources/ui/nautilus-toolbar.ui              | 26 +++++++---------
 4 files changed, 46 insertions(+), 29 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..03acabd4a 100644
--- a/src/resources/css/Adwaita.css
+++ b/src/resources/css/Adwaita.css
@@ -42,6 +42,13 @@
   animation-iteration-count: 3;
 }
 
+/* Remove white background and highlight on hover which GTK adds by default
+ * to GtkListBox. TODO: Switch to GtkListView and drop this CSS hack. */
+.operations-list,
+.operations-list > :hover {
+  background: none;
+}
+
 .disclosure-button {
   padding-left: 4px;
   padding-right: 4px;
diff --git a/src/resources/ui/nautilus-progress-info-widget.ui 
b/src/resources/ui/nautilus-progress-info-widget.ui
index ac10a9da8..629d7e796 100644
--- a/src/resources/ui/nautilus-progress-info-widget.ui
+++ b/src/resources/ui/nautilus-progress-info-widget.ui
@@ -10,8 +10,10 @@
   <template class="NautilusProgressInfoWidget" parent="GtkGrid">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="margin_start">5</property>
-    <property name="margin_end">5</property>
+    <property name="margin_start">6</property>
+    <property name="margin_end">6</property>
+    <property name="margin_top">6</property>
+    <property name="margin_bottom">6</property>
     <child>
       <object class="GtkLabel" id="status">
         <property name="width_request">300</property>
diff --git a/src/resources/ui/nautilus-toolbar.ui b/src/resources/ui/nautilus-toolbar.ui
index a1e6fccec..359f80aec 100644
--- a/src/resources/ui/nautilus-toolbar.ui
+++ b/src/resources/ui/nautilus-toolbar.ui
@@ -405,24 +405,18 @@
         <property name="max_content_height">270</property>
         <property name="propagate_natural_height">True</property>
         <child>
-          <object class="GtkViewport">
+          <object class="GtkListBox" id="operations_list">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <child>
-              <object class="GtkBox" id="operations_container">
-                <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>
-              </object>
-            </child>
+            <property name="margin_start">6</property>
+            <property name="margin_end">6</property>
+            <property name="margin_top">6</property>
+            <property name="margin_bottom">6</property>
+            <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]