ui/common/context.c

changeset 115
e57ca2747782
parent 113
dde28a806552
equal deleted inserted replaced
114:3da24640513a 115:e57ca2747782
62 ctx->destroy_handler = cxArrayListCreate(ctx->allocator, NULL, sizeof(UiDestroyHandler), 16); 62 ctx->destroy_handler = cxArrayListCreate(ctx->allocator, NULL, sizeof(UiDestroyHandler), 16);
63 ctx->obj = toplevel; 63 ctx->obj = toplevel;
64 ctx->vars = cxHashMapCreate(mp->allocator, CX_STORE_POINTERS, 16); 64 ctx->vars = cxHashMapCreate(mp->allocator, CX_STORE_POINTERS, 16);
65 65
66 ctx->documents = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, CX_STORE_POINTERS); 66 ctx->documents = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, CX_STORE_POINTERS);
67 ctx->group_widgets = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, sizeof(UiGroupWidget)); 67 ctx->state_widgets = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, sizeof(UiStateWidget));
68 ctx->groups = cxArrayListCreate(mp->allocator, cx_cmp_int, sizeof(int), 32); 68 ctx->states = cxArrayListCreate(mp->allocator, cx_cmp_int, sizeof(int), 32);
69 69
70 ctx->attach_document = uic_context_attach_document; 70 ctx->attach_document = uic_context_attach_document;
71 ctx->detach_document2 = uic_context_detach_document; 71 ctx->detach_document2 = uic_context_detach_document;
72 72
73 #if UI_GTK2 || UI_GTK3 73 #if UI_GTK2 || UI_GTK3
90 handler.data = data; 90 handler.data = data;
91 cxListAdd(ctx->destroy_handler, &handler); 91 cxListAdd(ctx->destroy_handler, &handler);
92 } 92 }
93 93
94 void uic_context_prepare_close(UiContext *ctx) { 94 void uic_context_prepare_close(UiContext *ctx) {
95 cxListClear(ctx->groups); 95 cxListClear(ctx->states);
96 cxListClear(ctx->group_widgets); 96 cxListClear(ctx->state_widgets);
97 } 97 }
98 98
99 void uic_context_attach_document(UiContext *ctx, void *document) { 99 void uic_context_attach_document(UiContext *ctx, void *document) {
100 if(ctx->single_document_mode) {
101 if(ctx->document) {
102 uic_context_detach_document(ctx, ctx->document);
103 }
104 }
105
100 cxListAdd(ctx->documents, document); 106 cxListAdd(ctx->documents, document);
101 ctx->document = document; 107 ctx->document = document;
102 108
103 UiContext *doc_ctx = ui_document_context(document); 109 UiContext *doc_ctx = ui_document_context(document);
104 doc_ctx->parent = ctx; 110 doc_ctx->parent = ctx;
112 printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data); 118 printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
113 UiVar *var = entry->value; 119 UiVar *var = entry->value;
114 UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key); 120 UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key);
115 if(docvar) { 121 if(docvar) {
116 // bind var to document var 122 // bind var to document var
117 uic_copy_binding(var, docvar, TRUE); 123 uic_copy_var_binding(var, docvar, TRUE);
118 cxIteratorFlagRemoval(i); 124 cxIteratorFlagRemoval(i);
119 } 125 }
120 } 126 }
121 127
122 var_ctx = var_ctx->parent; 128 var_ctx = var_ctx->parent;
123 } 129 }
124 } 130 }
125 131
126 static void uic_context_unbind_vars(UiContext *ctx) { 132 static void uic_context_unbind_vars(UiContext *ctx) {
133 ui_onchange_events_enable(FALSE);
127 CxMapIterator mi = cxMapIterator(ctx->vars); 134 CxMapIterator mi = cxMapIterator(ctx->vars);
128 cx_foreach(CxMapEntry*, entry, mi) { 135 cx_foreach(CxMapEntry*, entry, mi) {
136 printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
129 UiVar *var = entry->value; 137 UiVar *var = entry->value;
130 // var->from && var->from_ctx && var->from_ctx != ctx 138 // var->from && var->from_ctx && var->from_ctx != ctx
131 uic_save_var(var); 139 uic_save_var(var);
132 if(var->from) { 140 if(var->from) {
133 uic_copy_binding(var, var->from, FALSE); 141 uic_copy_var_binding(var, var->from, FALSE);
134 cxMapPut(var->from->from_ctx->vars, *entry->key, var->from); 142 cxMapPut(var->from->from_ctx->vars, *entry->key, var->from);
135 var->from = NULL; 143 var->from = NULL;
136 } 144 }
145 uic_unbind_var(var);
137 } 146 }
138 147
139 if(ctx->documents) { 148 if(ctx->documents) {
140 CxIterator i = cxListIterator(ctx->documents); 149 CxIterator i = cxListIterator(ctx->documents);
141 cx_foreach(void *, doc, i) { 150 cx_foreach(void *, doc, i) {
142 UiContext *subctx = ui_document_context(doc); 151 UiContext *subctx = ui_document_context(doc);
143 uic_context_unbind_vars(subctx); 152 uic_context_unbind_vars(subctx);
144 } 153 }
145 } 154 }
155
156 ui_onchange_events_enable(TRUE);
146 } 157 }
147 158
148 void uic_context_detach_document(UiContext *ctx, void *document) { 159 void uic_context_detach_document(UiContext *ctx, void *document) {
149 // find the document in the documents list 160 // find the document in the documents list
150 size_t docIndex = cxListFind(ctx->documents, document); 161 size_t docIndex = cxListFind(ctx->documents, document);
195 UiVar* uic_get_var(UiContext *ctx, const char *name) { 206 UiVar* uic_get_var(UiContext *ctx, const char *name) {
196 CxHashKey key = cx_hash_key(name, strlen(name)); 207 CxHashKey key = cx_hash_key(name, strlen(name));
197 return ctx_getvar(ctx, key); 208 return ctx_getvar(ctx, key);
198 } 209 }
199 210
211 UiVar* uic_get_var_t(UiContext *ctx,const char *name, UiVarType type) {
212 UiVar *var = uic_get_var(ctx, name);
213 if(var && var->type == type) {
214 return var;
215 }
216 return NULL;
217 }
218
200 UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type) { 219 UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type) {
201 UiVar *var = uic_get_var(ctx, name); 220 UiVar *var = uic_get_var(ctx, name);
202 if(var) { 221 if(var) {
203 if(var->type == type) { 222 if(var->type == type) {
204 return var; 223 return var;
211 var->type = type; 230 var->type = type;
212 var->value = uic_create_value(ctx, type); 231 var->value = uic_create_value(ctx, type);
213 var->original_value = NULL; 232 var->original_value = NULL;
214 var->from = NULL; 233 var->from = NULL;
215 var->from_ctx = ctx; 234 var->from_ctx = ctx;
216 235 var->bound = FALSE;
217 cxMempoolSetDestructor(var, (cx_destructor_func)uic_unbind_var); 236
237 cxMempoolSetDestructor(var, (cx_destructor_func)uic_unbind_var); // TODO: use another destructor that cleans the value (UiString free, UiText destroy, ...)
218 238
219 cxMapPut(ctx->vars, name, var); 239 cxMapPut(ctx->vars, name, var);
220 240
221 return var; 241 return var;
222 } 242 }
264 } 284 }
265 } 285 }
266 return val; 286 return val;
267 } 287 }
268 288
289 // destroys a value, that was created by uic_create_value
290 void uic_destroy_value(UiContext *ctx, UiVarType type, void *value) {
291 switch(type) {
292 default: {
293 ui_free(ctx, value);
294 break;
295 }
296 case UI_VAR_SPECIAL: break;
297 case UI_VAR_STRING: {
298 UiString *s = value;
299 if(s->value.free) {
300 s->value.free(s->value.ptr);
301 }
302 ui_free(ctx, value);
303 }
304 case UI_VAR_TEXT: {
305 UiText *t = value;
306 if(t->value.free) {
307 t->value.free(t->value.ptr);
308 t->value.free = NULL;
309 t->value.ptr = NULL;
310 }
311 if(t->destroy) {
312 t->destroy(t);
313 }
314 ui_free(ctx, value);
315 }
316 case UI_VAR_LIST: {
317 ui_list_free(ctx, value);
318 break;
319 }
320 }
321 }
322
269 323
270 UiVar* uic_widget_var(UiContext *toplevel, UiContext *current, void *value, const char *varname, UiVarType type) { 324 UiVar* uic_widget_var(UiContext *toplevel, UiContext *current, void *value, const char *varname, UiVarType type) {
271 if (value) { 325 if (value) {
272 return uic_create_value_var(current, value); 326 return uic_create_value_var(current, value);
273 } 327 }
276 } 330 }
277 return NULL; 331 return NULL;
278 } 332 }
279 333
280 334
281 void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc) { 335 void uic_copy_var_binding(UiVar *from, UiVar *to, UiBool copytodoc) {
282 // check type 336 // check type
283 if(from->type != to->type) { 337 if(from->type != to->type) {
284 fprintf(stderr, "UI Error: var has incompatible type.\n"); 338 fprintf(stderr, "UI Error: var has incompatible type.\n");
285 return; 339 return;
286 } 340 }
299 to->value = to->original_value; 353 to->value = to->original_value;
300 tovalue = to->value; 354 tovalue = to->value;
301 } 355 }
302 } 356 }
303 357
304 ui_setop_enable(TRUE); 358 uic_copy_value_binding(from->type, fromvalue, tovalue);
359 }
360
361 void uic_copy_value_binding(UiVarType type, void *from, void *to) {
362 ui_setop_enable(TRUE);
305 363
306 // copy binding 364 // copy binding
307 // we don't copy the observer, because the from var has never one 365 // we don't copy the observer, because the from value never has oberservers
308 switch(from->type) { 366 switch(type) {
309 default: fprintf(stderr, "uic_copy_binding: wtf!\n"); break; 367 default: fprintf(stderr, "uic_copy_binding: wtf!\n"); break;
310 case UI_VAR_SPECIAL: break; 368 case UI_VAR_SPECIAL: break;
311 case UI_VAR_INTEGER: { 369 case UI_VAR_INTEGER: {
312 UiInteger *f = fromvalue; 370 UiInteger *f = from;
313 UiInteger *t = tovalue; 371 UiInteger *t = to;
314 if(!f->obj) break; 372 if(!f->obj) break;
315 uic_int_copy(f, t); 373 uic_int_copy(f, t);
316 t->set(t, t->value); 374 t->set(t, t->value);
317 break; 375 break;
318 } 376 }
319 case UI_VAR_DOUBLE: { 377 case UI_VAR_DOUBLE: {
320 UiDouble *f = fromvalue; 378 UiDouble *f = from;
321 UiDouble *t = tovalue; 379 UiDouble *t = to;
322 if(!f->obj) break; 380 if(!f->obj) break;
323 uic_double_copy(f, t); 381 uic_double_copy(f, t);
324 t->set(t, t->value); 382 t->set(t, t->value);
325 break; 383 break;
326 } 384 }
327 case UI_VAR_STRING: { 385 case UI_VAR_STRING: {
328 UiString *f = fromvalue; 386 UiString *f = from;
329 UiString *t = tovalue; 387 UiString *t = to;
330 if(!f->obj) break; 388 if(!f->obj) break;
331 uic_string_copy(f, t); 389 uic_string_copy(f, t);
332 char *tvalue = t->value.ptr ? t->value.ptr : ""; 390 char *tvalue = t->value.ptr ? t->value.ptr : "";
333 char *fvalue = f->value.ptr ? f->value.ptr : ""; 391 char *fvalue = f->value.ptr ? f->value.ptr : "";
334 t->set(t, tvalue); 392 t->set(t, tvalue);
335 break; 393 break;
336 } 394 }
337 case UI_VAR_TEXT: { 395 case UI_VAR_TEXT: {
338 UiText *f = fromvalue; 396 UiText *f = from;
339 UiText *t = tovalue; 397 UiText *t = to;
340 if(!f->obj) break; 398 if(!f->obj) break;
341 uic_text_copy(f, t); 399 uic_text_copy(f, t);
342 t->restore(t); 400 t->restore(t);
343 break; 401 break;
344 } 402 }
345 case UI_VAR_LIST: { 403 case UI_VAR_LIST: {
346 UiList *f = fromvalue; 404 UiList *f = from;
347 UiList *t = tovalue; 405 UiList *t = to;
348 uic_list_copy(f, t); 406 uic_list_copy(f, t);
349 ui_list_update(t); 407 ui_list_update(t);
350 break; 408 break;
351 } 409 }
352 case UI_VAR_RANGE: { 410 case UI_VAR_RANGE: {
353 UiRange *f = fromvalue; 411 UiRange *f = from;
354 UiRange *t = tovalue; 412 UiRange *t = to;
355 if(!f->obj) break; 413 if(!f->obj) break;
356 uic_range_copy(f, t); 414 uic_range_copy(f, t);
357 t->setextent(t, t->extent); 415 t->setextent(t, t->extent);
358 t->setrange(t, t->min, t->max); 416 t->setrange(t, t->min, t->max);
359 t->set(t, t->value); 417 t->set(t, t->value);
360 break; 418 break;
361 } 419 }
362 case UI_VAR_GENERIC: { 420 case UI_VAR_GENERIC: {
363 UiGeneric *f = fromvalue; 421 UiGeneric *f = from;
364 UiGeneric *t = tovalue; 422 UiGeneric *t = to;
365 if(!f->obj) break; 423 if(!f->obj) break;
366 uic_generic_copy(f, t); 424 uic_generic_copy(f, t);
367 t->set(t, t->value, t->type); 425 t->set(t, t->value, t->type);
368 break; 426 break;
369 } 427 }
396 case UI_VAR_RANGE: uic_range_unbind(var->value); break; 454 case UI_VAR_RANGE: uic_range_unbind(var->value); break;
397 case UI_VAR_GENERIC: uic_generic_unbind(var->value); break; 455 case UI_VAR_GENERIC: uic_generic_unbind(var->value); break;
398 } 456 }
399 } 457 }
400 458
459 const char *uic_type2str(UiVarType type) {
460 switch(type) {
461 default: return "";
462 case UI_VAR_INTEGER: return "int";
463 case UI_VAR_DOUBLE: return "double";
464 case UI_VAR_STRING: return "string";
465 case UI_VAR_TEXT: return "text";
466 case UI_VAR_LIST: return "list";
467 case UI_VAR_RANGE: return "range";
468 case UI_VAR_GENERIC: return "generic";
469 }
470 }
471
401 void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value) { 472 void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value) {
402 // TODO: do we need/want this? Why adding vars to a context after 473 UiVar *var = cxMapGet(ctx->vars, name);
403 // widgets reference these? Workarounds: 474 if(!var) {
404 // 1. add vars to ctx before creating ui 475 // create new var and add it to the context var map
405 // 2. create ui, create new document with vars, attach doc 476 var = ui_malloc(ctx, sizeof(UiVar));
406 // also it would be possible to create a function, that scans unbound vars 477 cxMapPut(ctx->vars, name, var);
407 // and connects them to available vars 478 } else {
408 /* 479 // override var with new value
409 UiContext *rootctx = uic_root_context(ctx); 480 if(var->type != type) {
410 UiVar *b = NULL; 481 fprintf(stderr, "Error: var %s type mismatch: %s - %s\n", name, uic_type2str(var->type), uic_type2str(type));
411 if(rootctx->bound) { 482 return;
412 // some widgets are already bound to some vars 483 }
413 b = ucx_map_cstr_get(rootctx->bound, name); 484 if(var->bound) {
414 if(b) { 485 fprintf(stderr, "Error: var %s already bound\n", name);
415 // a widget is bound to a var with this name 486 return;
416 // if ctx is the root context we can remove the var from bound 487 }
417 // because set_doc or detach can't fuck things up 488 UiInteger *prev_value = var->value;
418 if(ctx == rootctx) { 489 uic_copy_value_binding(type, prev_value, value);
419 ucx_map_cstr_remove(ctx->bound, name); 490 uic_destroy_value(var->from_ctx, var->type, var->value);
420 // TODO: free stuff 491 }
421 } 492
422 }
423 }
424 */
425
426 // create new var and add it to doc's vars
427 UiVar *var = ui_malloc(ctx, sizeof(UiVar));
428 var->type = type; 493 var->type = type;
429 var->value = value; 494 var->value = value;
430 var->from = NULL; 495 var->from = NULL;
431 var->from_ctx = ctx; 496 var->from_ctx = ctx;
432 size_t oldcount = cxMapSize(ctx->vars); 497 var->bound = TRUE;
433 cxMapPut(ctx->vars, name, var); 498 }
434 if(cxMapSize(ctx->vars) != oldcount + 1) {
435 fprintf(stderr, "UiError: var '%s' already exists\n", name);
436 }
437
438 // TODO: remove?
439 // a widget is already bound to a var with this name
440 // copy the binding (like uic_context_set_document)
441 /*
442 if(b) {
443 uic_copy_binding(b, var, TRUE);
444 }
445 */
446 }
447
448 void uic_remove_bound_var(UiContext *ctx, UiVar *var) {
449 // TODO
450 }
451
452 499
453 // public API 500 // public API
501
502 void* ui_context_get_document(UiContext *ctx) {
503 return ctx->document;
504 }
505
506 void ui_context_single_attachment_mode(UiContext *ctx, UiBool enable) {
507 ctx->single_document_mode = enable;
508 }
454 509
455 void ui_attach_document(UiContext *ctx, void *document) { 510 void ui_attach_document(UiContext *ctx, void *document) {
456 uic_context_attach_document(ctx, document); 511 uic_context_attach_document(ctx, document);
457 } 512 }
458 513
476 UiContext* ui_context_parent(UiContext *ctx) { 531 UiContext* ui_context_parent(UiContext *ctx) {
477 return ctx->parent; 532 return ctx->parent;
478 } 533 }
479 534
480 535
481 void ui_set_group(UiContext *ctx, int group) { 536 void ui_set_state(UiContext *ctx, int state) {
482 if(!cxListIndexValid(ctx->groups, cxListFind(ctx->groups, &group))) { 537 if(!cxListIndexValid(ctx->states, cxListFind(ctx->states, &state))) {
483 cxListAdd(ctx->groups, &group); 538 cxListAdd(ctx->states, &state);
484 } 539 }
485 540
486 // enable/disable group widgets 541 // enable/disable group widgets
487 uic_check_group_widgets(ctx); 542 uic_check_state_widgets(ctx);
488 } 543 }
489 544
490 void ui_unset_group(UiContext *ctx, int group) { 545 void ui_unset_state(UiContext *ctx, int state) {
491 int i = cxListFind(ctx->groups, &group); 546 int i = cxListFind(ctx->states, &state);
492 if(i != -1) { 547 if(i != -1) {
493 cxListRemove(ctx->groups, i); 548 cxListRemove(ctx->states, i);
494 } 549 }
495 550
496 // enable/disable group widgets 551 // enable/disable group widgets
497 uic_check_group_widgets(ctx); 552 uic_check_state_widgets(ctx);
498 } 553 }
499 554
500 int* ui_active_groups(UiContext *ctx, int *ngroups) { 555 int* ui_active_states(UiContext *ctx, int *nstates) {
501 *ngroups = cxListSize(ctx->groups); 556 *nstates = cxListSize(ctx->states);
502 return cxListAt(ctx->groups, 0); 557 return cxListAt(ctx->states, 0);
503 } 558 }
504 559
505 void uic_check_group_widgets(UiContext *ctx) { 560 void uic_check_state_widgets(UiContext *ctx) {
506 int ngroups = 0; 561 int ngroups = 0;
507 int *groups = ui_active_groups(ctx, &ngroups); 562 int *groups = ui_active_states(ctx, &ngroups);
508 563
509 CxIterator i = cxListIterator(ctx->group_widgets); 564 CxIterator i = cxListIterator(ctx->state_widgets);
510 cx_foreach(UiGroupWidget *, gw, i) { 565 cx_foreach(UiStateWidget *, gw, i) {
511 char *check = calloc(1, gw->numgroups); 566 char *check = calloc(1, gw->numstates);
512 567
513 for(int i=0;i<ngroups;i++) { 568 for(int i=0;i<ngroups;i++) {
514 for(int k=0;k<gw->numgroups;k++) { 569 for(int k=0;k<gw->numstates;k++) {
515 if(groups[i] == gw->groups[k]) { 570 if(groups[i] == gw->states[k]) {
516 check[k] = 1; 571 check[k] = 1;
517 } 572 }
518 } 573 }
519 } 574 }
520 575
521 int enable = 1; 576 int enable = 1;
522 for(int i=0;i<gw->numgroups;i++) { 577 for(int i=0;i<gw->numstates;i++) {
523 if(check[i] == 0) { 578 if(check[i] == 0) {
524 enable = 0; 579 enable = 0;
525 break; 580 break;
526 } 581 }
527 } 582 }
528 free(check); 583 free(check);
529 gw->enable(gw->widget, enable); 584 gw->enable(gw->widget, enable);
530 } 585 }
531 } 586 }
532 587
533 void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) { 588 void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) {
534 if(enable == NULL) { 589 if(enable == NULL) {
535 enable = (ui_enablefunc)ui_set_enabled; 590 enable = (ui_enablefunc)ui_set_enabled;
536 } 591 }
537 // get groups 592 // get states
538 CxList *groups = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16); 593 CxList *states = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16);
539 va_list ap; 594 va_list ap;
540 va_start(ap, enable); 595 va_start(ap, enable);
541 int group; 596 int state;
542 while((group = va_arg(ap, int)) != -1) { 597 while((state = va_arg(ap, int)) != -1) {
543 cxListAdd(groups, &group); 598 cxListAdd(states, &state);
544 } 599 }
545 va_end(ap); 600 va_end(ap);
546 601
547 uic_add_group_widget(ctx, widget, enable, groups); 602 uic_add_state_widget(ctx, widget, enable, states);
548 603
549 cxListFree(groups); 604 cxListFree(states);
550 } 605 }
551 606
552 void ui_widget_set_groups2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *groups, int ngroups) { 607 void ui_widget_set_states2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *states, int nstates) {
553 if(enable == NULL) { 608 if(enable == NULL) {
554 enable = (ui_enablefunc)ui_set_enabled; 609 enable = (ui_enablefunc)ui_set_enabled;
555 } 610 }
556 CxList *ls = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), ngroups); 611 CxList *ls = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), nstates);
557 for(int i=0;i<ngroups;i++) { 612 for(int i=0;i<nstates;i++) {
558 cxListAdd(ls, groups+i); 613 cxListAdd(ls, states+i);
559 } 614 }
560 uic_add_group_widget(ctx, widget, enable, ls); 615 uic_add_state_widget(ctx, widget, enable, ls);
561 cxListFree(ls); 616 cxListFree(ls);
562 } 617 }
563 618
564 void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates) { 619 void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates) {
565 ui_widget_set_groups2(ctx, widget, (ui_enablefunc)ui_set_visible, states, nstates); 620 ui_widget_set_states2(ctx, widget, (ui_enablefunc)ui_set_visible, states, nstates);
566 } 621 }
567 622
568 size_t uic_group_array_size(const int *groups) { 623 size_t uic_state_array_size(const int *states) {
569 int i; 624 int i;
570 for(i=0;groups[i] >= 0;i++) { } 625 for(i=0;states[i] >= 0;i++) { }
571 return i; 626 return i;
572 } 627 }
573 628
574 void uic_add_group_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *groups) { 629 void uic_add_state_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *states) {
575 uic_add_group_widget_i(ctx, widget, enable, cxListAt(groups, 0), cxListSize(groups)); 630 uic_add_state_widget_i(ctx, widget, enable, cxListAt(states, 0), cxListSize(states));
576 } 631 }
577 632
578 void uic_add_group_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *groups, size_t numgroups) { 633 void uic_add_state_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *states, size_t numstates) {
579 const CxAllocator *a = ctx->allocator; 634 const CxAllocator *a = ctx->allocator;
580 UiGroupWidget gw; 635 UiStateWidget gw;
581 636
582 gw.widget = widget; 637 gw.widget = widget;
583 gw.enable = enable; 638 gw.enable = enable;
584 gw.numgroups = numgroups; 639 gw.numstates = numstates;
585 gw.groups = cxCalloc(a, numgroups, sizeof(int)); 640 gw.states = cxCalloc(a, numstates, sizeof(int));
586 641
587 // copy groups 642 // copy states
588 if(groups) { 643 if(states) {
589 memcpy(gw.groups, groups, gw.numgroups * sizeof(int)); 644 memcpy(gw.states, states, gw.numstates * sizeof(int));
590 } 645 }
591 646
592 cxListAdd(ctx->group_widgets, &gw); 647 cxListAdd(ctx->state_widgets, &gw);
593 } 648 }
594 649
595 void uic_remove_group_widget(UiContext *ctx, void *widget) { 650 void uic_remove_state_widget(UiContext *ctx, void *widget) {
596 (void)cxListFindRemove(ctx->group_widgets, widget); 651 (void)cxListFindRemove(ctx->state_widgets, widget);
597 } 652 }
598 653
599 UIEXPORT void *ui_allocator(UiContext *ctx) { 654 UIEXPORT void *ui_allocator(UiContext *ctx) {
600 return (void*)ctx->allocator; 655 return (void*)ctx->allocator;
601 } 656 }
636 } 691 }
637 692
638 void ui_set_destructor(void *mem, ui_destructor_func destr) { 693 void ui_set_destructor(void *mem, ui_destructor_func destr) {
639 cxMempoolSetDestructor(mem, (cx_destructor_func)destr); 694 cxMempoolSetDestructor(mem, (cx_destructor_func)destr);
640 } 695 }
696
697 UiInteger* ui_get_int_var(UiContext *ctx, const char *name) {
698 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_INTEGER);
699 return var ? var->value : NULL;
700 }
701
702 UiDouble* ui_get_double_var(UiContext *ctx, const char *name) {
703 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_DOUBLE);
704 return var ? var->value : NULL;
705 }
706
707 UiString* ui_get_string_var(UiContext *ctx, const char *name) {
708 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_STRING);
709 return var ? var->value : NULL;
710 }
711
712 UiText* ui_get_text_var(UiContext *ctx, const char *name) {
713 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_TEXT);
714 return var ? var->value : NULL;
715 }
716
717 UiRange* ui_get_range_var(UiContext *ctx, const char *name) {
718 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_RANGE);
719 return var ? var->value : NULL;
720 }
721
722 UiGeneric* ui_get_generic_var(UiContext *ctx, const char *name) {
723 UiVar *var = uic_get_var_t(ctx, name, UI_VAR_GENERIC);
724 return var ? var->value : NULL;
725 }

mercurial