# HG changeset patch # User Olaf Wintermann # Date 1755963915 -7200 # Node ID 673e7e41c93ebcc325f1134913315e39d7ebd61b # Parent 6c7f700e490013d6ee35dfb2835a7c228c9ffae4 add minimally working listview (Cocoa) diff -r 6c7f700e4900 -r 673e7e41c93e make/xcode/toolkit/toolkit.xcodeproj/project.pbxproj --- a/make/xcode/toolkit/toolkit.xcodeproj/project.pbxproj Sat Aug 23 14:24:09 2025 +0200 +++ b/make/xcode/toolkit/toolkit.xcodeproj/project.pbxproj Sat Aug 23 17:45:15 2025 +0200 @@ -46,6 +46,9 @@ ED65815F2CFF4BF200F5402F /* WindowManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ED65815E2CFF4BF200F5402F /* WindowManager.m */; }; ED8687E52D999CF3002F3EC2 /* menu.m in Sources */ = {isa = PBXBuildFile; fileRef = ED8687E42D999CF3002F3EC2 /* menu.m */; }; EDB452C32E302C65006FB12D /* image.m in Sources */ = {isa = PBXBuildFile; fileRef = EDB452C22E302C65006FB12D /* image.m */; }; + EDCD22272E59EEF5000612AF /* list.m in Sources */ = {isa = PBXBuildFile; fileRef = EDCD22262E59EEF5000612AF /* list.m */; }; + EDCD22352E59F3B1000612AF /* ListDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = EDCD22342E59F3B1000612AF /* ListDataSource.m */; }; + EDCD22382E5A160A000612AF /* ListDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EDCD22372E5A160A000612AF /* ListDelegate.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -149,6 +152,12 @@ ED8687E42D999CF3002F3EC2 /* menu.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = menu.m; path = ../../../ui/cocoa/menu.m; sourceTree = SOURCE_ROOT; }; EDB452C12E302C65006FB12D /* image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = image.h; path = /Users/olaf/Projekte/toolkit/ui/cocoa/image.h; sourceTree = ""; }; EDB452C22E302C65006FB12D /* image.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = image.m; path = /Users/olaf/Projekte/toolkit/ui/cocoa/image.m; sourceTree = ""; }; + EDCD22252E59EEF5000612AF /* list.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = list.h; path = /Users/olaf/Projekte/toolkit/ui/cocoa/list.h; sourceTree = ""; }; + EDCD22262E59EEF5000612AF /* list.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = list.m; path = /Users/olaf/Projekte/toolkit/ui/cocoa/list.m; sourceTree = ""; }; + EDCD22332E59F3B1000612AF /* ListDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ListDataSource.h; path = /Users/olaf/Projekte/toolkit/ui/cocoa/ListDataSource.h; sourceTree = ""; }; + EDCD22342E59F3B1000612AF /* ListDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ListDataSource.m; path = /Users/olaf/Projekte/toolkit/ui/cocoa/ListDataSource.m; sourceTree = ""; }; + EDCD22362E5A160A000612AF /* ListDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ListDelegate.h; path = /Users/olaf/Projekte/toolkit/ui/cocoa/ListDelegate.h; sourceTree = ""; }; + EDCD22372E5A160A000612AF /* ListDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ListDelegate.m; path = /Users/olaf/Projekte/toolkit/ui/cocoa/ListDelegate.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -269,6 +278,12 @@ ED65812E2CFF1A7200F5402F /* cocoa */ = { isa = PBXGroup; children = ( + EDCD22362E5A160A000612AF /* ListDelegate.h */, + EDCD22372E5A160A000612AF /* ListDelegate.m */, + EDCD22332E59F3B1000612AF /* ListDataSource.h */, + EDCD22342E59F3B1000612AF /* ListDataSource.m */, + EDCD22252E59EEF5000612AF /* list.h */, + EDCD22262E59EEF5000612AF /* list.m */, ED2F55AC2E34FAD800A84793 /* Toolbar.h */, ED2F55AD2E34FAD800A84793 /* Toolbar.m */, EDB452C12E302C65006FB12D /* image.h */, @@ -402,9 +417,11 @@ files = ( ED6580EE2CFF19F900F5402F /* context.c in Sources */, ED6580EF2CFF19F900F5402F /* menu.c in Sources */, + EDCD22352E59F3B1000612AF /* ListDataSource.m in Sources */, ED6580F02CFF19F900F5402F /* threadpool.c in Sources */, EDB452C32E302C65006FB12D /* image.m in Sources */, ED6580F12CFF19F900F5402F /* condvar.c in Sources */, + EDCD22272E59EEF5000612AF /* list.m in Sources */, ED65815F2CFF4BF200F5402F /* WindowManager.m in Sources */, ED6580F22CFF19F900F5402F /* document.c in Sources */, ED65811D2CFF1A3000F5402F /* linked_list.c in Sources */, @@ -437,6 +454,7 @@ ED6580F52CFF19F900F5402F /* types.c in Sources */, ED8687E52D999CF3002F3EC2 /* menu.m in Sources */, ED6580F62CFF19F900F5402F /* properties.c in Sources */, + EDCD22382E5A160A000612AF /* ListDelegate.m in Sources */, ED6580F72CFF19F900F5402F /* ucx_properties.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff -r 6c7f700e4900 -r 673e7e41c93e make/xcode/toolkit/toolkit/main.m --- a/make/xcode/toolkit/toolkit/main.m Sat Aug 23 14:24:09 2025 +0200 +++ b/make/xcode/toolkit/toolkit/main.m Sat Aug 23 17:45:15 2025 +0200 @@ -36,12 +36,18 @@ typedef struct MyDocument { UiInteger *tbtoggle; + UiList *list1; } MyDocument; MyDocument* create_doc(void) { MyDocument *doc = ui_document_new(sizeof(MyDocument)); UiContext *ctx = ui_document_context(doc); doc->tbtoggle = ui_int_new(ctx, "tbtoggle"); + doc->list1 = ui_list_new(ctx, "list1"); + ui_list_append(doc->list1, "Item 1"); + ui_list_append(doc->list1, "Item 2"); + ui_list_append(doc->list1, "Item 3"); + ui_list_append(doc->list1, "Item 4"); return doc; } @@ -63,6 +69,14 @@ printf("menuitem\n"); } +static void action_list_selection(UiEvent *event, void *userdata) { + printf("selection\n"); +} + +static void action_list_activate(UiEvent *event, void *userdata) { + printf("activate\n"); +} + void application_startup(UiEvent *event, void *data) { UiObject *obj = ui_window("My Window", NULL); //WindowData *wdata = ui_malloc(obj->ctx, sizeof(WindowData)); @@ -73,7 +87,7 @@ ui_grid(obj, .columnspacing = 10, .rowspacing = 10) { - ui_textarea(obj, .fill = UI_ON); + ui_listview(obj, .fill = UI_ON, .varname = "list1", .onactivate = action_list_activate, .onselection = action_list_selection); } diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/ListDataSource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/ListDataSource.h Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "toolkit.h" +#import "../ui/tree.h" + +@interface ListDataSource : NSObject + +@property NSArray *columns; +@property UiVar *var; +@property ui_getvaluefunc2 getvalue; +@property void *getvaluedata; +@property UiModel *model; + +- (id) init:(NSArray*) columns var:(UiVar*)var getvalue:(ui_getvaluefunc2) getvaluefunc getvaluedata:(void*)userdata; + +@end diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/ListDataSource.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/ListDataSource.m Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,110 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "ListDataSource.h" + +@implementation ListDataSource + +- (id) init:(NSArray*) columns var:(UiVar*)var getvalue:(ui_getvaluefunc2) getvaluefunc getvaluedata:(void*)userdata { + _columns = columns; + _var = var; + _getvalue = getvaluefunc; + _getvaluedata = userdata; + return self; +} + +- (NSInteger) numberOfRowsInTableView:(NSTableView *) tableView { + if(_var) { + UiList *list = _var->value; + if(list->count) { + return list->count(list); + } + } + return 0; +} + +- (id) tableView:(NSTableView *) tableView +objectValueForTableColumn:(NSTableColumn *) tableColumn + row:(NSInteger) row +{ + id ret = nil; + UiList *list = _var->value; + void *elm = list->get(list, (int)row); + if(elm) { + // get column index + NSUInteger colIndex = [_columns indexOfObject:tableColumn]; + if(colIndex == NSNotFound) { + return nil; + } + + // get UI model type for this column + UiModelType type = UI_STRING; + UiModel *model = _model; + if(model) { + if(colIndex >= model->columns) { + return nil; + } + type = model->types[colIndex]; + } + + // convert the list element + UiBool freeResult = FALSE; + void *data = _getvalue(list, elm, (int)row, (int)colIndex, _getvaluedata, &freeResult); + + switch(type) { + case UI_STRING: { + ret = [[NSString alloc] initWithUTF8String:data]; + break; + } + case UI_STRING_FREE: { + ret = [[NSString alloc] initWithUTF8String:data]; + freeResult = TRUE; + break; + } + case UI_INTEGER: { + break; + } + case UI_ICON: { + break; + } + case UI_ICON_TEXT: { + break; + } + case UI_ICON_TEXT_FREE: { + break; + } + } + + if(freeResult) { + free(data); + } + } + return ret; +} + +@end diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/ListDelegate.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/ListDelegate.h Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,43 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "toolkit.h" + +@interface ListDelegate : NSObject + +@property UiObject *obj; +@property ui_callback onselection; +@property void *onselectiondata; +@property ui_callback onactivate; +@property void *onactivatedata; + +- (id)init:(UiObject*)obj; + +- (void)activateEvent:(id)sender; + +@end diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/ListDelegate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/ListDelegate.m Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,60 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "ListDelegate.h" + +@implementation ListDelegate + +- (id)init:(UiObject*)obj { + _obj = obj; + return self; +} + +- (void)activateEvent:(id)sender { + NSTableView *table = sender; + if(_onactivate) { + int row = (int)table.clickedRow; + + UiListSelection sel; + sel.count = 1; + sel.rows = &row; + + UiEvent event; + event.obj = _obj; + event.window = event.obj->window; + event.document = event.obj->ctx->document; + event.eventdata = &sel; + event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; + event.intval = row; + event.set = ui_get_setop(); + + _onactivate(&event, _onactivatedata); + } +} + +@end diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/list.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/list.h Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,33 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "toolkit.h" +#import "container.h" +#import "../ui/tree.h" + +#import "ListDataSource.h" diff -r 6c7f700e4900 -r 673e7e41c93e ui/cocoa/list.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/list.m Sat Aug 23 17:45:15 2025 +0200 @@ -0,0 +1,90 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "list.h" +#import "ListDelegate.h" +#import + +static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { + ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata; + return getvalue(elm, col); +} + +static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { + return elm; +} + +UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args) { + NSScrollView *scrollview = [[NSScrollView alloc] init]; + + NSTableView *tableview = [[NSTableView alloc] init]; + tableview.autoresizingMask = NSViewWidthSizable; + tableview.headerView = nil; + + scrollview.documentView = tableview; + + UiLayout layout = UI_INIT_LAYOUT(args); + ui_container_add(obj, scrollview, &layout, TRUE); + + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); + if(var) { + ui_getvaluefunc2 getvalue = args->getvalue2; + void *getvaluedata = args->getvalue2data; + if(!getvalue) { + if(args->getvalue) { + getvalue = getvalue_wrapper; + getvaluedata = (void*)args->getvalue; + } else { + getvalue = str_getvalue; // by default list values are interpreted as strings + } + } + + NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:@"column"]; + column.width = 400; + [tableview addTableColumn:column]; + + ListDataSource *dataSource = [[ListDataSource alloc] init:tableview.tableColumns var:var getvalue:getvalue getvaluedata:getvaluedata]; + + tableview.dataSource = dataSource; + [tableview reloadData]; + + objc_setAssociatedObject(tableview, "ui_datasource", dataSource, OBJC_ASSOCIATION_RETAIN); + } + + ListDelegate *delegate = [[ListDelegate alloc] init:obj]; + delegate.onactivate = args->onactivate; + delegate.onactivatedata = args->onactivatedata; + delegate.onselection = args->onselection; + delegate.onselectiondata = args->onselectiondata; + tableview.delegate = delegate; + objc_setAssociatedObject(tableview, "ui_listdelegate", delegate, OBJC_ASSOCIATION_RETAIN); + tableview.doubleAction = @selector(activateEvent:); + tableview.target = delegate; + + return (__bridge void*)scrollview; +}