36 #include "document.h" |
36 #include "document.h" |
37 |
37 |
38 |
38 |
39 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { |
39 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { |
40 UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); |
40 UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); |
|
41 ctx->parent = NULL; |
41 ctx->mempool = mp; |
42 ctx->mempool = mp; |
42 |
43 ctx->document = NULL; |
43 ctx->obj = toplevel; |
44 ctx->obj = toplevel; |
44 ctx->vars = ucx_map_new_a(mp->allocator, 16); |
45 ctx->vars = ucx_map_new_a(mp->allocator, 16); |
45 ctx->groups = NULL; |
46 ctx->groups = NULL; |
46 ctx->group_widgets = NULL; |
47 ctx->group_widgets = NULL; |
47 |
48 |
|
49 ctx->set_document = uic_context_set_document; |
|
50 ctx->detach_document = uic_context_detach_document; |
|
51 |
48 #ifdef UI_GTK |
52 #ifdef UI_GTK |
49 ctx->accel_group = gtk_accel_group_new(); |
53 if(toplevel->widget) { |
50 gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); |
54 ctx->accel_group = gtk_accel_group_new(); |
|
55 gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); |
|
56 } |
51 #endif |
57 #endif |
52 |
58 |
53 return ctx; |
59 return ctx; |
|
60 } |
|
61 |
|
62 void uic_context_set_document(UiContext *ctx, void *document) { |
|
63 UiContext *docctx = ui_document_context(document); |
|
64 if(!docctx) { |
|
65 return; |
|
66 } |
|
67 docctx->obj = ctx->obj; |
|
68 |
|
69 if(ctx->document) { |
|
70 uic_context_detach_document(ctx, ctx->document); |
|
71 } |
|
72 //obj->document = document; |
|
73 ctx->document = document; |
|
74 |
|
75 UcxMapIterator i = ucx_map_iterator(docctx->vars); |
|
76 UiVar *var; |
|
77 UCX_MAP_FOREACH(key, var, i) { |
|
78 UiVar *v = ucx_map_get(ctx->vars, key); |
|
79 if(v) { |
|
80 if(v->isextern) { |
|
81 fprintf( |
|
82 stderr, |
|
83 "UI Error: external variable cannot be moved\n"); |
|
84 return; |
|
85 } |
|
86 // check type |
|
87 if(var->type != v->type) { |
|
88 fprintf(stderr, "UI Error: var has incompatible type.\n"); |
|
89 return; |
|
90 } |
|
91 |
|
92 // copy value |
|
93 uic_move_var(v, var, 1); |
|
94 var->from = v->from; |
|
95 |
|
96 // TODO: free var struct |
|
97 ucx_map_remove(ctx->vars, key); |
|
98 } |
|
99 } |
|
100 } |
|
101 |
|
102 void uic_context_detach_document(UiContext *ctx, void *document) { |
|
103 UiContext *docctx = ui_document_context(document); |
|
104 if(!docctx) { |
|
105 fprintf( |
|
106 stderr, |
|
107 "UiError: ui_detach_document: document is not registered\n"); |
|
108 return; |
|
109 } |
|
110 if(ctx->document != document) { |
|
111 fprintf(stderr, "UiError: ui_detach_document: wrong document\n"); |
|
112 return; |
|
113 } |
|
114 |
|
115 UcxMapIterator i = ucx_map_iterator(docctx->vars); |
|
116 UiVar *var; |
|
117 UCX_MAP_FOREACH(key, var, i) { |
|
118 if(var->from && var->from != docctx->vars) { |
|
119 // this var is bind to an outer widget, so we move it |
|
120 UcxAllocator *a = var->from->allocator; |
|
121 UiVar *newvar = a->malloc(a->pool, sizeof(UiVar)); |
|
122 newvar->value = uic_create_value(a, var->type); |
|
123 uic_move_var(var, newvar, 0); |
|
124 newvar->type = var->type; |
|
125 newvar->from = var->from; |
|
126 newvar->isextern = 0; |
|
127 |
|
128 ucx_map_put(var->from, key, newvar); |
|
129 |
|
130 //ucx_map_remove(doc->vars, key); // TODO: dont remove! |
|
131 } |
|
132 } |
|
133 |
|
134 docctx->obj->ctx->document = NULL; |
|
135 |
|
136 docctx->obj = NULL; |
54 } |
137 } |
55 |
138 |
56 UiVar* uic_get_var(UiContext *ctx, char *name) { |
139 UiVar* uic_get_var(UiContext *ctx, char *name) { |
57 // check document variables first |
140 // check document variables first |
58 UiVar *var = NULL; |
141 UiVar *var = NULL; |
267 fprintf(stderr, "UI Error: unkown variable %s.\n", name); |
350 fprintf(stderr, "UI Error: unkown variable %s.\n", name); |
268 } |
351 } |
269 return 0; |
352 return 0; |
270 } |
353 } |
271 |
354 |
|
355 char* ui_getstr(UiObject *obj, char *name) { |
|
356 UiVar *var = uic_get_var(obj->ctx, name); |
|
357 if(var) { |
|
358 if(var->type == UI_VAR_STRING) { |
|
359 UiString *s = var->value; |
|
360 if(s->get) { |
|
361 return s->get(s); |
|
362 } else { |
|
363 fprintf( |
|
364 stderr, |
|
365 "UI Error: variable %s is not connected.\n", |
|
366 name); |
|
367 } |
|
368 } else { |
|
369 fprintf( |
|
370 stderr, |
|
371 "UI Error: requested variable %s is not an string.\n", |
|
372 name); |
|
373 } |
|
374 } else { |
|
375 fprintf(stderr, "UI Error: unkown variable %s.\n", name); |
|
376 } |
|
377 return NULL; |
|
378 } |
|
379 |
|
380 char* ui_gettext(UiObject *obj, char *name) { |
|
381 UiVar *var = uic_get_var(obj->ctx, name); |
|
382 if(var) { |
|
383 if(var->type == UI_VAR_TEXT) { |
|
384 UiText *s = var->value; |
|
385 if(s->get) { |
|
386 return s->get(s); |
|
387 } else { |
|
388 fprintf( |
|
389 stderr, |
|
390 "UI Error: variable %s is not connected.\n", |
|
391 name); |
|
392 } |
|
393 } else { |
|
394 fprintf( |
|
395 stderr, |
|
396 "UI Error: requested variable %s is not an string.\n", |
|
397 name); |
|
398 } |
|
399 } else { |
|
400 fprintf(stderr, "UI Error: unkown variable %s.\n", name); |
|
401 } |
|
402 return NULL; |
|
403 } |
272 |
404 |
273 |
405 |
274 |
406 |
275 void ui_set_group(UiContext *ctx, int group) { |
407 void ui_set_group(UiContext *ctx, int group) { |
276 if(ucx_list_find(ctx->groups, (void*)(intptr_t)group, NULL, NULL) == -1) { |
408 if(ucx_list_find(ctx->groups, (void*)(intptr_t)group, NULL, NULL) == -1) { |