[gnome-control-center] background: Allow dropping colours as well



commit 8115ba4600597c024fa6cbc4aaea1a4e37378858
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Apr 14 16:36:59 2014 +0200

    background: Allow dropping colours as well
    
    https://bugzilla.gnome.org/show_bug.cgi?id=689351

 panels/background/bg-colors-source.c             |  132 ++++++++++++++-------
 panels/background/bg-colors-source.h             |    4 +
 panels/background/cc-background-chooser-dialog.c |   80 ++++++++++++-
 3 files changed, 166 insertions(+), 50 deletions(-)
---
diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c
index 3a589f5..24f9f90 100644
--- a/panels/background/bg-colors-source.c
+++ b/panels/background/bg-colors-source.c
@@ -55,69 +55,113 @@ struct {
 };
 
 static void
+bg_colors_source_add_color (BgColorsSource               *self,
+                            GnomeDesktopThumbnailFactory *thumb_factory,
+                            GtkListStore                 *store,
+                            const char                   *color,
+                            GtkTreeRowReference         **ret_row_ref)
+{
+  CcBackgroundItemFlags flags;
+  CcBackgroundItem *item;
+  GIcon *pixbuf;
+  cairo_surface_t *surface;
+  int scale_factor;
+  int thumbnail_height, thumbnail_width;
+  GtkTreeIter iter;
+
+  thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (self));
+  thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (self));
+
+  item = cc_background_item_new (NULL);
+  flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
+          CC_BACKGROUND_ITEM_HAS_SCOLOR |
+          CC_BACKGROUND_ITEM_HAS_SHADING |
+          CC_BACKGROUND_ITEM_HAS_PLACEMENT |
+          CC_BACKGROUND_ITEM_HAS_URI;
+  /* It does have a URI, it's "none" */
+
+  g_object_set (G_OBJECT (item),
+                "uri", "file:///" DATADIR "/gnome-control-center/pixmaps/noise-texture-light.png",
+                "primary-color", color,
+                "secondary-color", color,
+                "shading", G_DESKTOP_BACKGROUND_SHADING_SOLID,
+                "placement", G_DESKTOP_BACKGROUND_STYLE_WALLPAPER,
+                "flags", flags,
+                NULL);
+  cc_background_item_load (item, NULL);
+
+  /* insert the item into the liststore */
+  scale_factor = bg_source_get_scale_factor (BG_SOURCE (self));
+  pixbuf = cc_background_item_get_thumbnail (item,
+                                             thumb_factory,
+                                             thumbnail_width, thumbnail_height,
+                                             scale_factor);
+  surface = gdk_cairo_surface_create_from_pixbuf (GDK_PIXBUF (pixbuf), scale_factor, NULL);
+  gtk_list_store_insert_with_values (store, &iter, 0,
+                                     0, surface,
+                                     1, item,
+                                     -1);
+
+  if (ret_row_ref)
+    {
+      GtkTreePath *path;
+
+      path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
+      *ret_row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
+      gtk_tree_path_free (path);
+    }
+
+  cairo_surface_destroy (surface);
+  g_object_unref (pixbuf);
+  g_object_unref (item);
+}
+
+static void
 bg_colors_source_constructed (GObject *object)
 {
   BgColorsSource *self = BG_COLORS_SOURCE (object);
   GnomeDesktopThumbnailFactory *thumb_factory;
   guint i;
   GtkListStore *store;
-  gint thumbnail_height;
-  gint thumbnail_width;
 
   G_OBJECT_CLASS (bg_colors_source_parent_class)->constructed (object);
 
   store = bg_source_get_liststore (BG_SOURCE (self));
-
   thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
-  thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (self));
-  thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (self));
 
   for (i = 0; i < G_N_ELEMENTS (items); i++)
     {
-      CcBackgroundItemFlags flags;
-      CcBackgroundItem *item;
-      GIcon *pixbuf;
-      cairo_surface_t *surface;
-      int scale_factor;
-
-      item = cc_background_item_new (NULL);
-      flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
-             CC_BACKGROUND_ITEM_HAS_SCOLOR |
-             CC_BACKGROUND_ITEM_HAS_SHADING |
-             CC_BACKGROUND_ITEM_HAS_PLACEMENT |
-             CC_BACKGROUND_ITEM_HAS_URI;
-      /* It does have a URI, it's "none" */
-
-      g_object_set (G_OBJECT (item),
-                    "uri", "file:///" DATADIR "/gnome-control-center/pixmaps/noise-texture-light.png",
-                   "primary-color", items[i].pcolor,
-                   "secondary-color", items[i].pcolor,
-                   "shading", items[i].type,
-                   "placement", G_DESKTOP_BACKGROUND_STYLE_WALLPAPER,
-                   "flags", flags,
-                   NULL);
-      cc_background_item_load (item, NULL);
-
-      /* insert the item into the liststore */
-      scale_factor = bg_source_get_scale_factor (BG_SOURCE (self));
-      pixbuf = cc_background_item_get_thumbnail (item,
-                                                thumb_factory,
-                                                thumbnail_width, thumbnail_height,
-                                                scale_factor);
-      surface = gdk_cairo_surface_create_from_pixbuf (GDK_PIXBUF (pixbuf), scale_factor, NULL);
-      gtk_list_store_insert_with_values (store, NULL, 0,
-                                         0, surface,
-                                         1, item,
-                                         -1);
-
-      cairo_surface_destroy (surface);
-      g_object_unref (pixbuf);
-      g_object_unref (item);
+      bg_colors_source_add_color (self, thumb_factory, store, items[i].pcolor, NULL);
     }
 
   g_object_unref (thumb_factory);
 }
 
+gboolean
+bg_colors_source_add (BgColorsSource       *self,
+                      GdkRGBA              *rgba,
+                      GtkTreeRowReference **ret_row_ref)
+{
+  GnomeDesktopThumbnailFactory *thumb_factory;
+  GtkListStore *store;
+  gchar *c;
+
+  c = g_strdup_printf ("#%02x%02x%02x",
+                       (int)(255*rgba->red),
+                       (int)(255*rgba->green),
+                       (int)(255*rgba->blue));
+
+  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
+  store = bg_source_get_liststore (BG_SOURCE (self));
+
+  bg_colors_source_add_color (self, thumb_factory, store, c, ret_row_ref);
+
+  g_free (c);
+  g_object_unref (thumb_factory);
+
+  return TRUE;
+}
+
 static void
 bg_colors_source_init (BgColorsSource *self)
 {
diff --git a/panels/background/bg-colors-source.h b/panels/background/bg-colors-source.h
index 839e40b..032d166 100644
--- a/panels/background/bg-colors-source.h
+++ b/panels/background/bg-colors-source.h
@@ -66,6 +66,10 @@ GType bg_colors_source_get_type (void) G_GNUC_CONST;
 
 BgColorsSource *bg_colors_source_new (GtkWindow *window);
 
+gboolean bg_colors_source_add        (BgColorsSource       *self,
+                                      GdkRGBA              *rgba,
+                                      GtkTreeRowReference **ret_row_ref);
+
 G_END_DECLS
 
 #endif /* _BG_COLORS_SOURCE_H */
diff --git a/panels/background/cc-background-chooser-dialog.c 
b/panels/background/cc-background-chooser-dialog.c
index 3cb9cf9..4c5b812 100644
--- a/panels/background/cc-background-chooser-dialog.c
+++ b/panels/background/cc-background-chooser-dialog.c
@@ -51,6 +51,7 @@ struct _CcBackgroundChooserDialogPrivate
   GtkWidget *empty_pictures_box;
   GtkWidget *sw_content;
   GtkWidget *pictures_button;
+  GtkWidget *colors_button;
 
   BgWallpapersSource *wallpapers_source;
   BgPicturesSource *pictures_source;
@@ -76,6 +77,17 @@ enum
   PROP_0,
 };
 
+enum
+{
+  URI_LIST,
+  COLOR
+};
+
+static const GtkTargetEntry color_targets[] =
+{
+  { "application/x-color", 0, COLOR }
+};
+
 G_DEFINE_TYPE (CcBackgroundChooserDialog, cc_background_chooser_dialog, GTK_TYPE_DIALOG)
 
 static void
@@ -313,17 +325,67 @@ add_custom_wallpaper (CcBackgroundChooserDialog *chooser,
   /* and wait for the item to get added */
 }
 
+static gboolean
+cc_background_panel_drag_color (CcBackgroundChooserDialog *chooser,
+                                GtkSelectionData          *data)
+{
+  gint length;
+  guint16 *dropped;
+  GdkRGBA rgba;
+  GtkTreeRowReference *row_ref;
+  GtkTreePath *to_focus_path;
+
+  length = gtk_selection_data_get_length (data);
+
+  if (length < 0)
+    return FALSE;
+
+  if (length != 8)
+    {
+      g_warning ("%s: Received invalid color data", G_STRFUNC);
+      return FALSE;
+    }
+
+  dropped = (guint16 *) gtk_selection_data_get_data (data);
+  rgba.red   = dropped[0] / 65535.;
+  rgba.green = dropped[1] / 65535.;
+  rgba.blue  = dropped[2] / 65535.;
+  rgba.alpha = dropped[3] / 65535.;
+
+  if (bg_colors_source_add (chooser->priv->colors_source, &rgba, &row_ref) == FALSE)
+    return FALSE;
+
+  /* Change source */
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser->priv->colors_button), TRUE);
+
+  /* And select the newly added item */
+  to_focus_path = gtk_tree_row_reference_get_path (row_ref);
+  gtk_icon_view_select_path (GTK_ICON_VIEW (chooser->priv->icon_view), to_focus_path);
+  gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (chooser->priv->icon_view),
+                                to_focus_path, TRUE, 1.0, 1.0);
+  gtk_tree_row_reference_free (row_ref);
+  gtk_tree_path_free (to_focus_path);
+
+  return TRUE;
+}
+
 static void
-cc_background_panel_drag_uris (GtkWidget *widget,
-                               GdkDragContext *context, gint x, gint y,
-                               GtkSelectionData *data, guint info, guint time,
-                               CcBackgroundChooserDialog *chooser)
+cc_background_panel_drag_items (GtkWidget *widget,
+                                GdkDragContext *context, gint x, gint y,
+                                GtkSelectionData *data, guint info, guint time,
+                                CcBackgroundChooserDialog *chooser)
 {
   gint i;
   char *uri;
   gchar **uris;
   gboolean ret = FALSE;
 
+  if (info == COLOR)
+    {
+      ret = cc_background_panel_drag_color (chooser, data);
+      goto out;
+    }
+
   uris = gtk_selection_data_get_uris (data);
   if (!uris)
     goto out;
@@ -363,6 +425,7 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
   const gchar *pictures_dir;
   gchar *pictures_dir_basename;
   gchar *pictures_dir_uri;
+  GtkTargetList *target_list;
 
   chooser->priv = CC_CHOOSER_DIALOG_GET_PRIVATE (chooser);
   priv = chooser->priv;
@@ -421,6 +484,7 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
   gtk_container_add (GTK_CONTAINER (hbox), button);
   g_signal_connect (button, "toggled", G_CALLBACK (on_view_toggled), chooser);
   g_object_set_data (G_OBJECT (button), "source", priv->colors_source);
+  priv->colors_button = button;
 
   gtk_widget_show_all (hbox);
 
@@ -433,9 +497,13 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
 
   /* Add drag and drop support for bg images */
   gtk_drag_dest_set (priv->sw_content, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
-  gtk_drag_dest_add_uri_targets (priv->sw_content);
+  target_list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_uri_targets (target_list, URI_LIST);
+  gtk_target_list_add_table (target_list, color_targets, 1);
+  gtk_drag_dest_set_target_list (priv->sw_content, target_list);
+  gtk_target_list_unref (target_list);
   g_signal_connect (priv->sw_content, "drag-data-received",
-                    G_CALLBACK (cc_background_panel_drag_uris), chooser);
+                    G_CALLBACK (cc_background_panel_drag_items), chooser);
 
   priv->empty_pictures_box = gtk_grid_new ();
   gtk_widget_set_no_show_all (priv->empty_pictures_box, TRUE);


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