ui/cocoa/MainWindow.m

changeset 112
c3f2f16fa4b8
parent 110
c00e968d018b
child 113
dde28a806552
--- a/ui/cocoa/MainWindow.m	Sat Oct 04 14:54:25 2025 +0200
+++ b/ui/cocoa/MainWindow.m	Sun Oct 19 21:20:08 2025 +0200
@@ -31,6 +31,7 @@
 #import "GridLayout.h"
 #import "BoxContainer.h"
 #import "../common/object.h"
+#import "../ui/properties.h"
 #import <objc/runtime.h>
 
 #import "EventData.h"
@@ -39,7 +40,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 +59,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,31 +80,77 @@
             [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
+        const char *sidebarMaterialProperty = ui_get_property("ui.cocoa.sidebar.usematerial");
+        BOOL useMaterial = YES;
+        if(sidebarMaterialProperty && (sidebarMaterialProperty[0] == 'f' || sidebarMaterialProperty[0] == 'F')) {
+            useMaterial = NO;
+        }
+        
+        if(useMaterial) {
+            NSVisualEffectView *v = [[NSVisualEffectView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
+            v.material = NSVisualEffectMaterialSidebar;
+            v.blendingMode = NSVisualEffectBlendingModeBehindWindow;
+            v.state = NSVisualEffectStateActive;
+            _sidebar = v;
+        } else {
+            _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],
+        ]];
+        UiContainerX *container = ui_create_container(obj, vbox);
+        vbox.container = container;
+        uic_object_push_container(obj, container);
+    }
+    _topOffset = top;
     
     return self;
 }
 
+- (BOOL) getIsVisible {
+    return [self isVisible];
+}
+
+- (void) setVisible:(BOOL)visible {
+    if(visible) {
+        [self makeKeyAndOrderFront:nil];
+    } else {
+        [self close];
+    }
+}
+
+
 @end
 
 
@@ -312,6 +362,7 @@
     
     // create a vertical stackview as default container
     BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:args->spacing];
+    vbox.container = ui_create_container(obj, vbox);
     //GridLayout *vbox = [[GridLayout alloc] init];
     vbox.translatesAutoresizingMaskIntoConstraints = false;
     [sidebar addSubview:vbox];
@@ -321,7 +372,41 @@
         [vbox.trailingAnchor constraintEqualToAnchor:sidebar.trailingAnchor],
         [vbox.bottomAnchor constraintEqualToAnchor:sidebar.bottomAnchor]
     ]];
-    uic_object_push_container(obj, ui_create_container(obj, vbox));
+    uic_object_push_container(obj, vbox.container);
     
     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.container = ui_create_container(obj, vbox);
+    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, vbox.container);
+    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);
+}
+

mercurial