UNIXworkcode

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 } 392