# HG changeset patch # User Olaf Wintermann # Date 1400183333 -7200 # Node ID caa0df8ed0952ba6fddac06f5636ec866f22c037 # Parent 4e66271541e89ed26bfc6371847fef0f8e42e34a added table view (GTK) diff -r 4e66271541e8 -r caa0df8ed095 ui/gtk/model.c --- a/ui/gtk/model.c Thu May 15 20:06:28 2014 +0200 +++ b/ui/gtk/model.c Thu May 15 21:48:53 2014 +0200 @@ -97,13 +97,40 @@ instance->stamp = g_random_int(); } -UiListModel* ui_list_model_new(UiListPtr *list, ui_model_getvalue_f getvalue) { +static GType ui_gtk_type(UiModelType type) { + switch(type) { + case UI_STRING: return G_TYPE_STRING; + case UI_INTEGER: return G_TYPE_INT; + } + return G_TYPE_INVALID; +} + +static void ui_model_set_value(UiModelType type, void *data, GValue *value) { + switch(type) { + case UI_STRING: { + value->g_type = G_TYPE_STRING; + g_value_set_string(value, data); + return; + } + case UI_INTEGER: { + value->g_type = G_TYPE_INT; + int *i = data; + g_value_set_int(value, *i); + return; + } + } + value->g_type = G_TYPE_INVALID; +} + +UiListModel* ui_list_model_new(UiListPtr *list, UiModelInfo *info) { UiListModel *model = g_object_new(list_model_type, NULL); + model->info = info; model->list = list; - model->getvalue = getvalue; model->columntypes = malloc(sizeof(GType)); - model->numcolumns = 1; - model->columntypes[0] = G_TYPE_STRING; + model->numcolumns = info->columns; + for(int i=0;icolumns;i++) { + model->columntypes[i] = ui_gtk_type(info->types[i]); + } return model; } @@ -204,15 +231,15 @@ // TODO: return correct value from column - value->g_type = G_TYPE_STRING; + //value->g_type = G_TYPE_STRING; list->iter = iter->user_data; //list->index = (int)(intptr_t)iter->user_data2; //list->current = iter->user_data3; - if(model->getvalue) { - char *str = model->getvalue(iter->user_data3, column); - g_value_set_string(value, str); + if(model->info->getvalue) { + void *data = model->info->getvalue(iter->user_data3, column); + ui_model_set_value(model->info->types[column], data, value); } else { - g_value_set_string(value, iter->user_data3); + value->g_type = G_TYPE_INVALID; } } diff -r 4e66271541e8 -r caa0df8ed095 ui/gtk/model.h --- a/ui/gtk/model.h Thu May 15 20:06:28 2014 +0200 +++ b/ui/gtk/model.h Thu May 15 21:48:53 2014 +0200 @@ -31,6 +31,7 @@ #include "../ui/toolkit.h" #include "../common/context.h" +#include "../ui/tree.h" #ifdef __cplusplus extern "C" { @@ -42,12 +43,12 @@ * UiList to GtkTreeModel wrapper */ struct UiListModel { - GObject object; - UiListPtr *list; - GType *columntypes; - void* (*getvalue)(void*, int); - int numcolumns; - int stamp; + GObject object; + UiModelInfo *info; + UiListPtr *list; + GType *columntypes; + int numcolumns; + int stamp; }; /* @@ -58,7 +59,7 @@ /* * Creates a UiListModel for a given UiList */ -UiListModel* ui_list_model_new(UiListPtr *list, ui_model_getvalue_f getvalue); +UiListModel* ui_list_model_new(UiListPtr *list, UiModelInfo *info); // interface functions diff -r 4e66271541e8 -r caa0df8ed095 ui/gtk/tree.c --- a/ui/gtk/tree.c Thu May 15 20:06:28 2014 +0200 +++ b/ui/gtk/tree.c Thu May 15 21:48:53 2014 +0200 @@ -60,15 +60,17 @@ #endif - UiListModel *model = ui_list_model_new(list, getvalue); + UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1); + modelinfo->getvalue = getvalue; + UiListModel *model = ui_list_model_new(list, modelinfo); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); // add TreeView as observer to the UiList to update the TreeView if the // data changes - UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView)); + UiTableView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiTableView)); listview->widget = view; listview->list = list; - listview->getvalue = getvalue; + listview->modelinfo = modelinfo; list->list->observers = ui_add_observer( list->list->observers, (ui_callback)ui_listview_update, @@ -123,11 +125,98 @@ } -void ui_listview_update(UiEvent *event, UiListView *view) { - UiList *list = view->list->list; +UIWIDGET ui_table_var(UiObject *obj, UiListPtr *list, UiModelInfo *modelinfo) { + // create treeview + GtkWidget *view = gtk_tree_view_new(); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + for(int i=0;icolumns;i++) { + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes( + modelinfo->titles[i], + renderer, + "text", + 0, + NULL); + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); + } + + //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); +#else + +#endif + + UiListModel *model = ui_list_model_new(list, modelinfo); + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); + + // add TreeView as observer to the UiList to update the TreeView if the + // data changes + UiTableView *tableview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiTableView)); + tableview->widget = view; + tableview->list = list; + tableview->modelinfo = modelinfo; + list->list->observers = ui_add_observer( + list->list->observers, + (ui_callback)ui_listview_update, + tableview); - UiListModel *model = ui_list_model_new(view->list, view->getvalue); + // 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; + + g_signal_connect( + view, + "row-activated", + G_CALLBACK(ui_listview_selected), + event); + } + + // add widget to the current container + GtkWidget *scroll_area = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(scroll_area), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS + gtk_container_add(GTK_CONTAINER(scroll_area), view); + + UiContainer *ct = uic_get_current_container(obj); + ct->add(ct, scroll_area); + + return scroll_area; +} + +UIWIDGET ui_table(UiObject *obj, UiList *list, UiModelInfo *modelinfo) { + UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); + listptr->list = list; + return ui_table_var(obj, listptr, modelinfo); +} + +UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModelInfo *modelinfo) { + UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + if(var) { + UiListVar *value = var->value; + return ui_table_var(obj, value->listptr, modelinfo); + } else { + // TODO: error + } + return NULL; +} + + + +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( diff -r 4e66271541e8 -r caa0df8ed095 ui/gtk/tree.h --- a/ui/gtk/tree.h Thu May 15 20:06:28 2014 +0200 +++ b/ui/gtk/tree.h Thu May 15 21:48:53 2014 +0200 @@ -37,17 +37,18 @@ extern "C" { #endif -typedef struct UiListView { +typedef struct UiTableView { GtkWidget *widget; UiListPtr *list; - ui_model_getvalue_f getvalue; -} UiListView; + UiModelInfo *modelinfo; + //ui_model_getvalue_f getvalue; +} UiTableView; 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); -void ui_listview_update(UiEvent *event, UiListView *view); +void ui_listview_update(UiEvent *event, UiTableView *view); void ui_listview_selected( GtkTreeView *tree_view, GtkTreePath *path,