summaryrefslogtreecommitdiffstats
path: root/src/nautilus-star-cell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nautilus-star-cell.c')
-rw-r--r--src/nautilus-star-cell.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/nautilus-star-cell.c b/src/nautilus-star-cell.c
new file mode 100644
index 0000000..9f21028
--- /dev/null
+++ b/src/nautilus-star-cell.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2022 António Fernandes <antoniof@gnome.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "nautilus-star-cell.h"
+#include "nautilus-tag-manager.h"
+
+struct _NautilusStarCell
+{
+ NautilusViewCell parent_instance;
+
+ GSignalGroup *item_signal_group;
+
+ GtkImage *star;
+};
+
+G_DEFINE_TYPE (NautilusStarCell, nautilus_star_cell, NAUTILUS_TYPE_VIEW_CELL)
+
+static void
+on_star_click_released (GtkGestureClick *gesture,
+ gint n_press,
+ gdouble x,
+ gdouble y,
+ gpointer user_data)
+{
+ NautilusStarCell *self = user_data;
+ NautilusTagManager *tag_manager = nautilus_tag_manager_get ();
+ g_autoptr (NautilusViewItem) item = NULL;
+ NautilusFile *file;
+ g_autofree gchar *uri = NULL;
+
+ item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
+ g_return_if_fail (item != NULL);
+ file = nautilus_view_item_get_file (item);
+ uri = nautilus_file_get_uri (file);
+
+ if (nautilus_tag_manager_file_is_starred (tag_manager, uri))
+ {
+ nautilus_tag_manager_unstar_files (tag_manager,
+ G_OBJECT (item),
+ &(GList){ file, NULL },
+ NULL,
+ NULL);
+ gtk_widget_remove_css_class (GTK_WIDGET (self->star), "added");
+ }
+ else
+ {
+ nautilus_tag_manager_star_files (tag_manager,
+ G_OBJECT (item),
+ &(GList){ file, NULL },
+ NULL,
+ NULL);
+ gtk_widget_add_css_class (GTK_WIDGET (self->star), "added");
+ }
+
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+static void
+update_star (GtkImage *star,
+ NautilusFile *file)
+{
+ gboolean is_starred;
+ g_autofree gchar *file_uri = NULL;
+
+ g_return_if_fail (NAUTILUS_IS_FILE (file));
+
+ file_uri = nautilus_file_get_uri (file);
+ is_starred = nautilus_tag_manager_file_is_starred (nautilus_tag_manager_get (),
+ file_uri);
+
+ gtk_image_set_from_icon_name (star, is_starred ? "starred-symbolic" : "non-starred-symbolic");
+}
+
+static void
+on_file_changed (NautilusStarCell *self)
+{
+ g_autoptr (NautilusViewItem) item = NULL;
+ NautilusFile *file;
+ g_autofree gchar *string = NULL;
+
+ item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
+ g_return_if_fail (item != NULL);
+ file = nautilus_view_item_get_file (item);
+
+ update_star (self->star, file);
+}
+
+static void
+on_starred_changed (NautilusTagManager *tag_manager,
+ GList *changed_files,
+ gpointer user_data)
+{
+ NautilusStarCell *self = user_data;
+ g_autoptr (NautilusViewItem) item = NULL;
+ NautilusFile *file;
+
+ item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
+ if (item == NULL)
+ {
+ return;
+ }
+
+ file = nautilus_view_item_get_file (item);
+ if (g_list_find (changed_files, file))
+ {
+ update_star (self->star, file);
+ }
+}
+
+static void
+nautilus_star_cell_init (NautilusStarCell *self)
+{
+ GtkWidget *star;
+ GtkGesture *gesture;
+
+ /* Create star icon */
+ star = gtk_image_new ();
+ gtk_widget_set_halign (star, GTK_ALIGN_END);
+ gtk_widget_set_valign (star, GTK_ALIGN_CENTER);
+ gtk_widget_add_css_class (star, "dim-label");
+ gtk_widget_add_css_class (star, "star");
+ adw_bin_set_child (ADW_BIN (self), star);
+ self->star = GTK_IMAGE (star);
+
+ /* Make it clickable */
+ gesture = gtk_gesture_click_new ();
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_PRIMARY);
+ g_signal_connect (gesture, "released", G_CALLBACK (on_star_click_released), self);
+ gtk_widget_add_controller (star, GTK_EVENT_CONTROLLER (gesture));
+
+ /* Update on tag changes */
+ g_signal_connect_object (nautilus_tag_manager_get (), "starred-changed",
+ G_CALLBACK (on_starred_changed), self, 0);
+
+ /* Connect automatically to an item. */
+ self->item_signal_group = g_signal_group_new (NAUTILUS_TYPE_VIEW_ITEM);
+ g_signal_group_connect_swapped (self->item_signal_group, "file-changed",
+ (GCallback) on_file_changed, self);
+ g_signal_connect_object (self->item_signal_group, "bind",
+ (GCallback) on_file_changed, self,
+ G_CONNECT_SWAPPED);
+ g_object_bind_property (self, "item",
+ self->item_signal_group, "target",
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+nautilus_star_cell_finalize (GObject *object)
+{
+ NautilusStarCell *self = (NautilusStarCell *) object;
+
+ g_object_unref (self->item_signal_group);
+ G_OBJECT_CLASS (nautilus_star_cell_parent_class)->finalize (object);
+}
+
+static void
+nautilus_star_cell_class_init (NautilusStarCellClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = nautilus_star_cell_finalize;
+}
+
+NautilusViewCell *
+nautilus_star_cell_new (NautilusListBase *view)
+{
+ return NAUTILUS_VIEW_CELL (g_object_new (NAUTILUS_TYPE_STAR_CELL,
+ "view", view,
+ NULL));
+}