# HG changeset patch # User Olaf Wintermann # Date 1400249986 -7200 # Node ID 29b2821d1262da37e2621ed3fd3c8bc712780647 # Parent 394f3b06dba1b6d223f26f7d80e296ecb5493e3c added table view events (GTK) diff -r 394f3b06dba1 -r 29b2821d1262 application/main.c --- a/application/main.c Thu May 15 22:13:25 2014 +0200 +++ b/application/main.c Fri May 16 16:19:46 2014 +0200 @@ -51,6 +51,20 @@ return NULL; } +void action_activate(UiEvent *event, void *data) { + UiListSelection *selection = event->eventdata; + printf("activate: %d\n", event->intval); +} + +void action_select(UiEvent *event, void *data) { + UiListSelection *selection = event->eventdata; + printf("selection[%d]: ", selection->count); + for(int i=0;icount;i++) { + printf("%d ", selection->rows[i]); + } + printf("\n"); +} + int main(int argc, char** argv) { ui_init("app1", argc, argv); ui_locales_dir("/opt/app1/locales"); @@ -67,6 +81,8 @@ UiModelInfo *model = ui_model_info(window->ctx, UI_STRING, "Name", UI_STRING, "Email", -1); model->getvalue = (ui_model_getvalue_f)person_getvalue; + model->activate = action_activate; + model->selection = action_select; UiList *list = ui_list_new(); Person *p1 = ui_malloc(window->ctx, sizeof(Person)); Person *p2 = ui_malloc(window->ctx, sizeof(Person)); diff -r 394f3b06dba1 -r 29b2821d1262 make/configure_gtk2.sh --- a/make/configure_gtk2.sh Thu May 15 22:13:25 2014 +0200 +++ b/make/configure_gtk2.sh Fri May 16 16:19:46 2014 +0200 @@ -28,7 +28,7 @@ TK_CFLAGS="-DUI_GTK2 `pkg-config --cflags gtk+-2.0 libxml-2.0`" -TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread +TK_LDFLAGS="`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread" cat >> config.mk << __EOF__ diff -r 394f3b06dba1 -r 29b2821d1262 make/configure_gtk2legacy.sh --- a/make/configure_gtk2legacy.sh Thu May 15 22:13:25 2014 +0200 +++ b/make/configure_gtk2legacy.sh Fri May 16 16:19:46 2014 +0200 @@ -29,7 +29,7 @@ TK_CFLAGS="-DUI_GTK2 -DUI_GTK2LEGACY " TK_CFLAGS="$TK_CFLAGS `pkg-config --cflags gtk+-2.0 libxml-2.0`" -TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread +TK_LDFLAGS="`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread" cat >> config.mk << __EOF__ diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/button.c --- a/ui/gtk/button.c Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/button.c Fri May 16 16:19:46 2014 +0200 @@ -43,7 +43,7 @@ obj->ctx->mempool, sizeof(UiEventData)); event->obj = obj; - event->user_data = data; + event->userdata = data; event->callback = f; event->value = 0; @@ -73,7 +73,7 @@ e.document = event->obj->document; e.eventdata = NULL; e.intval = event->value; - event->callback(&e, event->user_data); + event->callback(&e, event->userdata); } void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event) { @@ -83,5 +83,5 @@ e.document = event->obj->document; e.eventdata = NULL; e.intval = gtk_toggle_tool_button_get_active(widget); - event->callback(&e, event->user_data); + event->callback(&e, event->userdata); } diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/menu.c --- a/ui/gtk/menu.c Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/menu.c Fri May 16 16:19:46 2014 +0200 @@ -245,7 +245,7 @@ if(i->callback != NULL) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; - event->user_data = i->userdata; + event->userdata = i->userdata; event->callback = i->callback; event->value = 0; @@ -281,7 +281,7 @@ if(i->callback != NULL) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; - event->user_data = i->userdata; + event->userdata = i->userdata; event->callback = i->callback; event->value = 0; @@ -323,7 +323,7 @@ if(ci->callback) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; - event->user_data = ci->userdata; + event->userdata = ci->userdata; event->callback = ci->callback; event->value = 0; @@ -413,7 +413,7 @@ // TODO: use mempool UiEventData *event = malloc(sizeof(UiEventData)); event->obj = list->object; - event->user_data = list->userdata; + event->userdata = list->userdata; event->callback = list->callback; event->value = i - 1; @@ -443,7 +443,7 @@ evt.document = event->obj->document; evt.eventdata = NULL; evt.intval = event->value; - event->callback(&evt, event->user_data); + event->callback(&evt, event->userdata); } void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiEventData *event) { @@ -453,7 +453,7 @@ evt.document = event->obj->document; evt.eventdata = NULL; evt.intval = gtk_check_menu_item_get_active(ci); - event->callback(&evt, event->user_data); + event->callback(&evt, event->userdata); } int ui_checkitem_get(UiInteger *i) { diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/model.c --- a/ui/gtk/model.c Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/model.c Fri May 16 16:19:46 2014 +0200 @@ -237,7 +237,6 @@ //list->current = iter->user_data3; if(model->info->getvalue) { void *data = model->info->getvalue(iter->user_data3, column); - printf("data[%d]: %s\n", column, data); ui_model_set_value(model->info->types[column], data, value); } else { value->g_type = G_TYPE_INVALID; diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/toolbar.c --- a/ui/gtk/toolbar.c Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/toolbar.c Fri May 16 16:19:46 2014 +0200 @@ -201,7 +201,7 @@ obj->ctx->mempool, sizeof(UiEventData)); event->obj = obj; - event->user_data = item->userdata; + event->userdata = item->userdata; event->callback = item->callback; g_signal_connect( @@ -230,7 +230,7 @@ obj->ctx->mempool, sizeof(UiEventData)); event->obj = obj; - event->user_data = item->userdata; + event->userdata = item->userdata; event->callback = item->callback; g_signal_connect( @@ -264,7 +264,7 @@ obj->ctx->mempool, sizeof(UiEventData)); event->obj = obj; - event->user_data = item->userdata; + event->userdata = item->userdata; event->callback = item->callback; g_signal_connect( @@ -290,7 +290,7 @@ obj->ctx->mempool, sizeof(UiEventData)); event->obj = obj; - event->user_data = item->userdata; + event->userdata = item->userdata; event->callback = item->callback; g_signal_connect( diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/toolkit.h --- a/ui/gtk/toolkit.h Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/toolkit.h Fri May 16 16:19:46 2014 +0200 @@ -40,7 +40,7 @@ typedef struct UiEventData { UiObject *obj; ui_callback callback; - void *user_data; + void *userdata; int value; } UiEventData; diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/tree.c --- 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]; +} diff -r 394f3b06dba1 -r 29b2821d1262 ui/gtk/tree.h --- a/ui/gtk/tree.h Thu May 15 22:13:25 2014 +0200 +++ b/ui/gtk/tree.h Fri May 16 16:19:46 2014 +0200 @@ -41,19 +41,33 @@ GtkWidget *widget; UiListPtr *list; UiModelInfo *modelinfo; - //ui_model_getvalue_f getvalue; } UiTableView; + +typedef struct UiTreeEventData { + UiObject *obj; + ui_callback activate; + ui_callback selection; + void *userdata; +} UiTreeEventData; void* ui_strmodel_getvalue(void *elm, int column); UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata); +UIWIDGET ui_table_var(UiObject *obj, UiListPtr *list, UiModelInfo *modelinfo); void ui_listview_update(UiEvent *event, UiTableView *view); -void ui_listview_selected( +void ui_listview_activate_event( GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, - UiEventData *event); + UiTreeEventData *event); +void ui_listview_selection_event( + GtkTreeSelection *treeselection, + UiTreeEventData *event); +UiListSelection* ui_listview_selection( + GtkTreeSelection *selection, + UiTreeEventData *event); +int ui_tree_path_list_index(GtkTreePath *path); #ifdef __cplusplus } diff -r 394f3b06dba1 -r 29b2821d1262 ui/ui/tree.h --- a/ui/ui/tree.h Thu May 15 22:13:25 2014 +0200 +++ b/ui/ui/tree.h Fri May 16 16:19:46 2014 +0200 @@ -35,7 +35,8 @@ extern "C" { #endif -typedef struct UiModelInfo UiModelInfo; +typedef struct UiModelInfo UiModelInfo; +typedef struct UiListSelection UiListSelection; typedef enum UiModelType UiModelType; @@ -73,14 +74,31 @@ /* * selection callback */ - ui_callback callback; + ui_callback activate; + + /* + * cursor callback + */ + ui_callback selection; /* - * userdata for callback + * userdata for both callback */ void *userdata; }; +struct UiListSelection { + /* + * number of selected items + */ + int count; + + /* + * indices of selected rows + */ + int *rows; +}; + UiModelInfo* ui_model_info(UiContext *ctx, ...); void ui_model_info_free(UiContext *ctx, UiModelInfo *mi);