[file-roller/wip/gtk4] selector dialog: added a custom PlacesSidebar widget
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [file-roller/wip/gtk4] selector dialog: added a custom PlacesSidebar widget
- Date: Sat, 15 Oct 2022 15:19:25 +0000 (UTC)
commit 781ef3af03cc5105260c8d7109112fcb02dcc8fd
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Oct 15 13:43:35 2022 +0200
selector dialog: added a custom PlacesSidebar widget
src/fr-file-selector-dialog.c | 27 +++--
src/fr-places-sidebar.c | 258 ++++++++++++++++++++++++++++++++++++++++++
src/fr-places-sidebar.h | 42 +++++++
src/meson.build | 2 +
src/ui/app.css | 10 ++
5 files changed, 327 insertions(+), 12 deletions(-)
---
diff --git a/src/fr-file-selector-dialog.c b/src/fr-file-selector-dialog.c
index 331d9c27..6b6d7bcb 100644
--- a/src/fr-file-selector-dialog.c
+++ b/src/fr-file-selector-dialog.c
@@ -23,6 +23,7 @@
#include "fr-enum-types.h"
#include "fr-file-selector-dialog.h"
#include "fr-location-bar.h"
+#include "fr-places-sidebar.h"
#include "gio-utils.h"
#include "glib-utils.h"
#include "gtk-utils.h"
@@ -113,6 +114,7 @@ struct _FrFileSelectorDialog {
GtkPopover *file_context_menu;
GtkWidget *location_bar;
FrFileSelectorMode selection_mode;
+ GtkWidget *places_sidebar;
};
@@ -202,7 +204,7 @@ set_current_folder (FrFileSelectorDialog *self,
return;
fr_location_bar_set_location (FR_LOCATION_BAR (self->location_bar), folder);
- //gtk_places_sidebar_set_location (GTK_PLACES_SIDEBAR (GET_WIDGET ("places_sidebar")), folder);
+ fr_places_sidebar_set_location (FR_PLACES_SIDEBAR (self->places_sidebar), folder);
}
@@ -561,16 +563,14 @@ location_bar_changed_cb (FrLocationBar *location_bar,
}
-/*static void
-places_sidebar_open_location_cb (GtkPlacesSidebar *sidebar,
- GFile *location,
- GtkPlacesOpenFlags open_flags,
- gpointer user_data)
+static void
+places_sidebar_open_cb (FrPlacesSidebar *sidebar,
+ GFile *location,
+ gpointer user_data)
{
FrFileSelectorDialog *self = user_data;
-
fr_file_selector_dialog_set_current_folder (self, location);
- }*/
+}
static gboolean
@@ -712,6 +712,13 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
G_CALLBACK (location_bar_changed_cb),
self);
+ self->places_sidebar = fr_places_sidebar_new ();
+ _gtk_box_pack_start (GTK_BOX (GET_WIDGET ("places_sidebar")), self->places_sidebar, TRUE, TRUE);
+ g_signal_connect (self->places_sidebar,
+ "open",
+ G_CALLBACK (places_sidebar_open_cb),
+ self);
+
g_signal_connect (GTK_CELL_RENDERER_TOGGLE (GET_WIDGET ("is_selected_cellrenderertoggle")),
"toggled",
G_CALLBACK (is_selected_cellrenderertoggle_toggled_cb),
@@ -724,10 +731,6 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
"changed",
G_CALLBACK (files_treeview_selection_changed_cb),
self);
- /*g_signal_connect (GTK_PLACES_SIDEBAR (GET_WIDGET ("places_sidebar")),
- "open-location",
- G_CALLBACK (places_sidebar_open_location_cb),
- self);*/
GtkEventController *event_controller = gtk_event_controller_legacy_new ();
g_signal_connect (event_controller,
diff --git a/src/fr-places-sidebar.c b/src/fr-places-sidebar.c
new file mode 100644
index 00000000..25552e46
--- /dev/null
+++ b/src/fr-places-sidebar.c
@@ -0,0 +1,258 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * File-Roller
+ *
+ * Copyright (C) 2022 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "fr-enum-types.h"
+#include "fr-places-sidebar.h"
+#include "gio-utils.h"
+#include "glib-utils.h"
+#include "gtk-utils.h"
+
+
+enum {
+ OPEN,
+ LAST_SIGNAL
+};
+static guint fr_places_sidebar_signals[LAST_SIGNAL] = { 0 };
+
+
+typedef struct {
+ GtkWidget *list_box;
+} FrPlacesSidebarPrivate;
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (FrPlacesSidebar, fr_places_sidebar, GTK_TYPE_BOX)
+
+
+static void
+fr_places_sidebar_finalize (GObject *object)
+{
+ //FrPlacesSidebar *self = FR_PLACES_SIDEBAR (object);
+ G_OBJECT_CLASS (fr_places_sidebar_parent_class)->finalize (object);
+}
+
+
+static void
+fr_places_sidebar_class_init (FrPlacesSidebarClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass*) klass;
+ object_class->finalize = fr_places_sidebar_finalize;
+
+ fr_places_sidebar_signals[OPEN] =
+ g_signal_new ("open",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (FrPlacesSidebarClass, open),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, G_TYPE_OBJECT);
+}
+
+
+static GtkWidget *
+row_box_for_file (GFile *file,
+ const char *display_name)
+{
+ GFileInfo *info;
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+ if (info == NULL)
+ return NULL;
+
+ GtkWidget *icon = gtk_image_new_from_gicon (g_file_info_get_symbolic_icon (info));
+ GtkWidget *label = gtk_label_new ((display_name != NULL) ? display_name :
g_file_info_get_display_name (info));
+
+ GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_box_append (GTK_BOX (box), icon);
+ gtk_box_append (GTK_BOX (box), label);
+
+ GtkWidget *row = gtk_list_box_row_new ();
+ gtk_style_context_add_class (gtk_widget_get_style_context (row), "fr-sidebar-row");
+ gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
+ g_object_set_data_full (G_OBJECT (row), "sidebar-file", g_object_ref (file), g_object_unref);
+
+ char *name = g_file_get_parse_name (file);
+ gtk_widget_set_tooltip_text (row, name);
+ g_free (name);
+
+ g_object_unref (info);
+
+ return row;
+}
+
+
+static void
+row_activated_cb (GtkListBox *list_box,
+ GtkListBoxRow *row,
+ gpointer user_data)
+{
+ FrPlacesSidebar *self = user_data;
+ GFile *file;
+
+ file = g_object_get_data (G_OBJECT (row), "sidebar-file");
+ if (file != NULL)
+ g_signal_emit (self,
+ fr_places_sidebar_signals[OPEN],
+ 0,
+ file);
+}
+
+
+static void
+fr_places_sidebar_init (FrPlacesSidebar *self)
+{
+ FrPlacesSidebarPrivate *private = fr_places_sidebar_get_instance_private (self);
+ GtkWidget *scrolled_window;
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
+
+ scrolled_window = gtk_scrolled_window_new ();
+ gtk_widget_set_vexpand (scrolled_window, TRUE);
+ gtk_box_append (GTK_BOX (self), scrolled_window);
+
+ private->list_box = gtk_list_box_new ();
+ gtk_style_context_add_class (gtk_widget_get_style_context (private->list_box), "fr-sidebar");
+ gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (private->list_box), TRUE);
+ gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled_window), private->list_box);
+ g_signal_connect (private->list_box, "row-activated", G_CALLBACK (row_activated_cb), self);
+
+ GHashTable *locations = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
+
+ /* Home */
+
+ GtkWidget *row;
+ GFile *location;
+
+ location = g_file_new_for_uri ("recent:///");
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = g_file_new_for_uri ("starred:///");
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = _g_file_get_home ();
+ row = row_box_for_file (location, _("Home"));
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+
+ /* Special directories. */
+
+ location = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_MUSIC));
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD));
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ location = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS));
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ /* Bookmarks */
+
+ //gtk_list_box_append (GTK_LIST_BOX (private->list_box), gtk_separator_new
(GTK_ORIENTATION_HORIZONTAL));
+
+ /* Root */
+
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), gtk_separator_new
(GTK_ORIENTATION_HORIZONTAL));
+
+ location = g_file_new_for_path ("/");
+ row = row_box_for_file (location, NULL);
+ if (row != NULL) {
+ gtk_list_box_append (GTK_LIST_BOX (private->list_box), row);
+ g_hash_table_add (locations, location);
+ }
+ g_object_unref (location);
+
+ g_hash_table_unref (locations);
+}
+
+
+GtkWidget *
+fr_places_sidebar_new (void)
+{
+ return (GtkWidget *) g_object_new (fr_places_sidebar_get_type (), NULL);
+}
+
+
+void
+fr_places_sidebar_set_location (FrPlacesSidebar *self,
+ GFile *location)
+{
+ FrPlacesSidebarPrivate *private = fr_places_sidebar_get_instance_private (self);
+
+ gtk_list_box_unselect_all (GTK_LIST_BOX (private->list_box));
+ for (int i = 0; /* void */; i++) {
+ GtkListBoxRow *row = gtk_list_box_get_row_at_index (GTK_LIST_BOX (private->list_box), i);
+ if (row == NULL)
+ break;
+ GFile *file = g_object_get_data (G_OBJECT (row), "sidebar-file");
+ if ((file != NULL) && g_file_equal (file, location))
+ gtk_list_box_select_row (GTK_LIST_BOX (private->list_box), row);
+ }
+}
diff --git a/src/fr-places-sidebar.h b/src/fr-places-sidebar.h
new file mode 100644
index 00000000..ed089e1d
--- /dev/null
+++ b/src/fr-places-sidebar.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * File-Roller
+ *
+ * Copyright (C) 2022 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FR_PLACES_SIDEBAR_H
+#define FR_PLACES_SIDEBAR_H
+
+#include <gtk/gtk.h>
+#include "typedefs.h"
+
+#define FR_TYPE_PLACES_SIDEBAR fr_places_sidebar_get_type ()
+G_DECLARE_DERIVABLE_TYPE (FrPlacesSidebar, fr_places_sidebar, FR, PLACES_SIDEBAR, GtkBox)
+
+struct _FrPlacesSidebarClass {
+ GtkBoxClass __parent_class;
+
+ /*< signals >*/
+
+ void (*open) (FrPlacesSidebar *self, GFile *location);
+};
+
+GtkWidget * fr_places_sidebar_new (void);
+void fr_places_sidebar_set_location (FrPlacesSidebar *self, GFile *location);
+
+#endif /* FR_PLACES_SIDEBAR_H */
diff --git a/src/meson.build b/src/meson.build
index 94a07c4a..5d9e1c73 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -42,6 +42,7 @@ source_files = files(
'fr-location-bar.c',
'fr-location-button.c',
'fr-new-archive-dialog.c',
+ 'fr-places-sidebar.c',
'fr-process.c',
'fr-window-actions-callbacks.c',
'fr-window.c',
@@ -86,6 +87,7 @@ fr_headers = files(
'fr-location-bar.h',
'fr-location-button.h',
'fr-new-archive-dialog.h',
+ 'fr-places-sidebar.h',
'fr-process.h',
'fr-window-actions-callbacks.h',
'fr-window-actions-entries.h',
diff --git a/src/ui/app.css b/src/ui/app.css
index 53b48479..2513a55a 100644
--- a/src/ui/app.css
+++ b/src/ui/app.css
@@ -15,3 +15,13 @@
.dialog-content.small-padding {
padding: 10px;
}
+
+.fr-sidebar {
+ padding: 6px;
+}
+
+.fr-sidebar-row {
+ border-radius: 6px;
+ padding: 7px 14px;
+ margin: 1px 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]