[nautilus/wip/cdavis/use-toasts] window: Use AdwToastOverlay and AdwToast




commit b03034eb3e60a6d2aaea42bd7dac1229d17aeca6
Author: Christopher Davis <christopherdavis gnome org>
Date:   Tue Jan 11 20:40:59 2022 -0800

    window: Use AdwToastOverlay and AdwToast
    
    AdwToastOverlay is the new recommended widget for the
    in-app notification pattern. Instead of using GtkFrame
    and the old pattern, we can use this instead.
    
    AdwToast's API uses GActions, so I added an action for
    opening `folder_to_open`.
    
    Closes https://gitlab.gnome.org/GNOME/nautilus/-/issues/2104

 src/nautilus-window.c               | 223 ++++++------------------------------
 src/resources/ui/nautilus-window.ui | 151 ++++--------------------
 2 files changed, 56 insertions(+), 318 deletions(-)
---
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index 93d3b56ff..a712439ee 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -117,20 +117,8 @@ struct _NautilusWindow
     GVolume *selected_volume;     /* the selected volume in the sidebar popup callback */
     GFile *selected_file;     /* the selected file in the sidebar popup callback */
 
-    /* Main view */
-    GtkWidget *main_view;
-
     /* Notifications */
-    GtkWidget *in_app_notification_undo;
-    GtkWidget *in_app_notification_undo_label;
-    GtkWidget *in_app_notification_undo_close_button;
-    GtkWidget *in_app_notification_undo_undo_button;
-    guint in_app_notification_undo_timeout_id;
-    GtkWidget *notification_operation;
-    GtkWidget *notification_operation_label;
-    GtkWidget *notification_operation_close;
-    GtkWidget *notification_operation_open;
-    guint notification_operation_timeout_id;
+    AdwToastOverlay *toast_overlay;
     GFile *folder_to_open;
 
     /* Toolbar */
@@ -469,6 +457,17 @@ action_show_current_location_menu (GSimpleAction *action,
     nautilus_path_bar_show_current_location_menu (NAUTILUS_PATH_BAR (path_bar));
 }
 
+static void
+action_operation_open (GSimpleAction *action,
+                       GVariant      *state,
+                       gpointer       user_data)
+{
+    NautilusWindow *window = NAUTILUS_WINDOW (user_data);
+
+    nautilus_window_open_location_full (window, window->folder_to_open,
+                                        0, NULL, NULL);
+}
+
 static void
 on_location_changed (NautilusWindow *window)
 {
@@ -1472,77 +1471,8 @@ nautilus_window_ensure_location_entry (NautilusWindow *window)
     return location_entry;
 }
 
-static void
-remove_notifications (NautilusWindow *window)
-{
-    GtkRevealerTransitionType transition_type;
-
-    /* Hide it inmediatily so we can animate the new notification. */
-    transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (window->in_app_notification_undo));
-    gtk_revealer_set_transition_type (GTK_REVEALER (window->in_app_notification_undo),
-                                      GTK_REVEALER_TRANSITION_TYPE_NONE);
-    gtk_revealer_set_reveal_child (GTK_REVEALER (window->in_app_notification_undo),
-                                   FALSE);
-    gtk_revealer_set_transition_type (GTK_REVEALER (window->in_app_notification_undo),
-                                      transition_type);
-    if (window->in_app_notification_undo_timeout_id != 0)
-    {
-        g_source_remove (window->in_app_notification_undo_timeout_id);
-        window->in_app_notification_undo_timeout_id = 0;
-    }
-
-    transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (window->notification_operation));
-    gtk_revealer_set_transition_type (GTK_REVEALER (window->notification_operation),
-                                      GTK_REVEALER_TRANSITION_TYPE_NONE);
-    gtk_revealer_set_reveal_child (GTK_REVEALER (window->notification_operation),
-                                   FALSE);
-    gtk_revealer_set_transition_type (GTK_REVEALER (window->notification_operation),
-                                      transition_type);
-    if (window->notification_operation_timeout_id != 0)
-    {
-        g_source_remove (window->notification_operation_timeout_id);
-        window->notification_operation_timeout_id = 0;
-    }
-}
-
-static void
-hide_in_app_notification_undo (NautilusWindow *window)
-{
-    if (window->in_app_notification_undo_timeout_id != 0)
-    {
-        g_source_remove (window->in_app_notification_undo_timeout_id);
-        window->in_app_notification_undo_timeout_id = 0;
-    }
-
-    gtk_revealer_set_reveal_child (GTK_REVEALER (window->in_app_notification_undo), FALSE);
-}
-
-static void
-on_in_app_notification_undo_undo_button_clicked (GtkWidget      *notification,
-                                                 NautilusWindow *window)
-{
-    hide_in_app_notification_undo (window);
-
-    nautilus_file_undo_manager_undo (GTK_WINDOW (window), NULL);
-}
-
-static void
-on_in_app_notification_undo_close_button_clicked (GtkWidget      *notification,
-                                                  NautilusWindow *window)
-{
-    hide_in_app_notification_undo (window);
-}
-
-static gboolean
-on_in_app_notification_undo_timeout (NautilusWindow *window)
-{
-    hide_in_app_notification_undo (window);
-
-    return G_SOURCE_REMOVE;
-}
-
 static gchar *
-in_app_notification_undo_deleted_get_label (NautilusFileUndoInfo *undo_info)
+toast_undo_deleted_get_label (NautilusFileUndoInfo *undo_info)
 {
     GList *files;
     gchar *file_label;
@@ -1569,7 +1499,7 @@ in_app_notification_undo_deleted_get_label (NautilusFileUndoInfo *undo_info)
 }
 
 static gchar *
-in_app_notification_undo_unstar_get_label (NautilusFileUndoInfo *undo_info)
+toast_undo_unstar_get_label (NautilusFileUndoInfo *undo_info)
 {
     GList *files;
     gchar *label;
@@ -1601,14 +1531,14 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
 {
     NautilusFileUndoInfo *undo_info;
     NautilusFileUndoManagerState state;
+    AdwToast *toast;
 
     undo_info = nautilus_file_undo_manager_get_action ();
     state = nautilus_file_undo_manager_get_state ();
-
     if (undo_info != NULL &&
         state == NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO)
     {
-        gboolean popup_notification = FALSE;
+        gboolean popup_toast = FALSE;
         g_autofree gchar *label = NULL;
 
         if (nautilus_file_undo_info_get_op_type (undo_info) == NAUTILUS_FILE_UNDO_OP_MOVE_TO_TRASH)
@@ -1622,8 +1552,8 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
              * was the delete operation made */
             if (files != NULL && gtk_window_is_active (GTK_WINDOW (window)))
             {
-                popup_notification = TRUE;
-                label = in_app_notification_undo_deleted_get_label (undo_info);
+                popup_toast = TRUE;
+                label = toast_undo_deleted_get_label (undo_info);
             }
         }
         else if (nautilus_file_undo_info_get_op_type (undo_info) == NAUTILUS_FILE_UNDO_OP_STARRED)
@@ -1640,64 +1570,20 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
                 gtk_window_is_active (GTK_WINDOW (window)) &&
                 !nautilus_file_undo_info_starred_is_starred (NAUTILUS_FILE_UNDO_INFO_STARRED (undo_info)))
             {
-                popup_notification = TRUE;
-                label = in_app_notification_undo_unstar_get_label (undo_info);
+                popup_toast = TRUE;
+                label = toast_undo_unstar_get_label (undo_info);
             }
         }
 
-        if (popup_notification)
+        if (popup_toast)
         {
-            remove_notifications (window);
-            gtk_label_set_markup (GTK_LABEL (window->in_app_notification_undo_label),
-                                  label);
-            gtk_revealer_set_reveal_child (GTK_REVEALER (window->in_app_notification_undo),
-                                           TRUE);
-            window->in_app_notification_undo_timeout_id = g_timeout_add_seconds (NOTIFICATION_TIMEOUT,
-                                                                                 (GSourceFunc) 
on_in_app_notification_undo_timeout,
-                                                                                 window);
+            toast = adw_toast_new (label);
+            adw_toast_set_button_label (toast, _("Undo"));
+            adw_toast_set_action_name (toast, "win.undo");
+            adw_toast_set_priority (toast, ADW_TOAST_PRIORITY_HIGH);
+            adw_toast_overlay_add_toast (window->toast_overlay, toast);
         }
     }
-    else
-    {
-        hide_in_app_notification_undo (window);
-    }
-}
-
-static void
-hide_notification_operation (NautilusWindow *window)
-{
-    if (window->notification_operation_timeout_id != 0)
-    {
-        g_source_remove (window->notification_operation_timeout_id);
-        window->notification_operation_timeout_id = 0;
-    }
-
-    gtk_revealer_set_reveal_child (GTK_REVEALER (window->notification_operation), FALSE);
-    g_clear_object (&window->folder_to_open);
-}
-
-static void
-on_notification_operation_open_clicked (GtkWidget      *notification,
-                                        NautilusWindow *window)
-{
-    nautilus_window_open_location_full (window, window->folder_to_open,
-                                        0, NULL, NULL);
-    hide_notification_operation (window);
-}
-
-static void
-on_notification_operation_close_clicked (GtkWidget      *notification,
-                                         NautilusWindow *window)
-{
-    hide_notification_operation (window);
-}
-
-static gboolean
-on_notification_operation_timeout (NautilusWindow *window)
-{
-    hide_notification_operation (window);
-
-    return FALSE;
 }
 
 void
@@ -1709,41 +1595,33 @@ nautilus_window_show_operation_notification (NautilusWindow *window,
     gchar *folder_name;
     NautilusFile *folder;
     GFile *current_location;
+    AdwToast *toast;
 
     if (window->active_slot == NULL)
     {
         return;
     }
 
+    toast = adw_toast_new (main_label);
+    adw_toast_set_priority (toast, ADW_TOAST_PRIORITY_HIGH);
+
     current_location = nautilus_window_slot_get_location (window->active_slot);
     if (gtk_window_is_active (GTK_WINDOW (window)))
     {
-        remove_notifications (window);
-        gtk_label_set_text (GTK_LABEL (window->notification_operation_label),
-                            main_label);
-
-        if (g_file_equal (folder_to_open, current_location))
+        if (!g_file_equal (folder_to_open, current_location))
         {
-            gtk_widget_hide (window->notification_operation_open);
-        }
-        else
-        {
-            gtk_widget_show (window->notification_operation_open);
             window->folder_to_open = g_object_ref (folder_to_open);
             folder = nautilus_file_get (folder_to_open);
             folder_name = nautilus_file_get_display_name (folder);
             button_label = g_strdup_printf (_("Open %s"), folder_name);
-            gtk_button_set_label (GTK_BUTTON (window->notification_operation_open),
-                                  button_label);
+            adw_toast_set_button_label (toast, button_label);
+            adw_toast_set_action_name (toast, "win.operation-open");
             nautilus_file_unref (folder);
             g_free (folder_name);
             g_free (button_label);
         }
 
-        gtk_revealer_set_reveal_child (GTK_REVEALER (window->notification_operation), TRUE);
-        window->notification_operation_timeout_id = g_timeout_add_seconds (NOTIFICATION_TIMEOUT,
-                                                                           (GSourceFunc) 
on_notification_operation_timeout,
-                                                                           window);
+        adw_toast_overlay_add_toast (window->toast_overlay, toast);
     }
 }
 
@@ -1964,6 +1842,7 @@ const GActionEntry win_entries[] =
     { "up", action_up },
     { "view-menu", action_toggle_state_view_button, NULL, "false", NULL },
     { "current-location-menu", action_show_current_location_menu },
+    { "operation-open", action_operation_open },
     { "reload", action_reload },
     { "stop", action_stop },
     { "new-tab", action_new_tab },
@@ -2161,8 +2040,6 @@ nautilus_window_dispose (GObject *object)
                                 nautilus_application_get_bookmarks (NAUTILUS_APPLICATION (application)));
     }
 
-    g_clear_handle_id (&window->in_app_notification_undo_timeout_id, g_source_remove);
-
     nautilus_window_unexport_handle (window);
 
     G_OBJECT_CLASS (nautilus_window_parent_class)->dispose (object);
@@ -2181,18 +2058,6 @@ nautilus_window_finalize (GObject *object)
         window->sidebar_width_handler_id = 0;
     }
 
-    if (window->in_app_notification_undo_timeout_id != 0)
-    {
-        g_source_remove (window->in_app_notification_undo_timeout_id);
-        window->in_app_notification_undo_timeout_id = 0;
-    }
-
-    if (window->notification_operation_timeout_id != 0)
-    {
-        g_source_remove (window->notification_operation_timeout_id);
-        window->notification_operation_timeout_id = 0;
-    }
-
     g_clear_object (&window->selected_file);
     g_clear_object (&window->selected_volume);
 
@@ -2607,11 +2472,6 @@ nautilus_window_init (NautilusWindow *window)
     g_signal_connect (window, "notify::is-maximized",
                       G_CALLBACK (on_is_maximized_changed), NULL);
 
-    g_signal_connect_object (window->in_app_notification_undo_close_button, "clicked",
-                             G_CALLBACK (on_in_app_notification_undo_close_button_clicked), window, 0);
-    g_signal_connect_object (window->in_app_notification_undo_undo_button, "clicked",
-                             G_CALLBACK (on_in_app_notification_undo_undo_button_clicked), window, 0);
-
     window->slots = NULL;
     window->active_slot = NULL;
 
@@ -2672,18 +2532,10 @@ nautilus_window_class_init (NautilusWindowClass *class)
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, toolbar);
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, content_paned);
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, sidebar);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, main_view);
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, notebook);
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_menu);
     gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_menu_model);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, in_app_notification_undo);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, in_app_notification_undo_label);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, in_app_notification_undo_undo_button);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, in_app_notification_undo_close_button);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation_label);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation_open);
-    gtk_widget_class_bind_template_child (wclass, NautilusWindow, notification_operation_close);
+    gtk_widget_class_bind_template_child (wclass, NautilusWindow, toast_overlay);
 
     signals[SLOT_ADDED] =
         g_signal_new ("slot-added",
@@ -2716,9 +2568,6 @@ nautilus_window_class_init (NautilusWindowClass *class)
                               "changed::" NAUTILUS_PREFERENCES_MOUSE_USE_EXTRA_BUTTONS,
                               G_CALLBACK (use_extra_mouse_buttons_changed),
                               NULL);
-
-    gtk_widget_class_bind_template_callback (wclass, on_notification_operation_open_clicked);
-    gtk_widget_class_bind_template_callback (wclass, on_notification_operation_close_clicked);
 }
 
 NautilusWindow *
diff --git a/src/resources/ui/nautilus-window.ui b/src/resources/ui/nautilus-window.ui
index cc033a153..d50d55851 100644
--- a/src/resources/ui/nautilus-window.ui
+++ b/src/resources/ui/nautilus-window.ui
@@ -30,148 +30,37 @@
     <property name="show-menubar">False</property>
     <property name="title" translatable="yes">_Files</property>
     <child>
-      <object class="GtkBox">
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="NautilusToolbar" id="toolbar"/>
-        </child>
-        <child>
-          <object class="GtkPaned" id="content_paned">
-            <property name="shrink-end-child">False</property>
-            <property name="shrink-start-child">False</property>
-            <property name="resize-start-child">False</property>
-            <property name="vexpand">True</property>
-            <property name="hexpand">True</property>
+      <object class="AdwToastOverlay" id="toast_overlay">
+        <property name="child">
+          <object class="GtkBox">
+            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkBox" id="sidebar">
-                <property name="visible">False</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">6</property>
-              </object>
+              <object class="NautilusToolbar" id="toolbar"/>
             </child>
             <child>
-              <object class="GtkOverlay" id="main_view">
-                <property name="child">
+              <object class="GtkPaned" id="content_paned">
+                <property name="shrink-end-child">False</property>
+                <property name="shrink-start-child">False</property>
+                <property name="resize-start-child">False</property>
+                <property name="vexpand">True</property>
+                <property name="hexpand">True</property>
+                <child>
+                  <object class="GtkBox" id="sidebar">
+                    <property name="visible">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                  </object>
+                </child>
+                <child>
                   <object class="GtkNotebook" id="notebook">
                     <property name="show-tabs">False</property>
                     <property name="show-border">False</property>
                   </object>
-                </property>
-                <child type="overlay">
-                  <object class="GtkRevealer" id="in_app_notification_undo">
-                    <property name="halign">center</property>
-                    <property name="valign">start</property>
-                    <property name="transition_duration">100</property>
-                    <property name="child">
-                      <object class="GtkFrame">
-                        <property name="child">
-                          <object class="GtkBox">
-                            <property name="margin_start">12</property>
-                            <property name="margin_end">4</property>
-                            <child>
-                              <object class="GtkLabel" id="in_app_notification_undo_label">
-                                <property name="max_width_chars">50</property>
-                                <property name="ellipsize">middle</property>
-                                <property name="margin_end">30</property>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkButton" id="in_app_notification_undo_undo_button">
-                                <property name="label" translatable="yes">Undo</property>
-                                <property name="focusable">True</property>
-                                <property name="receives_default">True</property>
-                                <property name="margin_end">6</property>
-                                <style>
-                                  <class name="text-button"/>
-                                </style>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkButton" id="in_app_notification_undo_close_button">
-                                <property name="focusable">True</property>
-                                <property name="receives_default">True</property>
-                                <property name="focus_on_click">False</property>
-                                <child>
-                                  <object class="GtkImage">
-                                    <property name="icon_name">window-close-symbolic</property>
-                                    <property name="icon_size">2</property>
-                                  </object>
-                                </child>
-                                <style>
-                                  <class name="image-button"/>
-                                  <class name="flat"/>
-                                </style>
-                              </object>
-                            </child>
-                          </object>
-                        </property>
-                        <style>
-                          <class name="app-notification"/>
-                        </style>
-                      </object>
-                    </property>
-                  </object>
-                </child>
-                <child type="overlay">
-                  <object class="GtkRevealer" id="notification_operation">
-                    <property name="halign">center</property>
-                    <property name="valign">start</property>
-                    <property name="transition_duration">100</property>
-                    <property name="child">
-                      <object class="GtkFrame">
-                        <property name="child">
-                          <object class="GtkBox">
-                            <property name="margin_start">12</property>
-                            <property name="margin_end">4</property>
-                            <child>
-                              <object class="GtkLabel" id="notification_operation_label">
-                                <property name="max_width_chars">50</property>
-                                <property name="ellipsize">middle</property>
-                                <property name="margin_end">30</property>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkButton" id="notification_operation_open">
-                                <property name="focusable">True</property>
-                                <property name="receives_default">True</property>
-                                <property name="margin_end">6</property>
-                                <signal name="clicked" handler="on_notification_operation_open_clicked" 
object="NautilusWindow" swapped="no"/>
-                                <style>
-                                  <class name="text-button"/>
-                                </style>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkButton" id="notification_operation_close">
-                                <property name="focusable">True</property>
-                                <property name="receives_default">True</property>
-                                <property name="focus_on_click">False</property>
-                                <signal name="clicked" handler="on_notification_operation_close_clicked" 
object="NautilusWindow" swapped="no"/>
-                                <child>
-                                  <object class="GtkImage">
-                                    <property name="icon_name">window-close-symbolic</property>
-                                    <property name="icon_size">2</property>
-                                  </object>
-                                </child>
-                                <style>
-                                  <class name="image-button"/>
-                                  <class name="flat"/>
-                                </style>
-                              </object>
-                            </child>
-                          </object>
-                        </property>
-                        <style>
-                          <class name="app-notification"/>
-                        </style>
-                      </object>
-                    </property>
-                  </object>
                 </child>
               </object>
             </child>
           </object>
-        </child>
+        </property>
       </object>
     </child>
   </template>


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