applies value binding refactoring and text refactoring to motif implementation

Sun, 01 Jul 2018 19:03:26 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 01 Jul 2018 19:03:26 +0200
changeset 153
ee49d1852a5f
parent 152
62921b370c60
child 154
8a4451fcb736

applies value binding refactoring and text refactoring to motif implementation

application/main.c file | annotate | diff | comparison | revisions
ui/motif/button.c file | annotate | diff | comparison | revisions
ui/motif/button.h file | annotate | diff | comparison | revisions
ui/motif/container.c file | annotate | diff | comparison | revisions
ui/motif/container.h file | annotate | diff | comparison | revisions
ui/motif/dnd.c file | annotate | diff | comparison | revisions
ui/motif/dnd.h file | annotate | diff | comparison | revisions
ui/motif/image.c file | annotate | diff | comparison | revisions
ui/motif/image.h file | annotate | diff | comparison | revisions
ui/motif/list.c file | annotate | diff | comparison | revisions
ui/motif/list.h file | annotate | diff | comparison | revisions
ui/motif/menu.c file | annotate | diff | comparison | revisions
ui/motif/objs.mk file | annotate | diff | comparison | revisions
ui/motif/text.c file | annotate | diff | comparison | revisions
ui/motif/toolbar.c file | annotate | diff | comparison | revisions
ui/motif/toolbar.h file | annotate | diff | comparison | revisions
ui/motif/tree.c file | annotate | diff | comparison | revisions
ui/motif/tree.h file | annotate | diff | comparison | revisions
ui/ui/container.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/application/main.c	Sun Jul 01 19:03:26 2018 +0200
@@ -163,9 +163,9 @@
     ui_set_document(obj, d1);
     
     //ui_textarea_nv(obj, "text");
-    ui_radiobutton_nv(obj, "1", "int");
-    ui_radiobutton_nv(obj, "2", "int");
-    ui_radiobutton_nv(obj, "3", "int");
+    //ui_radiobutton_nv(obj, "1", "int");
+    //ui_radiobutton_nv(obj, "2", "int");
+    //ui_radiobutton_nv(obj, "3", "int");
     
     ui_textfield_nv(obj, "t1");
     //ui_textarea_nv(obj, "text");
@@ -177,16 +177,16 @@
     model->drop = list_drop;
     model->data_get = list_data_get;
     UiListCallbacks cb = {NULL, NULL, NULL};
-    UIWIDGET table = ui_table_nv(obj, "list", model, cb);
-    ui_table_dragsource(table, 0, "text/plain", NULL);
+    //UIWIDGET table = ui_table_nv(obj, "list", model, cb);
+    //ui_table_dragsource(table, 0, "text/plain", NULL);
     
     //ui_spinner_setrange(ui_spinnerf_nv(obj, 1, 0, "d"), 0, 1000);
-    ui_spinnerr_nv(obj, "r");
-    d1->r->setrange(d1->r, 0, 10);
-    d1->r->setextent(d1->r, 1);
-    d1->d->observers = ui_add_observer(d1->d->observers, doublechanged, NULL);
+    //ui_spinnerr_nv(obj, "r");
+    //d1->r->setrange(d1->r, 0, 10);
+    //d1->r->setextent(d1->r, 1);
+    //d1->d->observers = ui_add_observer(d1->d->observers, doublechanged, NULL);
     
-    ui_progressbar_nv(obj, "progress");
+    //ui_progressbar_nv(obj, "progress");
     ui_button(obj, "Switch Document", action_newdoc, NULL);
     
     ui_show(obj);
--- a/ui/motif/button.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/button.c	Sun Jul 01 19:03:26 2018 +0200
@@ -70,14 +70,14 @@
 }
 
 // wrapper
-int ui_toggle_button_get(UiInteger *i) {
+int64_t ui_toggle_button_get(UiInteger *i) {
     int state = 0;
     XtVaGetValues(i->obj, XmNset, &state, NULL);
     i->value = state;
     return state;
 }
 
-void ui_toggle_button_set(UiInteger *i, int value) {
+void ui_toggle_button_set(UiInteger *i, int64_t value) {
     Arg arg;
     XtSetArg(arg, XmNset, value);
     XtSetValues(i->obj, &arg, 1);
@@ -178,7 +178,7 @@
     return button;
 }
 
-int ui_radiobutton_get(UiInteger *value) {
+int64_t ui_radiobutton_get(UiInteger *value) {
     RadioButtonGroup *group = value->obj;
     
     int i = ucx_list_find(group->buttons, group->current, NULL, NULL);
@@ -190,7 +190,7 @@
     }
 }
 
-void ui_radiobutton_set(UiInteger *value, int i) {
+void ui_radiobutton_set(UiInteger *value, int64_t i) {
     RadioButtonGroup *group = value->obj;
     Arg arg;
     
--- a/ui/motif/button.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/button.h	Sun Jul 01 19:03:26 2018 +0200
@@ -50,16 +50,16 @@
 } RadioEventData;
 
 // wrapper
-int ui_toggle_button_get(UiInteger *i);
-void ui_toggle_button_set(UiInteger *i, int value);
+int64_t ui_toggle_button_get(UiInteger *i);
+void ui_toggle_button_set(UiInteger *i, int64_t value);
 void ui_toggle_button_callback(
         Widget widget,
         UiEventData *data,
         XmToggleButtonCallbackStruct *e);
 void ui_push_button_callback(Widget widget, UiEventData *event, XtPointer d);
 
-int ui_radiobutton_get(UiInteger *value);
-void ui_radiobutton_set(UiInteger *value, int i);
+int64_t ui_radiobutton_get(UiInteger *value);
+void ui_radiobutton_set(UiInteger *value, int64_t i);
 
 #ifdef	__cplusplus
 }
--- a/ui/motif/container.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/container.c	Sun Jul 01 19:03:26 2018 +0200
@@ -769,8 +769,8 @@
     }
 }
 
-void ui_tab_detach_document(UiContext *ctx, void *document) {
-    uic_context_detach_document(ctx->parent, document);
+void ui_tab_detach_document(UiContext *ctx) {
+    uic_context_detach_document(ctx->parent);
 }
 
 
--- a/ui/motif/container.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/container.h	Sun Jul 01 19:03:26 2018 +0200
@@ -30,6 +30,7 @@
 #define	CONTAINER_H
 
 #include "../ui/toolkit.h"
+#include "../ui/container.h"
 #include "../../ucx/list.h"
 #include <string.h>
 
@@ -148,7 +149,7 @@
 void ui_change_tab(MotifTabbedPane *pane, UiTab *tab);
 
 void ui_tab_set_document(UiContext *ctx, void *document);
-void ui_tab_detach_document(UiContext *ctx, void *document);
+void ui_tab_detach_document(UiContext *ctx);
 
 
 #ifdef	__cplusplus
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/motif/dnd.c	Sun Jul 01 19:03:26 2018 +0200
@@ -0,0 +1,45 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2018 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "dnd.h"
+
+void ui_selection_settext(UiSelection *sel, char *str, int len) {
+    
+}
+
+void ui_selection_seturis(UiSelection *sel, char **uris, int nelm) {
+    
+}
+
+char* ui_selection_gettext(UiSelection *sel) {
+    
+}
+
+char** ui_selection_geturis(UiSelection *sel, size_t *nelm) {
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/motif/dnd.h	Sun Jul 01 19:03:26 2018 +0200
@@ -0,0 +1,46 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2018 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DND_H
+#define DND_H
+
+#include "../ui/dnd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DND_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/motif/image.c	Sun Jul 01 19:03:26 2018 +0200
@@ -0,0 +1,40 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+#include "image.h"
+
+UiIcon* ui_icon(const char *name, int size) {
+    
+}
+
+UiIcon* ui_icon_unscaled(const char *name, int size) {
+    
+}
+
+void ui_free_icon(UiIcon *icon) {
+    
+}
+
+UiImage* ui_icon_image(UiIcon *icon) {
+    
+}
+
+UiImage* ui_image(const char *filename) {
+    
+}
+
+UiImage* ui_named_image(const char *filename, const char *name) {
+    
+}
+
+UiImage* ui_load_image_from_path(const char *path, const char *name) {
+    
+}
+
+void ui_free_image(UiImage *img) {
+    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/motif/image.h	Sun Jul 01 19:03:26 2018 +0200
@@ -0,0 +1,31 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/* 
+ * File:   image.h
+ * Author: olaf
+ *
+ * Created on 1. Juli 2018, 19:01
+ */
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include "../ui/image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IMAGE_H */
+
--- a/ui/motif/list.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/list.c	Sun Jul 01 19:03:26 2018 +0200
@@ -44,11 +44,9 @@
     return ui_listview(obj, list, ui_strmodel_getvalue, f, udata);
 }
 
-UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
-    UiList *ls = list->list;
-    
+UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
     int count;
-    XmStringTable items = ui_create_stringlist(list->list, getvalue, &count);
+    XmStringTable items = ui_create_stringlist(var->value, getvalue, &count);
     
     Arg args[8];
     int n = 0;
@@ -65,14 +63,9 @@
     
     UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView));
     listview->widget = widget;
-    listview->list = list;
+    listview->list = var;
     listview->getvalue = getvalue;
     
-    list->list->observers = ui_add_observer(
-            list->list->observers,
-            (ui_callback)ui_listview_update,
-            listview);
-    
     for (int i=0;i<count;i++) {
         XmStringFree(items[i]);
     }
@@ -86,7 +79,7 @@
         event->event.userdata = udata;
         event->event.callback = f;
         event->event.value = 0;
-        event->list = list;
+        event->var = var;
         XtAddCallback(
                 widget,
                 XmNdefaultActionCallback,
@@ -97,17 +90,18 @@
     return widget;
 }
 
-UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
-    UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr));
-    listptr->list = list;
-    return ui_listview_var(obj, listptr, getvalue, f, 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) {
-    UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST);
+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) {
         UiListVar *value = var->value;
-        return ui_listview_var(obj, value->listptr, getvalue, f, udata);
+        return ui_listview_var(obj, var, getvalue, f, udata);
     } else {
         // TODO: error
     }
@@ -115,7 +109,7 @@
 }
 
 
-XmStringTable ui_create_stringlist(UiList *list, ui_model_getvalue_f getvalue, int *count) { 
+XmStringTable ui_create_stringlist(UiList *list, ui_getvaluefunc getvalue, int *count) { 
     int num = list->count(list);
     XmStringTable items = (XmStringTable)XtMalloc(num * sizeof(XmString));
     void *data = list->first(list);
@@ -132,7 +126,7 @@
 void ui_listview_update(UiEvent *event, UiListView *view) {
     int count;
     XmStringTable items = ui_create_stringlist(
-            view->list->list,
+            view->list->value,
             view->getvalue,
             &count);
     
@@ -156,7 +150,8 @@
     e.obj = event->event.obj;
     e.window = event->event.obj->window;
     e.document = event->event.obj->ctx->document;
-    e.eventdata = event->list->list->get(event->list->list, cbs->item_position - 1);
+    UiList *list = event->var->value;
+    e.eventdata = list->get(list, cbs->item_position - 1);
     e.intval = cbs->item_position - 1;
     event->event.callback(&e, event->event.userdata);
 }
@@ -168,24 +163,25 @@
     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) {
-    UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr));
-    listptr->list = list;
-    return ui_combobox_var(obj, listptr, getvalue, f, 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) {
-    UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST);
+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) {
         UiListVar *value = var->value;
-        return ui_combobox_var(obj, value->listptr, getvalue, f, udata);
+        return ui_combobox_var(obj, var, getvalue, f, udata);
     } else {
         // TODO: error
     }
     return NULL;
 }
 
-UIWIDGET ui_combobox_var(UiObject *obj, UiListPtr *list, 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) {
     UiListView *listview = ucx_mempool_malloc(
                 obj->ctx->mempool,
                 sizeof(UiListView));
@@ -203,14 +199,9 @@
     Widget combobox = XmCreateDropDownList(parent, "combobox", args, n);
     XtManageChild(combobox);
     listview->widget = combobox;
-    listview->list = list;
+    listview->list = var;
     listview->getvalue = getvalue;
     
     ui_listview_update(NULL, listview);
     
-    list->list->observers = ui_add_observer(
-            list->list->observers,
-            (ui_callback)ui_listview_update,
-            listview);
-    
 }
--- a/ui/motif/list.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/list.h	Sun Jul 01 19:03:26 2018 +0200
@@ -38,23 +38,23 @@
 #endif
 
 typedef struct UiListView {
-    Widget              widget;
-    UiListPtr           *list;
-    ui_model_getvalue_f getvalue;
+    Widget          widget;
+    UiVar           *list;
+    ui_getvaluefunc getvalue;
 } UiListView;
 
 typedef struct UiListViewEventData {
     UiEventData event;
-    UiListPtr *list;
+    UiVar *var;
 } UiListViewEventData;
 
 void* ui_strmodel_getvalue(void *elm, int column);
 
-XmStringTable ui_create_stringlist(UiList *list, ui_model_getvalue_f getvalue, int *count);
+XmStringTable ui_create_stringlist(UiList *list, ui_getvaluefunc getvalue, int *count);
 void ui_listview_update(UiEvent *event, UiListView *view);
 void ui_list_selection_callback (Widget widget, UiListViewEventData *event, XtPointer data);
 
-UIWIDGET ui_combobox_var(UiObject *obj, UiListPtr *list, 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);
 
 #ifdef	__cplusplus
 }
--- a/ui/motif/menu.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/menu.c	Sun Jul 01 19:03:26 2018 +0200
@@ -408,7 +408,7 @@
             2);
     XmStringFree(label);
     
-    UiVar *var = uic_connect_var(obj->ctx, ci->varname, UI_VAR_INTEGER);
+    UiVar *var = uic_create_var(obj->ctx, ci->varname, UI_VAR_INTEGER);
     if(var) {
         UiInteger *value = var->value;
         value->obj = checkbox;
--- a/ui/motif/objs.mk	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/objs.mk	Sun Jul 01 19:03:26 2018 +0200
@@ -42,6 +42,8 @@
 MOTIFOBJ += tree.o
 MOTIFOBJ += graphics.o
 MOTIFOBJ += range.o
+MOTIFOBJ += dnd.o
+MOTIFOBJ += image.o
 
 TOOLKITOBJS += $(MOTIFOBJ:%=$(MOTIF_OBJPRE)%)
 TOOLKITSOURCE += $(MOTIFOBJ:%.o=motif/%.c)
--- a/ui/motif/text.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/text.c	Sun Jul 01 19:03:26 2018 +0200
@@ -60,9 +60,9 @@
     
     // bind value
     if(value) {
-        if(value->value) {
-            XmTextSetString(text_area, value->value);
-            XtFree(value->value);
+        if(value->value.ptr) {
+            XmTextSetString(text_area, value->value.ptr);
+            value->value.free(value->value.ptr);
         }
         
         value->set = ui_textarea_set;
@@ -73,7 +73,7 @@
         value->position = ui_textarea_position;
         value->selection = ui_textarea_selection;
         value->length = ui_textarea_length;
-        value->value = NULL;
+        value->value.ptr = NULL;
         value->obj = text_area;
         
         if(!value->undomgr) {
@@ -91,7 +91,7 @@
 }
 
 UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) {
-    UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT);
+    UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_TEXT);
     if(var) {
         UiText *value = var->value;
         return ui_textarea(obj, value);
@@ -102,38 +102,40 @@
 }
 
 char* ui_textarea_get(UiText *text) {
-    if(text->value) {
-        XtFree(text->value);
+    if(text->value.ptr) {
+        text->value.free(text->value.ptr);
     }
     char *str = XmTextGetString(text->obj);
-    text->value = str;
+    text->value.ptr = str;
+    text->value.free = (ui_freefunc)XtFree;
     return str;
 }
 
 void ui_textarea_set(UiText *text, char *str) {
-    if(text->value) {
-        XtFree(text->value);
+    if(text->value.ptr) {
+        text->value.free(text->value.ptr);
     }
-    text->value = NULL;
+    text->value.ptr = NULL;
     XmTextSetString(text->obj, str);
 }
 
 char* ui_textarea_getsubstr(UiText *text, int begin, int end) {
-    if(text->value) {
-        XtFree(text->value);
+    if(text->value.ptr) {
+        text->value.free(text->value.ptr);
     }
     int length = end - begin;
     char *str = XtMalloc(length + 1);
     XmTextGetSubstring(text->obj, begin, length, length + 1, str);
-    text->value = str;
+    text->value.ptr = str;
+    text->value.free = (ui_freefunc)XtFree;
     return str;
 }
 
 void ui_textarea_insert(UiText *text, int pos, char *str) {
-    if(text->value) {
-        XtFree(text->value);
+    if(text->value.ptr) {
+        text->value.free(text->value.ptr);
     }
-    text->value = NULL;
+    text->value.ptr = NULL;
     XmTextInsert(text->obj, pos, str);
 }
 
@@ -162,10 +164,11 @@
     if(text->set) {
         text->set(text, str);
     } else {
-        if(text->value) {
-            XtFree(text->value);
+        if(text->value.ptr) {
+            text->value.free(text->value.ptr);
         }
-        text->value = XtNewString(str);
+        text->value.ptr = XtNewString(str);
+        text->value.free = (ui_freefunc)XtFree;
     }
 }
 
@@ -173,7 +176,7 @@
     if(text->get) {
         return text->get(text);
     } else {
-        return text->value;
+        return text->value.ptr;
     }
 }
 
@@ -382,14 +385,14 @@
     
     // bind value
     if(value) {
-        if(value->value) {
-            XmTextSetString(textfield, value->value);
-            XtFree(value->value);
+        if(value->value.ptr) {
+            XmTextSetString(textfield, value->value.ptr);
+            value->value.free(value->value.ptr);
         }
         
         value->set = ui_textfield_set;
         value->get = ui_textfield_get;
-        value->value = NULL;
+        value->value.ptr = NULL;
         value->obj = textfield;
     }
     
@@ -397,7 +400,7 @@
 }
 
 static UIWIDGET create_textfield_nv(UiObject *obj, int width, UiBool frameless, UiBool password, char *varname) {
-    UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_STRING);
+    UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_STRING);
     if(var) {
         UiString *value = var->value;
         return ui_textfield(obj, value);
@@ -449,19 +452,20 @@
 
 
 char* ui_textfield_get(UiString *str) {
-    if(str->value) {
-        XtFree(str->value);
+    if(str->value.ptr) {
+        str->value.free(str->value.ptr);
     }
     char *value = XmTextGetString(str->obj);
-    str->value = value;
+    str->value.ptr = value;
+    str->value.free = (ui_freefunc)XtFree;
     return value;
 }
 
 void ui_textfield_set(UiString *str, char *value) {
-    if(str->value) {
-        XtFree(str->value);
+    if(str->value.ptr) {
+        str->value.free(str->value.ptr);
     }
-    str->value = NULL;
+    str->value.ptr = NULL;
     XmTextSetString(str->obj, value);
 }
 
--- a/ui/motif/toolbar.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/toolbar.c	Sun Jul 01 19:03:26 2018 +0200
@@ -149,7 +149,7 @@
 void ui_toolbar_combobox(
         char *name,
         UiList *list,
-        ui_model_getvalue_f getvalue,
+        ui_getvaluefunc getvalue,
         ui_callback f,
         void *udata)
 {
@@ -175,7 +175,7 @@
 void ui_toolbar_combobox_nv(
         char *name,
         char *listname,
-        ui_model_getvalue_f getvalue,
+        ui_getvaluefunc getvalue,
         ui_callback f,
         void *udata)
 {
@@ -334,13 +334,13 @@
 }
 
 void add_toolbar_combobox(Widget tb, UiToolbarComboBox *item, UiObject *obj) {
-    UiListPtr *listptr = ucx_mempool_malloc(
-                obj->ctx->mempool,
-                sizeof(UiListPtr));
     UiListView *listview = ucx_mempool_malloc(
                 obj->ctx->mempool,
                 sizeof(UiListView));
-    listptr->list = item->list;
+    
+    UiVar *var = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiVar));
+    var->value = item->list;
+    var->type = UI_VAR_SPECIAL;
     
     Arg args[8];
     XtSetArg(args[0], XmNshadowThickness, 1);
@@ -350,16 +350,11 @@
     Widget combobox = XmCreateDropDownList(tb, "toolbar_combobox", args, 4);
     XtManageChild(combobox);
     listview->widget = combobox;
-    listview->list = listptr;
+    listview->list = var;
     listview->getvalue = item->getvalue;
     
     ui_listview_update(NULL, listview);
     
-    listptr->list->observers = ui_add_observer(
-            listptr->list->observers,
-            (ui_callback)ui_listview_update,
-            listview);
-    
     if(item->callback) {
         // TODO:
         
--- a/ui/motif/toolbar.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/toolbar.h	Sun Jul 01 19:03:26 2018 +0200
@@ -72,7 +72,7 @@
 struct UiToolbarComboBox {
     UiToolItemI         item;
     UiList              *list;
-    ui_model_getvalue_f getvalue;
+    ui_getvaluefunc     getvalue;
     ui_callback         callback;
     void                *userdata;
 };
@@ -80,7 +80,7 @@
 struct UiToolbarComboBoxNV {
     UiToolItemI         item;
     char                *listname;
-    ui_model_getvalue_f getvalue;
+    ui_getvaluefunc     getvalue;
     ui_callback         callback;
     void                *userdata;
 };
--- a/ui/motif/tree.c	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/tree.c	Sun Jul 01 19:03:26 2018 +0200
@@ -38,7 +38,7 @@
 #include "../common/context.h"
 #include "../../ucx/utils.h"
 
-UIWIDGET ui_table(UiObject *obj, UiList *model, UiModelInfo *modelinfo) {
+UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModel *model, UiListCallbacks cb) {
     // TODO: check if modelinfo is complete
     
     Arg args[32];
@@ -58,14 +58,14 @@
     
     // create table headers
     XmStringTable header = (XmStringTable)XtMalloc(
-            modelinfo->columns * sizeof(XmString));
-    for(int i=0;i<modelinfo->columns;i++) {
-        header[i] = XmStringCreateLocalized(modelinfo->titles[i]);
+            model->columns * sizeof(XmString));
+    for(int i=0;i<model->columns;i++) {
+        header[i] = XmStringCreateLocalized(model->titles[i]);
     }
     n = 0;
     XtSetArg(args[n], XmNdetailColumnHeading, header);
     n++;
-    XtSetArg(args[n], XmNdetailColumnHeadingCount, modelinfo->columns);
+    XtSetArg(args[n], XmNdetailColumnHeadingCount, model->columns);
     n++;
     
     // set res
@@ -88,18 +88,18 @@
     // add callbacks
     UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
     event->obj = obj;
-    event->activate = modelinfo->activate;
-    event->selection = modelinfo->selection;
-    event->userdata = modelinfo->userdata;
+    event->activate = cb.activate;
+    event->selection = cb.selection;
+    event->userdata = cb.userdata;
     event->last_selection = NULL;
-    if(modelinfo->selection) {
+    if(cb.selection) {
         XtAddCallback(
                 container,
                 XmNselectionCallback,
                 (XtCallbackProc)ui_table_select_callback,
                 event);
     }
-    if(modelinfo->activate) {
+    if(cb.activate) {
         XtAddCallback(
                 container,
                 XmNdefaultActionCallback,
@@ -108,30 +108,27 @@
     }
     
     // add initial data
-    void *data = model->first(model);
+    UiList *list = var->value;
+    void *data = list->first(list);
     int width = 0;
     while(data) {
-        int w = ui_add_icon_gadget(container, modelinfo, data);
+        int w = ui_add_icon_gadget(container, model, data);
         if(w > width) {
             width = w;
         }
-        data = model->next(model);
+        data = list->next(list);
     }
     
     UiTableView *tableview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiTableView));
     tableview->widget = container;
-    tableview->list = model;
-    tableview->modelinfo = modelinfo;
-    model->observers = ui_add_observer(
-            model->observers,
-            (ui_callback)ui_table_update,
-            tableview);
+    tableview->var = var;
+    tableview->model = model;
     
     // set new XmContainer width
     XtVaSetValues(container, XmNwidth, width, NULL);
     
     // cleanup
-    for(int i=0;i<modelinfo->columns;i++) {
+    for(int i=0;i<model->columns;i++) {
         XmStringFree(header[i]);
     }
     XtFree((char*)header);
@@ -139,6 +136,13 @@
     return scrollw;
 }
 
+UIWIDGET ui_table(UiObject *obj, UiList *data, UiModel *model, UiListCallbacks cb) {
+    UiVar *var = malloc(sizeof(UiVar));
+    var->value = data;
+    var->type = UI_VAR_SPECIAL;
+    return ui_table_var(obj, var, model, cb);
+}
+
 void ui_table_update(UiEvent *event, UiTableView *view) {
     // clear container
     Widget *children;
@@ -156,26 +160,26 @@
         XtDestroyWidget(children[i]);
     }
     
-    UiList *model = view->list;
+    UiList *list = view->var->value;
     
-    void *data = model->first(model);
+    void *data = list->first(list);
     int width = 0;
     while(data) {
-        int w = ui_add_icon_gadget(view->widget, view->modelinfo, data);
+        int w = ui_add_icon_gadget(view->widget, view->model, data);
         if(w > width) {
             width = w;
         }
-        data = model->next(model);
+        data = list->next(list);
     }
     
 }
 
 #define UI_COL_CHAR_WIDTH 12
 
-int ui_add_icon_gadget(Widget container, UiModelInfo *modelinfo, void *data) {
+int ui_add_icon_gadget(Widget container, UiModel *model, void *data) {
     int width = 50;
     
-    if(modelinfo->columns == 0) {
+    if(model->columns == 0) {
         return width;
     }
     
@@ -183,10 +187,10 @@
     Arg args[8];
     Boolean f;
     // first column
-    if(modelinfo->types[0] != 12345678) { // TODO: icon/label type
+    if(model->types[0] != 12345678) { // TODO: icon/label type
         char *str = ui_type_to_string(
-                modelinfo->types[0],
-                modelinfo->getvalue(data, 0),
+                model->types[0],
+                model->getvalue(data, 0),
                 &f);
         
         // column width
@@ -204,11 +208,11 @@
             
     // remaining columns are the icon gadget details
     XmStringTable details = (XmStringTable)XtMalloc(
-            (modelinfo->columns - 1) * sizeof(XmString));
-    for(int i=1;i<modelinfo->columns;i++) {
+            (model->columns - 1) * sizeof(XmString));
+    for(int i=1;i<model->columns;i++) {
         char *str = ui_type_to_string(
-                modelinfo->types[i],
-                modelinfo->getvalue(data, i),
+                model->types[i],
+                model->getvalue(data, i),
                 &f);
         
         // column width
@@ -220,7 +224,7 @@
         }
     }
     XtSetArg(args[1], XmNdetail, details);
-    XtSetArg(args[2], XmNdetailCount, modelinfo->columns - 1);
+    XtSetArg(args[2], XmNdetailCount, model->columns - 1);
     XtSetArg(args[3], XmNshadowThickness, 0); 
     // create widget
     Widget item = XmCreateIconGadget(container, "table_item", args, 4);
@@ -228,7 +232,7 @@
     
     // cleanup
     XmStringFree(label);
-    for(int i=0;i<modelinfo->columns-1;i++) {
+    for(int i=0;i<model->columns-1;i++) {
         XmStringFree(details[i]);
     }
     XtFree((char*)details);
--- a/ui/motif/tree.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/motif/tree.h	Sun Jul 01 19:03:26 2018 +0200
@@ -30,6 +30,7 @@
 #define	TREE_H
 
 #include "../ui/tree.h"
+#include "../common/context.h"
 
 #ifdef	__cplusplus
 extern "C" {
@@ -45,12 +46,12 @@
 
 typedef struct UiTableView {
     Widget      widget;
-    UiList      *list;
-    UiModelInfo *modelinfo;
+    UiVar       *var;
+    UiModel     *model;
 } UiTableView;
 
 void ui_table_update(UiEvent *event, UiTableView *view);
-int ui_add_icon_gadget(Widget container, UiModelInfo *modelinfo, void *data);
+int ui_add_icon_gadget(Widget container, UiModel *model, void *data);
 char* ui_type_to_string(UiModelType type, void *data, Boolean *free);
 
 void ui_table_action_callback(
--- a/ui/ui/container.h	Sun Jan 21 12:13:09 2018 +0100
+++ b/ui/ui/container.h	Sun Jul 01 19:03:26 2018 +0200
@@ -68,7 +68,6 @@
 
 
 
-
 #ifdef __cplusplus
 }
 #endif

mercurial