ui/common/types.c

changeset 965
5d4419042d9b
parent 964
c563220d9aea
child 971
0224108bd8c2
equal deleted inserted replaced
964:c563220d9aea 965:5d4419042d9b
250 return info; 250 return info;
251 } 251 }
252 252
253 #define UI_MODEL_DEFAULT_ALLOC_SIZE 16 253 #define UI_MODEL_DEFAULT_ALLOC_SIZE 16
254 254
255
256 static void model_notify_observer(UiModel *model, int insert, int delete) {
257 UiModelChangeObserver *obs = model->observer;
258 while(obs) {
259 obs->update(model, obs->userdata, insert, delete);
260 obs = obs->next;
261 }
262 }
263
255 UiModel* ui_model_new(UiContext *ctx) { 264 UiModel* ui_model_new(UiContext *ctx) {
256 UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel)); 265 UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
257 info->ctx = ctx; 266 info->ctx = ctx;
258 info->alloc = UI_MODEL_DEFAULT_ALLOC_SIZE; 267 info->alloc = UI_MODEL_DEFAULT_ALLOC_SIZE;
259 info->types = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(UiModelType)); 268 info->types = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(UiModelType));
260 info->titles = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(char*)); 269 info->titles = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(char*));
261 info->columnsize = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(int)); 270 info->columnsize = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(int));
262 return info; 271 return info;
263 } 272 }
264 273
265 void ui_model_add_column(UiContext *ctx, UiModel *model, UiModelType type, const char *title, int width) { 274 void ui_model_add_column(UiModel *model, UiModelType type, const char *title, int width) {
275 UiContext *ctx = model->ctx;
266 if(model->columns >= model->alloc) { 276 if(model->columns >= model->alloc) {
267 model->alloc += UI_MODEL_DEFAULT_ALLOC_SIZE; 277 model->alloc += UI_MODEL_DEFAULT_ALLOC_SIZE;
268 model->types = ui_realloc(ctx, model->types, model->alloc * sizeof(UiModelType)); 278 model->types = ui_realloc(ctx, model->types, model->alloc * sizeof(UiModelType));
269 model->titles = ui_realloc(ctx, model->titles, model->alloc * sizeof(char*)); 279 model->titles = ui_realloc(ctx, model->titles, model->alloc * sizeof(char*));
270 model->columnsize = ui_realloc(ctx, model->columnsize, model->alloc * sizeof(int)); 280 model->columnsize = ui_realloc(ctx, model->columnsize, model->alloc * sizeof(int));
271 } 281 }
272 model->types[model->columns] = type; 282 int index = model->columns;
273 model->titles[model->columns] = ui_strdup(ctx, title); 283 model->types[index] = type;
274 model->columnsize[model->columns] = width; 284 model->titles[index] = ui_strdup(ctx, title);
285 model->columnsize[index] = width;
286
287 model_notify_observer(model, index, -1);
288
275 model->columns++; 289 model->columns++;
276 } 290 }
277 291
278 UiModel* ui_model_copy(UiContext *ctx, UiModel* model) { 292 UiModel* ui_model_copy(UiContext *ctx, UiModel* model) {
279 const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator; 293 const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator;
297 311
298 void ui_model_ref(UiModel *model) { 312 void ui_model_ref(UiModel *model) {
299 model->ref++; 313 model->ref++;
300 } 314 }
301 315
302 void ui_model_unref(UiModel *model) { 316 void ui_model_unref(UiModel *model) {
303 if(--model->ref == 0) { 317 if(--model->ref == 0) {
304 ui_model_free(model); 318 ui_model_free(model);
319 }
320 }
321
322 void ui_model_add_observer(UiModel *model, ui_model_update_func update, void *data) {
323 UiModelChangeObserver *observer = ui_malloc(model->ctx, sizeof(UiModelChangeObserver));
324 observer->update = update;
325 observer->userdata = data;
326 observer->next = NULL;
327
328 if(model->observer) {
329 UiModelChangeObserver *last = model->observer;
330 while(last->next) {
331 last = last->next;
332 }
333 last->next = observer;
334 } else {
335 model->observer = observer;
336 }
337 }
338
339 void ui_model_remove_observer(UiModel *model, void *data) {
340 if(model->observer) {
341 UiModelChangeObserver *obs = model->observer;
342 UiModelChangeObserver *prev = NULL;
343 while(obs) {
344 if(obs->userdata == data) {
345 // remove
346 if(prev) {
347 prev->next = obs->next;
348 } else {
349 model->observer = obs->next;
350 }
351 // free
352 ui_free(model->ctx, obs);
353 break;
354 }
355 prev = obs;
356 obs = obs->next;
357 }
305 } 358 }
306 } 359 }
307 360
308 void ui_model_free(UiModel *mi) { 361 void ui_model_free(UiModel *mi) {
309 UiContext *ctx = mi->ctx; 362 UiContext *ctx = mi->ctx;
310 const CxAllocator* a = ctx->allocator; 363 const CxAllocator* a = ctx->allocator;
311 for(int i=0;i<mi->columns;i++) { 364 for(int i=0;i<mi->columns;i++) {
312 ui_free(ctx, mi->titles[i]); 365 ui_free(ctx, mi->titles[i]);
366 }
367 UiModelChangeObserver *obs = mi->observer;
368 while(obs) {
369 UiModelChangeObserver *n = obs->next;
370 cxFree(a, obs);
371 obs = n;
313 } 372 }
314 cxFree(a, mi->types); 373 cxFree(a, mi->types);
315 cxFree(a, mi->titles); 374 cxFree(a, mi->titles);
316 cxFree(a, mi->columnsize); 375 cxFree(a, mi->columnsize);
317 cxFree(a, mi); 376 cxFree(a, mi);

mercurial