ui/cocoa/list.m

changeset 828
a952337ae325
parent 718
06eec75a6fd5
child 829
0980245646b4
equal deleted inserted replaced
827:eae5b817aa47 828:a952337ae325
28 28
29 #import "list.h" 29 #import "list.h"
30 #import "ListDelegate.h" 30 #import "ListDelegate.h"
31 #import <objc/runtime.h> 31 #import <objc/runtime.h>
32 32
33 #import <inttypes.h>
34 #import <limits.h>
35
36 #import <cx/array_list.h>
37
33 static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { 38 static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
34 ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata; 39 ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata;
35 return getvalue(elm, col); 40 return getvalue(elm, col);
36 } 41 }
37 42
352 [combobox selectItemAtIndex:selection.rows[0]]; 357 [combobox selectItemAtIndex:selection.rows[0]];
353 } else { 358 } else {
354 [combobox selectItemAtIndex: -1]; 359 [combobox selectItemAtIndex: -1];
355 } 360 }
356 } 361 }
362
363
364 /* --------------------------- SourceList --------------------------- */
365
366 static void sublist_free(const CxAllocator *a, UiSubList *sl) {
367 cxFree(a, (char*)sl->varname);
368 cxFree(a, (char*)sl->header);
369 }
370
371 static UiSubList copy_sublist(const CxAllocator *a, UiSubList *sl) {
372 UiSubList new_sl;
373 new_sl.value = sl->value;
374 new_sl.varname = sl->varname ? cx_strdup_a(a, cx_str(sl->varname)).ptr : NULL;
375 new_sl.header = sl->header ? cx_strdup_a(a, cx_str(sl->header)).ptr : NULL;
376 new_sl.separator = sl->separator;
377 new_sl.userdata = sl->userdata;
378 return new_sl;
379 }
380
381 static CxList* copy_sublists(const CxAllocator *a, UiSourceListArgs *args) {
382 if(args->sublists) {
383 size_t max = args->numsublists;
384 if(max == 0) {
385 max = INT_MAX;
386 }
387
388 CxList *sublists = cxArrayListCreate(a, NULL, sizeof(UiSubList), args->numsublists);
389 sublists->collection.advanced_destructor = (cx_destructor_func2)sublist_free;
390
391 for(int i=0;i<max;i++) {
392 UiSubList *sl = &args->sublists[i];
393 if(sl->value == NULL && sl->varname == NULL) {
394 break;
395 }
396
397 UiSubList new_sl = copy_sublist(a, sl);
398 cxListAdd(sublists, &new_sl);
399 }
400
401 return sublists;
402 }
403 return NULL;
404 }
405
406 UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args) {
407 // create views
408 NSScrollView *scrollview = [[NSScrollView alloc] init];
409 scrollview.autoresizingMask = NSViewWidthSizable;
410
411 NSOutlineView *outline = [[NSOutlineView alloc]init];
412 NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:@"label"];
413 [outline addTableColumn:column];
414 outline.outlineTableColumn = column;
415 outline.headerView = NULL;
416
417 outline.style = NSTableViewStyleSourceList;
418
419 // Make background transparent so vibrancy shows through
420 outline.backgroundColor = [NSColor clearColor];
421 scrollview.drawsBackground = NO;
422
423 scrollview.documentView = outline;
424
425 UiLayout layout = UI_ARGS2LAYOUT(args);
426 ui_container_add(obj, scrollview, &layout);
427
428 // datasource and delegate
429 UiSourceList *data = [[UiSourceList alloc] init:obj];
430 data.sublists = copy_sublists(obj->ctx->allocator, args);
431 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->dynamic_sublist, args->varname, UI_VAR_LIST);
432 if(var) {
433 UiList *list = var->value;
434 list->obj = (__bridge void*)data;
435 list->update = ui_sourcelist_update;
436 }
437 data.dynamic_sublists = var;
438 data.getvalue = args->getvalue;
439 data.getvaluedata = args->getvaluedata;
440 data.onactivate = args->onactivate;
441 data.onactivatedata = args->onactivatedata;
442 data.onbuttonclick = args->onbuttonclick;
443 data.onactivatedata = args->onbuttonclickdata;
444 [data update:-1];
445
446 outline.dataSource = data;
447 //outline.delegate = data;
448
449 objc_setAssociatedObject(outline, "ui_datasource", data, OBJC_ASSOCIATION_RETAIN);
450
451 return (__bridge void*)scrollview;
452 }
453
454 void ui_sourcelist_update(UiList *list, int row) {
455 UiSourceList *sourcelist = (__bridge UiSourceList*)list->obj;
456 [sourcelist update:row];
457 }
458
459
460 @implementation UiSourceList
461
462 - (id)init:(UiObject*)obj {
463 _obj = obj;
464 _sections = [[NSMutableArray alloc] initWithCapacity:16];
465 return self;
466 }
467
468 - (void)dealloc {
469 cxListFree(_sublists);
470 }
471
472 - (void)update:(int)row {
473 // TODO: check row
474
475 [_sections removeAllObjects];
476
477 CxIterator i = cxListIterator(_sublists);
478 cx_foreach(UiSubList *, sl, i) {
479 UiSourceListItem *section = [[UiSourceListItem alloc] init:self sublist:sl];
480 [section update:-1];
481 [_sections addObject:section];
482 }
483 }
484
485 // NSOutlineViewDataSource implementation
486
487 - (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
488 if(item == nil) {
489 return _sections.count;
490 } else {
491 UiSourceListItem *i = item;
492 return i.items.count;
493 }
494 }
495
496 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
497 UiSourceListItem *i = item;
498 return [i isSection];
499 }
500
501 - (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
502 UiSourceListItem *i = item;
503 if(i) {
504 return [i.items objectAtIndex:index];
505 }
506 return [_sections objectAtIndex:index];
507 }
508
509 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
510 UiSourceListItem *i = item;
511 if([[tableColumn identifier] isEqualToString:@"label"]) {
512 return i.label;
513 }
514 return nil;
515 }
516
517 - (void)outlineView:(NSOutlineView *)outlineView
518 setObjectValue:(id)object
519 forTableColumn:(NSTableColumn *)tableColumn
520 byItem:(id)item {
521
522 }
523
524 @end
525
526 @implementation UiSourceListItem
527
528 - (id)init:(UiSourceList*)sourcelist sublist:(UiSubList*)sublist {
529 _sourcelist = sourcelist;
530 _sublist = sublist;
531 _items = [[NSMutableArray alloc]initWithCapacity:16];
532 if(sublist->header) {
533 _label = [[NSString alloc]initWithUTF8String:sublist->header];
534 }
535 UiVar *var = uic_widget_var(sourcelist.obj->ctx,
536 sourcelist.obj->ctx,
537 sublist->value,
538 sublist->varname,
539 UI_VAR_LIST);
540 _var = var;
541 return self;
542 }
543
544 - (id)init:(UiSubListItem*)item {
545 if(item->label) {
546 _label = [[NSString alloc]initWithUTF8String:item->label];
547 }
548 return self;
549 }
550
551 - (BOOL)isSection {
552 return _sublist != NULL;
553 }
554
555 - (void)update:(int)row {
556 [_items removeAllObjects];
557 if(_var == NULL) {
558 return;
559 }
560 UiList *list = _var->value;
561 void *elm = list->first(list);
562 int index = 0;
563 while(elm) {
564 UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL };
565 if(_sourcelist.getvalue) {
566 _sourcelist.getvalue(list, _sublist->userdata, elm, index, &item, _sourcelist.getvaluedata);
567 } else {
568 item.label = strdup(elm);
569 }
570
571 [_items addObject:[[UiSourceListItem alloc] init:&item]];
572
573 elm = list->next(list);
574 index++;
575 }
576 }
577
578 @end
579

mercurial