diff -r dd0ae1c62a72 -r 2e384acc89a6 ui/gtk/model.c --- 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; +}