add existing code (build system, libs, initial mizucp code)
[mizunara.git] / ui / common / types.c
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright 2017 Olaf Wintermann. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright
13  *      notice, this list of conditions and the following disclaimer in the
14  *      documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33
34 #include <ucx/list.h>
35 #include "../ui/tree.h"
36 #include "types.h"
37 #include "context.h"
38
39 UiObserver* ui_observer_new(ui_callback f, void *data) {
40     UiObserver *observer = malloc(sizeof(UiObserver));
41     observer->callback = f;
42     observer->data = data;
43     observer->next = NULL;
44     return observer;
45 }
46
47 UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer) {
48     if(!list) {
49         return observer;
50     } else {
51         UiObserver *l = list;
52         while(l->next) {
53             l = l->next;
54         }
55         l->next = observer;
56         return list;
57     }
58 }
59
60 UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data) {
61     UiObserver *observer = ui_observer_new(f, data);
62     return ui_obsvlist_add(list, observer);
63 }
64
65 void ui_notify(UiObserver *observer, void *data) {
66     ui_notify_except(observer, NULL, data);
67 }
68
69 void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) {
70     UiEvent evt;
71     evt.obj = NULL;
72     evt.window = NULL;
73     evt.document = NULL;
74     evt.eventdata = data;
75     evt.intval = 0;
76     
77     while(observer) {
78         if(observer != exc) { 
79             observer->callback(&evt, observer->data);
80         }
81         observer = observer->next;
82     }
83 }
84
85 void ui_notify_evt(UiObserver *observer, UiEvent *event) {
86     while(observer) {
87         observer->callback(event, observer->data);
88         observer = observer->next;
89     }
90 }
91
92 /* --------------------------- UiList --------------------------- */
93
94 UiList* ui_list_new(UiContext *ctx, char *name) {
95     UiList *list = malloc(sizeof(UiList));
96     list->first = ui_list_first;
97     list->next = ui_list_next;
98     list->get = ui_list_get;
99     list->count = ui_list_count;
100     list->observers = NULL;
101     
102     list->data = NULL;
103     list->iter = NULL;
104     
105     list->update = NULL;
106     list->obj = NULL;
107     
108     if(name) {
109         uic_reg_var(ctx, name, UI_VAR_LIST, list);
110     }
111     
112     return list;
113 }
114
115 void ui_list_free(UiList *list) {
116     ucx_list_free(list->data);
117     free(list);
118 }
119
120 void* ui_list_first(UiList *list) {
121     UcxList *elm = list->data;
122     list->iter = elm;
123     return elm ? elm->data : NULL;
124 }
125
126 void* ui_list_next(UiList *list) {
127     UcxList *elm = list->iter;
128     if(elm) {
129         elm = elm->next;
130         if(elm) {
131             list->iter = elm;
132             return elm->data;
133         }
134     }
135     return NULL;
136 }
137
138 void* ui_list_get(UiList *list, int i) {
139     UcxList *elm = ucx_list_get(list->data, i);
140     if(elm) {
141         list->iter = elm;
142         return elm->data;
143     } else {
144         return NULL;
145     }
146 }
147
148 int ui_list_count(UiList *list) {
149     UcxList *elm = list->data;
150     return (int)ucx_list_size(elm);
151 }
152
153 void ui_list_append(UiList *list, void *data) {
154     list->data = ucx_list_append(list->data, data);
155 }
156
157 void ui_list_prepend(UiList *list, void *data) {
158     list->data = ucx_list_prepend(list->data, data);
159 }
160
161 void ui_list_clear(UiList *list) {
162     ucx_list_free(list->data);
163     list->data = NULL;
164 }
165
166 void ui_list_addobsv(UiList *list, ui_callback f, void *data) {
167     list->observers = ui_add_observer(list->observers, f, data);
168 }
169
170 void ui_list_notify(UiList *list) {
171     ui_notify(list->observers, list);
172 }
173
174
175 typedef struct {
176     int  type;
177     char *name;
178 } UiColumn;
179
180 UiModel* ui_model(UiContext *ctx, ...) {
181     UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
182     
183     va_list ap;
184     va_start(ap, ctx);
185     
186     UcxList *cols = NULL;
187     int type;
188     while((type = va_arg(ap, int)) != -1) {
189         char *name = va_arg(ap, char*);
190         
191         UiColumn *column = malloc(sizeof(UiColumn));
192         column->type = type;
193         column->name = name;
194         
195         cols = ucx_list_append(cols, column);
196     }
197     
198     va_end(ap);
199     
200     size_t len = ucx_list_size(cols);
201     info->columns = len;
202     info->types = ui_calloc(ctx, len, sizeof(UiModelType));
203     info->titles = ui_calloc(ctx, len, sizeof(char*));
204     
205     int i = 0;
206     UCX_FOREACH(elm, cols) {
207         UiColumn *c = elm->data;
208         info->types[i] = c->type;
209         info->titles[i] = c->name;
210         free(c);
211         i++;
212     }
213     ucx_list_free(cols);
214     
215     return info;
216 }
217
218 void ui_model_free(UiContext *ctx, UiModel *mi) {
219     ucx_mempool_free(ctx->mempool, mi->types);
220     ucx_mempool_free(ctx->mempool, mi->titles);
221     ucx_mempool_free(ctx->mempool, mi);
222 }
223
224 // types
225
226 // public functions
227 UiInteger* ui_int_new(UiContext *ctx, char *name) {
228     UiInteger *i = ui_malloc(ctx, sizeof(UiInteger));
229     memset(i, 0, sizeof(UiInteger));
230     if(name) {
231         uic_reg_var(ctx, name, UI_VAR_INTEGER, i);
232     }
233     return i;
234 }
235
236 UiDouble* ui_double_new(UiContext *ctx, char *name) {
237     UiDouble *d = ui_malloc(ctx, sizeof(UiDouble));
238     memset(d, 0, sizeof(UiDouble));
239     if(name) {
240         uic_reg_var(ctx, name, UI_VAR_DOUBLE, d);
241     }
242     return d;
243 }
244
245 UiString* ui_string_new(UiContext *ctx, char *name) {
246     UiString *s = ui_malloc(ctx, sizeof(UiString));
247     memset(s, 0, sizeof(UiString));
248     if(name) {
249         uic_reg_var(ctx, name, UI_VAR_STRING, s);
250     }
251     return s;
252 }
253
254 UiText* ui_text_new(UiContext *ctx, char *name) {
255     UiText *t = ui_malloc(ctx, sizeof(UiText));
256     memset(t, 0, sizeof(UiText));
257     if(name) {
258         uic_reg_var(ctx, name, UI_VAR_TEXT, t);
259     }
260     return t;
261 }
262
263 UiRange* ui_range_new(UiContext *ctx, char *name) {
264     UiRange *r = ui_malloc(ctx, sizeof(UiRange));
265     memset(r, 0, sizeof(UiRange));
266     if(name) {
267         uic_reg_var(ctx, name, UI_VAR_RANGE, r);
268     }
269     return r;
270 }
271
272
273 // private functions
274 void uic_int_copy(UiInteger *from, UiInteger *to) {
275     to->get = from->get;
276     to->set = from->set;
277     to->obj = from->obj;
278 }
279
280 void uic_double_copy(UiDouble *from, UiDouble *to) {
281     to->get = from->get;
282     to->set = from->set;
283     to->obj = from->obj;
284 }
285
286 void uic_string_copy(UiString *from, UiString *to) {
287     to->get = from->get;
288     to->set = from->set;
289     to->obj = from->obj;
290 }
291
292 void uic_text_copy(UiText *from, UiText *to) {
293     to->get = from->get;
294     to->set = from->set;
295     to->getsubstr = from->getsubstr;
296     to->insert = from->insert;
297     to->setposition = from->setposition;
298     to->position = from->position;
299     to->selection = from->selection;
300     to->length = from->length;
301     to->remove = from->remove;
302     
303     to->obj = from->obj;
304     // do not copy the undo manager
305 }
306
307 void uic_range_copy(UiRange *from, UiRange *to) {
308     to->get = from->get;
309     to->set = from->set;
310     to->setrange = from->setrange;
311     to->setextent = from->setextent;
312     to->obj = from->obj;
313 }
314
315 void uic_list_copy(UiList *from, UiList *to) {
316     to->update = from->update;
317     to->obj = from->obj;
318 }
319
320
321 void uic_int_save(UiInteger *i) {
322     if(!i->obj) return;
323     i->value = i->get(i);
324 }
325
326 void uic_double_save(UiDouble *d) {
327     if(!d->obj) return;
328     d->value = d->get(d);
329 }
330
331 void uic_string_save(UiString *s) {
332     if(!s->obj) return;
333     s->get(s);
334 }
335
336 void uic_text_save(UiText *t) {
337     if(!t->obj) return;
338     t->get(t);
339     t->position(t);
340 }
341
342 void uic_range_save(UiRange *r) {
343     if(!r->obj) return;
344     r->get(r);
345 }
346
347
348 void uic_int_unbind(UiInteger *i) {
349     i->get = NULL;
350     i->set = NULL;
351     i->obj = NULL;
352 }
353
354 void uic_double_unbind(UiDouble *d) {
355     d->get = NULL;
356     d->set = NULL;
357     d->obj = NULL;
358 }
359
360 void uic_string_unbind(UiString *s) {
361     s->get = NULL;
362     s->set = NULL;
363     s->obj = NULL;
364 }
365
366 void uic_text_unbind(UiText *t) {
367     t->set = NULL;
368     t->get = NULL;
369     t->getsubstr = NULL;
370     t->insert = NULL;
371     t->setposition = NULL;
372     t->position = NULL;
373     t->selection = NULL;
374     t->length = NULL;
375     t->remove = NULL;
376     t->obj = NULL;
377     t->undomgr = NULL;
378 }
379
380 void uic_range_unbind(UiRange *r) {
381     r->get = NULL;
382     r->set = NULL;
383     r->setextent = NULL;
384     r->setrange = NULL;
385     r->obj = NULL;
386 }
387
388 void uic_list_unbind(UiList *l) {
389     l->update = NULL;
390     l->obj = NULL;
391 }