[nautilus/wip/antoniof/modernize-properties-dialog: 18/19] properties-window: use GtkStack for navigation




commit e8d72f4a05d93ed687c8c720ad1c5325cffa314d
Author: Peter Eisenmann <p3732 getgoogleoff me>
Date:   Fri Dec 31 08:12:29 2021 +0100

    properties-window: use GtkStack for navigation
    
    Replace the tabbed GtkNotebook view with inlined navigation rows that
    link to subpages and a back button that allows navigating back.
    
    Also, remove now-inadequate .view style class.
    
    Part of #1258

 src/nautilus-properties-window.c               | 218 +++++++++++++++++--------
 src/resources/ui/nautilus-properties-window.ui | 122 ++++++++++----
 2 files changed, 245 insertions(+), 95 deletions(-)
---
diff --git a/src/nautilus-properties-window.c b/src/nautilus-properties-window.c
index ca5d39070..51454ef92 100644
--- a/src/nautilus-properties-window.c
+++ b/src/nautilus-properties-window.c
@@ -76,9 +76,10 @@ struct _NautilusPropertiesWindow
     GList *original_files;
     GList *target_files;
 
-    GtkNotebook *notebook;
+    GtkStack *page_stack;
+    GtkRevealer *back_button_revealer;
 
-    /* Basic tab widgets */
+    /* Basic page */
 
     GtkStack *icon_stack;
     GtkWidget *icon_image;
@@ -94,6 +95,8 @@ struct _NautilusPropertiesWindow
     GtkWidget *type_row;
     GtkWidget *type_value_label;
 
+    GtkWidget *open_with_navigation_row;
+
     GtkWidget *link_target_row;
     GtkWidget *link_target_value_label;
 
@@ -128,6 +131,10 @@ struct _NautilusPropertiesWindow
     GtkWidget *created_row;
     GtkWidget *created_value_label;
 
+    GtkWidget *permissions_navigation_row;
+
+    GtkListBox *extension_list_box;
+
     GtkWidget *free_space_row;
     GtkWidget *free_space_value_label;
 
@@ -142,7 +149,7 @@ struct _NautilusPropertiesWindow
     GtkWidget *total_capacity_value;
     GtkWidget *file_system_value;
 
-    /* Permissions tab Widgets */
+    /* Permissions page */
 
     GtkWidget *permissions_stack;
 
@@ -176,7 +183,7 @@ struct _NautilusPropertiesWindow
     GtkWidget *change_permissions_button_box;
     GtkWidget *change_permissions_button;
 
-    /* Open With tab Widgets */
+    /* Open With page */
 
     GtkWidget *open_with_box;
     GtkWidget *open_with_label;
@@ -427,6 +434,51 @@ permission_value_to_string (PermissionValue permission_value,
 
 /* end NautilusPermissionEntry */
 
+/* NautilusExtensionPage - helper struct for extension pages */
+
+#define NAUTILUS_TYPE_EXTENSION_PAGE (nautilus_extension_page_get_type ())
+G_DECLARE_FINAL_TYPE (NautilusExtensionPage, nautilus_extension_page,
+                      NAUTILUS, EXTENSION_PAGE, GObject)
+
+struct _NautilusExtensionPage
+{
+    GObject parent;
+
+    GtkWidget *page;
+    gchar *name;
+};
+
+G_DEFINE_TYPE (NautilusExtensionPage,
+               nautilus_extension_page,
+               G_TYPE_OBJECT)
+
+static void
+nautilus_extension_page_init (NautilusExtensionPage *self)
+{
+    self->page = NULL;
+    self->name = NULL;
+}
+
+static void
+nautilus_extension_page_finalize (GObject *object)
+{
+    NautilusExtensionPage *self = NAUTILUS_EXTENSION_PAGE (object);
+
+    g_free (self->name);
+
+    G_OBJECT_CLASS (nautilus_extension_page_parent_class)->finalize (object);
+}
+
+static void
+nautilus_extension_page_class_init (NautilusExtensionPageClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    gobject_class->finalize = nautilus_extension_page_finalize;
+}
+
+/* end NautilusExtensionPage */
+
 enum
 {
     COLUMN_NAME,
@@ -507,7 +559,7 @@ static void set_icon (const char               *icon_path,
 static void remove_pending (StartupData *data,
                             gboolean     cancel_call_when_ready,
                             gboolean     cancel_timed_wait);
-static void append_extension_pages (NautilusPropertiesWindow *self);
+static void refresh_extension_pages (NautilusPropertiesWindow *self);
 
 static void setup_pie_widget (NautilusPropertiesWindow *self);
 
@@ -569,6 +621,43 @@ get_target_file (NautilusPropertiesWindow *self)
     return NAUTILUS_FILE (self->target_files->data);
 }
 
+static void
+navigate_main_page (NautilusPropertiesWindow *self,
+                    GParamSpec               *params,
+                    GtkWidget                *widget)
+{
+    gtk_stack_set_visible_child_name (self->page_stack, "main");
+    gtk_revealer_set_reveal_child (self->back_button_revealer, FALSE);
+}
+
+static void
+navigate_open_with_page (NautilusPropertiesWindow *self,
+                         GParamSpec               *params,
+                         GtkWidget                *widget)
+{
+    gtk_stack_set_visible_child_name (self->page_stack, "open-with");
+    gtk_revealer_set_reveal_child (self->back_button_revealer, TRUE);
+}
+
+static void
+navigate_permissions_page (NautilusPropertiesWindow *self,
+                           GParamSpec               *params,
+                           GtkWidget                *widget)
+{
+    gtk_stack_set_visible_child_name (self->page_stack, "permissions");
+    gtk_revealer_set_reveal_child (self->back_button_revealer, TRUE);
+}
+
+static void
+navigate_extension_page (NautilusPropertiesWindow *self,
+                         GParamSpec               *params,
+                         AdwPreferencesRow        *row)
+{
+    gtk_stack_set_visible_child_name (self->page_stack,
+                                      adw_preferences_row_get_title (row));
+    gtk_revealer_set_reveal_child (self->back_button_revealer, TRUE);
+}
+
 static void
 get_image_for_properties_window (NautilusPropertiesWindow  *self,
                                  char                     **icon_name,
@@ -578,7 +667,7 @@ get_image_for_properties_window (NautilusPropertiesWindow  *self,
     GList *l;
     gint icon_scale;
 
-    icon_scale = gtk_widget_get_scale_factor (GTK_WIDGET (self->notebook));
+    icon_scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
     /* FIXME: Temporary regression: HiDPI icons not supported, ignore scale. */
     icon_scale = 1;
 
@@ -853,36 +942,31 @@ update_properties_window_title (NautilusPropertiesWindow *self)
     gtk_window_set_title (GTK_WINDOW (self), title);
 }
 
-static void
-clear_extension_pages (NautilusPropertiesWindow *self)
+static GtkWidget *
+add_extension_page (NautilusExtensionPage    *extension_page,
+                    NautilusPropertiesWindow *self)
 {
-    int i;
-    int num_pages;
-    GtkWidget *page;
+    GtkWidget *row;
+    GtkWidget *image;
 
-    num_pages = gtk_notebook_get_n_pages
-                    (GTK_NOTEBOOK (self->notebook));
+    row = adw_action_row_new ();
+    image = gtk_image_new_from_icon_name ("go-next-symbolic");
 
-    for (i = 0; i < num_pages; i++)
-    {
-        page = gtk_notebook_get_nth_page
-                   (GTK_NOTEBOOK (self->notebook), i);
+    adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), extension_page->name);
+    adw_action_row_add_suffix (ADW_ACTION_ROW (row), image);
 
-        if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (page), "is-extension-page")))
-        {
-            gtk_notebook_remove_page
-                (GTK_NOTEBOOK (self->notebook), i);
-            num_pages--;
-            i--;
-        }
-    }
-}
+    gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
+    gtk_list_box_row_set_selectable (GTK_LIST_BOX_ROW (row), FALSE);
 
-static void
-refresh_extension_pages (NautilusPropertiesWindow *self)
-{
-    clear_extension_pages (self);
-    append_extension_pages (self);
+    g_signal_connect_swapped (row, "activated",
+                              G_CALLBACK (navigate_extension_page),
+                              self);
+
+    gtk_stack_add_named (self->page_stack,
+                         extension_page->page,
+                         extension_page->name);
+
+    return row;
 }
 
 static void
@@ -3687,48 +3771,44 @@ setup_permissions_page (NautilusPropertiesWindow *self)
 }
 
 static void
-append_extension_pages (NautilusPropertiesWindow *self)
+refresh_extension_pages (NautilusPropertiesWindow *self)
 {
-    g_autolist (GObject) providers = NULL;
-    GList *p;
+    GListStore *extension_providers = g_list_store_new (NAUTILUS_TYPE_EXTENSION_PAGE);
+    g_autolist (GObject) providers =
+        nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER);
 
-    providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER);
-
-    for (p = providers; p != NULL; p = p->next)
+    for (GList *p = providers; p != NULL; p = p->next)
     {
-        NautilusPropertyPageProvider *provider;
-        g_autolist (NautilusPropertyPage) pages = NULL;
-        GList *l;
-
-        provider = NAUTILUS_PROPERTY_PAGE_PROVIDER (p->data);
+        NautilusPropertyPageProvider *provider = NAUTILUS_PROPERTY_PAGE_PROVIDER (p->data);
+        g_autolist (NautilusPropertyPage) pages =
+            nautilus_property_page_provider_get_pages (provider, self->original_files);
 
-        pages = nautilus_property_page_provider_get_pages
-                    (provider, self->original_files);
-
-        for (l = pages; l != NULL; l = l->next)
+        for (GList *l = pages; l != NULL; l = l->next)
         {
-            NautilusPropertyPage *page;
-            g_autoptr (GtkWidget) page_widget = NULL;
-            g_autoptr (GtkWidget) label = NULL;
+            NautilusPropertyPage *page = NAUTILUS_PROPERTY_PAGE (l->data);
+            g_autoptr (NautilusExtensionPage) extension_page = NULL;
+            GtkLabel *label = NULL;
 
-            page = NAUTILUS_PROPERTY_PAGE (l->data);
+            extension_page = g_object_new (NAUTILUS_TYPE_EXTENSION_PAGE, NULL);
 
             g_object_get (G_OBJECT (page),
-                          "page", &page_widget, "label", &label,
+                          "page", &extension_page->page, "label", &label,
                           NULL);
 
-            gtk_notebook_append_page (self->notebook,
-                                      page_widget, label);
-            g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (self->notebook),
-                                                 GTK_WIDGET (page_widget)),
-                          "tab-expand", TRUE,
-                          NULL);
+            extension_page->name = g_strdup (gtk_label_get_text (label));
 
-            g_object_set_data (G_OBJECT (page_widget),
-                               "is-extension-page",
-                               GINT_TO_POINTER (TRUE));
+            g_list_store_append (extension_providers, extension_page);
         }
     }
+
+    gtk_widget_set_visible (GTK_WIDGET (self->extension_list_box),
+                            g_list_model_get_n_items (G_LIST_MODEL (extension_providers)) > 0);
+
+    gtk_list_box_bind_model (self->extension_list_box,
+                             G_LIST_MODEL (extension_providers),
+                             (GtkListBoxCreateWidgetFunc) add_extension_page,
+                             self,
+                             NULL);
 }
 
 static gboolean
@@ -4265,17 +4345,17 @@ create_properties_window (StartupData *startup_data)
     if (should_show_permissions (window))
     {
         setup_permissions_page (window);
-        gtk_widget_show (window->permissions_stack);
+        gtk_widget_show (window->permissions_navigation_row);
     }
 
     if (should_show_open_with (window))
     {
         setup_open_with_page (window);
-        gtk_widget_show (window->open_with_box);
+        gtk_widget_show (window->open_with_navigation_row);
     }
 
-    /* append pages from available views */
-    append_extension_pages (window);
+    /* Add available extension pages */
+    refresh_extension_pages (window);
 
     /* Update from initial state */
     properties_window_update (window, NULL);
@@ -4801,7 +4881,8 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *klass)
 
     gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/nautilus/ui/nautilus-properties-window.ui");
 
-    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, notebook);
+    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, page_stack);
+    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, back_button_revealer);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, icon_stack);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, icon_image);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, icon_button);
@@ -4810,6 +4891,7 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, name_value_label);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, type_row);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, type_value_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, open_with_navigation_row);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, link_target_row);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, link_target_value_label);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, contents_row);
@@ -4831,6 +4913,8 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, modified_value_label);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, created_row);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, created_value_label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, 
permissions_navigation_row);
+    gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, extension_list_box);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, free_space_row);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, free_space_value_label);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, volume_widget_box);
@@ -4872,6 +4956,10 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, forget_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, add_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, set_as_default_button);
+
+    gtk_widget_class_bind_template_callback (widget_class, navigate_main_page);
+    gtk_widget_class_bind_template_callback (widget_class, navigate_permissions_page);
+    gtk_widget_class_bind_template_callback (widget_class, navigate_open_with_page);
 }
 
 static void
diff --git a/src/resources/ui/nautilus-properties-window.ui b/src/resources/ui/nautilus-properties-window.ui
index ced428c75..db92acc53 100644
--- a/src/resources/ui/nautilus-properties-window.ui
+++ b/src/resources/ui/nautilus-properties-window.ui
@@ -8,16 +8,31 @@
       <object class="GtkBox" id="content_box">
         <property name="orientation">vertical</property>
         <child>
-          <object class="AdwHeaderBar"/>
+          <object class="AdwHeaderBar">
+            <child type="start">
+              <object class="GtkRevealer" id="back_button_revealer">
+                <property name="transition-type">crossfade</property>
+                <property name="reveal-child">False</property>
+                <child>
+                  <object class="GtkButton">
+                    <property name="icon-name">go-previous-symbolic</property>
+                    <signal name="clicked" handler="navigate_main_page" object="NautilusPropertiesWindow" 
swapped="yes"/>
+                    <style>
+                      <class name="image-button"/>
+                    </style>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
         </child>
         <child>
-          <object class="GtkNotebook" id="notebook">
+          <object class="GtkStack" id="page_stack">
             <property name="hexpand">True</property>
-            <property name="focusable">True</property>
-            <property name="show_border">False</property>
+            <property name="transition-type">slide-left-right</property>
             <child>
-              <object class="GtkNotebookPage">
-                <property name="tab_expand">True</property>
+              <object class="GtkStackPage">
+                <property name="name">main</property>
                 <property name="child">
                   <object class="GtkBox" id="basic_box">
                     <property name="margin-top">18</property>
@@ -119,6 +134,39 @@
                             </child>
                           </object>
                         </child>
+                        <child>
+                          <object class="AdwActionRow" id="open_with_navigation_row">
+                            <property name="visible">False</property>
+                            <property name="activatable">True</property>
+                            <property name="selectable">False</property>
+                            <property name="title" translatable="yes">_Open With</property>
+                            <property name="use-underline">True</property>
+                            <signal name="activated" handler="navigate_open_with_page" 
object="NautilusPropertiesWindow" swapped="yes"/>
+                            <child>
+                              <object class="GtkBox">
+                                <property name="spacing">12</property>
+                                <child>
+                                  <object class="GtkLabel" id="open_with_navigation_value_label">
+                                    <property name="hexpand">True</property>
+                                    <property name="selectable">True</property>
+                                    <property name="ellipsize">end</property>
+                                    <property name="max-width-chars">24</property>
+                                    <property name="xalign">1</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkBox" id="open_with_navigation_action_box">
+                                    <child>
+                                      <object class="GtkImage">
+                                        <property name="icon-name">go-next-symbolic</property>
+                                      </object>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
                         <child>
                           <object class="AdwActionRow" id="link_target_row">
                             <property name="visible">False</property>
@@ -428,6 +476,40 @@
                         </style>
                       </object>
                     </child>
+                    <child>
+                      <object class="GtkListBox" id="permissions_list_box">
+                        <property name="selection-mode">none</property>
+                        <child>
+                          <object class="AdwActionRow" id="permissions_navigation_row">
+                            <property name="activatable">True</property>
+                            <property name="selectable">False</property>
+                            <property name="title" translatable="yes">Set Custom _Permissions</property>
+                            <property name="use-underline">True</property>
+                            <signal name="activated" handler="navigate_permissions_page" 
object="NautilusPropertiesWindow" swapped="yes"/>
+                            <child>
+                              <object class="GtkBox" id="permissions_navigation_action_box">
+                                <child>
+                                  <object class="GtkImage">
+                                    <property name="icon-name">go-next-symbolic</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <style>
+                          <class name="boxed-list"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBox" id="extension_list_box">
+                        <property name="selection-mode">none</property>
+                        <style>
+                          <class name="boxed-list"/>
+                        </style>
+                      </object>
+                    </child>
                     <child>
                       <object class="GtkBox" id="volume_widget_box">
                         <property name="visible">False</property>
@@ -598,19 +680,13 @@
                     </child>
                   </object>
                 </property>
-                <property name="tab">
-                  <object class="GtkLabel" id="basic_label">
-                    <property name="label" translatable="yes">Basic</property>
-                  </object>
-                </property>
               </object>
             </child>
             <child>
-              <object class="GtkNotebookPage">
-                <property name="tab_expand">True</property>
+              <object class="GtkStackPage">
+                <property name="name">permissions</property>
                 <property name="child">
                   <object class="GtkStack" id="permissions_stack">
-                    <property name="visible">True</property>
                     <property name="margin-top">18</property>
                     <property name="margin-bottom">18</property>
                     <property name="margin-start">18</property>
@@ -849,19 +925,13 @@
                     </child>
                   </object>
                 </property>
-                <property name="tab">
-                  <object class="GtkLabel" id="permissions_label">
-                    <property name="label" translatable="yes">Permissions</property>
-                  </object>
-                </property>
               </object>
             </child>
             <child>
-              <object class="GtkNotebookPage">
-                <property name="tab_expand">True</property>
+              <object class="GtkStackPage">
+                <property name="name">open-with</property>
                 <property name="child">
                   <object class="GtkBox" id="open_with_box">
-                    <property name="visible">False</property>
                     <property name="margin-top">18</property>
                     <property name="margin-bottom">18</property>
                     <property name="margin-start">18</property>
@@ -921,18 +991,10 @@
                     </child>
                   </object>
                 </property>
-                <property name="tab">
-                  <object class="GtkLabel">
-                    <property name="label" translatable="yes">Open With</property>
-                  </object>
-                </property>
               </object>
             </child>
           </object>
         </child>
-        <style>
-          <class name="view"/>
-        </style>
       </object>
     </child>
   </template>


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