new checkbox and radionbutton features and more refactoring

Sat, 11 Nov 2017 08:34:06 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 11 Nov 2017 08:34:06 +0100
changeset 142
46448d38885c
parent 141
cc2170ea05ad
child 143
d499b29d7cb6

new checkbox and radionbutton features and more refactoring

application/main.c file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/types.c file | annotate | diff | comparison | revisions
ui/gtk/button.c file | annotate | diff | comparison | revisions
ui/gtk/button.h file | annotate | diff | comparison | revisions
ui/gtk/model.c file | annotate | diff | comparison | revisions
ui/gtk/model.h file | annotate | diff | comparison | revisions
ui/gtk/toolbar.c file | annotate | diff | comparison | revisions
ui/gtk/toolbar.h file | annotate | diff | comparison | revisions
ui/gtk/toolkit.c file | annotate | diff | comparison | revisions
ui/gtk/toolkit.h file | annotate | diff | comparison | revisions
ui/gtk/tree.c file | annotate | diff | comparison | revisions
ui/gtk/tree.h file | annotate | diff | comparison | revisions
ui/ui/button.h file | annotate | diff | comparison | revisions
ui/ui/toolbar.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
ui/ui/tree.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/application/main.c	Sat Nov 11 08:34:06 2017 +0100
@@ -76,12 +76,12 @@
     Document *doc = ui_document_new(sizeof(Document));
     UiContext *ctx = ui_document_context(doc);
     
-    doc->text = ui_text_new(ctx, "text");
+    //doc->text = ui_text_new(ctx, "text");
     //doc->t1 = ui_string_new(ctx, "t1");
     //doc->t2 = ui_string_new(ctx, "t2");
     //doc->t3 = ui_string_new(ctx, "t3");
     
-    //doc->i = ui_int_new(ctx, "int");
+    doc->i = ui_int_new(ctx, "int");
     return doc;
 }
 
@@ -101,9 +101,10 @@
     UiObject *obj = ui_window("Test", NULL);
     ui_set_document(obj, d1);
     
-    ui_textarea_nv(obj, "text");
-    
-    
+    //ui_textarea_nv(obj, "text");
+    ui_radiobutton_nv(obj, "1", "int");
+    ui_radiobutton_nv(obj, "2", "int");
+    ui_radiobutton_nv(obj, "3", "int");
     
     ui_button(obj, "Switch Document", action_newdoc, NULL);
     
--- a/ui/common/context.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/common/context.c	Sat Nov 11 08:34:06 2017 +0100
@@ -150,13 +150,29 @@
     // otherweise add it to the bound map
     UiVar *cv = ucx_map_cstr_get(ctx->vars, name);
     if(cv) {
-        return cv; // I'm not sure if this can actually happen, lol
+        if(cv->type == type) {
+            return cv;
+        } else {
+            fprintf(stderr, "UiError: var '%s' already exists with different type\n", name);
+        }
+    }
+    
+    UiVar *var;
+    if(ctx->bound) {
+        var = ucx_map_cstr_get(ctx->bound, name);
+        if(var) {
+            if(var->type != type) {
+                fprintf(stderr, "UiError: var '%s' already bound with different type\n", name);
+            } else {
+                return var;
+            }
+        }
     }
     
     // create var and add it to the bound map
     // this map contains vars that are created by widgets
     // the vars can later be moved to subdocuments
-    UiVar *var = ui_malloc(ctx, sizeof(UiVar));
+    var = ui_malloc(ctx, sizeof(UiVar));
     var->type = type;
     var->value = uic_create_value(ctx, type);
     var->orig_val = NULL;
@@ -165,11 +181,7 @@
     if(!ctx->bound) {
         ctx->bound = ucx_map_new_a(ctx->mempool->allocator, 16);
     }
-    size_t oldcount = ctx->bound->count;
     ucx_map_cstr_put(ctx->bound, name, var);
-    if(ctx->bound->count != oldcount + 1) {
-        fprintf(stderr, "UiError: var '%s' already bound\n", name);
-    }
     
     // if a subdocument has a variable with this name, we must copy
     // the binding to the doc var
@@ -234,9 +246,7 @@
             UiInteger *f = from->value;
             UiInteger *t = to->value;
             uic_int_copy(f, t);
-            if(t->value != 0) {
-                t->set(t, t->value);
-            }
+            t->set(t, t->value);
             break;
         }
         case UI_VAR_STRING: {
--- a/ui/common/types.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/common/types.c	Sat Nov 11 08:34:06 2017 +0100
@@ -81,6 +81,13 @@
     }
 }
 
+void ui_notify_evt(UiObserver *observer, UiEvent *event) {
+    while(observer) {
+        observer->callback(event, observer->data);
+        observer = observer->next;
+    }
+}
+
 /* --------------------------- UiList --------------------------- */
 
 UiList* ui_list_new(void) {
@@ -160,8 +167,8 @@
     char *name;
 } UiColumn;
 
-UiModelInfo* ui_model_info(UiContext *ctx, ...) {
-    UiModelInfo *info = ui_calloc(ctx, 1, sizeof(UiModelInfo));
+UiModel* ui_model_info(UiContext *ctx, ...) {
+    UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
     
     va_list ap;
     va_start(ap, ctx);
@@ -198,7 +205,7 @@
     return info;
 }
 
-void ui_model_info_free(UiContext *ctx, UiModelInfo *mi) {
+void ui_model_info_free(UiContext *ctx, UiModel *mi) {
     ucx_mempool_free(ctx->mempool, mi->types);
     ucx_mempool_free(ctx->mempool, mi->titles);
     ucx_mempool_free(ctx->mempool, mi);
--- a/ui/gtk/button.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/button.c	Sat Nov 11 08:34:06 2017 +0100
@@ -99,48 +99,42 @@
     gtk_toggle_button_set_active(button, value != 0 ? TRUE : FALSE);
 }
 
+void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event) {
+    UiEvent e;
+    e.obj = event->obj;
+    e.window = event->obj->window;
+    e.document = event->obj->ctx->document;
+    e.eventdata = NULL;
+    e.intval = gtk_toggle_tool_button_get_active(widget);
+    
+    UiInteger *i = event->var->value;
+    ui_notify_evt(i->observers, &e);
+}
 
-UIWIDGET ui_checkbox(UiObject *obj, char *label, UiInteger *value) {
+UIWIDGET ui_checkbox_var(UiObject *obj, char *label, UiVar *var) {
     GtkWidget *button = gtk_check_button_new_with_label(label);
     
     // bind value
-    if(value) {
+    if(var) {
+        UiInteger *value = var->value;
         value->obj = GTK_TOGGLE_BUTTON(button);
         value->get = ui_toggle_button_get;
         value->set = ui_toggle_button_set;
-        if(value->value != 0) {
-            gtk_toggle_button_set_active(value->obj, TRUE);
-        }
-    }
-    
-    UiContainer *ct = uic_get_current_container(obj);
-    ct->add(ct, button, FALSE);
-    
-    return button;
-}
-
-UIWIDGET ui_checkbox_cb(UiObject *obj, char *label, ui_callback f, void *data) {
-    GtkWidget *button = gtk_check_button_new_with_label(label);
-    
-    if(f) {
-        //UiEventData *event = ucx_mempool_malloc(
-        //        obj->ctx->mempool,
-        //        sizeof(UiEventData));
-        UiEventData *event = malloc(sizeof(UiEventData));
+        gtk_toggle_button_set_active(value->obj, value->value);
+        
+        UiVarEventData *event = malloc(sizeof(UiVarEventData));
         event->obj = obj;
-        event->userdata = data;
-        event->callback = f;
-        event->value = 0;
+        event->var = var;
 
         g_signal_connect(
                 button,
                 "clicked",
-                G_CALLBACK(ui_button_toggled),
+                G_CALLBACK(ui_toggled_obs),
                 event);
         g_signal_connect(
                 button,
                 "destroy",
-                G_CALLBACK(ui_destroy_userdata),
+                G_CALLBACK(ui_destroy_vardata),
                 event);
     }
     
@@ -150,10 +144,30 @@
     return button;
 }
 
+UIWIDGET ui_checkbox(UiObject *obj, char *label, UiInteger *value) {
+    UiVar *var = NULL;
+    if(value) {
+        var = malloc(sizeof(UiVar));
+        var->value = value;
+        var->type = UI_VAR_SPECIAL;
+    }
+    return ui_checkbox_var(obj, label, var);
+}
+
+UIWIDGET ui_checkbox_nv(UiObject *obj, char *label, char *varname) {
+    UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER);
+    return ui_checkbox_var(obj, label, var);
+}
 
 
-UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup) {
-    GSList *rg = rgroup ? rgroup->obj : NULL;
+UIWIDGET ui_radiobutton_var(UiObject *obj, char *label, UiVar *var) {
+    GSList *rg = NULL;
+    UiInteger *rgroup;
+    
+    if(var) {
+        rgroup = var->value;
+        rg = rgroup->obj;
+    }
     
     GtkWidget *rbutton = gtk_radio_button_new_with_label(rg, label);
     rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
@@ -162,9 +176,23 @@
         rgroup->obj = rg;
         rgroup->get = ui_radiobutton_get;
         rgroup->set = ui_radiobutton_set;
-        if(rgroup->value > 0) {
-            ui_radiobutton_set(rgroup, rgroup->value);
-        }
+        
+        ui_radiobutton_set(rgroup, rgroup->value);
+        
+        UiVarEventData *event = malloc(sizeof(UiVarEventData));
+        event->obj = obj;
+        event->var = var;
+        
+        g_signal_connect(
+                rbutton,
+                "clicked",
+                G_CALLBACK(ui_radio_obs),
+                event);
+        g_signal_connect(
+                rbutton,
+                "destroy",
+                G_CALLBACK(ui_destroy_vardata),
+                event);
     }
     
     UiContainer *ct = uic_get_current_container(obj);
@@ -173,13 +201,42 @@
     return rbutton;
 }
 
+UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup) {
+    UiVar *var = NULL;
+    if(rgroup) {
+        var = malloc(sizeof(UiVar));
+        var->value = rgroup;
+        var->type = UI_VAR_SPECIAL;
+    }
+    return ui_radiobutton_var(obj, label, var);
+}
+
+UIWIDGET ui_radiobutton_nv(UiObject *obj, char *label, char *varname) {
+    UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER);
+    return ui_radiobutton_var(obj, label, var);
+}
+
+void ui_radio_obs(GtkToggleToolButton *widget, UiVarEventData *event) {
+    UiInteger *i = event->var->value;
+    
+    UiEvent e;
+    e.obj = event->obj;
+    e.window = event->obj->window;
+    e.document = event->obj->ctx->document;
+    e.eventdata = NULL;
+    e.intval = i->get(i);
+    
+    ui_notify_evt(i->observers, &e);
+}
+
 int ui_radiobutton_get(UiInteger *value) {
     int selection = 0;
     GSList *ls = value->obj;
     int i = 0;
+    guint len = g_slist_length(ls);
     while(ls) {
         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ls->data))) {
-            selection = g_slist_length(value->obj) - i - 1;
+            selection = len - i - 1;
             break;
         }
         ls = ls->next;
@@ -203,6 +260,6 @@
         j++;
     }
     
-    value->value = j;
+    value->value = i;
 }
 
--- a/ui/gtk/button.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/button.h	Sat Nov 11 08:34:06 2017 +0100
@@ -41,6 +41,15 @@
 void ui_button_clicked(GtkWidget *widget, UiEventData *event);
 void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event);
 
+
+void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event);
+
+UIWIDGET ui_checkbox_var(UiObject *obj, char *label, UiVar *var);
+
+UIWIDGET ui_radiobutton_var(UiObject *obj, char *label, UiVar *var);
+
+void ui_radio_obs(GtkToggleToolButton *widget, UiVarEventData *event);
+
 int ui_radiobutton_get(UiInteger *value);
 void ui_radiobutton_set(UiInteger *value, int i);
 
--- a/ui/gtk/model.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/model.c	Sat Nov 11 08:34:06 2017 +0100
@@ -122,7 +122,7 @@
     value->g_type = G_TYPE_INVALID; 
 }
 
-UiListModel* ui_list_model_new(UiVar *var, UiModelInfo *info) {
+UiListModel* ui_list_model_new(UiVar *var, UiModel *info) {
     UiListModel *model = g_object_new(list_model_type, NULL);
     model->info = info;
     model->var = var;
--- a/ui/gtk/model.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/model.h	Sat Nov 11 08:34:06 2017 +0100
@@ -44,7 +44,7 @@
  */
 struct UiListModel {
     GObject     object;
-    UiModelInfo *info;
+    UiModel *info;
     UiVar       *var;
     GType       *columntypes;
     int         numcolumns;
@@ -59,7 +59,7 @@
 /*
  * Creates a UiListModel for a given UiList
  */
-UiListModel* ui_list_model_new(UiVar *var, UiModelInfo *info);
+UiListModel* ui_list_model_new(UiVar *var, UiModel *info);
 
 
 // interface functions
--- a/ui/gtk/toolbar.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/toolbar.c	Sat Nov 11 08:34:06 2017 +0100
@@ -159,7 +159,7 @@
 void ui_toolbar_combobox(
         char *name,
         UiList *list,
-        ui_model_getvalue_f getvalue,
+        ui_getvaluefunc getvalue,
         ui_callback f,
         void *udata)
 {
@@ -188,7 +188,7 @@
 void ui_toolbar_combobox_nv(
         char *name,
         char *listname,
-        ui_model_getvalue_f getvalue,
+        ui_getvaluefunc getvalue,
         ui_callback f,
         void *udata)
 {
@@ -358,7 +358,7 @@
 }
 
 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) {
-    UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
+    UiModel *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
     modelinfo->getvalue = cb->getvalue;
     UiListModel *model = ui_list_model_new(cb->var, modelinfo);
     
@@ -371,7 +371,7 @@
 void add_toolbar_combobox_nv(GtkToolbar *tb, UiToolbarComboBoxNV *cb, UiObject *obj) {
     UiVar *var = uic_create_var(obj->ctx, cb->listname, UI_VAR_LIST);
     if(var) {
-        UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
+        UiModel *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
         modelinfo->getvalue = cb->getvalue;
         UiListModel *model = ui_list_model_new(var, modelinfo);
         
--- a/ui/gtk/toolbar.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/toolbar.h	Sat Nov 11 08:34:06 2017 +0100
@@ -75,7 +75,7 @@
 struct UiToolbarComboBox {
     UiToolItemI         item;
     UiVar               *var;
-    ui_model_getvalue_f getvalue;
+    ui_getvaluefunc getvalue;
     ui_callback         callback;
     void                *userdata;
 };
@@ -83,7 +83,7 @@
 struct UiToolbarComboBoxNV {
     UiToolItemI         item;
     char                *listname;
-    ui_model_getvalue_f getvalue;
+    ui_getvaluefunc getvalue;
     ui_callback         callback;
     void                *userdata;
 };
--- a/ui/gtk/toolkit.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/toolkit.c	Sat Nov 11 08:34:06 2017 +0100
@@ -226,6 +226,11 @@
     free(userdata);
 }
 
+void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data) {
+    ui_destroy_boundvar(data->obj->ctx, data->var);
+    free(data);
+}
+
 void ui_destroy_boundvar(UiContext *ctx, UiVar *var) {
     if(var->type == UI_VAR_SPECIAL) {
         free(var);
--- a/ui/gtk/toolkit.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/toolkit.h	Sat Nov 11 08:34:06 2017 +0100
@@ -44,6 +44,12 @@
     int         value;
 } UiEventData;
 
+typedef struct UiVarEventData {
+    UiObject   *obj;
+    UiVar      *var;
+} UiVarEventData;
+
+
 typedef struct UiJob {
     UiObject      *obj;
     ui_threadfunc job_func;
@@ -61,7 +67,7 @@
 #endif
 
 void ui_destroy_userdata(GtkWidget *object, void *userdata);
-
+void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data);
 void ui_destroy_boundvar(UiContext *ctx, UiVar *var);
 
 void ui_set_active_window(UiObject *obj);
--- a/ui/gtk/tree.c	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/tree.c	Sat Nov 11 08:34:06 2017 +0100
@@ -46,7 +46,7 @@
     return ui_listview(obj, list, ui_strmodel_getvalue, f, udata);
 }
 
-UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
+UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     // create treeview
     GtkWidget *view = gtk_tree_view_new();
     GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
@@ -64,17 +64,17 @@
     // TODO: implement for gtk2
 #endif
     
-    UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
-    modelinfo->getvalue = getvalue;
+    UiModel *model = ui_model_info(obj->ctx, UI_STRING, "", -1);
+    model->getvalue = getvalue;
     UiList *list = var->value;
-    UiListModel *model = ui_list_model_new(var, modelinfo);
-    gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model));
+    UiListModel *listmodel = ui_list_model_new(var, model);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
     
-    UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView));
+    UiListView *listview = malloc(sizeof(UiListView));
     listview->ctx = obj->ctx;
     listview->widget = view;
     listview->var = var;
-    listview->modelinfo = modelinfo;
+    listview->model = model;
     g_signal_connect(
                 view,
                 "destroy",
@@ -118,14 +118,14 @@
     return scroll_area;
 }
 
-UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
+UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     UiVar *var = malloc(sizeof(UiVar));
     var->value = list;
     var->type = UI_VAR_SPECIAL;
     return ui_listview_var(obj, var, getvalue, f, udata);
 }
 
-UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
+UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
     if(var) {
         return ui_listview_var(obj, var, getvalue, f, udata);
@@ -136,15 +136,15 @@
 }
 
 
-UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModelInfo *modelinfo) {
+UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModel *model, UiListCallbacks cb) {
     // create treeview
     GtkWidget *view = gtk_tree_view_new();
     int addi = 0;
-    for(int i=0;i<modelinfo->columns;i++) {
+    for(int i=0;i<model->columns;i++) {
         GtkTreeViewColumn *column = NULL;
-        if(modelinfo->types[i] == UI_ICON_TEXT) {
+        if(model->types[i] == UI_ICON_TEXT) {
             column = gtk_tree_view_column_new();
-            gtk_tree_view_column_set_title(column, modelinfo->titles[i]);
+            gtk_tree_view_column_set_title(column, model->titles[i]);
             
             GtkCellRenderer *iconrenderer = gtk_cell_renderer_pixbuf_new();
             GtkCellRenderer *textrenderer = gtk_cell_renderer_text_new();
@@ -160,7 +160,7 @@
         } else {
             GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
             column = gtk_tree_view_column_new_with_attributes(
-                modelinfo->titles[i],
+                model->titles[i],
                 renderer,
                 "text",
                 i + addi,
@@ -178,8 +178,8 @@
 #endif
     
     UiList *list = var->value;
-    UiListModel *model = ui_list_model_new(var, modelinfo);
-    gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model));
+    UiListModel *listmodel = ui_list_model_new(var, model);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel));
     
     // add TreeView as observer to the UiList to update the TreeView if the
     // data changes
@@ -187,7 +187,7 @@
     tableview->ctx = obj->ctx;
     tableview->widget = view;
     tableview->var = var;
-    tableview->modelinfo = modelinfo;
+    tableview->model = model;
     g_signal_connect(
                 view,
                 "destroy",
@@ -201,17 +201,17 @@
     // add callback
     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) {
+    event->activate = cb.activate;
+    event->selection = cb.selection;
+    event->userdata = cb.userdata;
+    if(cb.activate) {
         g_signal_connect(
                 view,
                 "row-activated",
                 G_CALLBACK(ui_listview_activate_event),
                 event);
     }
-    if(modelinfo->selection) {
+    if(cb.selection) {
         GtkTreeSelection *selection = gtk_tree_view_get_selection(
                 GTK_TREE_VIEW(view));
         g_signal_connect(
@@ -243,17 +243,17 @@
     return scroll_area;
 }
 
-UIWIDGET ui_table(UiObject *obj, UiList *list, UiModelInfo *modelinfo) {
+UIWIDGET ui_table(UiObject *obj, UiList *list, UiModel *model, UiListCallbacks cb) {
     UiVar *var = malloc(sizeof(UiVar));
     var->value = list;
     var->type = UI_VAR_SPECIAL;
-    return ui_table_var(obj, var, modelinfo);
+    return ui_table_var(obj, var, model, cb);
 }
 
-UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModelInfo *modelinfo) {
+UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModel *model, UiListCallbacks cb) {
     UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
     if(var) {
-        return ui_table_var(obj, var, modelinfo);
+        return ui_table_var(obj, var, model, cb);
     } else {
         // TODO: error
     }
@@ -262,7 +262,7 @@
 
 void ui_listview_update(UiList *list, int i) {
     UiListView *view = list->obj;
-    UiListModel *model = ui_list_model_new(view->var, view->modelinfo);
+    UiListModel *model = ui_list_model_new(view->var, view->model);
     gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model));
     // TODO: free old model
 }
@@ -355,14 +355,14 @@
     return ui_combobox(obj, list, ui_strmodel_getvalue, f, udata);
 }
 
-UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
+UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     UiVar *var = malloc(sizeof(UiVar));
     var->value = list;
     var->type = UI_VAR_SPECIAL;
     return ui_combobox_var(obj, var, getvalue, f, udata);
 }
 
-UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
+UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
     if(var) {
         return ui_combobox_var(obj, var, getvalue, f, udata);
@@ -372,13 +372,12 @@
     return NULL;
 }
 
-UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
-    UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1);
-    modelinfo->getvalue = getvalue;
-    UiList *list = var->value;
-    UiListModel *model = ui_list_model_new(var, modelinfo);
+UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
+    UiModel *model = ui_model_info(obj->ctx, UI_STRING, "", -1);
+    model->getvalue = getvalue;
+    UiListModel *listmodel = ui_list_model_new(var, model);
     
-    GtkWidget *combobox = ui_create_combobox(obj, model, f, udata);
+    GtkWidget *combobox = ui_create_combobox(obj, listmodel, f, udata);
     UiContainer *ct = uic_get_current_container(obj);
     ct->add(ct, combobox, FALSE);
 }
@@ -390,7 +389,7 @@
     uicbox->ctx = obj->ctx;
     uicbox->widget = combobox;
     uicbox->var = model->var;
-    uicbox->modelinfo = model->info;
+    uicbox->model = model->info;
     
     g_signal_connect(
                 combobox,
@@ -443,7 +442,7 @@
 
 void ui_combobox_modelupdate(UiList *list, int i) {
     UiListView *view = list->obj;
-    UiListModel *model = ui_list_model_new(view->var, view->modelinfo);
+    UiListModel *model = ui_list_model_new(view->var, view->model);
     gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(model));
 }
 
--- a/ui/gtk/tree.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/gtk/tree.h	Sat Nov 11 08:34:06 2017 +0100
@@ -41,7 +41,7 @@
     UiContext   *ctx;
     GtkWidget   *widget;
     UiVar       *var;
-    UiModelInfo *modelinfo;
+    UiModel     *model;
 } UiListView;
 
 typedef struct UiTreeEventData {
@@ -53,8 +53,8 @@
     
 void* ui_strmodel_getvalue(void *elm, int column);
 
-UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
-UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModelInfo *modelinfo);
+UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata);
+UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModel *model, UiListCallbacks cb);
 
 void ui_listview_update(UiList *list, int i);
 void ui_listview_destroy(GtkWidget *w, UiListView *v);
@@ -72,7 +72,7 @@
         UiTreeEventData *event);
 int ui_tree_path_list_index(GtkTreePath *path);
 
-UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
+UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 GtkWidget* ui_create_combobox(UiObject *obj, UiListModel *model, ui_callback f, void *udata);
 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e);
 void ui_combobox_modelupdate(UiList *list, int i);
--- a/ui/ui/button.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/ui/button.h	Sat Nov 11 08:34:06 2017 +0100
@@ -38,9 +38,10 @@
 UIWIDGET ui_button(UiObject *obj, char *label, ui_callback f, void *data);
 
 UIWIDGET ui_checkbox(UiObject *obj, char *label, UiInteger *value);
-UIWIDGET ui_checkbox_cb(UiObject *obj, char *label, ui_callback f, void *data);
+UIWIDGET ui_checkbox_nv(UiObject *obj, char *label, char *varname);
 
 UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup);
+UIWIDGET ui_radiobutton_nv(UiObject *obj, char *label, char *varname);
 
 
 #ifdef	__cplusplus
--- a/ui/ui/toolbar.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/ui/toolbar.h	Sat Nov 11 08:34:06 2017 +0100
@@ -46,9 +46,9 @@
 void ui_toolitem_toggle_stgr(char *name, char *stockid, ui_callback f, void *udata, ...);
 void ui_toolitem_toggle_imggr(char *name, char *label, char *img, ui_callback f, void *udata, ...);
 
-void ui_toolbar_combobox(char *name, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
+void ui_toolbar_combobox(char *name, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 void ui_toolbar_combobox_str(char *name, UiList *list, ui_callback f, void *udata);
-void ui_toolbar_combobox_nv(char *name, char *listname, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
+void ui_toolbar_combobox_nv(char *name, char *listname, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 
 void ui_toolbar_add_default(char *name);
 
--- a/ui/ui/toolkit.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/ui/toolkit.h	Sat Nov 11 08:34:06 2017 +0100
@@ -112,7 +112,7 @@
   
 typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */
 
-typedef void*(*ui_model_getvalue_f)(void*, int);
+typedef void*(*ui_getvaluefunc)(void*, int);
 
 typedef int(*ui_threadfunc)(void*);
 
@@ -314,6 +314,7 @@
 UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data);
 void ui_notify(UiObserver *observer, void *data);
 void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data);
+void ui_notify_evt(UiObserver *observer, UiEvent *event);
 
 
 UiList* ui_list_new(void);
--- a/ui/ui/tree.h	Fri Nov 10 18:04:40 2017 +0100
+++ b/ui/ui/tree.h	Sat Nov 11 08:34:06 2017 +0100
@@ -35,7 +35,8 @@
 extern "C" {
 #endif
 
-typedef struct UiModelInfo     UiModelInfo;
+typedef struct UiModel         UiModel;
+typedef struct UiListCallbacks UiListCallbacks;
 typedef struct UiListSelection UiListSelection;
 
 
@@ -46,7 +47,7 @@
     UI_ICON_TEXT,
 } UiModelType;
 
-struct UiModelInfo {
+struct UiModel {
     /*
      * number of columns
      */
@@ -71,7 +72,9 @@
      * TODO: return
      */
     void*(*getvalue)(void*, int);
-    
+};
+
+struct UiListCallbacks {
     /*
      * selection callback
      */
@@ -100,18 +103,19 @@
     int *rows;
 };
 
-UiModelInfo* ui_model_info(UiContext *ctx, ...);
-void ui_model_info_free(UiContext *ctx, UiModelInfo *mi);
+UiModel* ui_model_info(UiContext *ctx, ...);
+void ui_model_info_free(UiContext *ctx, UiModel *mi);
 
-UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
+UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata);
-UIWIDGET ui_listview_nv(UiObject *obj, char *listname, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
-
-UIWIDGET ui_table(UiObject *obj, UiList *model, UiModelInfo *modelinfo);
+UIWIDGET ui_listview_nv(UiObject *obj, char *listname, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 
+UIWIDGET ui_table(UiObject *obj, UiList *data, UiModel *model, UiListCallbacks cb);
+UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModel *model, UiListCallbacks cb);
+
+UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 UIWIDGET ui_combobox_str(UiObject *obj, UiList *list, ui_callback f, void *udata);
-UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
-UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata);
+UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 
 #ifdef	__cplusplus
 }

mercurial