--- a/ui/cocoa/container.m Tue Oct 14 09:45:44 2025 +0200 +++ b/ui/cocoa/container.m Tue Oct 14 10:41:21 2025 +0200 @@ -76,7 +76,8 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { NSString *title = args->label ? [[NSString alloc]initWithUTF8String:args->label] : nil; - FrameContainer *frame = [[FrameContainer alloc] init:title]; UiLayout layout = UI_ARGS2LAYOUT(args); + FrameContainer *frame = [[FrameContainer alloc] init:title]; + UiLayout layout = UI_ARGS2LAYOUT(args); ui_container_add(obj, frame, &layout); // add container to the chain @@ -115,7 +116,27 @@ uic_object_push_container(obj, container); - return NULL; + return (__bridge void*)frame; +} + +UIWIDGET ui_scrolledwindow_create(UiObject *obj, UiFrameArgs *args) { + int colspacing = args->spacing; + int rowspacing = args->spacing; + if(args->subcontainer == UI_CONTAINER_GRID) { + colspacing = args->columnspacing; + rowspacing = args->rowspacing; + } + ScrollViewContainer *scrollview = [[ScrollViewContainer alloc]init:args->subcontainer columnSpacing:colspacing rowSpacing:rowspacing]; + scrollview.hasVerticalScroller = YES; + scrollview.scrollerStyle = NSScrollerStyleOverlay; + scrollview.autohidesScrollers = YES; + UiLayout layout = UI_ARGS2LAYOUT(args); + ui_container_add(obj, scrollview, &layout); + + UiContainerX *container = ui_create_container(obj, scrollview); + uic_object_push_container(obj, container); + + return (__bridge void*)scrollview; } void ui_container_begin_close(UiObject *obj) { @@ -161,6 +182,65 @@ @end + +/* -------------------------- Expander Container -------------------------- */ + +// TODO + + +/* ------------------------ ScrollView Container ------------------------ */ + +@implementation ScrollViewContainer + +@synthesize container = _container; + +- (id)init:(UiSubContainerType)subContainer columnSpacing:(int)columnSpacing rowSpacing:(int)rowSpacing { + self = [super init]; + + if(subContainer != UI_CONTAINER_NO_SUB) { + GridLayout *child; + switch(subContainer) { + default: + case UI_CONTAINER_VBOX: { + child = [[BoxContainer alloc]init:NSUserInterfaceLayoutOrientationVertical spacing:columnSpacing]; + break; + } + case UI_CONTAINER_HBOX: { + child = [[BoxContainer alloc]init:NSUserInterfaceLayoutOrientationHorizontal spacing:columnSpacing]; + break; + } + case UI_CONTAINER_GRID: { + child = [[GridLayout alloc]init]; + child.columnspacing = columnSpacing; + child.rowspacing = rowSpacing; + break; + } + } + child.translatesAutoresizingMaskIntoConstraints = NO; + + self.documentView = child; + [child.widthAnchor constraintEqualToAnchor:self.contentView.widthAnchor].active = YES; + + _child = child; + } + + + return self; +} + +- (void) addView:(NSView*)view layout:(UiLayout*)layout { + if(_child != nil) { + _child.container = self.container; // required, otherwise child has no container and can't access the newline property + view.translatesAutoresizingMaskIntoConstraints = NO; + [_child addView:view layout:layout]; + } else { + self.documentView = view; + [view.widthAnchor constraintEqualToAnchor:self.contentView.widthAnchor].active = YES; + } +} + +@end + /* ------------------------- private functions ------------------------- */ UiContainerX* ui_create_container(UiObject *obj, id<Container> container) { @@ -183,6 +263,6 @@ adjustedLayout.margin_top = adjustedLayout.margin; adjustedLayout.margin_bottom = adjustedLayout.margin; } - [container addView:view layout:layout]; + [container addView:view layout:&adjustedLayout]; }