[gtk+] icon browser: Add some dnd support



commit ae63b21c61633186c4a5c2330c84877e6524765b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Feb 22 12:30:49 2015 -0500

    icon browser: Add some dnd support
    
    Use a custom tree model and enable dragging from the icon view.
    Currently, we just support dropping the icon name as text.

 demos/icon-browser/Makefile.am      |    1 +
 demos/icon-browser/iconbrowserwin.c |   52 +++++++++++++-------
 demos/icon-browser/iconstore.c      |   91 +++++++++++++++++++++++++++++++++++
 demos/icon-browser/iconstore.h      |   26 ++++++++++
 demos/icon-browser/window.ui        |    8 +---
 5 files changed, 152 insertions(+), 26 deletions(-)
---
diff --git a/demos/icon-browser/Makefile.am b/demos/icon-browser/Makefile.am
index 9ab3861..ddaf2c7 100644
--- a/demos/icon-browser/Makefile.am
+++ b/demos/icon-browser/Makefile.am
@@ -20,6 +20,7 @@ gtk3_icon_browser_SOURCES = \
        main.c \
        iconbrowserapp.c iconbrowserapp.h \
        iconbrowserwin.c iconbrowserwin.h \
+       iconstore.c iconstore.h \
        resources.c
 
 BUILT_SOURCES = \
diff --git a/demos/icon-browser/iconbrowserwin.c b/demos/icon-browser/iconbrowserwin.c
index 50709a0..fdf51e9 100644
--- a/demos/icon-browser/iconbrowserwin.c
+++ b/demos/icon-browser/iconbrowserwin.c
@@ -1,6 +1,7 @@
 #include <string.h>
 #include "iconbrowserapp.h"
 #include "iconbrowserwin.h"
+#include "iconstore.h"
 #include <gtk/gtk.h>
 
 typedef struct
@@ -42,13 +43,6 @@ struct _IconBrowserWindowClass
   GtkApplicationWindowClass parent_class;
 };
 
-enum {
-  NAME_COLUMN,
-  SYMBOLIC_NAME_COLUMN,
-  DESCRIPTION_COLUMN,
-  CONTEXT_COLUMN
-};
-
 G_DEFINE_TYPE(IconBrowserWindow, icon_browser_window, GTK_TYPE_APPLICATION_WINDOW);
 
 static void
@@ -82,12 +76,12 @@ item_activated (GtkIconView *icon_view, GtkTreePath *path, IconBrowserWindow *wi
   gtk_tree_model_get_iter (GTK_TREE_MODEL (win->filter_model), &iter, path);
 
   if (win->symbolic)
-    column = SYMBOLIC_NAME_COLUMN;
+    column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
   else
-    column = NAME_COLUMN;
+    column = ICON_STORE_NAME_COLUMN;
   gtk_tree_model_get (GTK_TREE_MODEL (win->filter_model), &iter,
                       column, &name,
-                      DESCRIPTION_COLUMN, &description,
+                      ICON_STORE_DESCRIPTION_COLUMN, &description,
                       -1);
       
   if (name == NULL || !gtk_icon_theme_has_icon (gtk_icon_theme_get_default (), name))
@@ -141,10 +135,10 @@ add_icon (IconBrowserWindow *win,
       symbolic_name = NULL;
     }
   gtk_list_store_insert_with_values (win->store, NULL, -1,
-                                     NAME_COLUMN, regular_name,
-                                     SYMBOLIC_NAME_COLUMN, symbolic_name,
-                                     DESCRIPTION_COLUMN, description,
-                                     CONTEXT_COLUMN, context,
+                                     ICON_STORE_NAME_COLUMN, regular_name,
+                                     ICON_STORE_SYMBOLIC_NAME_COLUMN, symbolic_name,
+                                     ICON_STORE_DESCRIPTION_COLUMN, description,
+                                     ICON_STORE_CONTEXT_COLUMN, context,
                                      -1);
 }
 
@@ -697,13 +691,13 @@ icon_visible_func (GtkTreeModel *model,
   search_text = gtk_entry_get_text (GTK_ENTRY (win->searchentry));
 
   if (win->symbolic)
-    column = SYMBOLIC_NAME_COLUMN;
+    column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
   else
-    column = NAME_COLUMN;
+    column = ICON_STORE_NAME_COLUMN;
 
   gtk_tree_model_get (model, iter,
                       column, &name,
-                      CONTEXT_COLUMN, &context,
+                      ICON_STORE_CONTEXT_COLUMN, &context,
                       -1);
   if (!name)
     visible = FALSE;
@@ -726,9 +720,11 @@ symbolic_toggled (GtkToggleButton *toggle, IconBrowserWindow *win)
   win->symbolic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
 
   if (win->symbolic)
-    column = SYMBOLIC_NAME_COLUMN;
+    column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
   else
-    column = NAME_COLUMN;
+    column = ICON_STORE_NAME_COLUMN;
+
+  icon_store_set_text_column (ICON_STORE (win->store), column);
 
   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->cell, "icon-name", column, NULL);
   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->text_cell, "text", column, NULL);
@@ -747,8 +743,24 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
 static void
 icon_browser_window_init (IconBrowserWindow *win)
 {
+  GtkTargetList *list;
+  GtkTargetEntry *targets;
+  gint n_targets;
+
   gtk_widget_init_template (GTK_WIDGET (win));
 
+  list = gtk_target_list_new (NULL, 0);
+  gtk_target_list_add_text_targets (list, 0);
+  targets = gtk_target_table_new_from_list (list, &n_targets);
+  gtk_target_list_unref (list);
+
+  gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (win->list),
+                                          GDK_BUTTON1_MASK,
+                                          targets, n_targets,
+                                          GDK_ACTION_COPY);
+
+  gtk_target_table_free (targets, n_targets);
+
   win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
 
   gtk_tree_model_filter_set_visible_func (win->filter_model, icon_visible_func, win, NULL);
@@ -765,6 +777,8 @@ icon_browser_window_init (IconBrowserWindow *win)
 static void
 icon_browser_window_class_init (IconBrowserWindowClass *class)
 {
+  g_type_ensure (ICON_STORE_TYPE);
+
   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
                                                "/org/gtk/iconbrowser/window.ui");
 
diff --git a/demos/icon-browser/iconstore.c b/demos/icon-browser/iconstore.c
new file mode 100644
index 0000000..b43691f
--- /dev/null
+++ b/demos/icon-browser/iconstore.c
@@ -0,0 +1,91 @@
+#include "iconstore.h"
+#include <gtk/gtk.h>
+
+struct _IconStore
+{
+  GtkListStore parent;
+
+  gint text_column;
+};
+
+struct _IconStoreClass
+{
+  GtkListStoreClass parent_class;
+};
+
+static void icon_store_drag_source_init (GtkTreeDragSourceIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (IconStore, icon_store, GTK_TYPE_LIST_STORE,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
+                                                icon_store_drag_source_init))
+
+
+static void
+icon_store_init (IconStore *store)
+{
+  GType types[4] = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
+
+  gtk_list_store_set_column_types (GTK_LIST_STORE (store), 4, types);
+
+  store->text_column = ICON_STORE_NAME_COLUMN;
+}
+
+static void
+icon_store_class_init (IconStoreClass *class)
+{
+}
+
+static gboolean
+row_draggable (GtkTreeDragSource *drag_source,
+               GtkTreePath       *path)
+{
+  return TRUE;
+}
+
+static gboolean
+drag_data_delete (GtkTreeDragSource *drag_source,
+                  GtkTreePath       *path)
+{
+  GtkTreeIter iter;
+
+  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
+    return gtk_list_store_remove (GTK_LIST_STORE (drag_source), &iter);
+  return FALSE;
+}
+
+static gboolean
+drag_data_get (GtkTreeDragSource *drag_source,
+               GtkTreePath       *path,
+               GtkSelectionData  *selection)
+{
+  GtkTreeIter iter;
+  gchar *text;
+
+  if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
+    return FALSE;
+
+  gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter,
+                      ICON_STORE (drag_source)->text_column, &text,
+                      -1);
+
+  gtk_selection_data_set_text (selection, text, -1);
+
+  g_free (text);
+
+  return TRUE;
+}
+
+
+static void
+icon_store_drag_source_init (GtkTreeDragSourceIface *iface)
+{
+  iface->row_draggable = row_draggable;
+  iface->drag_data_delete = drag_data_delete;
+  iface->drag_data_get = drag_data_get;
+}
+
+void
+icon_store_set_text_column (IconStore *store, gint text_column)
+{
+  store->text_column = text_column;
+}
diff --git a/demos/icon-browser/iconstore.h b/demos/icon-browser/iconstore.h
new file mode 100644
index 0000000..a21f7bd
--- /dev/null
+++ b/demos/icon-browser/iconstore.h
@@ -0,0 +1,26 @@
+#ifndef __ICON_STORE_H
+#define __ICON_STORE_H
+
+#include <gtk/gtk.h>
+
+
+#define ICON_STORE_TYPE (icon_store_get_type ())
+#define ICON_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICON_STORE_TYPE, IconStore))
+
+
+typedef struct _IconStore       IconStore;
+typedef struct _IconStoreClass  IconStoreClass;
+
+enum {
+  ICON_STORE_NAME_COLUMN,
+  ICON_STORE_SYMBOLIC_NAME_COLUMN,
+  ICON_STORE_DESCRIPTION_COLUMN,
+  ICON_STORE_CONTEXT_COLUMN
+};
+
+GType   icon_store_get_type     (void);
+
+void    icon_store_set_text_column (IconStore *store,
+                                    gint       column);
+
+#endif /* __ICON_STORE_H */
diff --git a/demos/icon-browser/window.ui b/demos/icon-browser/window.ui
index 4c61860..e91d16b 100644
--- a/demos/icon-browser/window.ui
+++ b/demos/icon-browser/window.ui
@@ -1,13 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.8 -->
-  <object class="GtkListStore" id="store">
-    <columns>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-      <column type="gchararray"/>
-    </columns>
+  <object class="IconStore" id="store">
   </object>
   <object class="GtkTreeModelFilter" id="filter_model">
     <property name="child_model">store</property>


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