--- a/ui/common/types.c Sun May 23 09:44:43 2021 +0200 +++ b/ui/common/types.c Sat Jan 04 16:38:48 2025 +0100 @@ -31,11 +31,14 @@ #include <string.h> #include <stdarg.h> -#include <ucx/list.h> +#include <cx/list.h> +#include <cx/array_list.h> #include "../ui/tree.h" #include "types.h" #include "context.h" + + UiObserver* ui_observer_new(ui_callback f, void *data) { UiObserver *observer = malloc(sizeof(UiObserver)); observer->callback = f; @@ -99,10 +102,11 @@ list->count = ui_list_count; list->observers = NULL; - list->data = NULL; + list->data = cxArrayListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS, 32); list->iter = NULL; list->update = NULL; + list->getselection = NULL; list->obj = NULL; if(name) { @@ -113,54 +117,53 @@ } void ui_list_free(UiList *list) { - ucx_list_free(list->data); + cxListDestroy(list->data); free(list); } void* ui_list_first(UiList *list) { - UcxList *elm = list->data; - list->iter = elm; - return elm ? elm->data : NULL; + list->iter = (void*)(intptr_t)0; + return cxListAt(list->data, 0); } void* ui_list_next(UiList *list) { - UcxList *elm = list->iter; + intptr_t iter = (intptr_t)list->iter; + iter++; + void *elm = cxListAt(list->data, iter); if(elm) { - elm = elm->next; - if(elm) { - list->iter = elm; - return elm->data; - } + list->iter = (void*)iter; } - return NULL; + return elm; } void* ui_list_get(UiList *list, int i) { - UcxList *elm = ucx_list_get(list->data, i); - if(elm) { - list->iter = elm; - return elm->data; - } else { - return NULL; - } + return cxListAt(list->data, i); } int ui_list_count(UiList *list) { - UcxList *elm = list->data; - return (int)ucx_list_size(elm); + return cxListSize(list->data); } void ui_list_append(UiList *list, void *data) { - list->data = ucx_list_append(list->data, data); + cxListAdd(list->data, data); } void ui_list_prepend(UiList *list, void *data) { - list->data = ucx_list_prepend(list->data, data); + cxListInsert(list->data, 0, data); +} + +void ui_list_remove(UiList *list, int i) { + cxListRemove(list->data, i); } void ui_list_clear(UiList *list) { - ucx_list_free(list->data); - list->data = NULL; + cxListClear(list->data); +} + +UIEXPORT void ui_list_update(UiList *list) { + if(list->update) { + list->update(list, 0); + } } void ui_list_addobsv(UiList *list, ui_callback f, void *data) { @@ -183,42 +186,60 @@ va_list ap; va_start(ap, ctx); - UcxList *cols = NULL; + CxList *cols = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(UiColumn), 32); int type; while((type = va_arg(ap, int)) != -1) { char *name = va_arg(ap, char*); - UiColumn *column = malloc(sizeof(UiColumn)); - column->type = type; - column->name = name; + UiColumn column; + column.type = type; + column.name = name; - cols = ucx_list_append(cols, column); + cxListAdd(cols, &column); } va_end(ap); - size_t len = ucx_list_size(cols); + size_t len = cxListSize(cols); info->columns = len; info->types = ui_calloc(ctx, len, sizeof(UiModelType)); info->titles = ui_calloc(ctx, len, sizeof(char*)); + info->columnsize = ui_calloc(ctx, len, sizeof(int)); int i = 0; - UCX_FOREACH(elm, cols) { - UiColumn *c = elm->data; + CxIterator iter = cxListIterator(cols); + cx_foreach(UiColumn*, c, iter) { info->types[i] = c->type; info->titles[i] = c->name; - free(c); i++; } - ucx_list_free(cols); + cxListDestroy(cols); return info; } +UiModel* ui_model_copy(UiContext *ctx, UiModel* model) { + const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator; + + UiModel* newmodel = cxMalloc(a, sizeof(UiModel)); + *newmodel = *model; + + newmodel->types = cxCalloc(a, model->columns, sizeof(UiModelType)); + memcpy(newmodel->types, model->types, model->columns); + + newmodel->titles = cxCalloc(a, model->columns, sizeof(char*)); + for (int i = 0; i < model->columns; i++) { + newmodel->titles[i] = model->titles[i] ? cx_strdup_a(a, cx_str(model->titles[i])).ptr : NULL; + } + + return newmodel; +} + void ui_model_free(UiContext *ctx, UiModel *mi) { - ucx_mempool_free(ctx->mempool, mi->types); - ucx_mempool_free(ctx->mempool, mi->titles); - ucx_mempool_free(ctx->mempool, mi); + const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator; + cxFree(a, mi->types); + cxFree(a, mi->titles); + cxFree(a, mi); } // types @@ -269,6 +290,75 @@ return r; } +UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, char *name) { + UiGeneric *g = ui_malloc(ctx, sizeof(UiGeneric)); + memset(g, 0, sizeof(UiGeneric)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_GENERIC, g); + } + return g; +} + + +void ui_int_set(UiInteger* i, int64_t value) { + if (i && i->set) { + i->set(i, value); + } +} + +int64_t ui_int_get(UiInteger* i) { + if (i) { + return i->get ? i->get(i) : i->value; + } else { + return 0; + } +} + +void ui_double_set(UiDouble* d, double value) { + if (d && d->set) { + d->set(d, value); + } +} + +double ui_double_get(UiDouble* d) { + if (d) { + return d->get ? d->get(d) : d->value; + } + else { + return 0; + } +} + +void ui_string_set(UiString* s, const char* value) { + if (s && s->set) { + s->set(s, value); + } +} + +char* ui_string_get(UiString* s) { + if (s) { + return s->get ? s->get(s) : s->value.ptr; + } + else { + return 0; + } +} + +void ui_text_set(UiText* s, const char* value) { + if (s && s->set) { + s->set(s, value); + } +} + +char* ui_text_get(UiText* s) { + if (s) { + return s->get ? s->get(s) : s->value.ptr; + } + else { + return 0; + } +} + // private functions void uic_int_copy(UiInteger *from, UiInteger *to) { @@ -317,6 +407,12 @@ to->obj = from->obj; } +void uic_generic_copy(UiGeneric *from, UiGeneric *to) { + to->get = from->get; + to->get_type = from->get_type; + to->set = from->set; + to->obj = from->obj; +} void uic_int_save(UiInteger *i) { if(!i->obj) return; @@ -344,6 +440,11 @@ r->get(r); } +void uic_generic_save(UiGeneric *g) { + if(!g->obj) return; + g->get(g); +} + void uic_int_unbind(UiInteger *i) { i->get = NULL; @@ -389,3 +490,90 @@ l->update = NULL; l->obj = NULL; } + +void uic_generic_unbind(UiGeneric *g) { + g->get = NULL; + g->get_type = NULL; + g->set = NULL; + g->obj = NULL; +} + + +UIEXPORT UiListSelection ui_list_getselection(UiList *list) { + if (list->getselection) { + return list->getselection(list); + } + return (UiListSelection){ 0, NULL }; +} + +UIEXPORT void ui_list_setselection(UiList *list, int index) { + if (list->setselection && index >= 0) { + UiListSelection sel; + sel.count = 1; + sel.rows = &index; + list->setselection(list, sel); + } +} + +UIEXPORT void ui_listselection_free(UiListSelection selection) { + if (selection.rows) { + free(selection.rows); + } +} + +UIEXPORT UiStr ui_str(char *cstr) { + return (UiStr) { cstr, NULL }; +} + +UIEXPORT UiStr ui_str_free(char *str, void (*freefunc)(void *v)) { + return (UiStr) { str, freefunc }; +} + + +UIEXPORT UiFileList ui_filelist_copy(UiFileList list) { + char **newlist = calloc(sizeof(char*), list.nfiles); + for (int i = 0; i < list.nfiles; i++) { + newlist[i] = strdup(list.files[i]); + } + return (UiFileList) { newlist, list.nfiles }; +} + +UIEXPORT void ui_filelist_free(UiFileList list) { + for (int i = 0; i < list.nfiles; i++) { + free(list.files[i]); + } + free(list.files); +} + + +typedef struct UiObserverDestructor { + UiList *list; + UiObserver *observer; +} UiObserverDestructor; + +static void observer_destructor(UiObserverDestructor *destr) { + UiObserver *remove_obs = destr->observer; + UiObserver *obs = destr->list->observers; + UiObserver *prev = NULL; + while(obs) { + if(obs == remove_obs) { + if(prev) { + prev->next = obs->next; + } else { + destr->list->observers = obs->next; + } + break; + } + prev = obs; + obs = obs->next; + } + free(remove_obs); +} + +void uic_list_register_observer_destructor(UiContext *ctx, UiList *list, UiObserver *observer) { + CxMempool *mp = ctx->mp; + UiObserverDestructor *destr = cxMalloc(mp->allocator, sizeof(UiObserverDestructor)); + destr->list = list; + destr->observer = observer; + cxMempoolSetDestructor(destr, (cx_destructor_func)observer_destructor); +}