Package: ruby-gnome2
Severity: wishlist
Tags: patch

Hi Dafydd,

could you please take a look at the attached patch? It adds
"row-draggable" and "row-drop-possible" signals to Gtk::ListStore and
Gtk::TreeStore, thus enabling users to use the Gtk high-level DND API.

Kind regards,
Philipp Kern
diff -Naur ruby-gnome2-0.14.1~/gtk/src/rbgtkliststore.c ruby-gnome2-0.14.1/gtk/src/rbgtkliststore.c
--- ruby-gnome2-0.14.1~/gtk/src/rbgtkliststore.c	2005-11-14 09:14:00.000000000 +0100
+++ ruby-gnome2-0.14.1/gtk/src/rbgtkliststore.c	2006-08-16 03:00:54.000000000 +0200
@@ -11,6 +11,8 @@
 
 #include "global.h"
 
+#include "rbgtktreedrag.h"
+
 #define _SELF(s) (GTK_LIST_STORE(RVAL2GOBJ(s)))
 #define ITR2RVAL(i) (BOXED2RVAL(i, GTK_TYPE_TREE_ITER))
 #define RVAL2ITR(i) ((GtkTreeIter*)RVAL2BOXED(i, GTK_TYPE_TREE_ITER))
@@ -34,7 +36,8 @@
         buf[cnt] = CLASS2GTYPE(argv[cnt]);
     }
 
-    store = gtk_list_store_newv(argc, buf);
+    store = GTK_LIST_STORE(g_object_new(RB_TYPE_DND_LIST_STORE, NULL));
+    gtk_list_store_set_column_types(store, argc, buf);
  
     G_INITIALIZE(self, store);
 
@@ -282,11 +285,11 @@
 void
 Init_gtk_list_store()
 {
-    VALUE ls = G_DEF_CLASS(GTK_TYPE_LIST_STORE, "ListStore", mGtk);
+    VALUE ls = G_DEF_CLASS(RB_TYPE_DND_LIST_STORE, "ListStore", mGtk);
 
     id_to_a = rb_intern("to_a");
 
-    rbgtk_register_treeiter_set_value_func(GTK_TYPE_LIST_STORE, 
+    rbgtk_register_treeiter_set_value_func(RB_TYPE_DND_LIST_STORE, 
                                            (rbgtkiter_set_value_func)&gtk_list_store_set_value);
     rb_define_method(ls, "initialize", lstore_initialize, -1);
     rb_define_method(ls, "set_column_types", lstore_set_column_types, -1);
diff -Naur ruby-gnome2-0.14.1~/gtk/src/rbgtktreedrag.c ruby-gnome2-0.14.1/gtk/src/rbgtktreedrag.c
--- ruby-gnome2-0.14.1~/gtk/src/rbgtktreedrag.c	1970-01-01 01:00:00.000000000 +0100
+++ ruby-gnome2-0.14.1/gtk/src/rbgtktreedrag.c	2006-08-16 02:55:40.000000000 +0200
@@ -0,0 +1,184 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/************************************************
+
+  rbgtktreedrag.c -
+
+  $Author: ck $
+  $Date: 2006/08/16 02:06:00 $
+
+  Copyright (C) 2006 Armin Burgmeier
+************************************************/
+
+#include "global.h"
+#include "rbgtktreedrag.h"
+
+#define g_marshal_value_peek_boxed(v)    g_value_get_boxed(v)
+#define g_marshal_value_peek_object(v)   g_value_get_object(v)
+
+static void
+_rb_marshal_BOOLEAN__BOXED(GClosure     *closure,
+                           GValue       *return_value,
+                           guint         n_param_values,
+                           const GValue *param_values,
+                           gpointer      invocation_hint,
+                           gpointer      marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer     data1,
+                                                   gpointer     arg_1,
+                                                   gpointer     data2);
+  register GMarshalFunc_BOOLEAN__BOXED callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       g_marshal_value_peek_boxed (param_values + 1),
+                       data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+static void
+_rb_marshal_BOOLEAN__BOXED_BOXED(GClosure     *closure,
+                                 GValue       *return_value,
+                                 guint         n_param_values,
+                                 const GValue *param_values,
+                                 gpointer      invocation_hint,
+                                 gpointer      marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_BOXED) (gpointer     data1,
+                                                         gpointer     arg_1,
+                                                         gpointer     arg_2,
+                                                         gpointer     data2);
+  register GMarshalFunc_BOOLEAN__BOXED_BOXED callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 3);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_BOOLEAN__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       g_marshal_value_peek_boxed (param_values + 1),
+                       g_marshal_value_peek_boxed (param_values + 2),
+                       data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+static void
+rb_dnd_tree_drag_class_init(GType type)
+{
+    g_signal_new("row-draggable",
+                 type,
+                 G_SIGNAL_RUN_LAST,
+                 0,
+                 NULL, NULL,
+                 _rb_marshal_BOOLEAN__BOXED,
+                 G_TYPE_BOOLEAN, 1,
+                 GTK_TYPE_TREE_PATH);
+
+    g_signal_new("row-drop-possible",
+                 type,
+                 G_SIGNAL_RUN_LAST,
+                 0,
+                 NULL, NULL,
+                 _rb_marshal_BOOLEAN__BOXED_BOXED,
+                 G_TYPE_BOOLEAN, 2,
+                 GTK_TYPE_TREE_PATH,
+                 GTK_TYPE_SELECTION_DATA);
+}
+
+static gboolean
+rb_dnd_tree_drag_row_draggable(GtkTreeDragSource *drag_source,
+                               GtkTreePath *path)
+{
+  gboolean retval;
+  g_assert(G_TYPE_FROM_INSTANCE(drag_source) == RB_TYPE_DND_TREE_STORE ||
+           G_TYPE_FROM_INSTANCE(drag_source) == RB_TYPE_DND_LIST_STORE);
+
+  guint signal_id = g_signal_lookup("row-draggable", G_TYPE_FROM_INSTANCE(drag_source));
+
+  if(g_signal_has_handler_pending(drag_source, signal_id, 0, FALSE))
+    g_signal_emit(drag_source, signal_id, 0, path, &retval);
+  else
+    retval = TRUE; /* default value */
+
+  return retval;
+}
+
+static gboolean
+rb_dnd_tree_drag_row_drop_possible(GtkTreeDragDest* drag_dest,
+                                   GtkTreePath* dest_path,
+                                   GtkSelectionData* selection_data)
+{
+  gboolean retval;
+
+  g_assert(G_TYPE_FROM_INSTANCE(drag_dest) == RB_TYPE_DND_TREE_STORE ||
+           G_TYPE_FROM_INSTANCE(drag_dest) == RB_TYPE_DND_LIST_STORE);
+
+  guint signal_id = g_signal_lookup("row-drop-possible", G_TYPE_FROM_INSTANCE(drag_dest));
+
+  if(g_signal_has_handler_pending(drag_dest, signal_id, 0, FALSE))
+    g_signal_emit(drag_dest, signal_id, 0, dest_path, selection_data, &retval);
+  else
+    retval = TRUE; /* default value */
+
+  return retval;
+}
+
+static void
+rb_dnd_tree_store_init(RbDndTreeStore* store)
+{
+  GTK_TREE_DRAG_SOURCE_GET_IFACE(store)->row_draggable = rb_dnd_tree_drag_row_draggable;
+  GTK_TREE_DRAG_DEST_GET_IFACE(store)->row_drop_possible = rb_dnd_tree_drag_row_drop_possible;
+}
+
+static void
+rb_dnd_list_store_init(RbDndListStore* store)
+{
+  GTK_TREE_DRAG_SOURCE_GET_IFACE(store)->row_draggable = rb_dnd_tree_drag_row_draggable;
+  GTK_TREE_DRAG_DEST_GET_IFACE(store)->row_drop_possible = rb_dnd_tree_drag_row_drop_possible;
+}
+
+static void
+rb_dnd_tree_store_class_init(RbDndTreeStoreClass* klass)
+{
+  rb_dnd_tree_drag_class_init(G_TYPE_FROM_CLASS(klass));
+}
+
+static void
+rb_dnd_list_store_class_init(RbDndListStoreClass* klass)
+{
+  rb_dnd_tree_drag_class_init(G_TYPE_FROM_CLASS(klass));
+}
+
+G_DEFINE_TYPE(RbDndTreeStore, rb_dnd_tree_store, GTK_TYPE_TREE_STORE)
+G_DEFINE_TYPE(RbDndListStore, rb_dnd_list_store, GTK_TYPE_LIST_STORE)
diff -Naur ruby-gnome2-0.14.1~/gtk/src/rbgtktreedrag.h ruby-gnome2-0.14.1/gtk/src/rbgtktreedrag.h
--- ruby-gnome2-0.14.1~/gtk/src/rbgtktreedrag.h	1970-01-01 01:00:00.000000000 +0100
+++ ruby-gnome2-0.14.1/gtk/src/rbgtktreedrag.h	2006-08-16 02:28:40.000000000 +0200
@@ -0,0 +1,49 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/************************************************
+
+  rbgtktreedrag.h -
+
+  $Author: ck $
+  $Date: 2006/08/16 02:24:00 $
+
+  Copyright (C) 2006 Armin Burgmeier
+************************************************/
+
+#ifndef __RBGTKTREEDRAG_H__
+#define __RBGTKTREEDRAG_H__
+
+#include <gtk/gtktreestore.h>
+#include <gtk/gtkliststore.h>
+
+#define RB_TYPE_DND_TREE_STORE (rb_dnd_tree_store_get_type())
+#define RB_TYPE_DND_LIST_STORE (rb_dnd_list_store_get_type())
+
+typedef struct _RbDndTreeStore RbDndTreeStore;
+typedef struct _RbDndListStore RbDndListStore;
+
+typedef struct _RbDndTreeStoreClass RbDndTreeStoreClass;
+typedef struct _RbDndListStoreClass RbDndListStoreClass;
+
+struct _RbDndTreeStore {
+    GtkTreeStore parent;
+};
+
+struct _RbDndTreeStoreClass {
+    GtkTreeStoreClass parent_class;
+};
+
+struct _RbDndListStore {
+    GtkListStore parent;
+};
+
+struct _RbDndListStoreClass {
+    GtkListStoreClass parent_class;
+};
+
+GType
+rb_dnd_tree_store_get_type(void) G_GNUC_CONST;
+
+GType
+rb_dnd_list_store_get_type(void) G_GNUC_CONST;
+
+#endif /* __RBGTKTREEDRAG_H__ */
diff -Naur ruby-gnome2-0.14.1~/gtk/src/rbgtktreestore.c ruby-gnome2-0.14.1/gtk/src/rbgtktreestore.c
--- ruby-gnome2-0.14.1~/gtk/src/rbgtktreestore.c	2005-11-14 09:14:00.000000000 +0100
+++ ruby-gnome2-0.14.1/gtk/src/rbgtktreestore.c	2006-08-16 02:34:56.000000000 +0200
@@ -11,6 +11,8 @@
 
 #include "global.h"
 
+#include "rbgtktreedrag.h"
+
 #define _SELF(s) (GTK_TREE_STORE(RVAL2GOBJ(s)))
 #define ITR2RVAL(i) (BOXED2RVAL(i, GTK_TYPE_TREE_ITER))
 #define RVAL2ITR(i) ((GtkTreeIter*)RVAL2BOXED(i, GTK_TYPE_TREE_ITER))
@@ -32,7 +34,8 @@
         buf[cnt] = CLASS2GTYPE(argv[cnt]);
     }
 
-    store = gtk_tree_store_newv(argc, buf);
+    store = GTK_TREE_STORE(g_object_new(RB_TYPE_DND_TREE_STORE, NULL));
+    gtk_tree_store_set_column_types(store, argc, buf);
  
     G_INITIALIZE(self, store);
 
@@ -256,9 +259,9 @@
 void
 Init_gtk_tree_store()
 {
-    VALUE ts = G_DEF_CLASS(GTK_TYPE_TREE_STORE, "TreeStore", mGtk);
+    VALUE ts = G_DEF_CLASS(RB_TYPE_DND_TREE_STORE, "TreeStore", mGtk);
 
-    rbgtk_register_treeiter_set_value_func(GTK_TYPE_TREE_STORE, 
+    rbgtk_register_treeiter_set_value_func(RB_TYPE_DND_TREE_STORE,
                                            (rbgtkiter_set_value_func)&gtk_tree_store_set_value);
 
     rb_define_method(ts, "initialize", tstore_initialize, -1);

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to