--- a/ui/common/context.c Wed Dec 17 22:36:41 2025 +0100 +++ b/ui/common/context.c Sat Dec 27 22:47:56 2025 +0100 @@ -59,13 +59,14 @@ memset(ctx, 0, sizeof(UiContext)); ctx->mp = mp; ctx->allocator = mp->allocator; - ctx->destroy_handler = cxArrayListCreate(ctx->allocator, NULL, sizeof(UiDestroyHandler), 16); + ctx->destroy_handler = cxArrayListCreate(ctx->allocator, sizeof(UiDestroyHandler), 16); ctx->obj = toplevel; ctx->vars = cxHashMapCreate(mp->allocator, CX_STORE_POINTERS, 16); - ctx->documents = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, CX_STORE_POINTERS); - ctx->state_widgets = cxLinkedListCreate(mp->allocator, cx_cmp_ptr, sizeof(UiStateWidget)); - ctx->states = cxArrayListCreate(mp->allocator, cx_cmp_int, sizeof(int), 32); + ctx->documents = cxLinkedListCreate(mp->allocator, CX_STORE_POINTERS); + ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget)); + ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32); + cxSetCompareFunc(ctx->states, cx_cmp_int); ctx->attach_document = uic_context_attach_document; ctx->detach_document2 = uic_context_detach_document; @@ -173,7 +174,7 @@ void uic_context_detach_all(UiContext *ctx) { // copy list - CxList *ls = cxLinkedListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS); + CxList *ls = cxLinkedListCreate(cxDefaultAllocator, CX_STORE_POINTERS); CxIterator i = cxListIterator(ctx->documents); cx_foreach(void *, doc, i) { cxListAdd(ls, doc); @@ -590,7 +591,7 @@ enable = (ui_enablefunc)ui_set_enabled; } // get states - CxList *states = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), 16); + CxList *states = cxArrayListCreate(cxDefaultAllocator, sizeof(int), 16); va_list ap; va_start(ap, enable); int state; @@ -608,7 +609,7 @@ if(enable == NULL) { enable = (ui_enablefunc)ui_set_enabled; } - CxList *ls = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(int), nstates); + CxList *ls = cxArrayListCreate(cxDefaultAllocator, sizeof(int), nstates); for(int i=0;i<nstates;i++) { cxListAdd(ls, states+i); } @@ -694,6 +695,115 @@ cxMempoolSetDestructor(mem, (cx_destructor_func)destr); } +void ui_var_set_int(UiContext *ctx, const char *name, int64_t value) { + UiInteger *i = ui_get_int_var(ctx, name); + if(i) { + ui_set(i, value); + } +} + +int64_t ui_var_get_int(UiContext *ctx, const char *name) { + UiInteger *i = ui_get_int_var(ctx, name); + if(i) { + return ui_get(i); + } + return 0; +} + +void ui_var_set_double(UiContext *ctx, const char *name, double value) { + UiDouble *d = ui_get_double_var(ctx, name); + if(d) { + ui_set(d, value); + } +} + +double ui_var_get_double(UiContext *ctx, const char *name) { + UiDouble *d = ui_get_double_var(ctx, name); + if(d) { + return ui_get(d); + } + return 0; +} + +void ui_var_set_string(UiContext *ctx, const char *name, char *value) { + UiString *s = ui_get_string_var(ctx, name); + if(s) { + ui_set(s, value); + } +} + +char* ui_var_get_string(UiContext *ctx, const char *name) { + UiString *s = ui_get_string_var(ctx, name); + if(s) { + return ui_get(s); + } + return NULL; +} + +UIEXPORT void ui_var_add_observer(UiContext *ctx, const char *varname, ui_callback f, void *data) { + UiVar *var = uic_get_var(ctx, varname); + if(!var) { + return; + } + + switch(var->type) { + case UI_VAR_INTEGER: { + UiInteger *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + case UI_VAR_DOUBLE: { + UiDouble *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + case UI_VAR_RANGE: { + UiRange *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + case UI_VAR_STRING: { + UiString *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + case UI_VAR_TEXT: { + UiText *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + case UI_VAR_LIST: { + UiList *v = var->value; + v->observers = ui_add_observer(v->observers, f, data); + break; + } + } +} + +void ui_int_add_observer(UiInteger *i, ui_callback f, void *data) { + i->observers = ui_add_observer(i->observers, f, data); +} + +void ui_double_add_observer(UiDouble *d, ui_callback f, void *data) { + d->observers = ui_add_observer(d->observers, f, data); +} + +void ui_range_add_observer(UiRange *r, ui_callback f, void *data) { + r->observers = ui_add_observer(r->observers, f, data); +} + +void ui_string_add_observer(UiString *s, ui_callback f, void *data) { + s->observers = ui_add_observer(s->observers, f, data); +} + +void ui_text_add_observer(UiText *t, ui_callback f, void *data) { + t->observers = ui_add_observer(t->observers, f, data); +} + +void ui_list_add_observer(UiList *l, ui_callback f, void *data) { + l->observers = ui_add_observer(l->observers, f, data); +} + UiInteger* ui_get_int_var(UiContext *ctx, const char *name) { UiVar *var = uic_get_var_t(ctx, name, UI_VAR_INTEGER); return var ? var->value : NULL; @@ -719,6 +829,11 @@ return var ? var->value : NULL; } +UIEXPORT UiList* ui_get_list_var(UiContext *ctx, const char *name) { + UiVar *var = uic_get_var_t(ctx, name, UI_VAR_LIST); + return var ? var->value : NULL; +} + UiGeneric* ui_get_generic_var(UiContext *ctx, const char *name) { UiVar *var = uic_get_var_t(ctx, name, UI_VAR_GENERIC); return var ? var->value : NULL;