ui/cocoa/container.m

changeset 100
d2bd73d28ff1
parent 0
2483f517c562
equal deleted inserted replaced
99:b9767cb5b06b 100:d2bd73d28ff1
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2014 Olaf Wintermann. All rights reserved. 4 * Copyright 2024 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #import <stdio.h> 29 #import "Container.h"
30 #import <stdlib.h> 30 #import "GridLayout.h"
31 31
32 #import "container.h" 32 /* ------------------------- container classes ------------------------- */
33
34 @implementation BoxContainer
35
36 @synthesize label=_label;
37 @synthesize uilayout=_uilayout;
38 @synthesize newline=_newline;
39
40 - (BoxContainer*)init:(NSUserInterfaceLayoutOrientation)orientation spacing:(int)spacing {
41 self = [super init];
42 _label = NULL;
43 _uilayout = (UiLayout){ 0 };
44 _newline = false;
45
46 self.distribution = NSStackViewDistributionFillProportionally;
47 self.spacing = spacing;
48
49 self.orientation = orientation;
50 if(orientation == NSUserInterfaceLayoutOrientationHorizontal) {
51 self.alignment = NSLayoutAttributeHeight;
52 } else {
53 self.alignment = NSLayoutAttributeWidth;
54 }
55
56
57 return self;
58 }
59
60 - (void) addView:(NSView*)view fill:(BOOL)fill {
61 if(_uilayout.fill != UI_LAYOUT_UNDEFINED) {
62 fill = ui_lb2bool(_uilayout.fill);
63 }
64
65 [self addArrangedSubview:view];
66
67 if(self.orientation == NSUserInterfaceLayoutOrientationHorizontal) {
68 [view.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = YES;
69 if(!fill) {
70 [view.widthAnchor constraintEqualToConstant:view.intrinsicContentSize.width].active = YES;
71 }
72 } else {
73 [view.widthAnchor constraintEqualToAnchor:self.widthAnchor].active = YES;
74 if(!fill) {
75 [view.heightAnchor constraintEqualToConstant:view.intrinsicContentSize.height].active = YES;
76 }
77 }
78
79 // at the moment, only the fill layout option needs to be reset
80 _uilayout.fill = UI_DEFAULT;
81 }
82
83 @end
33 84
34 85
35 UiContainer* ui_window_container(UiObject *obj, NSWindow *window) { 86
36 UiContainer *ct = ucx_mempool_malloc( 87 /* -------------------- public container functions --------------------- */
37 obj->ctx->mempool, 88
38 sizeof(UiContainer)); 89 static UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs args, NSUserInterfaceLayoutOrientation orientation) {
39 ct->widget = [window contentView]; 90 BoxContainer *box = [[BoxContainer alloc] init:orientation spacing:args.spacing];
40 ct->add = ui_container_add; 91 box.translatesAutoresizingMaskIntoConstraints = false;
41 ct->getframe = ui_container_getframe; 92
42 return ct; 93 // add box to the parent
94 UiLayout layout = UI_INIT_LAYOUT(args);
95 ui_container_add(obj, box, &layout, TRUE);
96
97 // add new box to the obj container chain
98 uic_object_push_container(obj, ui_create_container(obj, box));
99
100 return (__bridge void*)box;
43 } 101 }
44 102
45 UIWIDGET ui_sidebar(UiObject *obj) { 103 UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) {
46 UiContainer *ct = uic_get_current_container(obj); 104 return ui_box_create(obj, args, NSUserInterfaceLayoutOrientationVertical);
47 NSRect frame = ct->getframe(ct); 105 }
106
107 UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) {
108 return ui_box_create(obj, args, NSUserInterfaceLayoutOrientationHorizontal);
109 }
110
111 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) {
112 GridLayout *grid = [[GridLayout alloc] init];
113 grid.translatesAutoresizingMaskIntoConstraints = false;
48 114
49 // create and add views 115 // add box to the parent
50 NSSplitView *splitview = [[NSSplitView alloc] initWithFrame:frame]; 116 UiLayout layout = UI_INIT_LAYOUT(args);
51 [splitview setVertical:YES]; 117 ui_container_add(obj, grid, &layout, TRUE);
52 [splitview setDividerStyle:NSSplitViewDividerStyleThin];
53 ct->add(ct, splitview);
54 118
55 NSRect lframe; 119 // add new box to the obj container chain
56 lframe.origin.x = 0; 120 uic_object_push_container(obj, ui_create_container(obj, grid));
57 lframe.origin.y = 0;
58 lframe.size.width = 200;
59 lframe.size.height = frame.size.height;
60 121
61 NSRect rframe; 122 return (__bridge void*)grid;
62 rframe.origin.x = 0;
63 rframe.origin.y = 0;
64 rframe.size.width = frame.size.width - 201;
65 rframe.size.height = frame.size.height;
66
67 NSView *sidebar = [[NSView alloc]initWithFrame:lframe];
68 NSView *contentarea = [[NSView alloc]initWithFrame:rframe];
69
70 [splitview addSubview:sidebar];
71 [splitview addSubview:contentarea];
72
73 // add ui objects for the sidebar and contentarea
74 // the sidebar is added last, so that new views are added first to it
75 UiObject *left = uic_object_new(obj, sidebar);
76 UiContainer *ct1 = ucx_mempool_malloc(
77 obj->ctx->mempool,
78 sizeof(UiContainer));
79 ct1->widget = sidebar;
80 ct1->add = ui_container_add;
81 ct1->getframe = ui_container_getframe;
82 left->container = ct1;
83
84 UiObject *right = uic_object_new(obj, sidebar);
85 UiContainer *ct2 = ucx_mempool_malloc(
86 obj->ctx->mempool,
87 sizeof(UiContainer));
88 ct2->widget = contentarea;
89 ct2->add = ui_container_add;
90 ct2->getframe = ui_container_getframe;
91 right->container = ct2;
92
93 uic_obj_add(obj, right);
94 uic_obj_add(obj, left);
95
96 return splitview;
97 } 123 }
98 124
99 125
100 NSRect ui_container_getframe(UiContainer *ct) { 126 void ui_container_begin_close(UiObject *obj) {
101 return [ct->widget frame]; 127 UiContainerX *ct = obj->container_end;
128 ct->close = 1;
102 } 129 }
103 130
104 void ui_container_add(UiContainer *ct, NSView *view) { 131 int ui_container_finish(UiObject *obj) {
105 [ct->widget addSubview: view]; 132 UiContainerX *ct = obj->container_end;
133 if(ct->close) {
134 ui_end_new(obj);
135 return 0;
136 }
137 return 1;
106 } 138 }
139
140 /* ------------------------- private functions ------------------------- */
141
142 UiContainerX* ui_create_container(UiObject *obj, id<Container> container) {
143 UiContainerX *ctn = ui_malloc(obj->ctx, sizeof(UiContainerX));
144 ctn->container = (__bridge void*)container;
145 ctn->close = 0;
146 ctn->prev = NULL;
147 ctn->next = NULL;
148 return ctn;
149 }
150
151 void ui_container_add(UiObject *obj, NSView *view, UiLayout *layout, UiBool fill) {
152 UiContainerX *ctn = obj->container_end;
153 id<Container> container = (__bridge id<Container>)ctn->container;
154 container.uilayout = *layout;
155 [container addView:view fill:fill];
156 }
157
158 /* ---------------------- public layout functions ----------------------- */
159
160 void ui_newline(UiObject *obj) {
161 UiContainerX *ctn = obj->container_end;
162 if(ctn) {
163 id<Container> container = (__bridge id<Container>)ctn->container;
164 container.newline = TRUE;
165 } else {
166 fprintf(stderr, "Error: obj has no container\n");
167 }
168 }

mercurial