# HG changeset patch # User Olaf Wintermann # Date 1400162009 -7200 # Node ID 56016468753d9130db49b5faaf1f1ecb8e01e896 # Parent e4198fc2ead4977adc1ef99e10307db9eef2a63f refactored value binding system diff -r e4198fc2ead4 -r 56016468753d application/main.c --- a/application/main.c Sun May 11 11:35:33 2014 +0200 +++ b/application/main.c Thu May 15 15:53:29 2014 +0200 @@ -47,7 +47,7 @@ UiList *list; -/* +///* void action_new(UiEvent *event, void *data) { UiObject *window = ui_window("Mod1", NULL); @@ -162,7 +162,7 @@ ui_load_lang_def(NULL, "en_EN"); //ui_openfilefunc(action_new, NULL); - /* + ///* list = ui_list_new(); ui_list_append(list, "file1.txt"); ui_list_append(list, "hello.txt"); @@ -209,11 +209,11 @@ ui_toolbar_add_default("redo"); //*/ - ui_menu("File"); - ui_menuitem("New", NULL, NULL); - ui_menuitem("Close", NULL, NULL); - ui_menu("Edit"); - ui_menuitem("Preferences", NULL, NULL); + //ui_menu("File"); + //ui_menuitem("New", NULL, NULL); + //ui_menuitem("Close", NULL, NULL); + //ui_menu("Edit"); + //ui_menuitem("Preferences", NULL, NULL); printf("create window\n"); UiObject *window = ui_window("Mod0", NULL); @@ -230,7 +230,7 @@ ui_set_document(window, doc1); //ui_button(window, "OK", action_open, NULL); - //ui_textarea(window, &wdata->text); + ui_textarea(window, &wdata->text); //ui_window_addint(window, "check1"); ui_show(window); diff -r e4198fc2ead4 -r 56016468753d make/configure_gtk2.sh --- a/make/configure_gtk2.sh Sun May 11 11:35:33 2014 +0200 +++ b/make/configure_gtk2.sh Thu May 15 15:53:29 2014 +0200 @@ -28,7 +28,7 @@ TK_CFLAGS="-DUI_GTK2 `pkg-config --cflags gtk+-2.0 libxml-2.0`" -TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` +TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread cat >> config.mk << __EOF__ diff -r e4198fc2ead4 -r 56016468753d make/configure_gtk2legacy.sh --- a/make/configure_gtk2legacy.sh Sun May 11 11:35:33 2014 +0200 +++ b/make/configure_gtk2legacy.sh Thu May 15 15:53:29 2014 +0200 @@ -29,7 +29,7 @@ TK_CFLAGS="-DUI_GTK2 -DUI_GTK2LEGACY " TK_CFLAGS="$TK_CFLAGS `pkg-config --cflags gtk+-2.0 libxml-2.0`" -TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` +TK_LDFLAGS=`pkg-config --libs gtk+-2.0 libxml-2.0` -lpthread cat >> config.mk << __EOF__ diff -r e4198fc2ead4 -r 56016468753d make/configure_gtk3.sh --- a/make/configure_gtk3.sh Sun May 11 11:35:33 2014 +0200 +++ b/make/configure_gtk3.sh Thu May 15 15:53:29 2014 +0200 @@ -28,7 +28,7 @@ TK_CFLAGS="-DUI_GTK3 `pkg-config --cflags gtk+-3.0 libxml-2.0`" -TK_LDFLAGS=`pkg-config --libs gtk+-3.0 libxml-2.0` +TK_LDFLAGS="`pkg-config --libs gtk+-3.0 libxml-2.0` -lpthread" cat >> config.mk << __EOF__ diff -r e4198fc2ead4 -r 56016468753d make/configure_motif.sh --- a/make/configure_motif.sh Sun May 11 11:35:33 2014 +0200 +++ b/make/configure_motif.sh Thu May 15 15:53:29 2014 +0200 @@ -26,9 +26,9 @@ # POSSIBILITY OF SUCH DAMAGE. # -TK_CFLAGS="-DUI_MOTIF `pkg-config --cflags libxml-2.0`" +TK_CFLAGS="-DUI_MOTIF " -TK_LDFLAGS="`pkg-config --libs libxml-2.0` -lXm -lXt -lX11" +TK_LDFLAGS="-lXm -lXt -lX11 -lpthread" cat >> config.mk << __EOF__ diff -r e4198fc2ead4 -r 56016468753d ui/common/context.c --- a/ui/common/context.c Sun May 11 11:35:33 2014 +0200 +++ b/ui/common/context.c Thu May 15 15:53:29 2014 +0200 @@ -40,7 +40,7 @@ UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); ctx->mempool = mp; - ctx->toplevel = toplevel; + ctx->obj = toplevel; ctx->vars = ucx_map_new_a(mp->allocator, 16); ctx->groups = NULL; ctx->group_widgets = NULL; @@ -53,12 +53,15 @@ return ctx; } -UiVar* uic_getvar(UiContext *ctx, char *name) { +UiVar* uic_get_var(UiContext *ctx, char *name) { // check document variables first - UiVar *var = uic_document_getvar( - uic_getdocument(ctx->toplevel->document), - name); - // check window vars + UiVar *var = NULL; + UiContext *doc_ctx = ui_document_context(ctx->document); + if(doc_ctx) { + var = uic_get_var(doc_ctx, name); + } + + // check variables of this context if(!var) { var = ucx_map_cstr_get(ctx->vars, name); } @@ -67,10 +70,10 @@ } UiVar* uic_connect_var(UiContext *ctx, char *name, int type) { - // TODO: get current map + // TODO: get current map (Document Container, Tabbed Pane) UcxMap *from = ctx->vars; - UiVar *var = uic_getvar(ctx, name); + UiVar *var = uic_get_var(ctx, name); if(var) { // the value is registered @@ -103,6 +106,107 @@ } } +void uic_move_var(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); + f->value = f->get(f); + //t->value = 0; + } + break; + } + case UI_VAR_STRING: { + // TODO + break; + } + case UI_VAR_TEXT: { + UiText *f = from->value; + UiText *t = to->value; + char *tvalue = t->value; + memcpy(t, f, sizeof(UiText)); + if(set) { + t->set(t, tvalue); + } else { + f->value = f->get(f); + } + break; + } + case UI_VAR_LIST: { + UiListVar *f = from->value; + UiListVar *t = to->value; + UiList *list = t->listptr->list; + UiObserver *observers = f->listptr->list->observers; + t->listptr = f->listptr; + if(set) { + t->listptr->list = list; + list->observers = observers; + ui_notify(observers, list); + } + break; + } + } +} + +void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value) { + UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar)); + newvar->isextern = 1; + newvar->type = type; + newvar->value = value; + newvar->from = NULL; + + uic_add_var(ctx, name, newvar, type, vs); +} + +void uic_add_var( + UiContext *ctx, + char *name, + UiVar *newvar, + int type, + size_t vs) +{ + // if a parent context has a variable with this name, we remove it and put + // it to this context + UiVar *var = ctx->obj ? uic_get_var(ctx->obj->ctx, name) : NULL; + + if(var && var->from != ctx->vars) { + // 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(var->from, name); + } + + // finally, add the new variable to the document + ucx_map_cstr_put(ctx->vars, name, newvar); +} + void* uic_create_value(UcxAllocator *a, int type) { switch(type) { case UI_VAR_INTEGER: { @@ -138,12 +242,10 @@ return NULL; } - - // public API int ui_getint(UiObject *obj, char *name) { - UiVar *var = uic_getvar(obj->ctx, name); + UiVar *var = uic_get_var(obj->ctx, name); if(var) { if(var->type == UI_VAR_INTEGER) { UiInteger *i = var->value; diff -r e4198fc2ead4 -r 56016468753d ui/common/context.h --- a/ui/common/context.h Sun May 11 11:35:33 2014 +0200 +++ b/ui/common/context.h Thu May 15 15:53:29 2014 +0200 @@ -44,9 +44,10 @@ typedef struct UiGroupWidget UiGroupWidget; struct UiContext { - UiObject *toplevel; + UiObject *obj; UcxMempool *mempool; UcxMap *vars; // key: char* value: UiVar* + void *document; UcxList *groups; // int list UcxList *group_widgets; // UiGroupWidget* list @@ -84,8 +85,17 @@ }; UiContext* uic_context(UiObject *toplevel, UcxMempool *mp); -UiVar* uic_getvar(UiContext *ctx, char *name); +UiVar* uic_get_var(UiContext *ctx, char *name); UiVar* uic_connect_var(UiContext *ctx, char *name, int type); +void uic_move_var(UiVar *from, UiVar *to, int set); +void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value); +void uic_add_var( + UiContext *ctx, + char *name, + UiVar *newvar, + int type, + size_t vs); + void* uic_create_value(UcxAllocator *a, int type); void uic_check_group_widgets(UiContext *ctx); diff -r e4198fc2ead4 -r 56016468753d ui/common/document.c --- a/ui/common/document.c Sun May 11 11:35:33 2014 +0200 +++ b/ui/common/document.c Thu May 15 15:53:29 2014 +0200 @@ -39,18 +39,19 @@ } void ui_set_document(UiObject *obj, void *document) { - UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); - if(!doc) { + UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); + if(!ctx) { return; } - doc->obj = obj; + ctx->obj = obj; if(obj->document) { ui_detach_document(obj, obj->document); } obj->document = document; + obj->ctx->document = document; - UcxMapIterator i = ucx_map_iterator(doc->vars); + UcxMapIterator i = ucx_map_iterator(ctx->vars); UiVar *var; UCX_MAP_FOREACH(key, var, i) { UiVar *v = ucx_map_get(obj->ctx->vars, key); @@ -68,7 +69,7 @@ } // copy value - uic_var_move(v, var, 1); + uic_move_var(v, var, 1); var->from = v->from; // TODO: free var struct @@ -79,20 +80,27 @@ } void ui_detach_document(UiObject *obj, void *document) { - UiDocument *doc = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); - if(!doc) { + UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); + if(!ctx) { + fprintf( + stderr, + "UiError: ui_detach_document: document is not registered\n"); + return; + } + if(obj->document != document) { + fprintf(stderr, "UiError: ui_detach_document: wrong document\n"); return; } - UcxMapIterator i = ucx_map_iterator(doc->vars); + UcxMapIterator i = ucx_map_iterator(ctx->vars); UiVar *var; UCX_MAP_FOREACH(key, var, i) { - if(var->from && var->from != doc->vars) { + if(var->from && var->from != ctx->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); + uic_move_var(var, newvar, 0); newvar->type = var->type; newvar->from = var->from; newvar->isextern = 0; @@ -103,20 +111,22 @@ } } - doc->obj->document = NULL; - doc->obj = NULL; + ctx->obj->document = NULL; + ctx->obj->ctx->document = NULL; + + ctx->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 = NULL; - uidoc->mempool = mp; - uidoc->vars = ucx_map_new_a(mp->allocator, 16); - uidoc->subdocument = NULL; + UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); + ctx->obj = NULL; + ctx->mempool = mp; + ctx->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); + ucx_map_put(documents, ucx_key(&document, sizeof(void*)), ctx); return document; } @@ -124,158 +134,45 @@ // TODO } +UiContext* ui_document_context(void *doc) { + if(doc) { + return ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); + } else { + return NULL; + } +} + void* ui_document_malloc(void *doc, size_t size) { - UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); + UiContext *uidoc = ui_document_context(doc); return ucx_mempool_malloc(uidoc->mempool, size); } void* ui_document_calloc(void *doc, size_t nelem, size_t elsize) { - UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); + UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); return ucx_mempool_calloc(uidoc->mempool, nelem, elsize); } void ui_document_free(void *doc, void *ptr) { - UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); + UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); ucx_mempool_free(uidoc->mempool, ptr); } void* ui_document_realloc(void *doc, void *ptr, size_t size) { - UiDocument *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); + UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); 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 doc ? ucx_map_cstr_get(doc->vars, name) : NULL; -} - 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 *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); -} + // TODO: remove + UiContext *ctx = ui_document_context(doc); + if(ctx) { + UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar)); + newvar->isextern = 0; + newvar->type = type; + newvar->value = ucx_mempool_calloc(ctx->mempool, 1, vs); + newvar->from = NULL; -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); - f->value = f->get(f); - //t->value = 0; - } - break; - } - case UI_VAR_STRING: { - // TODO - break; - } - case UI_VAR_TEXT: { - UiText *f = from->value; - UiText *t = to->value; - char *tvalue = t->value; - memcpy(t, f, sizeof(UiText)); - if(set) { - t->set(t, tvalue); - } else { - f->value = f->get(f); - } - break; - } - case UI_VAR_LIST: { - UiListVar *f = from->value; - UiListVar *t = to->value; - UiList *list = t->listptr->list; - UiObserver *observers = f->listptr->list->observers; - t->listptr = f->listptr; - if(set) { - t->listptr->list = list; - list->observers = observers; - ui_notify(observers, list); - } - break; - } + uic_add_var(ctx, name, newvar, type, vs); } } @@ -283,18 +180,29 @@ 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); + UiContext *ctx = ui_document_context(doc); + if(ctx) { + uic_reg_var(ctx, name, UI_VAR_INTEGER, sizeof(UiInteger), i); + } } void ui_document_regtext(void *doc, char *name, UiText *text) { - uic_document_regvar(doc, name, UI_VAR_TEXT, sizeof(UiText), text); + UiContext *ctx = ui_document_context(doc); + if(ctx) { + uic_reg_var(doc, name, UI_VAR_TEXT, sizeof(UiText), text); + } } void ui_document_reglist(void *doc, char *name, UiList *list) { - UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar)); - UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); - lv->listptr = lp; - lp->list = list; - uic_document_regvar(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv); + UiContext *ctx = ui_document_context(doc); + if(ctx) { + UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar)); + UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); + lv->listptr = lp; + lp->list = list; + uic_reg_var(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv); + } } diff -r e4198fc2ead4 -r 56016468753d ui/common/document.h --- a/ui/common/document.h Sun May 11 11:35:33 2014 +0200 +++ b/ui/common/document.h Thu May 15 15:53:29 2014 +0200 @@ -36,33 +36,14 @@ extern "C" { #endif -typedef struct UiDocument UiDocument; - -struct UiDocument { - UiObject *obj; - UcxMempool *mempool; - 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, + UiContext *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); diff -r e4198fc2ead4 -r 56016468753d ui/ui/toolkit.h --- a/ui/ui/toolkit.h Sun May 11 11:35:33 2014 +0200 +++ b/ui/ui/toolkit.h Thu May 15 15:53:29 2014 +0200 @@ -218,6 +218,8 @@ void* ui_document_new(size_t size); void ui_document_destroy(void *doc); +UiContext* ui_document_context(void *doc); + void* ui_document_malloc(void *doc, size_t size); void* ui_document_calloc(void *doc, size_t nelem, size_t elsize); void ui_document_free(void *doc, void *ptr);