[gnome-flashback] desktop: add enumerated icons to desktop



commit 673b308e63c2c50fa1d9ca0460835db66c09f1e7
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sun Nov 10 00:00:29 2019 +0200

    desktop: add enumerated icons to desktop

 gnome-flashback/libdesktop/gf-icon-view.c    | 120 +++++++++++++++++++++++++++
 gnome-flashback/libdesktop/gf-monitor-view.c |  75 +++++++++++++++++
 gnome-flashback/libdesktop/gf-monitor-view.h |   3 +
 3 files changed, 198 insertions(+)
---
diff --git a/gnome-flashback/libdesktop/gf-icon-view.c b/gnome-flashback/libdesktop/gf-icon-view.c
index 017eb7d..c676a82 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.c
+++ b/gnome-flashback/libdesktop/gf-icon-view.c
@@ -36,10 +36,109 @@ struct _GfIconView
   GCancellable *cancellable;
 
   GList        *icons;
+
+  guint         add_icons_id;
 };
 
 G_DEFINE_TYPE (GfIconView, gf_icon_view, GTK_TYPE_EVENT_BOX)
 
+static GList *
+get_monitor_views (GfIconView *self)
+{
+  GList *views;
+  GList *children;
+  GList *l;
+
+  views = NULL;
+
+  children = gtk_container_get_children (GTK_CONTAINER (self->fixed));
+
+  for (l = children; l != NULL; l = l->next)
+    {
+      GfMonitorView *view;
+
+      view = GF_MONITOR_VIEW (l->data);
+
+      if (gf_monitor_view_is_primary (view))
+        views = g_list_prepend (views, view);
+      else
+        views = g_list_append (views, view);
+    }
+
+  g_list_free (children);
+  return views;
+}
+
+static void
+add_icons (GfIconView *self)
+{
+  GList *views;
+  GList *view;
+  GList *l;
+
+  views = get_monitor_views (self);
+  view = views;
+
+  for (l = self->icons; l != NULL; l = l->next)
+    {
+      while (view != NULL)
+        {
+          if (!gf_monitor_view_add_icon (GF_MONITOR_VIEW (view->data), l->data))
+            {
+              view = view->next;
+              continue;
+            }
+
+          break;
+        }
+
+      if (view == NULL)
+        break;
+    }
+
+  g_list_free (views);
+}
+
+static gboolean
+add_icons_cb (gpointer user_data)
+{
+  GfIconView *self;
+
+  self = GF_ICON_VIEW (user_data);
+
+  add_icons (self);
+  self->add_icons_id = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+add_icons_idle (GfIconView *self)
+{
+  if (self->add_icons_id != 0)
+    return;
+
+  self->add_icons_id = g_idle_add (add_icons_cb, self);
+
+  g_source_set_name_by_id (self->add_icons_id,
+                           "[gnome-flashback] add_icons_cb");
+}
+
+static void
+view_foreach_cb (GtkWidget *widget,
+                 gpointer   user_data)
+{
+  gtk_container_remove (GTK_CONTAINER (user_data), widget);
+}
+
+static void
+size_changed_cb (GtkWidget  *view,
+                 GfIconView *self)
+{
+  gtk_container_foreach (GTK_CONTAINER (view), view_foreach_cb, view);
+  add_icons_idle (self);
+}
+
 static void
 next_files_cb (GObject      *object,
                GAsyncResult *res,
@@ -92,6 +191,8 @@ next_files_cb (GObject      *object,
 
   self->icons = g_list_reverse (self->icons);
   g_list_free_full (files, g_object_unref);
+
+  add_icons (self);
 }
 
 static void
@@ -215,6 +316,8 @@ create_monitor_view (GfIconView *self,
                               column_spacing,
                               row_spacing);
 
+  g_signal_connect (view, "size-changed", G_CALLBACK (size_changed_cb), self);
+
   gtk_fixed_put (GTK_FIXED (self->fixed), view, workarea.x, workarea.y);
   gtk_widget_show (view);
 
@@ -283,6 +386,22 @@ gf_icon_view_dispose (GObject *object)
   G_OBJECT_CLASS (gf_icon_view_parent_class)->dispose (object);
 }
 
+static void
+gf_icon_view_finalize (GObject *object)
+{
+  GfIconView *self;
+
+  self = GF_ICON_VIEW (object);
+
+  if (self->add_icons_id != 0)
+    {
+      g_source_remove (self->add_icons_id);
+      self->add_icons_id = 0;
+    }
+
+  G_OBJECT_CLASS (gf_icon_view_parent_class)->finalize (object);
+}
+
 static void
 gf_icon_view_class_init (GfIconViewClass *self_class)
 {
@@ -291,6 +410,7 @@ gf_icon_view_class_init (GfIconViewClass *self_class)
   object_class = G_OBJECT_CLASS (self_class);
 
   object_class->dispose = gf_icon_view_dispose;
+  object_class->finalize = gf_icon_view_finalize;
 }
 
 static void
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.c b/gnome-flashback/libdesktop/gf-monitor-view.c
index fbcee21..3d84a4b 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.c
+++ b/gnome-flashback/libdesktop/gf-monitor-view.c
@@ -50,6 +50,8 @@ struct _GfMonitorView
 
   int         offset_x;
   int         offset_y;
+
+  int        *grid;
 };
 
 enum
@@ -70,8 +72,42 @@ enum
 
 static GParamSpec *view_properties[LAST_PROP] = { NULL };
 
+enum
+{
+  SIZE_CHANGED,
+
+  LAST_SIGNAL
+};
+
+static guint view_signals[LAST_SIGNAL] = { 0 };
+
 G_DEFINE_TYPE (GfMonitorView, gf_monitor_view, GTK_TYPE_FIXED)
 
+static gboolean
+find_free_grid_position (GfMonitorView *self,
+                         int           *column_out,
+                         int           *row_out)
+{
+  int column;
+  int row;
+
+  for (column = 0; column < self->columns; column++)
+    {
+      for (row = 0; row < self->rows; row++)
+        {
+          if (self->grid[column * self->rows + row] == 0)
+            {
+              *column_out = column;
+              *row_out = row;
+
+              return TRUE;
+            }
+        }
+    }
+
+  return FALSE;
+}
+
 static void
 icon_destroy_cb (GtkWidget *widget,
                  GFile     *file)
@@ -208,6 +244,11 @@ calculate_grid_size (GfMonitorView *self)
   self->offset_y = (self->view_height - rows * icon_size.height -
                     (rows - 1) * self->row_spacing) / 2;
 
+  g_clear_pointer (&self->grid, g_free);
+  self->grid = g_new0 (int, columns * rows);
+
+  g_signal_emit (self, view_signals[SIZE_CHANGED], 0);
+
   if (self->grid_points)
     gtk_widget_queue_draw (GTK_WIDGET (self));
 }
@@ -343,6 +384,8 @@ gf_monitor_view_finalize (GObject *object)
       self->grid_size_id = 0;
     }
 
+  g_clear_pointer (&self->grid, g_free);
+
   G_OBJECT_CLASS (gf_monitor_view_parent_class)->finalize (object);
 }
 
@@ -554,6 +597,14 @@ install_properties (GObjectClass *object_class)
   g_object_class_install_properties (object_class, LAST_PROP, view_properties);
 }
 
+static void
+install_signals (void)
+{
+  view_signals[SIZE_CHANGED] =
+    g_signal_new ("size-changed", GF_TYPE_MONITOR_VIEW, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
 static void
 gf_monitor_view_class_init (GfMonitorViewClass *self_class)
 {
@@ -575,6 +626,7 @@ gf_monitor_view_class_init (GfMonitorViewClass *self_class)
   widget_class->get_request_mode = gf_monitor_view_get_request_mode;
 
   install_properties (object_class);
+  install_signals ();
 }
 
 static void
@@ -609,3 +661,26 @@ gf_monitor_view_is_primary (GfMonitorView *self)
 {
   return gdk_monitor_is_primary (self->monitor);
 }
+
+gboolean
+gf_monitor_view_add_icon (GfMonitorView *self,
+                          GtkWidget     *icon)
+{
+  int column;
+  int row;
+  int x;
+  int y;
+
+  if (!find_free_grid_position (self, &column, &row))
+    return FALSE;
+
+  x = self->offset_x + column * self->spacing_x;
+  y = self->offset_y + row * self->spacing_y;
+
+  self->grid[column * self->rows + row] = 1;
+
+  gtk_fixed_put (GTK_FIXED (self), icon, x, y);
+  gtk_widget_show (icon);
+
+  return TRUE;
+}
diff --git a/gnome-flashback/libdesktop/gf-monitor-view.h b/gnome-flashback/libdesktop/gf-monitor-view.h
index 1004921..0d358c9 100644
--- a/gnome-flashback/libdesktop/gf-monitor-view.h
+++ b/gnome-flashback/libdesktop/gf-monitor-view.h
@@ -36,6 +36,9 @@ GdkMonitor *gf_monitor_view_get_monitor (GfMonitorView *self);
 
 gboolean    gf_monitor_view_is_primary  (GfMonitorView *self);
 
+gboolean    gf_monitor_view_add_icon    (GfMonitorView *self,
+                                         GtkWidget     *icon);
+
 G_END_DECLS
 
 #endif


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