// 31 july 2015 import Cocoa // leave a whole lot of space around the alignment rect, just to be safe // TODO fine tune this // TODO de-duplicate this from spinbox.m class tBoxContainer : NSView { override var alignmentRectInsets: NSEdgeInsets { get { return NSEdgeInsetsMake(50, 50, 50, 50) } } } struct tBoxChild { var c: tControl 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 spaced: Bool // TODO rename to padded init(vertical: Bool, spaced: Bool) { self.v = tBoxContainer(frame: NSZeroRect) self.v.translatesAutoresizingMaskIntoConstraints = false self.children = [] self.vertical = vertical self.parent = nil self.spaced = spaced } func tAddControl(c: tControl, stretchy: Bool) { c.tSetParent(self, addToView: self.v) self.children.append(tBoxChild( c: c, stretchy: stretchy)) self.tRelayout() } func tSetParent(p: tControl, addToView v: NSView) { self.parent = p v.addSubview(self.v) } // TODO make the other dimension not hug (as an experiment) func tFillAutoLayout(inout p: tAutoLayoutParams) { var hasStretchy = false if self.children.count != 0 { 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 Int var i, n: Int var nStretchy: Int self.v.removeConstraints(self.v.constraints) orientation = NSLayoutConstraintOrientation.Horizontal if self.vertical { orientation = NSLayoutConstraintOrientation.Vertical } var views = [String: NSView]() n = 0 var predicates = [String]() var pp = tAutoLayoutParams() for child in self.children { var priority: NSLayoutPriority pp.nonStretchyWidthPredicate = "" pp.nonStretchyHeightPredicate = "" // this also resets the hugging priority // TODO do this when adding and removing controls instead child.c.tFillAutoLayout(&pp) priority = myNSLayoutPriorityDefaultHigh // forcibly hug; avoid stretching out if child.stretchy { 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) views[tAutoLayoutKey(n)] = pp.view n++ } // first string the views together var constraint = "H:|" if self.vertical { constraint = "V:|" } var firstStretchy = true // swift can't tell that nStretchy isn't used until firstStretchy becomes false nStretchy = 0 for i in 0..