[nautilus/wip/antoniof/new-list-view-continuation: 28/32] list-view-item-ui: Show spinner while loading subfolders
- From: António Fernandes <antoniof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/antoniof/new-list-view-continuation: 28/32] list-view-item-ui: Show spinner while loading subfolders
- Date: Thu, 21 Apr 2022 09:57:39 +0000 (UTC)
commit d40a86d898d71a7357c727722ebdf1e76bcf45d5
Author: António Fernandes <antoniof gnome org>
Date: Thu Apr 7 00:17:45 2022 +0100
list-view-item-ui: Show spinner while loading subfolders
The spinner is shown only after 1 second without the directory having
finished loading, to avoid visual noise when directories loads quickly.
src/nautilus-list-view-item-ui.c | 61 ++++++++++++++++++++++++++
src/nautilus-list-view.c | 22 ++++++++++
src/nautilus-view-item-model.c | 29 ++++++++++++
src/nautilus-view-item-model.h | 2 +
src/resources/ui/nautilus-list-view-item-ui.ui | 8 ++++
5 files changed, 122 insertions(+)
---
diff --git a/src/nautilus-list-view-item-ui.c b/src/nautilus-list-view-item-ui.c
index 007d975ff..c64395612 100644
--- a/src/nautilus-list-view-item-ui.c
+++ b/src/nautilus-list-view-item-ui.c
@@ -4,6 +4,8 @@
#include "nautilus-file-utilities.h"
#include "nautilus-thumbnails.h"
+#define LOADING_TIMEOUT_SECONDS 1
+
struct _NautilusListViewItemUi
{
GtkBox parent_instance;
@@ -13,6 +15,7 @@ struct _NautilusListViewItemUi
GFile *file_path_base_location;
GtkWidget *fixed_height_box;
+ GtkWidget *spinner;
GtkWidget *icon;
GtkWidget *label;
GtkWidget *snippet;
@@ -20,6 +23,7 @@ struct _NautilusListViewItemUi
gboolean show_snippet;
gboolean called_once;
+ guint loading_timeout_id;
};
G_DEFINE_TYPE (NautilusListViewItemUi, nautilus_list_view_item_ui, GTK_TYPE_BOX)
@@ -197,6 +201,15 @@ static void
set_model (NautilusListViewItemUi *self,
NautilusViewItemModel *model);
+static void
+dispose (GObject *object)
+{
+ NautilusListViewItemUi *self = (NautilusListViewItemUi *) object;
+
+ g_clear_handle_id (&self->loading_timeout_id, g_source_remove);
+ G_OBJECT_CLASS (nautilus_list_view_item_ui_parent_class)->dispose (object);
+}
+
static void
finalize (GObject *object)
{
@@ -246,6 +259,50 @@ on_view_item_is_cut_changed (GObject *object,
}
}
+static gboolean
+on_loading_timeout (gpointer user_data)
+{
+ NautilusListViewItemUi *self = NAUTILUS_LIST_VIEW_ITEM_UI (user_data);
+ gboolean is_loading;
+
+ g_object_get (self->model, "is-loading", &is_loading, NULL);
+ if (is_loading)
+ {
+ gtk_widget_show (self->spinner);
+ gtk_spinner_start (GTK_SPINNER (self->spinner));
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+on_view_item_is_loading_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NautilusListViewItemUi *self = NAUTILUS_LIST_VIEW_ITEM_UI (user_data);
+ gboolean is_loading;
+
+ if (object != G_OBJECT (self->model))
+ {
+ return;
+ }
+
+ g_clear_handle_id (&self->loading_timeout_id, g_source_remove);
+ g_object_get (object, "is-loading", &is_loading, NULL);
+ if (is_loading)
+ {
+ self->loading_timeout_id = g_timeout_add_seconds (LOADING_TIMEOUT_SECONDS,
+ G_SOURCE_FUNC (on_loading_timeout),
+ self);
+ }
+ else
+ {
+ gtk_widget_hide (self->spinner);
+ gtk_spinner_stop (GTK_SPINNER (self->spinner));
+ }
+}
+
static void
set_model (NautilusListViewItemUi *self,
NautilusViewItemModel *model)
@@ -281,6 +338,8 @@ set_model (NautilusListViewItemUi *self,
(GCallback) on_view_item_size_changed, self);
g_signal_connect (self->model, "notify::is-cut",
(GCallback) on_view_item_is_cut_changed, self);
+ g_signal_connect (self->model, "notify::is-loading",
+ (GCallback) on_view_item_is_loading_changed, self);
g_signal_connect_swapped (self->model, "file-changed",
(GCallback) on_file_changed, self);
}
@@ -312,6 +371,7 @@ nautilus_list_view_item_ui_class_init (NautilusListViewItemUiClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;
object_class->set_property = set_property;
@@ -327,6 +387,7 @@ nautilus_list_view_item_ui_class_init (NautilusListViewItemUiClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/nautilus/ui/nautilus-list-view-item-ui.ui");
gtk_widget_class_bind_template_child (widget_class, NautilusListViewItemUi, fixed_height_box);
+ gtk_widget_class_bind_template_child (widget_class, NautilusListViewItemUi, spinner);
gtk_widget_class_bind_template_child (widget_class, NautilusListViewItemUi, icon);
gtk_widget_class_bind_template_child (widget_class, NautilusListViewItemUi, label);
gtk_widget_class_bind_template_child (widget_class, NautilusListViewItemUi, snippet);
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 51c7ddb4b..07ed7bf14 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -1589,6 +1589,18 @@ unload_file_timeout (gpointer data)
return G_SOURCE_REMOVE;
}
+static void
+on_subdirectory_done_loading (NautilusDirectory *directory,
+ GtkTreeListRow *row)
+{
+ NautilusViewItemModel *item;
+
+ g_signal_handlers_disconnect_by_func (directory, on_subdirectory_done_loading, row);
+
+ item = NAUTILUS_VIEW_ITEM_MODEL (gtk_tree_list_row_get_item (row));
+ nautilus_view_item_model_set_loading (item, FALSE);
+}
+
static void
on_row_expanded_changed (GObject *gobject,
GParamSpec *pspec,
@@ -1615,9 +1627,19 @@ on_row_expanded_changed (GObject *gobject,
{
nautilus_files_view_add_subdirectory (NAUTILUS_FILES_VIEW (self), directory);
}
+ if (!nautilus_directory_are_all_files_seen (directory))
+ {
+ nautilus_view_item_model_set_loading (item_model, TRUE);
+ g_signal_connect_object (directory,
+ "done-loading",
+ G_CALLBACK (on_subdirectory_done_loading),
+ row,
+ 0);
+ }
}
else
{
+ nautilus_view_item_model_set_loading (item_model, FALSE);
g_timeout_add_seconds (COLLAPSE_TO_UNLOAD_DELAY,
unload_file_timeout,
unload_delay_data_new (self, item_model, directory));
diff --git a/src/nautilus-view-item-model.c b/src/nautilus-view-item-model.c
index 13fecb98c..54bae18c4 100644
--- a/src/nautilus-view-item-model.c
+++ b/src/nautilus-view-item-model.c
@@ -6,6 +6,7 @@ struct _NautilusViewItemModel
GObject parent_instance;
guint icon_size;
gboolean is_cut;
+ gboolean is_loading;
NautilusFile *file;
GtkWidget *item_ui;
};
@@ -18,6 +19,7 @@ enum
PROP_FILE,
PROP_ICON_SIZE,
PROP_IS_CUT,
+ PROP_IS_LOADING,
PROP_ITEM_UI,
N_PROPS
};
@@ -78,6 +80,12 @@ nautilus_view_item_model_get_property (GObject *object,
}
break;
+ case PROP_IS_LOADING:
+ {
+ g_value_set_boolean (value, self->is_loading);
+ }
+ break;
+
case PROP_ITEM_UI:
{
g_value_set_object (value, self->item_ui);
@@ -119,6 +127,12 @@ nautilus_view_item_model_set_property (GObject *object,
}
break;
+ case PROP_IS_LOADING:
+ {
+ self->is_loading = g_value_get_boolean (value);
+ }
+ break;
+
case PROP_ITEM_UI:
{
g_set_object (&self->item_ui, g_value_get_object (value));
@@ -162,6 +176,12 @@ nautilus_view_item_model_class_init (NautilusViewItemModelClass *klass)
"", "",
FALSE,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_IS_LOADING,
+ g_param_spec_boolean ("is-loading",
+ "", "",
+ FALSE,
+ G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_FILE,
g_param_spec_object ("file",
@@ -223,6 +243,15 @@ nautilus_view_item_model_set_cut (NautilusViewItemModel *self,
g_object_set (self, "is-cut", is_cut, NULL);
}
+void
+nautilus_view_item_model_set_loading (NautilusViewItemModel *self,
+ gboolean loading)
+{
+ g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
+
+ g_object_set (self, "is-loading", loading, NULL);
+}
+
NautilusFile *
nautilus_view_item_model_get_file (NautilusViewItemModel *self)
{
diff --git a/src/nautilus-view-item-model.h b/src/nautilus-view-item-model.h
index 27c4a8fd9..80a8c79a9 100644
--- a/src/nautilus-view-item-model.h
+++ b/src/nautilus-view-item-model.h
@@ -20,6 +20,8 @@ void nautilus_view_item_model_set_icon_size (NautilusViewItemModel *self,
guint nautilus_view_item_model_get_icon_size (NautilusViewItemModel *self);
void nautilus_view_item_model_set_cut (NautilusViewItemModel *self,
gboolean is_cut);
+void nautilus_view_item_model_set_loading (NautilusViewItemModel *self,
+ gboolean is_loading);
NautilusFile * nautilus_view_item_model_get_file (NautilusViewItemModel *self);
diff --git a/src/resources/ui/nautilus-list-view-item-ui.ui b/src/resources/ui/nautilus-list-view-item-ui.ui
index fe2c0e30d..22b311632 100644
--- a/src/resources/ui/nautilus-list-view-item-ui.ui
+++ b/src/resources/ui/nautilus-list-view-item-ui.ui
@@ -6,6 +6,14 @@
<property name="orientation">horizontal</property>
<property name="halign">fill</property>
<property name="valign">center</property>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">False</property>
+ <property name="spinning">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
<child>
<object class="GtkBox" id="fixed_height_box">
<property name="orientation">vertical</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]