[gnome-flashback] desktop: make icons selectable
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: make icons selectable
- Date: Sun, 10 Nov 2019 20:47:33 +0000 (UTC)
commit a9bf9ce60eaadcb6bb77f90844362a921e7c5ab2
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Sun Nov 10 22:35:37 2019 +0200
desktop: make icons selectable
gnome-flashback/libdesktop/Makefile.am | 1 +
gnome-flashback/libdesktop/gf-icon-view.c | 127 ++++++++++++++++++++++++------
gnome-flashback/libdesktop/gf-icon.c | 98 ++++++++++++++++++++++-
gnome-flashback/libdesktop/gf-icon.h | 19 +++--
4 files changed, 216 insertions(+), 29 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/Makefile.am b/gnome-flashback/libdesktop/Makefile.am
index 50da485..827ce32 100644
--- a/gnome-flashback/libdesktop/Makefile.am
+++ b/gnome-flashback/libdesktop/Makefile.am
@@ -45,6 +45,7 @@ libdesktop_la_LIBADD = \
ENUM_TYPES = \
$(srcdir)/gf-desktop-enums.h \
+ $(srcdir)/gf-icon.h \
$(NULL)
gf-desktop-enum-types.c: gf-desktop-enum-types.c.in gf-desktop-enum-types.h $(ENUM_TYPES)
diff --git a/gnome-flashback/libdesktop/gf-icon-view.c b/gnome-flashback/libdesktop/gf-icon-view.c
index 71407d5..f95884e 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.c
+++ b/gnome-flashback/libdesktop/gf-icon-view.c
@@ -34,6 +34,8 @@ struct _GfIconView
{
GtkEventBox parent;
+ GtkGesture *multi_press;
+
GFile *desktop;
GFileMonitor *monitor;
@@ -46,6 +48,8 @@ struct _GfIconView
GList *icons;
guint add_icons_id;
+
+ GList *selected_icons;
};
G_DEFINE_TYPE (GfIconView, gf_icon_view, GTK_TYPE_EVENT_BOX)
@@ -186,6 +190,8 @@ file_deleted (GfIconView *self,
gf_monitor_view_remove_icon (GF_MONITOR_VIEW (info->view),
info->icon);
+ self->selected_icons = g_list_remove (self->selected_icons, l->data);
+
self->icons = g_list_remove_link (self->icons, l);
g_list_free_full (l, gf_icon_info_free);
@@ -194,6 +200,60 @@ file_deleted (GfIconView *self,
}
}
+static void
+unselect_cb (gpointer data,
+ gpointer user_data)
+{
+ gf_icon_set_selected (data, FALSE, GF_ICON_SELECTED_NONE);
+}
+
+static void
+unselect_icons (GfIconView *self)
+{
+ if (self->selected_icons == NULL)
+ return;
+
+ g_list_foreach (self->selected_icons, unselect_cb, NULL);
+ g_clear_pointer (&self->selected_icons, g_list_free);
+}
+
+static void
+icon_selected_cb (GfIcon *icon,
+ GfIconSelectedFlags flags,
+ GfIconView *self)
+{
+ if ((flags & GF_ICON_SELECTED_CLEAR) == GF_ICON_SELECTED_CLEAR)
+ unselect_icons (self);
+
+ if ((flags & GF_ICON_SELECTED_ADD) == GF_ICON_SELECTED_ADD)
+ self->selected_icons = g_list_append (self->selected_icons, icon);
+
+ if ((flags & GF_ICON_SELECTED_REMOVE) == GF_ICON_SELECTED_REMOVE)
+ self->selected_icons = g_list_remove (self->selected_icons, icon);
+}
+
+static GfIconInfo *
+create_icon_info (GfIconView *self,
+ GFile *file,
+ GFileInfo *info)
+{
+ GtkWidget *icon;
+
+ icon = gf_icon_new (file, info);
+
+ g_signal_connect (icon, "selected", G_CALLBACK (icon_selected_cb), self);
+
+ g_settings_bind (self->settings, "icon-size",
+ icon, "icon-size",
+ G_SETTINGS_BIND_GET);
+
+ g_settings_bind (self->settings, "extra-text-width",
+ icon, "extra-text-width",
+ G_SETTINGS_BIND_GET);
+
+ return gf_icon_info_new (icon);
+}
+
static void
query_info_cb (GObject *object,
GAsyncResult *res,
@@ -203,7 +263,7 @@ query_info_cb (GObject *object,
GFileInfo *file_info;
GError *error;
GfIconView *self;
- GtkWidget *icon;
+ GfIconInfo *icon_info;
file = G_FILE (object);
@@ -221,18 +281,10 @@ query_info_cb (GObject *object,
self = GF_ICON_VIEW (user_data);
- icon = gf_icon_new (file, file_info);
+ icon_info = create_icon_info (self, file, file_info);
g_object_unref (file_info);
- g_settings_bind (self->settings, "icon-size",
- icon, "icon-size",
- G_SETTINGS_BIND_GET);
-
- g_settings_bind (self->settings, "extra-text-width",
- icon, "extra-text-width",
- G_SETTINGS_BIND_GET);
-
- self->icons = g_list_append (self->icons, gf_icon_info_new (icon));
+ self->icons = g_list_append (self->icons, icon_info);
add_icons (self);
}
@@ -308,6 +360,34 @@ desktop_changed_cb (GFileMonitor *monitor,
}
}
+static void
+multi_press_pressed_cb (GtkGestureMultiPress *gesture,
+ gint n_press,
+ gdouble x,
+ gdouble y,
+ GfIconView *self)
+{
+ guint button;
+ GdkEventSequence *sequence;
+ const GdkEvent *event;
+
+ button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
+ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+ event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+
+ if (event == NULL)
+ return;
+
+ unselect_icons (self);
+
+ if (button == GDK_BUTTON_PRIMARY)
+ {
+ }
+ else if (button == GDK_BUTTON_SECONDARY)
+ {
+ }
+}
+
static void
view_foreach_cb (GtkWidget *widget,
gpointer user_data)
@@ -371,23 +451,15 @@ next_files_cb (GObject *object,
{
GFileInfo *info;
GFile *file;
- GtkWidget *icon;
+ GfIconInfo *icon_info;
info = l->data;
file = g_file_enumerator_get_child (enumerator, info);
- icon = gf_icon_new (file, info);
+ icon_info = create_icon_info (self, file, info);
g_object_unref (file);
- g_settings_bind (self->settings, "icon-size",
- icon, "icon-size",
- G_SETTINGS_BIND_GET);
-
- g_settings_bind (self->settings, "extra-text-width",
- icon, "extra-text-width",
- G_SETTINGS_BIND_GET);
-
- self->icons = g_list_prepend (self->icons, gf_icon_info_new (icon));
+ self->icons = g_list_prepend (self->icons, icon_info);
}
self->icons = g_list_reverse (self->icons);
@@ -572,6 +644,7 @@ gf_icon_view_dispose (GObject *object)
self = GF_ICON_VIEW (object);
+ g_clear_object (&self->multi_press);
g_clear_object (&self->desktop);
g_clear_object (&self->monitor);
g_clear_object (&self->settings);
@@ -585,6 +658,8 @@ gf_icon_view_dispose (GObject *object)
self->icons = NULL;
}
+ g_clear_pointer (&self->selected_icons, g_list_free);
+
G_OBJECT_CLASS (gf_icon_view_parent_class)->dispose (object);
}
@@ -624,6 +699,14 @@ gf_icon_view_init (GfIconView *self)
int n_monitors;
int i;
+ self->multi_press = gtk_gesture_multi_press_new (GTK_WIDGET (self));
+
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (self->multi_press), 0);
+
+ g_signal_connect (self->multi_press, "pressed",
+ G_CALLBACK (multi_press_pressed_cb),
+ self);
+
desktop_dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
self->desktop = g_file_new_for_path (desktop_dir);
diff --git a/gnome-flashback/libdesktop/gf-icon.c b/gnome-flashback/libdesktop/gf-icon.c
index b3f93ca..9eab1b9 100644
--- a/gnome-flashback/libdesktop/gf-icon.c
+++ b/gnome-flashback/libdesktop/gf-icon.c
@@ -25,6 +25,8 @@ struct _GfIcon
{
GtkButton parent;
+ GtkGesture *multi_press;
+
GFile *file;
GFileInfo *info;
@@ -52,6 +54,15 @@ enum
static GParamSpec *icon_properties[LAST_PROP] = { NULL };
+enum
+{
+ SELECTED,
+
+ LAST_SIGNAL
+};
+
+static guint icon_signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (GfIcon, gf_icon, GTK_TYPE_BUTTON)
static void
@@ -68,6 +79,66 @@ update_state (GfIcon *self)
gtk_widget_set_state_flags (GTK_WIDGET (self), state, TRUE);
}
+static void
+multi_press_pressed_cb (GtkGestureMultiPress *gesture,
+ gint n_press,
+ gdouble x,
+ gdouble y,
+ GfIcon *self)
+{
+ guint button;
+ GdkEventSequence *sequence;
+ const GdkEvent *event;
+ GfIconSelectedFlags flags;
+ GdkModifierType state;
+ gboolean control_pressed;
+ gboolean shift_pressed;
+
+ button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
+ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+ event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+ flags = GF_ICON_SELECTED_NONE;
+
+ if (event == NULL)
+ return;
+
+ gdk_event_get_state (event, &state);
+
+ control_pressed = (state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK;
+ shift_pressed = (state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
+
+ if (button == GDK_BUTTON_PRIMARY)
+ {
+ gboolean selected;
+
+ if (!control_pressed && !shift_pressed)
+ flags |= GF_ICON_SELECTED_CLEAR;
+
+ if (control_pressed || shift_pressed)
+ {
+ selected = !self->selected;
+
+ if (self->selected)
+ flags |= GF_ICON_SELECTED_REMOVE;
+ else
+ flags |= GF_ICON_SELECTED_ADD;
+ }
+ else
+ {
+ selected = TRUE;
+ flags |= GF_ICON_SELECTED_ADD;
+ }
+
+ gf_icon_set_selected (self, selected, flags);
+ }
+ else if (button == GDK_BUTTON_SECONDARY)
+ {
+ }
+ else if (button == GDK_BUTTON_MIDDLE)
+ {
+ }
+}
+
static void
gf_icon_constructed (GObject *object)
{
@@ -94,6 +165,8 @@ gf_icon_dispose (GObject *object)
self = GF_ICON (object);
+ g_clear_object (&self->multi_press);
+
g_clear_object (&self->file);
g_clear_object (&self->info);
@@ -200,6 +273,15 @@ install_properties (GObjectClass *object_class)
g_object_class_install_properties (object_class, LAST_PROP, icon_properties);
}
+static void
+install_signals (void)
+{
+ icon_signals[SELECTED] =
+ g_signal_new ("selected", GF_TYPE_ICON, G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL, G_TYPE_NONE, 1,
+ GF_TYPE_ICON_SELECTED_FLAGS);
+}
+
static void
gf_icon_class_init (GfIconClass *self_class)
{
@@ -216,6 +298,7 @@ gf_icon_class_init (GfIconClass *self_class)
widget_class->get_preferred_width = gf_icon_get_preferred_width;
install_properties (object_class);
+ install_signals ();
gtk_widget_class_set_css_name (widget_class, "gf-icon");
}
@@ -229,6 +312,14 @@ gf_icon_init (GfIcon *self)
PangoAttrList *attrs;
#endif
+ self->multi_press = gtk_gesture_multi_press_new (GTK_WIDGET (self));
+
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (self->multi_press), 0);
+
+ g_signal_connect (self->multi_press, "pressed",
+ G_CALLBACK (multi_press_pressed_cb),
+ self);
+
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (self), box);
gtk_widget_show (box);
@@ -270,14 +361,17 @@ gf_icon_new (GFile *file,
}
void
-gf_icon_set_selected (GfIcon *self,
- gboolean selected)
+gf_icon_set_selected (GfIcon *self,
+ gboolean selected,
+ GfIconSelectedFlags flags)
{
if (self->selected == selected)
return;
self->selected = selected;
update_state (self);
+
+ g_signal_emit (self, icon_signals[SELECTED], 0, flags);
}
GFile *
diff --git a/gnome-flashback/libdesktop/gf-icon.h b/gnome-flashback/libdesktop/gf-icon.h
index 2903c8f..2ff4961 100644
--- a/gnome-flashback/libdesktop/gf-icon.h
+++ b/gnome-flashback/libdesktop/gf-icon.h
@@ -22,16 +22,25 @@
G_BEGIN_DECLS
+typedef enum
+{
+ GF_ICON_SELECTED_NONE = 0,
+ GF_ICON_SELECTED_CLEAR = (1 << 0),
+ GF_ICON_SELECTED_ADD = (1 << 1),
+ GF_ICON_SELECTED_REMOVE = (1 << 2)
+} GfIconSelectedFlags;
+
#define GF_TYPE_ICON (gf_icon_get_type ())
G_DECLARE_FINAL_TYPE (GfIcon, gf_icon, GF, ICON, GtkButton)
-GtkWidget *gf_icon_new (GFile *file,
- GFileInfo *info);
+GtkWidget *gf_icon_new (GFile *file,
+ GFileInfo *info);
-void gf_icon_set_selected (GfIcon *self,
- gboolean selected);
+void gf_icon_set_selected (GfIcon *self,
+ gboolean selected,
+ GfIconSelectedFlags flags);
-GFile *gf_icon_get_file (GfIcon *self);
+GFile *gf_icon_get_file (GfIcon *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]