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;