ui/cocoa/container.m

branch
newapi
changeset 404
384f6d1f5784
parent 51
42506e19eb6b
--- a/ui/cocoa/container.m	Sat Nov 30 20:33:16 2024 +0100
+++ b/ui/cocoa/container.m	Wed Dec 04 08:55:49 2024 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2014 Olaf Wintermann. All rights reserved.
+ * Copyright 2024 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:
@@ -26,81 +26,143 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#import <stdio.h>
-#import <stdlib.h>
+#import "Container.h"
+#import "GridLayout.h"
+
+/* ------------------------- container classes ------------------------- */
 
-#import "container.h"
+@implementation BoxContainer
 
+@synthesize label=_label;
+@synthesize uilayout=_uilayout;
+@synthesize newline=_newline;
 
-UiContainer* ui_window_container(UiObject *obj, NSWindow *window) {
-    UiContainer *ct = ucx_mempool_malloc(
-                                         obj->ctx->mempool,
-                                         sizeof(UiContainer));
-    ct->widget = [window contentView];
-    ct->add = ui_container_add;
-    ct->getframe = ui_container_getframe;
-    return ct;
+- (BoxContainer*)init:(NSUserInterfaceLayoutOrientation)orientation spacing:(int)spacing {
+    self = [super init];
+    _label = NULL;
+    _uilayout = (UiLayout){ 0 };
+    _newline = false;
+    
+    self.distribution = NSStackViewDistributionFillProportionally;
+    self.spacing = spacing;
+    
+    self.orientation = orientation;
+    if(orientation == NSUserInterfaceLayoutOrientationHorizontal) {
+        self.alignment = NSLayoutAttributeHeight;
+    } else {
+        self.alignment = NSLayoutAttributeWidth;
+    }
+    
+    
+    return self;
 }
 
-UIWIDGET ui_sidebar(UiObject *obj) {
-    UiContainer *ct = uic_get_current_container(obj);
-    NSRect frame = ct->getframe(ct);
+- (void) addView:(NSView*)view fill:(BOOL)fill {
+    if(_uilayout.fill != UI_LAYOUT_UNDEFINED) {
+        fill = ui_lb2bool(_uilayout.fill);
+    }
     
-    // create and add views
-    NSSplitView *splitview = [[NSSplitView alloc] initWithFrame:frame];
-    [splitview setVertical:YES];
-    [splitview setDividerStyle:NSSplitViewDividerStyleThin];
-    ct->add(ct, splitview);
+    [self addArrangedSubview:view];
     
-    NSRect lframe;
-    lframe.origin.x = 0;
-    lframe.origin.y = 0;
-    lframe.size.width = 200;
-    lframe.size.height = frame.size.height;
-    
-    NSRect rframe;
-    rframe.origin.x = 0;
-    rframe.origin.y = 0;
-    rframe.size.width = frame.size.width - 201;
-    rframe.size.height = frame.size.height;
-    
-    NSView *sidebar = [[NSView alloc]initWithFrame:lframe];
-    NSView *contentarea = [[NSView alloc]initWithFrame:rframe];
+    if(self.orientation == NSUserInterfaceLayoutOrientationHorizontal) {
+        [view.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = YES;
+        if(!fill) {
+            [view.widthAnchor constraintEqualToConstant:view.intrinsicContentSize.width].active = YES;
+        }
+    } else {
+        [view.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
+        if(!fill) {
+            [view.heightAnchor constraintEqualToConstant:view.intrinsicContentSize.height].active = YES;
+        }
+    }
     
-    [splitview addSubview:sidebar];
-    [splitview addSubview:contentarea];
+    // at the moment, only the fill layout option needs to be reset
+    _uilayout.fill = UI_DEFAULT;
+}
+
+@end
+
+
+
+/* -------------------- public container functions --------------------- */
+
+static UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs args, NSUserInterfaceLayoutOrientation orientation) {
+    BoxContainer *box = [[BoxContainer alloc] init:orientation spacing:args.spacing];
+    box.translatesAutoresizingMaskIntoConstraints = false;
     
-    // add ui objects for the sidebar and contentarea
-    // the sidebar is added last, so that new views are added first to it
-    UiObject *left = uic_object_new(obj, sidebar);
-    UiContainer *ct1 = ucx_mempool_malloc(
-            obj->ctx->mempool,
-            sizeof(UiContainer));
-    ct1->widget = sidebar;
-    ct1->add = ui_container_add;
-    ct1->getframe = ui_container_getframe;
-    left->container = ct1;
+    // add box to the parent
+    UiLayout layout = UI_INIT_LAYOUT(args);
+    ui_container_add(obj, box, &layout, TRUE);
+    
+    // add new box to the obj container chain
+    uic_object_push_container(obj, ui_create_container(obj, box));
     
-    UiObject *right = uic_object_new(obj, sidebar);
-    UiContainer *ct2 = ucx_mempool_malloc(
-            obj->ctx->mempool,
-            sizeof(UiContainer));
-    ct2->widget = contentarea;
-    ct2->add = ui_container_add;
-    ct2->getframe = ui_container_getframe;
-    right->container = ct2;
+    return (__bridge void*)box;
+}
+
+UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) {
+    return ui_box_create(obj, args, NSUserInterfaceLayoutOrientationVertical);
+}
+
+UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) {
+    return ui_box_create(obj, args, NSUserInterfaceLayoutOrientationHorizontal);
+}
+
+UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) {
+    GridLayout *grid = [[GridLayout alloc] init];
+    grid.translatesAutoresizingMaskIntoConstraints = false;
     
-    uic_obj_add(obj, right);
-    uic_obj_add(obj, left);
+    // add box to the parent
+    UiLayout layout = UI_INIT_LAYOUT(args);
+    ui_container_add(obj, grid, &layout, TRUE);
     
-    return splitview;
+    // add new box to the obj container chain
+    uic_object_push_container(obj, ui_create_container(obj, grid));
+    
+    return (__bridge void*)grid;
 }
 
 
-NSRect ui_container_getframe(UiContainer *ct) {
-    return [ct->widget frame];
+void ui_container_begin_close(UiObject *obj) {
+    UiContainerX *ct = obj->container_end;
+    ct->close = 1;
+}
+
+int ui_container_finish(UiObject *obj) {
+    UiContainerX *ct = obj->container_end;
+    if(ct->close) {
+        ui_end_new(obj);
+        return 0;
+    }
+    return 1;
 }
 
-void ui_container_add(UiContainer *ct, NSView *view) {
-    [ct->widget addSubview: view];
+/* ------------------------- private functions ------------------------- */
+
+UiContainerX* ui_create_container(UiObject *obj, id<Container> container) {
+    UiContainerX *ctn = ui_malloc(obj->ctx, sizeof(UiContainerX));
+    ctn->container = (__bridge void*)container;
+    ctn->close = 0;
+    ctn->prev = NULL;
+    ctn->next = NULL;
+    return ctn;
 }
+
+void ui_container_add(UiObject *obj, NSView *view, UiLayout *layout, UiBool fill) {
+    UiContainerX *ctn = obj->container_end;
+    id<Container> container = (__bridge id<Container>)ctn->container;
+    container.uilayout = *layout;
+    [container addView:view fill:fill];
+}
+
+/* ---------------------- public layout functions ----------------------- */
+
+void ui_newline(UiObject *obj) {
+    UiContainerX *ctn = obj->container_end;
+    if(ctn) {
+        id<Container> container = (__bridge id<Container>)ctn->container;
+        container.newline = TRUE;
+    } else {
+        fprintf(stderr, "Error: obj has no container\n");
+    }
+}

mercurial