added table view (GTK)

Thu, 15 May 2014 21:48:53 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 15 May 2014 21:48:53 +0200
changeset 40
caa0df8ed095
parent 39
4e66271541e8
child 41
394f3b06dba1

added table view (GTK)

ui/gtk/model.c file | annotate | diff | comparison | revisions
ui/gtk/model.h file | annotate | diff | comparison | revisions
ui/gtk/tree.c file | annotate | diff | comparison | revisions
ui/gtk/tree.h file | annotate | diff | comparison | revisions
--- 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;i<info->columns;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;
     }
 }
 
--- 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
--- 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;i<modelinfo->columns;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(
--- 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,

mercurial