ui/common/types.c

changeset 0
804d8803eade
child 2
ea89bbb0c4c8
--- /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;
+}

mercurial