diff --git a/redo/osxaltest/box.swift b/redo/osxaltest/box.swift index 537fe91e..62295a14 100644 --- a/redo/osxaltest/box.swift +++ b/redo/osxaltest/box.swift @@ -5,8 +5,11 @@ import Cocoa // TODO fine tune this // TODO de-duplicate this from spinbox.m class tBoxContainer : NSView { - override func alignmentRectInsets() -> NSEdgeInsets { - return NSEdgeInsetsMake(50, 50, 50, 50) + override var alignmentRectInsets: NSEdgeInsets { + get { +debugPrint("in tBoxContainer.alignmentRectInsets") + return NSEdgeInsetsMake(50, 50, 50, 50) + } } } @@ -15,11 +18,21 @@ struct tBoxChild { var stretchy: Bool } +// the swift bridge isn't perfect; it won't recognize these properly +// thanks to Eridius in freenode/#swift-lang +let myNSLayoutPriorityRequired: NSLayoutPriority = 1000 +let myNSLayoutPriorityDefaultHigh: NSLayoutPriority = 750 +let myNSLayoutPriorityDragThatCanResizeWindow: NSLayoutPriority = 510 +let myNSLayoutPriorityWindowSizeStayPut: NSLayoutPriority = 500 +let myNSLayoutPriorityDragThatCannotResizeWindow: NSLayoutPriority = 490 +let myNSLayoutPriorityDefaultLow: NSLayoutPriority = 250 +let myNSLayoutPriorityFittingSizeCompression: NSLayoutPriority = 50 + class tBox : tControl { private var v: NSView private var children: [tBoxChild] private var vertical: Bool - private var parent: tControl + private var parent: tControl? private var spaced: Bool // TODO rename to padded @@ -46,15 +59,29 @@ class tBox : tControl { } // TODO make the other dimension not hug (as an experiment) - func tFillAutoLayout(p: tAutoLayoutParams) { - var orientation: NSLayoutConstraintOrientation - var i, n: UIntMax - var pp: tAutoLayoutParams - var nStretchy: UIntMax - + func tFillAutoLayout(inout p: tAutoLayoutParams) { + var hasStretchy = false if self.children.count == 0 { - goto selfOnly + hasStretchy = self.actualLayoutWork() } + p.view = self.v + p.attachLeft = true + p.attachTop = true + // don't attach to the end if there weren't any stretchy controls + if self.vertical { + p.attachRight = true + p.attachBottom = hasStretchy + } else { + p.attachRight = hasStretchy + p.attachBottom = true + } + } + + func actualLayoutWork() -> Bool { + var orientation: NSLayoutConstraintOrientation + // TODO don't use UIntMax + var i, n: UIntMax + var nStretchy: UIntMax self.v.removeConstraints(self.v.constraints) @@ -66,6 +93,7 @@ class tBox : tControl { var views = [String: NSView]() n = 0 var predicates = [String]() + var pp = tAutoLayoutParams() for child in self.children { var priority: NSLayoutPriority @@ -73,17 +101,17 @@ class tBox : tControl { pp.nonStretchyHeightPredicate = "" // this also resets the hugging priority // TODO do this when adding and removing controls instead - child.c.tFillAutoLayout(pp) - priority = NSLayoutPriorityDefaultHigh // forcibly hug; avoid stretching out + child.c.tFillAutoLayout(&pp) + priority = myNSLayoutPriorityDefaultHigh // forcibly hug; avoid stretching out if child.stretchy { - priority = NSLayoutPriorityDefaultLow // do not forcibly hug; freely stretch out + priority = myNSLayoutPriorityDefaultLow // do not forcibly hug; freely stretch out } if self.vertical { predicates.append(pp.nonStretchyHeightPredicate) } else { predicates.append(pp.nonStretchyWidthPredicate) } - pp.view.setContentHuggingPriority(priority, forOrientation:orientation) + pp.view?.setContentHuggingPriority(priority, forOrientation:orientation) views[tAutoLayoutKey(n)] = pp.view n++ } @@ -94,12 +122,16 @@ class tBox : tControl { constraint = "V:" } var firstStretchy = true - for i = 0; i < n; i++ { + // swift can't tell that nStretchy isn't used until firstStretchy becomes false + nStretchy = 0 + for i in 0.. String { - return NSString(format: "view%d", n) + return NSString(format: "view%d", n) as String } diff --git a/redo/osxaltest/entry.swift b/redo/osxaltest/entry.swift index c88c3dc0..de5b84ca 100644 --- a/redo/osxaltest/entry.swift +++ b/redo/osxaltest/entry.swift @@ -2,19 +2,22 @@ import Cocoa class tEntry : tControl { - private var b: NSButton - private var parent: tControl + private var t: NSTextField + private var parent: tControl? private var horzpri, vertpri: NSLayoutPriority init() { + var cell: NSTextFieldCell + self.t = NSTextField(frame: NSZeroRect) self.t.selectable = true - self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSRegularControlSize)) + self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize)) self.t.bordered = false - self.t.bezelStyle = NSTextFieldSquareBezel + self.t.bezelStyle = NSTextFieldBezelStyle.SquareBezel self.t.bezeled = true - self.t.cell.lineBreakMode = NSLineBreakByClipping - self.t.cell.scrollable = true + cell = self.t.cell() as! NSTextFieldCell + cell.lineBreakMode = NSLineBreakMode.ByClipping + cell.scrollable = true self.t.translatesAutoresizingMaskIntoConstraints = false self.parent = nil @@ -28,7 +31,7 @@ class tEntry : tControl { v.addSubview(self.t) } - func tFillAutoLayout(p: tAutoLayoutParams) { + func tFillAutoLayout(inout p: tAutoLayoutParams) { // reset the hugging priority self.t.setContentHuggingPriority(self.horzpri, forOrientation:NSLayoutConstraintOrientation.Horizontal) self.t.setContentHuggingPriority(self.vertpri, forOrientation:NSLayoutConstraintOrientation.Vertical) @@ -43,7 +46,7 @@ class tEntry : tControl { func tRelayout() { if self.parent != nil { - self.parent.tRelayout() + self.parent?.tRelayout() } } } diff --git a/redo/osxaltest/label.swift b/redo/osxaltest/label.swift index 001374e9..88422eb2 100644 --- a/redo/osxaltest/label.swift +++ b/redo/osxaltest/label.swift @@ -1,23 +1,26 @@ // 31 july 2015 import Cocoa -class tEntry : tControl { - private var b: NSButton - private var parent: tControl +class tLabel : tControl { + private var t: NSTextField + private var parent: tControl? private var horzpri, vertpri: NSLayoutPriority init() { + var cell: NSTextFieldCell + self.t = NSTextField(frame: NSZeroRect) self.t.stringValue = "Label" - self.t.setEditable = false + self.t.editable = false self.t.selectable = false self.t.drawsBackground = false - self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSRegularControlSize)) + self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize)) self.t.bordered = false - self.t.bezelStyle = NSTextFieldSquareBezel + self.t.bezelStyle = NSTextFieldBezelStyle.SquareBezel self.t.bezeled = false - self.t.cell.lineBreakMode = NSLineBreakByClipping - self.t.cell.scrollable = true + cell = self.t.cell() as! NSTextFieldCell + cell.lineBreakMode = NSLineBreakMode.ByClipping + cell.scrollable = true self.t.translatesAutoresizingMaskIntoConstraints = false self.parent = nil @@ -31,7 +34,7 @@ class tEntry : tControl { v.addSubview(self.t) } - func tFillAutoLayout(p: tAutoLayoutParams) { + func tFillAutoLayout(inout p: tAutoLayoutParams) { // reset the hugging priority self.t.setContentHuggingPriority(self.horzpri, forOrientation:NSLayoutConstraintOrientation.Horizontal) self.t.setContentHuggingPriority(self.vertpri, forOrientation:NSLayoutConstraintOrientation.Vertical) @@ -45,7 +48,7 @@ class tEntry : tControl { func tRelayout() { if self.parent != nil { - self.parent.tRelayout() + self.parent?.tRelayout() } } } diff --git a/redo/osxaltest/main.swift b/redo/osxaltest/main.swift index 31741c94..8fa07dbc 100644 --- a/redo/osxaltest/main.swift +++ b/redo/osxaltest/main.swift @@ -70,7 +70,7 @@ func appLaunched() { mainwin.tShow() } -class appDelegate : NSApplicationDelegate { +class appDelegate : NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(note: NSNotification) { appLaunched() } @@ -84,8 +84,8 @@ func main() { spaced = Process.arguments.count > 1 var app = NSApplication.sharedApplication() - app.setActivationPolicy(NSApplicationActivationPolicyRegular) - app.setDelegate(appDelegate()) + app.setActivationPolicy(NSApplicationActivationPolicy.Regular) + app.delegate = appDelegate() app.run() } diff --git a/redo/osxaltest/spinbox.swift b/redo/osxaltest/spinbox.swift index 2b5fcea2..325d4691 100644 --- a/redo/osxaltest/spinbox.swift +++ b/redo/osxaltest/spinbox.swift @@ -3,8 +3,11 @@ import Cocoa // leave a whole lot of space around the alignment rect, just to be safe class tSpinboxContainer : NSView { - override func alignmentRectInsets() -> NSEdgeInsets { - return NSEdgeInsetsMake(50, 50, 50, 50) + override var alignmentRectInsets: NSEdgeInsets { + get { +debugPrint("in tSpinboxContainer.alignmentRectInsets") + return NSEdgeInsetsMake(50, 50, 50, 50) + } } } @@ -14,10 +17,12 @@ class tSpinbox : tControl { private var c: tSpinboxContainer private var t: NSTextField private var s: NSStepper - private var parent: tControl + private var parent: tControl? private var horzpri, vertpri: NSLayoutPriority init() { + var cell: NSTextFieldCell + self.c = tSpinboxContainer(frame: NSZeroRect) self.c.translatesAutoresizingMaskIntoConstraints = false @@ -25,16 +30,17 @@ class tSpinbox : tControl { self.t.stringValue = "\(nspinbox)" nspinbox++ self.t.selectable = true - self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSRegularControlSize)) + self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize)) self.t.bordered = false - self.t.bezelStyle = NSTextFieldSquareBezel + self.t.bezelStyle = NSTextFieldBezelStyle.SquareBezel self.t.bezeled = true - self.t.cell.lineBreakMode = NSLineBreakByClipping - self.t.cell.scrollable = true + cell = self.t.cell() as! NSTextFieldCell + cell.lineBreakMode = NSLineBreakMode.ByClipping + cell.scrollable = true self.t.translatesAutoresizingMaskIntoConstraints = false self.c.addSubview(self.t) - self.s = NSStepper(NSZeroFrame) + self.s = NSStepper(frame: NSZeroRect) self.s.increment = 1 self.s.valueWraps = false self.s.autorepeat = true @@ -46,20 +52,20 @@ nspinbox++ "s": self.s, ] var constraints = NSLayoutConstraint.constraintsWithVisualFormat( - visualFormat: "H:|[t]-[s]|", - options: 0, + "H:|[t]-[s]|", + options: NSLayoutFormatOptions(0), metrics: nil, views: views) self.c.addConstraints(constraints) constraints = NSLayoutConstraint.constraintsWithVisualFormat( - visualFormat: "V:|[t]|", - options: 0, + "V:|[t]|", + options: NSLayoutFormatOptions(0), metrics: nil, views: views) self.c.addConstraints(constraints) constraints = NSLayoutConstraint.constraintsWithVisualFormat( - visualFormat: "V:|[s]|", - options: 0, + "V:|[s]|", + options: NSLayoutFormatOptions(0), metrics: nil, views: views) self.c.addConstraints(constraints) @@ -75,7 +81,7 @@ nspinbox++ v.addSubview(self.c) } - func tFillAutoLayout(p: tAutoLayoutParams) { + func tFillAutoLayout(inout p: tAutoLayoutParams) { // reset the hugging priority self.c.setContentHuggingPriority(self.horzpri, forOrientation:NSLayoutConstraintOrientation.Horizontal) self.c.setContentHuggingPriority(self.vertpri, forOrientation:NSLayoutConstraintOrientation.Vertical) @@ -90,7 +96,7 @@ nspinbox++ func tRelayout() { if self.parent != nil { - self.parent.tRelayout() + self.parent?.tRelayout() } } } diff --git a/redo/osxaltest/window.swift b/redo/osxaltest/window.swift index f72cd7af..81f18f71 100644 --- a/redo/osxaltest/window.swift +++ b/redo/osxaltest/window.swift @@ -3,71 +3,73 @@ import Cocoa // auto layout helpers func tIsAmbiguous(view: NSView, indent: Int) { - var s = string(indent, ' ') + var s = String(count: indent, repeatedValue: " " as Character) debugPrint("\(s) \(view.className) \(view.hasAmbiguousLayout)") if view.hasAmbiguousLayout { - view.window.visualizeConstraints(view.superview.constraints) + view.window?.visualizeConstraints(view.superview!.constraints) } for subview in view.subviews { - tIsAmbiguous(subview, indent + 1) + tIsAmbiguous(subview as! NSView, indent + 1) } } class tWindow : tControl { private var w: NSWindow - private var c: tControl + private var c: tControl? private var margined: Bool init() { self.w = NSWindow( contentRect: NSMakeRect(0, 0, 320, 240), styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask), - backing: NSBackingStoreBuffered, + backing: NSBackingStoreType.Buffered, defer: true) self.w.title = "Auto Layout Test" self.c = nil self.margined = false } - public func tSetControl(c: tControl) { + func tSetControl(c: tControl) { self.c = c - self.c.tSetParent(self, addToView: self.w.contentView) + // TODO use self.c here + c.tSetParent(self, addToView: self.w.contentView as! NSView) self.tRelayout() } - public func tSetMargined(m: Bool) { + func tSetMargined(m: Bool) { self.margined = m self.tRelayout() } - public func tShow() { + func tShow() { self.w.cascadeTopLeftFromPoint(NSMakePoint(20, 20)) self.w.makeKeyAndOrderFront(self) - tIsAmbiguous(self.w.contentView, 0) + tIsAmbiguous(self.w.contentView as! NSView, 0) } func tSetParent(p: tControl, addToView: NSView) { fatalError("cannot call tWindow.tSetParent()") } - func tFillAutoLayout(p: tAutoLayoutParams) { + func tFillAutoLayout(inout p: tAutoLayoutParams) { fatalError("cannot call tWindow.tFillAutoLayout()") } - public func tRelayout() { + func tRelayout() { if self.c == nil { return } - var contentView = self.w.contentView + var contentView = self.w.contentView as! NSView contentView.removeConstraints(contentView.constraints) var p = tAutoLayoutParams() - self.c.tFillAutoLayout(p) + c?.tFillAutoLayout(&p) - var views = [ - "view": p.view, - ] + // TODO why can't I just say var views = [ "view": p.view ]? + // I think the parser is getting confused + var views = [String: NSView]() + views["view"] = p.view var margin = "" if self.margined { margin = "-" @@ -84,10 +86,10 @@ class tWindow : tControl { constraint += margin + "|" } var constraints = NSLayoutConstraint.constraintsWithVisualFormat( - visualFormat:constraint, - options:0, - metrics:nil, - views:views) + constraint, + options: NSLayoutFormatOptions(0), + metrics: nil, + views: views) contentView.addConstraints(constraints) constraint = "V:" @@ -99,10 +101,10 @@ class tWindow : tControl { constraint += margin + "|" } constraints = NSLayoutConstraint.constraintsWithVisualFormat( - visualFormat:constraint, - options:0, - metrics:nil, - views:views) + constraint, + options: NSLayoutFormatOptions(0), + metrics: nil, + views: views) contentView.addConstraints(constraints) } }