--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/common/types.c Wed Dec 09 11:32:01 2020 +0100 @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2017 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include <ucx/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; + observer->data = data; + observer->next = NULL; + return observer; +} + +UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer) { + if(!list) { + return observer; + } else { + UiObserver *l = list; + while(l->next) { + l = l->next; + } + l->next = observer; + return list; + } +} + +UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data) { + UiObserver *observer = ui_observer_new(f, data); + return ui_obsvlist_add(list, observer); +} + +void ui_notify(UiObserver *observer, void *data) { + ui_notify_except(observer, NULL, data); +} + +void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) { + while(observer) { + if(observer != exc) { + UiEvent evt; + evt.obj = NULL; + evt.window = NULL; + evt.document = NULL; + evt.eventdata = data; + evt.intval = 0; + observer->callback(&evt, observer->data); + } + observer = observer->next; + } +} + +void ui_notify_evt(UiObserver *observer, UiEvent *event) { + while(observer) { + observer->callback(event, observer->data); + observer = observer->next; + } +} + +/* --------------------------- UiList --------------------------- */ + +UiList* ui_list_new(UiContext *ctx, char *name) { + UiList *list = malloc(sizeof(UiList)); + list->first = ui_list_first; + list->next = ui_list_next; + list->get = ui_list_get; + list->count = ui_list_count; + list->observers = NULL; + + list->data = NULL; + list->iter = NULL; + + list->update = NULL; + list->obj = NULL; + + if(name) { + uic_reg_var(ctx, name, UI_VAR_LIST, list); + } + + return list; +} + +void ui_list_free(UiList *list) { + ucx_list_free(list->data); + free(list); +} + +void* ui_list_first(UiList *list) { + UcxList *elm = list->data; + list->iter = elm; + return elm ? elm->data : NULL; +} + +void* ui_list_next(UiList *list) { + UcxList *elm = list->iter; + if(elm) { + elm = elm->next; + if(elm) { + list->iter = elm; + return elm->data; + } + } + return NULL; +} + +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; + } +} + +int ui_list_count(UiList *list) { + UcxList *elm = list->data; + return (int)ucx_list_size(elm); +} + +void ui_list_append(UiList *list, void *data) { + list->data = ucx_list_append(list->data, data); +} + +void ui_list_prepend(UiList *list, void *data) { + list->data = ucx_list_prepend(list->data, data); +} + +void ui_list_clear(UiList *list) { + ucx_list_free(list->data); + list->data = NULL; +} + +void ui_list_addobsv(UiList *list, ui_callback f, void *data) { + list->observers = ui_add_observer(list->observers, f, data); +} + +void ui_list_notify(UiList *list) { + ui_notify(list->observers, list); +} + + +typedef struct { + int type; + char *name; +} UiColumn; + +UiModel* ui_model(UiContext *ctx, ...) { + UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel)); + + va_list ap; + va_start(ap, ctx); + + UcxList *cols = NULL; + 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; + + cols = ucx_list_append(cols, column); + } + + va_end(ap); + + size_t len = ucx_list_size(cols); + info->columns = len; + info->types = ui_calloc(ctx, len, sizeof(UiModelType)); + info->titles = ui_calloc(ctx, len, sizeof(char*)); + + int i = 0; + UCX_FOREACH(elm, cols) { + UiColumn *c = elm->data; + info->types[i] = c->type; + info->titles[i] = c->name; + free(c); + i++; + } + ucx_list_free(cols); + + return info; +} + +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); +} + +// types + +// public functions +UiInteger* ui_int_new(UiContext *ctx, char *name) { + UiInteger *i = ui_malloc(ctx, sizeof(UiInteger)); + memset(i, 0, sizeof(UiInteger)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_INTEGER, i); + } + return i; +} + +UiDouble* ui_double_new(UiContext *ctx, char *name) { + UiDouble *d = ui_malloc(ctx, sizeof(UiDouble)); + memset(d, 0, sizeof(UiDouble)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_DOUBLE, d); + } + return d; +} + +UiString* ui_string_new(UiContext *ctx, char *name) { + UiString *s = ui_malloc(ctx, sizeof(UiString)); + memset(s, 0, sizeof(UiString)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_STRING, s); + } + return s; +} + +UiText* ui_text_new(UiContext *ctx, char *name) { + UiText *t = ui_malloc(ctx, sizeof(UiText)); + memset(t, 0, sizeof(UiText)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_TEXT, t); + } + return t; +} + +UiRange* ui_range_new(UiContext *ctx, char *name) { + UiRange *r = ui_malloc(ctx, sizeof(UiRange)); + memset(r, 0, sizeof(UiRange)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_RANGE, r); + } + return r; +} + + +// private functions +void uic_int_copy(UiInteger *from, UiInteger *to) { + to->get = from->get; + to->set = from->set; + to->obj = from->obj; +} + +void uic_double_copy(UiDouble *from, UiDouble *to) { + to->get = from->get; + to->set = from->set; + to->obj = from->obj; +} + +void uic_string_copy(UiString *from, UiString *to) { + to->get = from->get; + to->set = from->set; + to->obj = from->obj; +} + +void uic_text_copy(UiText *from, UiText *to) { + to->get = from->get; + to->set = from->set; + to->getsubstr = from->getsubstr; + to->insert = from->insert; + to->setposition = from->setposition; + to->position = from->position; + to->selection = from->selection; + to->length = from->length; + to->remove = from->remove; + + to->obj = from->obj; + // do not copy the undo manager +} + +void uic_range_copy(UiRange *from, UiRange *to) { + to->get = from->get; + to->set = from->set; + to->setrange = from->setrange; + to->setextent = from->setextent; + to->obj = from->obj; +} + +void uic_list_copy(UiList *from, UiList *to) { + to->update = from->update; + to->obj = from->obj; +} + + +void uic_int_save(UiInteger *i) { + if(!i->obj) return; + i->value = i->get(i); +} + +void uic_double_save(UiDouble *d) { + if(!d->obj) return; + d->value = d->get(d); +} + +void uic_string_save(UiString *s) { + if(!s->obj) return; + s->get(s); +} + +void uic_text_save(UiText *t) { + if(!t->obj) return; + t->get(t); + t->position(t); +} + +void uic_range_save(UiRange *r) { + if(!r->obj) return; + r->get(r); +} + + +void uic_int_unbind(UiInteger *i) { + i->get = NULL; + i->set = NULL; + i->obj = NULL; +} + +void uic_double_unbind(UiDouble *d) { + d->get = NULL; + d->set = NULL; + d->obj = NULL; +} + +void uic_string_unbind(UiString *s) { + s->get = NULL; + s->set = NULL; + s->obj = NULL; +} + +void uic_text_unbind(UiText *t) { + t->set = NULL; + t->get = NULL; + t->getsubstr = NULL; + t->insert = NULL; + t->setposition = NULL; + t->position = NULL; + t->selection = NULL; + t->length = NULL; + t->remove = NULL; + t->obj = NULL; + t->undomgr = NULL; +} + +void uic_range_unbind(UiRange *r) { + r->get = NULL; + r->set = NULL; + r->setextent = NULL; + r->setrange = NULL; + r->obj = NULL; +} + +void uic_list_unbind(UiList *l) { + l->update = NULL; + l->obj = NULL; +}