diff -r 7b5ba65b246f -r 1391ba7e533f ui/cocoa/MainWindow.m --- a/ui/cocoa/MainWindow.m Tue Oct 07 14:59:11 2025 +0200 +++ b/ui/cocoa/MainWindow.m Tue Oct 07 15:42:18 2025 +0200 @@ -39,7 +39,7 @@ @implementation MainWindow -- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)sidebar { +- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview{ NSRect frame = NSMakeRect(300, 200, 600, 500); self = [self initWithContentRect:frame @@ -58,12 +58,15 @@ int top = 4; NSView *content = self.contentView; - if(sidebar) { + + // A sidebar or splitview window need a NSSplitView + NSSplitView *splitview; + if(hasSidebar || hasSplitview) { self.styleMask |= NSWindowStyleMaskFullSizeContentView; self.titleVisibility = NSWindowTitleHidden; self.titlebarAppearsTransparent = YES; - NSSplitView *splitview = [[NSSplitView alloc]init]; + splitview = [[NSSplitView alloc]init]; splitview.vertical = YES; splitview.dividerStyle = NSSplitViewDividerStyleThin; splitview.translatesAutoresizingMaskIntoConstraints = false; @@ -76,27 +79,44 @@ [splitview.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor] ]]; - _sidebar = [[NSView alloc]initWithFrame:NSMakeRect(0,0,100,100)]; - [splitview addArrangedSubview:_sidebar]; - - content = [[NSView alloc]initWithFrame:NSMakeRect(0,0,100,100)]; - [splitview addArrangedSubview:content]; - top = 34; } - // create a vertical stackview as default container - BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0]; - //GridLayout *vbox = [[GridLayout alloc] init]; - vbox.translatesAutoresizingMaskIntoConstraints = false; - [content addSubview:vbox]; - [NSLayoutConstraint activateConstraints:@[ - [vbox.topAnchor constraintEqualToAnchor:content.topAnchor constant:top], - [vbox.leadingAnchor constraintEqualToAnchor:content.leadingAnchor], - [vbox.trailingAnchor constraintEqualToAnchor:content.trailingAnchor], - [vbox.bottomAnchor constraintEqualToAnchor:content.bottomAnchor], - ]]; - uic_object_push_container(obj, ui_create_container(obj, vbox)); + if(hasSidebar) { + // add the sidebar + _sidebar = [[NSView alloc]initWithFrame:NSMakeRect(0,0,0,0)]; + _sidebar.translatesAutoresizingMaskIntoConstraints = NO; + [splitview addArrangedSubview:_sidebar]; + [_sidebar.widthAnchor constraintGreaterThanOrEqualToConstant:250].active = YES; + } + if(hasSplitview) { + // add the splitview window left/right panels + _leftPanel = [[NSView alloc]initWithFrame:NSMakeRect(0,0,100,100)]; + [splitview addArrangedSubview:_leftPanel]; + _rightPanel = [[NSView alloc]initWithFrame:NSMakeRect(0,0,100,100)]; + [splitview addArrangedSubview:_rightPanel]; + } else if(hasSidebar) { + // sidebar only window: add content view + content = [[NSView alloc]initWithFrame:NSMakeRect(0,0,100,100)]; + [splitview addArrangedSubview:content]; + } + + // normal or sidebar-only windows get a container + if(!hasSplitview) { + // create a vertical stackview as default container + BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0]; + //GridLayout *vbox = [[GridLayout alloc] init]; + vbox.translatesAutoresizingMaskIntoConstraints = false; + [content addSubview:vbox]; + [NSLayoutConstraint activateConstraints:@[ + [vbox.topAnchor constraintEqualToAnchor:content.topAnchor constant:top], + [vbox.leadingAnchor constraintEqualToAnchor:content.leadingAnchor], + [vbox.trailingAnchor constraintEqualToAnchor:content.trailingAnchor], + [vbox.bottomAnchor constraintEqualToAnchor:content.bottomAnchor], + ]]; + uic_object_push_container(obj, ui_create_container(obj, vbox)); + } + _topOffset = top; return self; } @@ -325,3 +345,36 @@ return NULL; } + +static UIWIDGET splitview_window_add_panel(UiObject *obj, NSView *panel, UiSidebarArgs *args) { + MainWindow *window = (__bridge MainWindow*)obj->wobj; + BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0]; + //GridLayout *vbox = [[GridLayout alloc] init]; + vbox.translatesAutoresizingMaskIntoConstraints = false; + [panel addSubview:vbox]; + [NSLayoutConstraint activateConstraints:@[ + [vbox.topAnchor constraintEqualToAnchor:panel.topAnchor constant:window.topOffset], + [vbox.leadingAnchor constraintEqualToAnchor:panel.leadingAnchor], + [vbox.trailingAnchor constraintEqualToAnchor:panel.trailingAnchor], + [vbox.bottomAnchor constraintEqualToAnchor:panel.bottomAnchor], + ]]; + uic_object_push_container(obj, ui_create_container(obj, vbox)); + return (__bridge void*)vbox; +} + +UIWIDGET ui_left_panel_create(UiObject *obj, UiSidebarArgs *args) { + MainWindow *window = (__bridge MainWindow*)obj->wobj; + if(window.leftPanel == nil) { + return NULL; + } + return splitview_window_add_panel(obj, window.leftPanel, args); +} + +UIWIDGET ui_right_panel_create(UiObject *obj, UiSidebarArgs *args) { + MainWindow *window = (__bridge MainWindow*)obj->wobj; + if(window.rightPanel == nil) { + return NULL; + } + return splitview_window_add_panel(obj, window.rightPanel, args); +} +