added support for replaceable documents

Fri, 21 Mar 2014 13:20:53 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 21 Mar 2014 13:20:53 +0100
changeset 2
eeb50c534497
parent 1
eb5269000bc8
child 3
c1a75454b444

added support for replaceable documents

application/main.c file | annotate | diff | comparison | revisions
ucx/mempool.c file | annotate | diff | comparison | revisions
ucx/mempool.h file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/common/document.c file | annotate | diff | comparison | revisions
ui/common/document.h file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/motif/menu.c file | annotate | diff | comparison | revisions
ui/motif/window.c file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/application/main.c	Fri Mar 21 13:20:53 2014 +0100
@@ -31,6 +31,15 @@
 
 #include <ui/ui.h>
 
+typedef struct TestDocument {
+    UiInteger check1;
+} TestDocument;
+
+typedef struct TestWindowData {
+    TestDocument *doc1;
+    TestDocument *doc2;
+} TestWindowData;
+
 UiInteger check1;
 
 void action_new(UiEvent *event, void *data) {
@@ -40,13 +49,29 @@
 }
 
 void action_open(UiEvent *event, void *data) {
-    printf("check1: %s\n", ui_window_getint(event->obj, "check1") ? "true" : "false");
+    //printf("check1: %s\n", ui_getint(event->obj, "check1") ? "true" : "false");
+    TestDocument *doc = event->document;
+    printf("check1: %s\n", ui_getval(doc->check1) ? "true" : "false");
 }
 
 void action_close(UiEvent *event, void *data) {
     exit(0);
 }
 
+void action_doc1(UiEvent *event, void *data) {
+    TestWindowData *wdata = event->window;
+    if(event->obj->document != wdata->doc1) {
+        ui_set_document(event->obj, wdata->doc1);
+    }
+}
+
+void action_doc2(UiEvent *event, void *data) {
+    TestWindowData *wdata = event->window;
+    if(event->obj->document != wdata->doc2) {
+        ui_set_document(event->obj, wdata->doc2);
+    }
+}
+
 int main(int argc, char** argv) {
     ui_init("app1", argc, argv);
     
@@ -54,12 +79,24 @@
     ui_menuitem("New", action_new, NULL);
     ui_menuitem("Open", action_open, NULL);
     ui_menuseparator();
+    ui_menuitem("Dokument 1", action_doc1, NULL);
+    ui_menuitem("Dokument 2", action_doc2, NULL);
+    ui_menuseparator();
     ui_checkitem_nv("Check", "check1");
     ui_menuitem("Close", action_close, NULL);
     
     UiObject *window = ui_window("Mod0", NULL);
+    TestWindowData *wdata = malloc(sizeof(TestWindowData));
+    window->window = wdata;
     
+    TestDocument *doc1 = ui_document_new(sizeof(TestDocument));
+    TestDocument *doc2 = ui_document_new(sizeof(TestDocument));
+    ui_document_regint(doc1, "check1", &doc1->check1);
+    ui_document_regint(doc2, "check1", &doc2->check1);
+    wdata->doc1 = doc1;
+    wdata->doc2 = doc2;
     
+    ui_set_document(window, doc1);
     
     //ui_window_addint(window, "check1");
     ui_show(window);
--- a/ucx/mempool.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ucx/mempool.c	Fri Mar 21 13:20:53 2014 +0100
@@ -75,6 +75,20 @@
     
     pool->ndata = 0;
     pool->size = n;
+    
+    UcxAllocator *allocator = (UcxAllocator*)malloc(sizeof(UcxAllocator));
+    if(!allocator) {
+        free(pool->data);
+        free(pool);
+        return NULL;
+    }
+    allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc;
+    allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc;
+    allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc;
+    allocator->free = (ucx_allocator_free)ucx_mempool_free;
+    allocator->pool = pool;
+    pool->allocator = allocator;
+    
     return pool;
 }
 
@@ -173,6 +187,7 @@
         }
     }
     free(pool->data);
+    free(pool->allocator);
     free(pool);
 }
 
@@ -189,16 +204,3 @@
     ucx_mempool_set_destr(rd, ucx_mempool_shared_destr);
 }
 
-UcxAllocator* ucx_mempool_allocator(UcxMempool *pool) {
-    UcxAllocator *allocator = (UcxAllocator*)ucx_mempool_malloc(
-            pool, sizeof(UcxAllocator));
-    if(!allocator) {
-        return NULL;
-    }
-    allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc;
-    allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc;
-    allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc;
-    allocator->free = (ucx_allocator_free)ucx_mempool_free;
-    allocator->pool = pool;
-    return allocator;
-}
--- a/ucx/mempool.h	Sun Dec 08 11:20:41 2013 +0000
+++ b/ucx/mempool.h	Fri Mar 21 13:20:53 2014 +0100
@@ -57,14 +57,17 @@
  * UCX mempool structure.
  */
 typedef struct {
+    /** UcxAllocator based on this pool */
+    UcxAllocator *allocator;
+    
     /** List of pointers to pooled memory. */
-    void   **data;
+    void         **data;
     
     /** Count of pooled memory items. */
-    size_t ndata;
+    size_t       ndata;
     
     /** Memory pool size. */
-    size_t size;
+    size_t       size;
 } UcxMempool;
 
 /** Shorthand for a new default memory pool with a capacity of 16 elements. */
@@ -210,14 +213,6 @@
  */
 void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr);
 
-/**
- * Creates an UcxAllocator based on an UcxMempool.
- * 
- * @param pool the mempool to create the UcxAllocator for
- * @return a new UcxAllocator based on the specified pool
- */
-UcxAllocator* ucx_mempool_allocator(UcxMempool *pool);
-
 #ifdef	__cplusplus
 }
 #endif
--- a/ui/common/context.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/common/context.c	Fri Mar 21 13:20:53 2014 +0100
@@ -32,80 +32,117 @@
 
 #include "context.h"
 #include "../ui/window.h"
+#include "document.h"
 
 
 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) {
     UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext));
-    UcxAllocator *allocator = ucx_mempool_allocator(mp);
     ctx->mempool = mp;
-    ctx->allocator = allocator;
     
     ctx->toplevel = toplevel;
-    ctx->vars = ucx_map_new_a(allocator, 16);
+    ctx->vars = ucx_map_new_a(mp->allocator, 16);
     
     return ctx;
 }
 
-UiVar* uic_getvar(UiObject *obj, char *name) {
-    if(!obj) {
-        return NULL;
+UiVar* uic_getvar(UiContext *ctx, char *name) {
+    // check document variables first
+    UiVar *var = uic_document_getvar(
+            uic_getdocument(ctx->toplevel->document),
+            name);
+    // check window vars
+    if(!var) {
+        var = ucx_map_cstr_get(ctx->vars, name);
     }
-    return ucx_map_cstr_get(obj->ctx->vars, name);
+    
+    return var;
 }
 
-void uic_rmvar(UiObject *obj, char *name) {
-    if(obj) {
-        UiVar *var = uic_getvar(obj, name);
-        if(var) {
-            if(var->isextern) {
-                ucx_mempool_free(obj->ctx->mempool, var->value);
-            }
-            ucx_mempool_free(obj->ctx->mempool, var);
+UiVar* uic_connect_var(UiContext *ctx, char *name, int type) {
+    // TODO: get current map
+    UcxMap *from = ctx->vars;
+    
+    UiVar *var = uic_getvar(ctx, name);
+    if(var) {
+        // the value is registered
+        
+        // a little type check
+        if(var->type != type) {
+            fprintf(stderr, "UI Error: var %s has incompatible type.\n", name);
+            return NULL;
+        } else {
+            // register the current document/wdata map
+            // if the document is closed, the var will be moved to this map
+            
+            // TODO: get current map
+            var->from = from;
+            
+            return var;
         }
+    } else {
+        // create an empty value and add it first to the window variables
+        // it can be moved to the document vars later
+        void *value = uic_create_value(ctx->mempool->allocator, type);
+        if(!value) {
+            fprintf(stderr, "UI Error: Cannot create empty value.\n");
+            return NULL;
+        }
+        UiVar *var = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar));
+        var->value = value;
+        var->type = type;
+        var->isextern = 0;
+        var->from = from;
+        ucx_map_cstr_put(ctx->vars, name, var);
+        return var;
     }
 }
 
-void ui_window_addint(UiObject *obj, char *name) {
-    if(uic_getvar(obj, name)) {
-        // var already exists
-        return;
+void* uic_create_value(UcxAllocator *a, int type) {
+    switch(type) {
+        case UI_VAR_INTEGER: {
+            UiInteger *i = a->calloc(
+                    a->pool,
+                    1,
+                    sizeof(UiInteger));
+            return i;
+        }
+        case UI_VAR_STRING: {
+            UiString *s = a->calloc(
+                    a->pool,
+                    1,
+                    sizeof(UiInteger));
+            return s;
+        }
     }
-    UiInteger *i = ucx_mempool_calloc(obj->ctx->mempool, 1, sizeof(UiInteger));
-    UiVar *var = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiVar));
-    var->value = i;
-    var->type = 1;
-    var->isextern = 0;
-    ucx_map_cstr_put(obj->ctx->vars, name, var);
+    return NULL;
 }
 
-void ui_window_regint(UiObject *obj, char *name, UiInteger *i) {
-    if(uic_getvar(obj, name)) {
-        // var already exists
-        return;
+
+
+// public API
+
+int ui_getint(UiObject *obj, char *name) {
+    UiVar *var = uic_getvar(obj->ctx, name);
+    if(var) {
+        if(var->type == UI_VAR_INTEGER) {
+            UiInteger *i = var->value;
+            if(i->get) {
+                return i->get(i);
+            } else {
+                fprintf(
+                        stderr,
+                        "UI Error: variable %s is not connected.\n",
+                        name);
+            }
+        } else {
+            fprintf(
+                    stderr,
+                    "UI Error: requested variable %s is not an integer.\n",
+                    name);
+        }
+    } else {
+        fprintf(stderr, "UI Error: unkown variable %s.\n", name);
     }
-    UiVar *var = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiVar));
-    var->value = i;
-    var->type = 1;
-    var->isextern = 1;
-    ucx_map_cstr_put(obj->ctx->vars, name, var);
+    return 0;
 }
 
-void ui_window_setint(UiObject *obj, char *name, int val) {
-    UiVar *var = uic_getvar(obj, name);
-    if(var && var->type == 1) {
-        UiInteger *i = var->value;
-        i->set(i, val);
-    } else {
-        // TODO: error message
-    }
-}
-
-int ui_window_getint(UiObject *obj, char *name) {
-    UiVar *var = uic_getvar(obj, name);
-    if(var && var->type == 1) {
-        UiInteger *i = var->value;
-        return i->get(i);
-    } else {
-        return 0; // TODO: error message
-    }
-}
--- a/ui/common/context.h	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/common/context.h	Fri Mar 21 13:20:53 2014 +0100
@@ -42,20 +42,25 @@
 struct UiContext {
     UiObject     *toplevel;
     UcxMempool   *mempool;
-    UcxAllocator *allocator;
     UcxMap       *vars; // key: char*  value: UiVar*
 };
 
 struct UiVar {
-    void *value;
-    int  type;
-    int  isextern;
+    void   *value;
+    int    type;
+    int    isextern;
+    UcxMap *from;
+};
+
+enum UiVarType {
+    UI_VAR_INTEGER = 0,
+    UI_VAR_STRING
 };
 
 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp);
-
-UiVar* uic_getvar(UiObject *obj, char *name);
-void uic_rmvar(UiObject *obj, char *name);
+UiVar* uic_getvar(UiContext *ctx, char *name);
+UiVar* uic_connect_var(UiContext *ctx, char *name, int type);
+void* uic_create_value(UcxAllocator *a, int type);
 
 
 #ifdef	__cplusplus
--- a/ui/common/document.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/common/document.c	Fri Mar 21 13:20:53 2014 +0100
@@ -38,13 +38,82 @@
     documents = ucx_map_new(32);
 }
 
-void* ui_document_create(UiObject *obj, size_t size) {
+void ui_set_document(UiObject *obj, void *document) {
+    UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
+    if(!doc) {
+        return;
+    }
+    doc->obj = obj;
+    
+    if(obj->document) {
+        ui_detach_document(obj, obj->document);
+    }
+    obj->document = document;
+    
+    UcxMapIterator i = ucx_map_iterator(doc->vars);
+    UiVar *var;
+    UCX_MAP_FOREACH(key, var, i) {
+        UiVar *v = ucx_map_get(obj->ctx->vars, key);
+        if(v) {
+            if(v->isextern) {
+                fprintf(
+                        stderr,
+                        "UI Error: external variable cannot be moved\n");
+                return;
+            }
+            // check type
+            if(var->type != v->type) {
+                fprintf(stderr, "UI Error: var has incompatible type.\n");
+                return;
+            }
+            
+            // copy value
+            uic_var_move(v, var, 1);
+            var->from = v->from;
+            
+            // TODO: free var struct
+            ucx_map_remove(obj->ctx->vars, key);
+        }
+    }
+    
+}
+
+void ui_detach_document(UiObject *obj, void *document) {
+    UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*)));
+    if(!doc) {
+        return;
+    }
+    
+    UcxMapIterator i = ucx_map_iterator(doc->vars);
+    UiVar *var;
+    UCX_MAP_FOREACH(key, var, i) {
+        if(var->from && var->from != doc->vars) {
+            // this var is bind to an outer widget, so we move it          
+            UcxAllocator *a = var->from->allocator;
+            UiVar *newvar = a->malloc(a->pool, sizeof(UiVar));
+            newvar->value = uic_create_value(a, var->type);
+            uic_var_move(var, newvar, 0);
+            newvar->type = var->type;
+            newvar->from = var->from;
+            newvar->isextern = 0;
+            
+            ucx_map_put(var->from, key, newvar);
+            
+            //ucx_map_remove(doc->vars, key); // TODO: dont remove!
+        }
+    }
+    
+    doc->obj->document = NULL;
+    doc->obj = NULL;
+}
+
+void* ui_document_new(size_t size) {
     UcxMempool *mp = ucx_mempool_new(256);
     UiDocument *uidoc = ucx_mempool_malloc(mp, sizeof(UiDocument));
-    uidoc->obj = obj;
-    uidoc->allocator = ucx_mempool_allocator(mp);
+    uidoc->obj = NULL;
     uidoc->mempool = mp;
-    uidoc->vars = ucx_map_new_a(uidoc->allocator, 16);
+    uidoc->vars = ucx_map_new_a(mp->allocator, 16);
+    uidoc->subdocument = NULL;
     
     void *document = ucx_mempool_calloc(mp, 1, size);
     ucx_map_put(documents, ucx_key(&document, sizeof(void*)), uidoc);
@@ -75,43 +144,119 @@
     return ucx_mempool_realloc(uidoc->mempool, ptr, size);
 }
 
+UiDocument* uic_getdocument(void *doc) {
+    return doc ? ucx_map_get(documents, ucx_key(&doc, sizeof(void*))) : NULL;
+}
 
 UiVar* uic_document_getvar(UiDocument *doc, char *name) {
-    return ucx_map_cstr_get(doc->vars, name);
+    return doc ? ucx_map_cstr_get(doc->vars, name) : NULL;
 }
 
-void ui_document_addint(void *doc, char *name) {
+void uic_document_addvar(void *doc, char *name, int type, size_t vs) {
     UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
     if(!uidoc) {
         return;
     }
     
-    UiVar *dvar = uic_document_getvar(uidoc, name);
-    UiVar *wvar = uic_getvar(uidoc->obj, name);
-    if(!dvar) {
-        UiVar *var = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
-        var->isextern = 0;
-        var->type = 1;
-        UiInteger *i = ucx_mempool_calloc(uidoc->mempool, 1, sizeof(UiVar));
-        if(wvar && !wvar->isextern) {
-            *i = *(UiInteger*)wvar->value;
+    UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
+    newvar->isextern = 0;
+    newvar->type = type;
+    newvar->value = ucx_mempool_calloc(uidoc->mempool, 1, vs);
+    newvar->from = NULL;
+    
+    uic_document_addvar_v(uidoc, name, newvar, type, vs);
+}
+
+void uic_document_addvar_v(
+        UiDocument *uidoc,
+        char *name,
+        UiVar *newvar,
+        int type,
+        size_t vs)
+{ 
+    // if the window context has this variable, we remove it and put it to
+    // the document vars
+    UiVar *var = uidoc->obj ?
+            ucx_map_cstr_get(uidoc->obj->ctx->vars, name) : NULL;
+    if(var) {
+        // external variables cannot be moved
+        if(var->isextern) {
+            fprintf(
+                    stderr,
+                    "UI Error: external variable %s "
+                    "cannot be moved to the document.\n",
+                    name);
+            return;
+        }
+        
+        // check type
+        if(var->type != type) {
+            fprintf(stderr, "UI Error: var %s has incompatible type.\n", name);
+            return;
+        }
+        
+        // override document var with window context var
+        memcpy(newvar->value, var->value, vs);
+        
+        newvar->from = var->from;
+        
+        // TODO: free var struct
+        ucx_map_cstr_remove(uidoc->obj->ctx->vars, name);
+    }
+    
+    // finally, add the new variable to the document
+    ucx_map_cstr_put(uidoc->vars, name, newvar);
+}
+
+void uic_document_regvar(
+        void *doc,
+        char *name, 
+        int type,
+        size_t vs,
+        void *value)
+{
+    UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*)));
+    if(!uidoc) {
+        return;
+    }
+    
+    UiVar *newvar = ucx_mempool_malloc(uidoc->mempool, sizeof(UiVar));
+    newvar->isextern = 1;
+    newvar->type = type;
+    newvar->value = value;
+    newvar->from = NULL;
+    
+    uic_document_addvar_v(uidoc, name, newvar, type, vs);
+}
+
+void uic_var_move(UiVar *from, UiVar *to, int set) {
+    switch(from->type) {
+        case UI_VAR_INTEGER: {
+            //memcpy(to->value, from->value, sizeof(UiInteger));
+            UiInteger *f = from->value;
+            UiInteger *t = to->value;
+            t->get = f->get;
+            t->set = f->set;
+            t->obj = f->obj; 
+            if(set) {
+                t->set(t, t->value);
+            } else {
+                //t->value = t->get(t);
+                //t->value = 0;
+            }
+            break;
+        }
+        case UI_VAR_STRING: {
+            break;
         }
     }
-    
-    if(wvar && wvar->isextern) {
-        fprintf(stderr, "UI Error: window variable moved to document!\n");
-    }
-    uic_rmvar(uidoc->obj, name);
+}
+
+void ui_document_addint(void *doc, char *name) {
+    uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger));
 }
 
 void ui_document_regint(void *doc, char *name, UiInteger *i) {
-    
+    uic_document_regvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger), i);
 }
 
-void ui_document_setint(void *doc, char *name, int val) {
-    
-}
-
-int  ui_document_getint(void *doc, char *name) {
-    
-}
--- a/ui/common/document.h	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/common/document.h	Fri Mar 21 13:20:53 2014 +0100
@@ -41,12 +41,29 @@
 struct UiDocument {
     UiObject     *obj;
     UcxMempool   *mempool;
-    UcxAllocator *allocator;
     UcxMap       *vars; // key: char*  value: UiVar*
+    void         *subdocument;
 };
 
 void uic_docmgr_init();
+UiDocument* uic_getdocument(void *doc);
 UiVar* uic_document_getvar(UiDocument *doc, char *name);
+void uic_document_addvar(void *doc, char *name, int type, size_t vs);
+void uic_document_addvar_v(
+        UiDocument *uidoc,
+        char *name,
+        UiVar *newvar,
+        int type,
+        size_t vs);
+void uic_document_regvar(
+        void *doc,
+        char *name, 
+        int type,
+        size_t vs,
+        void *value);
+
+void uic_var_move(UiVar *from, UiVar *to, int set);
+
 
 
 #ifdef	__cplusplus
--- a/ui/gtk/menu.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/gtk/menu.c	Fri Mar 21 13:20:53 2014 +0100
@@ -253,19 +253,15 @@
     GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label);
     gtk_menu_shell_append(GTK_MENU_SHELL(p), widget);
     
-    UiVar *var = uic_getvar(obj, ci->varname);
-    if(!var) {
-        ui_window_addint(obj, ci->varname);
-        var = uic_getvar(obj, ci->varname);
-    }
-    if(var->type == 1) {
+    UiVar *var = uic_connect_var(obj->ctx, ci->varname, UI_VAR_INTEGER);
+    if(var) {
         UiInteger *value = var->value;
         value->obj = widget;
         value->get = ui_checkitem_get;
         value->set = ui_checkitem_set;
         value = 0;
     } else {
-        // TODO: error message
+        // TODO: error
     }
 }
 
@@ -275,7 +271,7 @@
     UiEvent evt;
     evt.obj = event->obj;
     evt.window = event->obj->window;
-    evt.document = NULL;
+    evt.document = event->obj->document;
     evt.intval = 0;
     event->callback(&evt, event->user_data);    
 }
@@ -284,7 +280,7 @@
     UiEvent evt;
     evt.obj = event->obj;
     evt.window = event->obj->window;
-    evt.document = NULL;
+    evt.document = event->obj->document;
     evt.intval = gtk_check_menu_item_get_active(ci);
     event->callback(&evt, event->user_data);    
 }
--- a/ui/motif/menu.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/motif/menu.c	Fri Mar 21 13:20:53 2014 +0100
@@ -278,19 +278,15 @@
             2);
     XmStringFree(label);
     
-    UiVar *var = uic_getvar(obj, ci->varname);
-    if(!var) {
-        ui_window_addint(obj, ci->varname);
-        var = uic_getvar(obj, ci->varname);
-    }
-    if(var->type == 1) {
+    UiVar *var = uic_connect_var(obj->ctx, ci->varname, UI_VAR_INTEGER);
+    if(var) {
         UiInteger *value = var->value;
         value->obj = checkbox;
         value->get = ui_toggle_button_get;
         value->set = ui_toggle_button_set;
         value = 0;
     } else {
-        // TODO: error message
+        // TODO: error
     }
 }
 
@@ -300,7 +296,7 @@
     UiEvent e;
     e.obj = event->obj;
     e.window = event->obj->window;
-    // TODO: e.document
+    e.document = event->obj->document;
     e.intval = 0;
     event->callback(&e, event->user_data);    
 }
--- a/ui/motif/window.c	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/motif/window.c	Fri Mar 21 13:20:53 2014 +0100
@@ -89,7 +89,7 @@
             NULL);
     obj->widget = window;
     ui_create_menubar(obj);
-    
+      
     obj->widget = toplevel;
     nwindows++;
     return obj;
--- a/ui/ui/toolkit.h	Sun Dec 08 11:20:41 2013 +0000
+++ b/ui/ui/toolkit.h	Fri Mar 21 13:20:53 2014 +0100
@@ -70,9 +70,24 @@
 typedef void(*ui_callback)(UiEvent*, void*); // event, user data
 
 struct UiObject {
+    /*
+     * native widget
+     */
     UIWIDGET  widget;
+    
+    /*
+     * window context
+     */
     UiContext *ctx;
+    
+    /*
+     * user window data
+     */
     void      *window;
+    
+    /*
+     * current document
+     */
     void      *document;
 };
 
@@ -106,7 +121,10 @@
 void ui_main();
 void ui_show(UiObject *obj);
 
-void* ui_document_create(UiObject *obj, size_t size);
+void ui_set_document(UiObject *obj, void *document);
+void ui_detach_document(UiObject *obj, void *document);
+
+void* ui_document_new(size_t size);
 void  ui_document_destroy(void *doc);
 
 void* ui_document_malloc(void *doc, size_t size);
@@ -114,11 +132,16 @@
 void  ui_document_free(void *doc, void *ptr);
 void* ui_document_realloc(void *doc, void *ptr, size_t size);
 
+// TODO: remove (or not)
 void ui_document_addint(void *doc, char *name);
 void ui_document_regint(void *doc, char *name, UiInteger *i);
 void ui_document_setint(void *doc, char *name, int val);
 int  ui_document_getint(void *doc, char *name);
 
+// new:
+int ui_getint(UiObject *obj, char *name);
+
+
 
 #ifdef	__cplusplus
 }

mercurial