ui/common/context.c

changeset 52
25e5390cce41
parent 39
4e66271541e8
child 53
62205699cd0e
--- 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;
+}
 
 
 

mercurial