ui/common/types.c

changeset 0
2483f517c562
child 3
f154867f54dc
equal deleted inserted replaced
-1:000000000000 0:2483f517c562
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 <cx/list.h>
35 #include <cx/array_list.h>
36 #include "../ui/tree.h"
37 #include "types.h"
38 #include "context.h"
39
40 UiObserver* ui_observer_new(ui_callback f, void *data) {
41 UiObserver *observer = malloc(sizeof(UiObserver));
42 observer->callback = f;
43 observer->data = data;
44 observer->next = NULL;
45 return observer;
46 }
47
48 UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer) {
49 if(!list) {
50 return observer;
51 } else {
52 UiObserver *l = list;
53 while(l->next) {
54 l = l->next;
55 }
56 l->next = observer;
57 return list;
58 }
59 }
60
61 UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data) {
62 UiObserver *observer = ui_observer_new(f, data);
63 return ui_obsvlist_add(list, observer);
64 }
65
66 void ui_notify(UiObserver *observer, void *data) {
67 ui_notify_except(observer, NULL, data);
68 }
69
70 void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) {
71 UiEvent evt;
72 evt.obj = NULL;
73 evt.window = NULL;
74 evt.document = NULL;
75 evt.eventdata = data;
76 evt.intval = 0;
77
78 while(observer) {
79 if(observer != exc) {
80 observer->callback(&evt, observer->data);
81 }
82 observer = observer->next;
83 }
84 }
85
86 void ui_notify_evt(UiObserver *observer, UiEvent *event) {
87 while(observer) {
88 observer->callback(event, observer->data);
89 observer = observer->next;
90 }
91 }
92
93 /* --------------------------- UiList --------------------------- */
94
95 UiList* ui_list_new(UiContext *ctx, char *name) {
96 UiList *list = malloc(sizeof(UiList));
97 list->first = ui_list_first;
98 list->next = ui_list_next;
99 list->get = ui_list_get;
100 list->count = ui_list_count;
101 list->observers = NULL;
102
103 list->data = cxArrayListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS, 32);
104 list->iter = NULL;
105
106 list->update = NULL;
107 list->obj = NULL;
108
109 if(name) {
110 uic_reg_var(ctx, name, UI_VAR_LIST, list);
111 }
112
113 return list;
114 }
115
116 void ui_list_free(UiList *list) {
117 cxListDestroy(list->data);
118 free(list);
119 }
120
121 void* ui_list_first(UiList *list) {
122 list->iter = (void*)(intptr_t)0;
123 return cxListAt(list->data, 0);
124 }
125
126 void* ui_list_next(UiList *list) {
127 intptr_t iter = (intptr_t)list->iter;
128 iter++;
129 void *elm = cxListAt(list->data, iter);
130 if(elm) {
131 list->iter = (void*)iter;
132 }
133 return elm;
134 }
135
136 void* ui_list_get(UiList *list, int i) {
137 return cxListAt(list->data, i);
138 }
139
140 int ui_list_count(UiList *list) {
141 return ((CxList*)list->data)->size;
142 }
143
144 void ui_list_append(UiList *list, void *data) {
145 cxListAdd(list->data, data);
146 }
147
148 void ui_list_prepend(UiList *list, void *data) {
149 cxListInsert(list->data, 0, data);
150 }
151
152 void ui_list_clear(UiList *list) {
153 cxListClear(list->data);
154 }
155
156 void ui_list_addobsv(UiList *list, ui_callback f, void *data) {
157 list->observers = ui_add_observer(list->observers, f, data);
158 }
159
160 void ui_list_notify(UiList *list) {
161 ui_notify(list->observers, list);
162 }
163
164
165 typedef struct {
166 int type;
167 char *name;
168 } UiColumn;
169
170 UiModel* ui_model(UiContext *ctx, ...) {
171 UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
172
173 va_list ap;
174 va_start(ap, ctx);
175
176 CxList *cols = cxArrayListCreate(cxDefaultAllocator, NULL, sizeof(UiColumn), 32);
177 int type;
178 while((type = va_arg(ap, int)) != -1) {
179 char *name = va_arg(ap, char*);
180
181 UiColumn column;
182 column.type = type;
183 column.name = name;
184
185 cxListAdd(cols, &column);
186 }
187
188 va_end(ap);
189
190 size_t len = cols->size;
191 info->columns = len;
192 info->types = ui_calloc(ctx, len, sizeof(UiModelType));
193 info->titles = ui_calloc(ctx, len, sizeof(char*));
194
195 int i = 0;
196 CxIterator iter = cxListIterator(cols);
197 cx_foreach(UiColumn*, c, iter) {
198 info->types[i] = c->type;
199 info->titles[i] = c->name;
200 i++;
201 }
202 cxListDestroy(cols);
203
204 return info;
205 }
206
207 UiModel* ui_model_copy(UiContext *ctx, UiModel* model) {
208 const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator;
209
210 UiModel* newmodel = cxMalloc(a, sizeof(UiModel));
211 *newmodel = *model;
212
213 newmodel->types = cxCalloc(a, model->columns, sizeof(UiModelType));
214 memcpy(newmodel->types, model->types, model->columns);
215
216 newmodel->titles = cxCalloc(a, model->columns, sizeof(char*));
217 for (int i = 0; i < model->columns; i++) {
218 newmodel->titles[i] = model->titles[i] ? cx_strdup_a(a, cx_str(model->titles[i])).ptr : NULL;
219 }
220
221 return newmodel;
222 }
223
224 void ui_model_free(UiContext *ctx, UiModel *mi) {
225 const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator;
226 cxFree(a, mi->types);
227 cxFree(a, mi->titles);
228 cxFree(a, mi);
229 }
230
231 // types
232
233 // public functions
234 UiInteger* ui_int_new(UiContext *ctx, char *name) {
235 UiInteger *i = ui_malloc(ctx, sizeof(UiInteger));
236 memset(i, 0, sizeof(UiInteger));
237 if(name) {
238 uic_reg_var(ctx, name, UI_VAR_INTEGER, i);
239 }
240 return i;
241 }
242
243 UiDouble* ui_double_new(UiContext *ctx, char *name) {
244 UiDouble *d = ui_malloc(ctx, sizeof(UiDouble));
245 memset(d, 0, sizeof(UiDouble));
246 if(name) {
247 uic_reg_var(ctx, name, UI_VAR_DOUBLE, d);
248 }
249 return d;
250 }
251
252 UiString* ui_string_new(UiContext *ctx, char *name) {
253 UiString *s = ui_malloc(ctx, sizeof(UiString));
254 memset(s, 0, sizeof(UiString));
255 if(name) {
256 uic_reg_var(ctx, name, UI_VAR_STRING, s);
257 }
258 return s;
259 }
260
261 UiText* ui_text_new(UiContext *ctx, char *name) {
262 UiText *t = ui_malloc(ctx, sizeof(UiText));
263 memset(t, 0, sizeof(UiText));
264 if(name) {
265 uic_reg_var(ctx, name, UI_VAR_TEXT, t);
266 }
267 return t;
268 }
269
270 UiRange* ui_range_new(UiContext *ctx, char *name) {
271 UiRange *r = ui_malloc(ctx, sizeof(UiRange));
272 memset(r, 0, sizeof(UiRange));
273 if(name) {
274 uic_reg_var(ctx, name, UI_VAR_RANGE, r);
275 }
276 return r;
277 }
278
279
280 // private functions
281 void uic_int_copy(UiInteger *from, UiInteger *to) {
282 to->get = from->get;
283 to->set = from->set;
284 to->obj = from->obj;
285 }
286
287 void uic_double_copy(UiDouble *from, UiDouble *to) {
288 to->get = from->get;
289 to->set = from->set;
290 to->obj = from->obj;
291 }
292
293 void uic_string_copy(UiString *from, UiString *to) {
294 to->get = from->get;
295 to->set = from->set;
296 to->obj = from->obj;
297 }
298
299 void uic_text_copy(UiText *from, UiText *to) {
300 to->get = from->get;
301 to->set = from->set;
302 to->getsubstr = from->getsubstr;
303 to->insert = from->insert;
304 to->setposition = from->setposition;
305 to->position = from->position;
306 to->selection = from->selection;
307 to->length = from->length;
308 to->remove = from->remove;
309
310 to->obj = from->obj;
311 // do not copy the undo manager
312 }
313
314 void uic_range_copy(UiRange *from, UiRange *to) {
315 to->get = from->get;
316 to->set = from->set;
317 to->setrange = from->setrange;
318 to->setextent = from->setextent;
319 to->obj = from->obj;
320 }
321
322 void uic_list_copy(UiList *from, UiList *to) {
323 to->update = from->update;
324 to->obj = from->obj;
325 }
326
327
328 void uic_int_save(UiInteger *i) {
329 if(!i->obj) return;
330 i->value = i->get(i);
331 }
332
333 void uic_double_save(UiDouble *d) {
334 if(!d->obj) return;
335 d->value = d->get(d);
336 }
337
338 void uic_string_save(UiString *s) {
339 if(!s->obj) return;
340 s->get(s);
341 }
342
343 void uic_text_save(UiText *t) {
344 if(!t->obj) return;
345 t->get(t);
346 t->position(t);
347 }
348
349 void uic_range_save(UiRange *r) {
350 if(!r->obj) return;
351 r->get(r);
352 }
353
354
355 void uic_int_unbind(UiInteger *i) {
356 i->get = NULL;
357 i->set = NULL;
358 i->obj = NULL;
359 }
360
361 void uic_double_unbind(UiDouble *d) {
362 d->get = NULL;
363 d->set = NULL;
364 d->obj = NULL;
365 }
366
367 void uic_string_unbind(UiString *s) {
368 s->get = NULL;
369 s->set = NULL;
370 s->obj = NULL;
371 }
372
373 void uic_text_unbind(UiText *t) {
374 t->set = NULL;
375 t->get = NULL;
376 t->getsubstr = NULL;
377 t->insert = NULL;
378 t->setposition = NULL;
379 t->position = NULL;
380 t->selection = NULL;
381 t->length = NULL;
382 t->remove = NULL;
383 t->obj = NULL;
384 t->undomgr = NULL;
385 }
386
387 void uic_range_unbind(UiRange *r) {
388 r->get = NULL;
389 r->set = NULL;
390 r->setextent = NULL;
391 r->setrange = NULL;
392 r->obj = NULL;
393 }
394
395 void uic_list_unbind(UiList *l) {
396 l->update = NULL;
397 l->obj = NULL;
398 }

mercurial