ui/cocoa/window.m

changeset 112
c3f2f16fa4b8
parent 110
c00e968d018b
child 113
dde28a806552
equal deleted inserted replaced
111:81c4f73236a4 112:c3f2f16fa4b8
28 28
29 #import "window.h" 29 #import "window.h"
30 30
31 #import "MainWindow.h" 31 #import "MainWindow.h"
32 #import "WindowManager.h" 32 #import "WindowManager.h"
33 #import "BoxContainer.h"
34 #import "EventData.h"
33 35
34 #import <objc/runtime.h> 36 #import <objc/runtime.h>
35 37
36 #include "../ui/window.h" 38 #include "../ui/window.h"
37 #include "../ui/properties.h" 39 #include "../ui/properties.h"
38 #include "../common/context.h" 40 #include "../common/context.h"
39 #include "../common/menu.h" 41 #include "../common/menu.h"
40 #include "../common/toolbar.h" 42 #include "../common/toolbar.h"
43 #include "../common/object.h"
41 44
42 #include <cx/mempool.h> 45 #include <cx/mempool.h>
43 46
44 47
45 static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar) { 48 static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar, BOOL splitview) {
46 CxMempool *mp = cxMempoolCreateSimple(256); 49 UiObject *obj = uic_object_new_toplevel();
47 UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); 50
48 obj->ref = 0; 51 MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar withSplitview:splitview];
49
50 obj->ctx = uic_context(obj, mp);
51
52 MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar];
53 [[WindowManager sharedWindowManager] addWindow:window]; 52 [[WindowManager sharedWindowManager] addWindow:window];
54 window.releasedWhenClosed = false; 53 window.releasedWhenClosed = false; // TODO: we still need a cleanup strategy
55 54
56 obj->wobj = (__bridge void*)window; 55 obj->wobj = (__bridge void*)window;
57 56
58 MainWindowController *controller = [[MainWindowController alloc] initWithWindow:obj window:window]; 57 MainWindowController *controller = [[MainWindowController alloc] initWithWindow:obj window:window];
59 window.windowController = controller; 58 window.windowController = controller;
62 61
63 return obj; 62 return obj;
64 } 63 }
65 64
66 UiObject* ui_window(const char *title, void *window_data) { 65 UiObject* ui_window(const char *title, void *window_data) {
67 UiObject *obj = create_window(title, FALSE, FALSE); 66 UiObject *obj = create_window(title, FALSE, FALSE, FALSE);
68 obj->window = window_data; 67 obj->window = window_data;
69 return obj; 68 return obj;
70 } 69 }
71 70
72 UiObject* ui_simple_window(const char *title, void *window_data) { 71 UiObject* ui_simple_window(const char *title, void *window_data) {
73 UiObject *obj = create_window(title, TRUE, FALSE); 72 UiObject *obj = create_window(title, TRUE, FALSE, FALSE);
74 obj->window = window_data; 73 obj->window = window_data;
75 return obj; 74 return obj;
76 } 75 }
77 76
78 UiObject* ui_sidebar_window(const char *title, void *window_data) { 77 UiObject* ui_sidebar_window(const char *title, void *window_data) {
79 UiObject *obj = create_window(title, FALSE, TRUE); 78 UiObject *obj = create_window(title, FALSE, TRUE, FALSE);
80 obj->window = window_data; 79 obj->window = window_data;
81 return obj; 80 return obj;
81 }
82
83 UiObject* ui_splitview_window(const char *title, UiBool sidebar) {
84 return create_window(title, FALSE, sidebar, TRUE);
82 } 85 }
83 86
84 /* --------------------------------- File Dialogs --------------------------------- */ 87 /* --------------------------------- File Dialogs --------------------------------- */
85 88
86 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { 89 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) {
228 callback(&event, userdata); 231 callback(&event, userdata);
229 } 232 }
230 }]; 233 }];
231 234
232 } 235 }
236
237 /* ------------------------------------- Dialog Window ------------------------------------- */
238
239 @implementation UiDialogWindow
240
241 - (BOOL) getIsVisible {
242 return self.isVisible;
243 }
244
245 - (void) setVisible:(BOOL)visible {
246 //[self makeKeyAndOrderFront:nil];
247 if(visible) {
248 [_parent beginSheet:self completionHandler:^(NSModalResponse returnCode) {
249 // TODO: close event
250 }];
251 } else {
252 [self.sheetParent endSheet:self returnCode:NSModalResponseCancel];
253 }
254 }
255
256 - (void)cancelOperation:(id)sender {
257 [self.sheetParent endSheet:self returnCode:NSModalResponseCancel];
258 // TODO: close event
259 }
260
261 @end
262
263 UiObject *ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs *args) {
264 UiObject *obj = uic_object_new_toplevel();
265 UiDialogWindow *panel = [[UiDialogWindow alloc] initWithContentRect:NSMakeRect(0, 0, args->width, args->height)
266 styleMask:(NSWindowStyleMaskTitled |
267 NSWindowStyleMaskClosable |
268 NSWindowStyleMaskResizable |
269 NSWindowStyleMaskUtilityWindow)
270 backing:NSBackingStoreBuffered
271 defer:NO];
272 panel.parent = (__bridge NSWindow*)parent->wobj;
273 panel.obj = obj;
274 panel.modal = args->modal;
275 panel.onclick = args->onclick;
276 panel.onclickdata = args->onclickdata;
277 [panel center];
278 [[WindowManager sharedWindowManager] addWindow:panel];
279 obj->wobj = (__bridge void*)panel;
280
281 NSView *content = panel.contentView;
282
283 // Create a view for the dialog window buttons (lbutton1, lbutton2, rbutton3, rbutton4)
284 NSView *buttonArea = [[NSView alloc]init];
285 buttonArea.translatesAutoresizingMaskIntoConstraints = NO;
286 [content addSubview:buttonArea];
287 [NSLayoutConstraint activateConstraints:@[
288 [buttonArea.bottomAnchor constraintEqualToAnchor:content.bottomAnchor constant:-10],
289 [buttonArea.leadingAnchor constraintEqualToAnchor:content.leadingAnchor constant:10],
290 [buttonArea.trailingAnchor constraintEqualToAnchor:content.trailingAnchor constant:-10],
291 [buttonArea.heightAnchor constraintEqualToConstant:20]
292 ]];
293
294 NSButton *lbutton1 = nil;
295 if(args->lbutton1) {
296 lbutton1 = [[NSButton alloc]init];
297 lbutton1.title = [[NSString alloc]initWithUTF8String:args->lbutton1];
298 lbutton1.translatesAutoresizingMaskIntoConstraints = NO;
299 [buttonArea addSubview:lbutton1];
300 [NSLayoutConstraint activateConstraints:@[
301 [lbutton1.topAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0],
302 [lbutton1.leadingAnchor constraintEqualToAnchor:buttonArea.leadingAnchor constant:0]
303 ]];
304
305 EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
306 event.obj = obj;
307 event.value = 1;
308 lbutton1.target = event;
309 lbutton1.action = @selector(handleEvent:);
310 objc_setAssociatedObject(lbutton1, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
311 }
312 NSButton *lbutton2 = nil;
313 if(args->lbutton2) {
314 lbutton2 = [[NSButton alloc]init];
315 lbutton2.title = [[NSString alloc]initWithUTF8String:args->lbutton2];
316 lbutton2.translatesAutoresizingMaskIntoConstraints = NO;
317 [buttonArea addSubview:lbutton2];
318 NSLayoutXAxisAnchor *anchor = lbutton1 != nil ? lbutton1.trailingAnchor : buttonArea.leadingAnchor;
319 int off = lbutton1 != nil ? 4 : 0;
320 [NSLayoutConstraint activateConstraints:@[
321 [lbutton2.topAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0],
322 [lbutton2.leadingAnchor constraintEqualToAnchor:anchor constant:off]
323 ]];
324
325 EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
326 event.obj = obj;
327 event.value = 2;
328 lbutton2.target = event;
329 lbutton2.action = @selector(handleEvent:);
330 objc_setAssociatedObject(lbutton2, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
331 }
332
333 NSButton *rbutton4 = nil;
334 if(args->rbutton4) {
335 rbutton4 = [[NSButton alloc]init];
336 rbutton4.title = [[NSString alloc]initWithUTF8String:args->rbutton4];
337 rbutton4.translatesAutoresizingMaskIntoConstraints = NO;
338 [buttonArea addSubview:rbutton4];
339 [NSLayoutConstraint activateConstraints:@[
340 [rbutton4.topAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0],
341 [rbutton4.trailingAnchor constraintEqualToAnchor:buttonArea.trailingAnchor constant:0]
342 ]];
343
344 EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
345 event.obj = obj;
346 event.value = 2;
347 rbutton4.target = event;
348 rbutton4.action = @selector(handleEvent:);
349 objc_setAssociatedObject(rbutton4, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
350 }
351 NSButton *rbutton3 = nil;
352 if(args->rbutton3) {
353 rbutton3 = [[NSButton alloc]init];
354 rbutton3.title = [[NSString alloc]initWithUTF8String:args->rbutton3];
355 rbutton3.translatesAutoresizingMaskIntoConstraints = NO;
356 [buttonArea addSubview:rbutton3];
357 NSLayoutXAxisAnchor *anchor = rbutton4 != nil ? rbutton4.leadingAnchor : buttonArea.trailingAnchor;
358 int off = rbutton4 != nil ? -4 : 0;
359 [NSLayoutConstraint activateConstraints:@[
360 [rbutton3.topAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0],
361 [rbutton3.trailingAnchor constraintEqualToAnchor:anchor constant:off]
362 ]];
363
364 EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
365 event.obj = obj;
366 event.value = 2;
367 rbutton3.target = event;
368 rbutton3.action = @selector(handleEvent:);
369 objc_setAssociatedObject(rbutton3, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
370 }
371 switch(args->default_button) {
372 default: break;
373 case 1: if(lbutton1 != nil) lbutton1.keyEquivalent = @"\r"; break;
374 case 2: if(lbutton2 != nil) lbutton2.keyEquivalent = @"\r"; break;
375 case 3: if(rbutton3 != nil) rbutton3.keyEquivalent = @"\r"; break;
376 case 4: if(rbutton4 != nil) rbutton4.keyEquivalent = @"\r"; break;
377 }
378
379 // space between left and right buttons
380 NSView *space = [[NSView alloc]init];
381 space.translatesAutoresizingMaskIntoConstraints = NO;
382 [buttonArea addSubview:space];
383 NSLayoutXAxisAnchor *leftAnchor = buttonArea.leadingAnchor;
384 NSLayoutXAxisAnchor *rightAnchor = buttonArea.trailingAnchor;
385 if(lbutton2 != nil) {
386 leftAnchor = lbutton2.trailingAnchor;
387 } else if(lbutton1 != nil) {
388 leftAnchor = lbutton1.trailingAnchor;
389 }
390
391 if(rbutton3 != nil) {
392 rightAnchor = rbutton3.leadingAnchor;
393 } else if(rbutton4 != nil) {
394 rightAnchor = rbutton4.leadingAnchor;
395 }
396 [NSLayoutConstraint activateConstraints:@[
397 [space.topAnchor constraintEqualToAnchor:buttonArea.topAnchor],
398 [space.leadingAnchor constraintEqualToAnchor:leftAnchor constant:10],
399 [space.trailingAnchor constraintEqualToAnchor:rightAnchor constant:-10]
400 ]];
401
402 // dialog window main content
403 BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0];
404 vbox.translatesAutoresizingMaskIntoConstraints = NO;
405 [content addSubview:vbox];
406
407 [NSLayoutConstraint activateConstraints:@[
408 [vbox.topAnchor constraintEqualToAnchor:content.topAnchor constant:0],
409 [vbox.leadingAnchor constraintEqualToAnchor:content.leadingAnchor],
410 [vbox.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
411 [vbox.bottomAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0]
412 ]];
413
414 UiContainerX *container = ui_create_container(obj, vbox);
415 vbox.container = container;
416 uic_object_push_container(obj, container);
417
418 return obj;
419 }
420

mercurial