ui/gtk/model.c

changeset 147
2e384acc89a6
parent 146
dd0ae1c62a72
child 152
62921b370c60
--- a/ui/gtk/model.c	Thu Nov 16 12:04:10 2017 +0100
+++ b/ui/gtk/model.c	Sun Nov 19 09:00:16 2017 +0100
@@ -31,6 +31,7 @@
 
 #include "model.h"
 #include "image.h"
+#include "toolkit.h"
 
 #define IS_UI_LIST_MODEL(obj) \
         (G_TYPE_CHECK_INSTANCE_TYPE((obj), list_model_type))
@@ -41,6 +42,9 @@
 static void list_model_interface_init(GtkTreeModelIface *i, gpointer data);
 static void list_model_init(UiListModel *instance, GObjectClass *cl);
 
+static void list_model_dnd_dest_interface_init(GtkTreeDragDestIface *i, gpointer data);
+static void list_model_dnd_src_interface_init(GtkTreeDragSourceIface *i, gpointer data);
+
 static GObjectClass list_model_class;
 static const GTypeInfo list_model_info = {
     sizeof(GObjectClass),
@@ -60,6 +64,17 @@
 };
 static GType list_model_type;
 
+static const GInterfaceInfo list_model_dnd_dest_interface_info = {
+    (GInterfaceInitFunc)list_model_dnd_dest_interface_init,
+    NULL,
+    NULL
+};
+static const GInterfaceInfo list_model_dnd_src_interface_info = {
+    (GInterfaceInitFunc)list_model_dnd_src_interface_init,
+    NULL,
+    NULL
+};
+
 void ui_list_init() {
     list_model_type = g_type_register_static(
             G_TYPE_OBJECT,
@@ -70,10 +85,19 @@
             list_model_type,
             GTK_TYPE_TREE_MODEL,
             &list_model_interface_info);
+    g_type_add_interface_static(
+            list_model_type,
+            GTK_TYPE_TREE_DRAG_DEST,
+            &list_model_dnd_dest_interface_info);
+    g_type_add_interface_static(
+            list_model_type,
+            GTK_TYPE_TREE_DRAG_SOURCE,
+            &list_model_dnd_src_interface_info);
 }
 
 static void list_model_class_init(GObjectClass *cl, gpointer data) {
     //cl->finalize = ...; // TODO
+    
 }
 
 static void list_model_interface_init(GtkTreeModelIface *i, gpointer data) {
@@ -91,6 +115,17 @@
     i->iter_parent     = ui_list_model_iter_parent;
 }
 
+static void list_model_dnd_dest_interface_init(GtkTreeDragDestIface *i, gpointer data) {
+    i->drag_data_received = ui_list_model_drag_data_received;
+    i->row_drop_possible = ui_list_model_row_drop_possible;
+}
+
+static void list_model_dnd_src_interface_init(GtkTreeDragSourceIface *i, gpointer data) {
+    i->drag_data_delete = ui_list_model_drag_data_delete;
+    i->drag_data_get = ui_list_model_drag_data_get;
+    i->row_draggable = ui_list_model_row_draggable;
+}
+
 static void list_model_init(UiListModel *instance, GObjectClass *cl) {
     instance->columntypes = NULL;
     instance->var = NULL;
@@ -128,9 +163,10 @@
     value->g_type = G_TYPE_INVALID; 
 }
 
-UiListModel* ui_list_model_new(UiVar *var, UiModel *info) {
+UiListModel* ui_list_model_new(UiObject *obj, UiVar *var, UiModel *info) {
     UiListModel *model = g_object_new(list_model_type, NULL);
-    model->info = info;
+    model->obj = obj;
+    model->model = info;
     model->var = var;
     model->columntypes = calloc(sizeof(GType), 2 * info->columns);
     int ncol = 0;
@@ -249,8 +285,8 @@
     list->iter = iter->user_data;
     //list->index = (int)(intptr_t)iter->user_data2;
     //list->current = iter->user_data3;
-    if(model->info->getvalue) {
-        void *data = model->info->getvalue(iter->user_data3, column);
+    if(model->model->getvalue) {
+        void *data = model->model->getvalue(iter->user_data3, column);
         if(model->columntypes[column] == G_TYPE_OBJECT) {
             UiImage *img = data;
             ui_model_set_value(model->columntypes[column], img->pixbuf, value);
@@ -379,3 +415,114 @@
 {
     return FALSE;
 }
+
+// ****** dnd ******
+
+gboolean ui_list_model_drag_data_received(
+        GtkTreeDragDest   *drag_dest,
+        GtkTreePath       *dest_path,
+        GtkSelectionData  *selection_data)
+{
+    //printf("drag received\n");
+    UiListModel *model = UI_LIST_MODEL(drag_dest);
+    if(model->model->drop) {
+        gint *indices = gtk_tree_path_get_indices(dest_path);
+        gint row = indices[0];
+        UiEvent e;
+        e.obj = model->obj;
+        e.window = e.obj->window;
+        e.document = e.obj->ctx->document;
+        e.eventdata = NULL;
+        e.intval = 0;
+        UiSelection s;
+        s.data = selection_data;
+        model->model->drop(&e, &s, model->var->value, row);
+    }
+    return TRUE;
+}
+
+gboolean ui_list_model_row_drop_possible(
+        GtkTreeDragDest   *drag_dest,
+        GtkTreePath       *dest_path,
+	GtkSelectionData  *selection_data)
+{
+    //printf("row_drop_possible\n");
+    UiListModel *model = UI_LIST_MODEL(drag_dest);
+    if(model->model->candrop) {
+        gint *indices = gtk_tree_path_get_indices(dest_path);
+        gint row = indices[0];
+        UiEvent e;
+        e.obj = model->obj;
+        e.window = e.obj->window;
+        e.document = e.obj->ctx->document;
+        e.eventdata = NULL;
+        e.intval = 0;
+        UiSelection s;
+        s.data = selection_data;
+        return model->model->candrop(&e, &s, model->var->value, row);
+    }
+    return TRUE;
+}
+
+gboolean ui_list_model_row_draggable(
+        GtkTreeDragSource   *drag_source,
+        GtkTreePath         *path)
+{
+    //printf("row_draggable\n");
+    UiListModel *model = UI_LIST_MODEL(drag_source);
+    if(model->model->candrag) {
+        gint *indices = gtk_tree_path_get_indices(path);
+        gint row = indices[0];
+        UiEvent e;
+        e.obj = model->obj;
+        e.window = e.obj->window;
+        e.document = e.obj->ctx->document;
+        e.eventdata = NULL;
+        e.intval = 0;
+        return model->model->candrag(&e, model->var->value, row);
+    }
+    return TRUE;
+}
+
+gboolean ui_list_model_drag_data_get(
+        GtkTreeDragSource   *drag_source,
+        GtkTreePath         *path,
+        GtkSelectionData    *selection_data)
+{
+    //printf("drag_data_get\n");
+    UiListModel *model = UI_LIST_MODEL(drag_source);
+    if(model->model->data_get) {
+        gint *indices = gtk_tree_path_get_indices(path);
+        gint row = indices[0];
+        UiEvent e;
+        e.obj = model->obj;
+        e.window = e.obj->window;
+        e.document = e.obj->ctx->document;
+        e.eventdata = NULL;
+        e.intval = 0;
+        UiSelection s;
+        s.data = selection_data;
+        model->model->data_get(&e, &s, model->var->value, row);
+    }
+    return TRUE;
+}
+
+gboolean ui_list_model_drag_data_delete(
+        GtkTreeDragSource *drag_source,
+        GtkTreePath       *path)
+{
+    //printf("drag_data_delete\n");
+    UiListModel *model = UI_LIST_MODEL(drag_source);
+    if(model->model->data_get) {
+        gint *indices = gtk_tree_path_get_indices(path);
+        gint row = indices[0];
+        UiEvent e;
+        e.obj = model->obj;
+        e.window = e.obj->window;
+        e.document = e.obj->ctx->document;
+        e.eventdata = NULL;
+        e.intval = 0;
+        model->model->data_delete(&e, model->var->value, row);
+    }
+    return TRUE;
+}

mercurial