diff -r 42506e19eb6b -r 25e5390cce41 ui/common/context.c --- a/ui/common/context.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/context.c Tue Jul 22 09:51:17 2014 +0200 @@ -38,21 +38,104 @@ UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); + ctx->parent = NULL; ctx->mempool = mp; - + ctx->document = NULL; ctx->obj = toplevel; ctx->vars = ucx_map_new_a(mp->allocator, 16); ctx->groups = NULL; ctx->group_widgets = NULL; + ctx->set_document = uic_context_set_document; + ctx->detach_document = uic_context_detach_document; + #ifdef UI_GTK - ctx->accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); + if(toplevel->widget) { + ctx->accel_group = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); + } #endif return ctx; } +void uic_context_set_document(UiContext *ctx, void *document) { + UiContext *docctx = ui_document_context(document); + if(!docctx) { + return; + } + docctx->obj = ctx->obj; + + if(ctx->document) { + uic_context_detach_document(ctx, ctx->document); + } + //obj->document = document; + ctx->document = document; + + UcxMapIterator i = ucx_map_iterator(docctx->vars); + UiVar *var; + UCX_MAP_FOREACH(key, var, i) { + UiVar *v = ucx_map_get(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_move_var(v, var, 1); + var->from = v->from; + + // TODO: free var struct + ucx_map_remove(ctx->vars, key); + } + } +} + +void uic_context_detach_document(UiContext *ctx, void *document) { + UiContext *docctx = ui_document_context(document); + if(!docctx) { + fprintf( + stderr, + "UiError: ui_detach_document: document is not registered\n"); + return; + } + if(ctx->document != document) { + fprintf(stderr, "UiError: ui_detach_document: wrong document\n"); + return; + } + + UcxMapIterator i = ucx_map_iterator(docctx->vars); + UiVar *var; + UCX_MAP_FOREACH(key, var, i) { + if(var->from && var->from != docctx->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_move_var(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! + } + } + + docctx->obj->ctx->document = NULL; + + docctx->obj = NULL; +} + UiVar* uic_get_var(UiContext *ctx, char *name) { // check document variables first UiVar *var = NULL; @@ -133,7 +216,7 @@ UiText *t = to->value; char *tvalue = t->value; memcpy(t, f, sizeof(UiText)); - if(set) { + if(set && tvalue) { t->set(t, tvalue); } else { f->value = f->get(f); @@ -269,6 +352,55 @@ return 0; } +char* ui_getstr(UiObject *obj, char *name) { + UiVar *var = uic_get_var(obj->ctx, name); + if(var) { + if(var->type == UI_VAR_STRING) { + UiString *s = var->value; + if(s->get) { + return s->get(s); + } else { + fprintf( + stderr, + "UI Error: variable %s is not connected.\n", + name); + } + } else { + fprintf( + stderr, + "UI Error: requested variable %s is not an string.\n", + name); + } + } else { + fprintf(stderr, "UI Error: unkown variable %s.\n", name); + } + return NULL; +} + +char* ui_gettext(UiObject *obj, char *name) { + UiVar *var = uic_get_var(obj->ctx, name); + if(var) { + if(var->type == UI_VAR_TEXT) { + UiText *s = var->value; + if(s->get) { + return s->get(s); + } else { + fprintf( + stderr, + "UI Error: variable %s is not connected.\n", + name); + } + } else { + fprintf( + stderr, + "UI Error: requested variable %s is not an string.\n", + name); + } + } else { + fprintf(stderr, "UI Error: unkown variable %s.\n", name); + } + return NULL; +}