ui/gtk/tree.c

changeset 42
29b2821d1262
parent 41
394f3b06dba1
child 52
25e5390cce41
--- a/ui/gtk/tree.c	Thu May 15 22:13:25 2014 +0200
+++ b/ui/gtk/tree.c	Fri May 16 16:19:46 2014 +0200
@@ -78,18 +78,16 @@
     
     // add callback
     if(f) {
-        UiEventData *event = ucx_mempool_malloc(
-                obj->ctx->mempool,
-                sizeof(UiEventData));
+        UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData));
         event->obj = obj;
-        event->user_data = udata;
-        event->callback = f;
-        event->value = 0;
+        event->userdata = udata;
+        event->activate = f;
+        event->selection = NULL;
 
         g_signal_connect(
                 view,
                 "row-activated",
-                G_CALLBACK(ui_listview_selected),
+                G_CALLBACK(ui_listview_activate_event),
                 event);
     }
     
@@ -142,7 +140,7 @@
     
     //gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
 #ifdef UI_GTK3
-    gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE);
+    //gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE);
 #else
     
 #endif
@@ -162,21 +160,31 @@
             tableview);
     
     // add callback
-    if(modelinfo->callback) {
-        UiEventData *event = ucx_mempool_malloc(
-                obj->ctx->mempool,
-                sizeof(UiEventData));
-        event->obj = obj;
-        event->user_data = modelinfo->userdata;
-        event->callback = modelinfo->callback;
-        event->value = 0;
-
+    UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
+    event->obj = obj;
+    event->activate = modelinfo->activate;
+    event->selection = modelinfo->selection;
+    event->userdata = modelinfo->userdata;
+    if(modelinfo->activate) {
         g_signal_connect(
                 view,
                 "row-activated",
-                G_CALLBACK(ui_listview_selected),
+                G_CALLBACK(ui_listview_activate_event),
                 event);
     }
+    if(modelinfo->selection) {
+        GtkTreeSelection *selection = gtk_tree_view_get_selection(
+                GTK_TREE_VIEW(view));
+        g_signal_connect(
+                selection,
+                "changed",
+                G_CALLBACK(ui_listview_selection_event),
+                event);
+    }
+    // TODO: destroy callback
+    
+    GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
+    gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
     
     // add widget to the current container
     GtkWidget *scroll_area = gtk_scrolled_window_new(NULL, NULL);
@@ -212,36 +220,76 @@
 
 
 void ui_listview_update(UiEvent *event, UiTableView *view) {
-    UiList *list = view->list->list;
     UiListModel *model = ui_list_model_new(view->list, view->modelinfo);
     gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model));   
     
     // TODO: free old model
 }
 
-void ui_listview_selected(
+void ui_listview_activate_event(
         GtkTreeView *treeview,
         GtkTreePath *path,
         GtkTreeViewColumn *column,
-        UiEventData *event)
+        UiTreeEventData *event)
 {
-    int *indices = gtk_tree_path_get_indices(path);
-    int depth = gtk_tree_path_get_depth(path);
-    if(depth == 0) {
-        fprintf(stderr, "UiError: ui_treeview_selected: depth == 0\n");
-        return;
-    }
-    GtkTreeModel *model = gtk_tree_view_get_model(treeview);
-    GtkTreeIter iter;
-    gtk_tree_model_get_iter (model, &iter, path);
-    void *value = NULL;
-    gtk_tree_model_get(model, &iter, 0, &value, -1);
+    UiListSelection *selection = ui_listview_selection(
+            gtk_tree_view_get_selection(treeview),
+            event);
+    
+    UiEvent e;
+    e.obj = event->obj;
+    e.window = event->obj->window;
+    e.document = event->obj->document;
+    e.eventdata = selection;
+    e.intval = selection->count > 0 ? selection->rows[0] : -1;
+    event->activate(&e, event->userdata);
+    
+    free(selection);
+}
+
+void ui_listview_selection_event(
+        GtkTreeSelection *treeselection,
+        UiTreeEventData *event)
+{
+    UiListSelection *selection = ui_listview_selection(treeselection, event);
     
     UiEvent e;
     e.obj = event->obj;
     e.window = event->obj->window;
     e.document = event->obj->document;
-    e.eventdata = value;
-    e.intval = indices[depth-1];
-    event->callback(&e, event->user_data);
+    e.eventdata = selection;
+    e.intval = selection->count > 0 ? selection->rows[0] : -1;
+    event->selection(&e, event->userdata);
+    
+    free(selection);
 }
+
+UiListSelection* ui_listview_selection(
+        GtkTreeSelection *selection,
+        UiTreeEventData *event)
+{
+    GList *rows = gtk_tree_selection_get_selected_rows(selection, NULL);
+    
+    UiListSelection *ls = malloc(sizeof(UiListSelection));
+    ls->count = g_list_length(rows);
+    ls->rows = calloc(ls->count, sizeof(int));
+    GList *r = rows;
+    int i = 0;
+    while(r) {
+        GtkTreePath *path = r->data;
+        ls->rows[i] = ui_tree_path_list_index(path);
+        r = r->next;
+        i++;
+    }
+    return ls;
+}
+
+int ui_tree_path_list_index(GtkTreePath *path) {
+    int depth = gtk_tree_path_get_depth(path);
+    if(depth == 0) {
+        fprintf(stderr, "UiError: treeview selection: depth == 0\n");
+        return -1;
+    }
+    int *indices = gtk_tree_path_get_indices(path);
+    return indices[depth - 1];
+}

mercurial