ui/common/context.c

changeset 37
56016468753d
parent 33
458831c574f4
child 38
8ccdde37275b
--- 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;

mercurial