Removed the old osxaltest. Not needed now. I'll just design grids against master.

This commit is contained in:
Pietro Gagliardi 2016-05-06 17:49:09 -04:00
parent ac3ee981b3
commit 885e7157d7
10 changed files with 0 additions and 816 deletions

View File

@ -1,175 +0,0 @@
// 7 august 2015
import Cocoa
struct BoxControl {
var c: Control
var stretchy: Bool
var horzHuggingPri: NSLayoutPriority
var vertHuggingPri: NSLayoutPriority
}
class Box : NSView, Control {
private var controls: [BoxControl]
private var parent: Control?
private var vertical: Bool
private var padded: Bool
private var primaryDirPrefix: String
private var secondaryDirPrefix: String
private var primaryOrientation: NSLayoutConstraintOrientation
private var secondaryOrientation: NSLayoutConstraintOrientation
// we implement a lack of stretchy controls by adding a stretchy view at the end of the view list when we assemble layouts
// this is that view
private var noStretchyView: NSView
init(vertical: Bool, padded: Bool) {
self.controls = []
self.parent = nil
self.vertical = vertical
self.padded = padded
self.primaryDirPrefix = "H:"
self.secondaryDirPrefix = "V:"
self.primaryOrientation = NSLayoutConstraintOrientation.Horizontal
self.secondaryOrientation = NSLayoutConstraintOrientation.Vertical
if self.vertical {
self.primaryDirPrefix = "V:"
self.secondaryDirPrefix = "H:"
self.primaryOrientation = NSLayoutConstraintOrientation.Vertical
self.secondaryOrientation = NSLayoutConstraintOrientation.Horizontal
}
self.noStretchyView = NSView(frame: NSZeroRect)
self.noStretchyView.translatesAutoresizingMaskIntoConstraints = false
// make the view stretchy in both directions
// you can tell this is correct by synthesizing an Add() in your head; see below
setHorzHuggingPri(self.noStretchyView, myNSLayoutPriorityDefaultLow)
setVertHuggingPri(self.noStretchyView, myNSLayoutPriorityDefaultLow)
super.init(frame: NSZeroRect)
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
func Add(control: Control, _ stretchy: Bool) {
var c: BoxControl
var view = control.View()
c = BoxControl(
c: control,
stretchy: stretchy,
horzHuggingPri: horzHuggingPri(view),
vertHuggingPri: vertHuggingPri(view))
self.addSubview(view)
self.controls.append(c)
// if a control is stretchy, it should not hug in the primary direction
// otherwise, it should *forcibly* hug
if c.stretchy {
setHuggingPri(view, myNSLayoutPriorityDefaultLow, self.primaryOrientation)
} else {
// TODO will default high work?
setHuggingPri(view, myNSLayoutPriorityRequired, self.primaryOrientation)
}
// make sure controls don't hug their secondary direction so they fill the width of the view
setHuggingPri(view, myNSLayoutPriorityDefaultLow, self.secondaryOrientation)
self.relayout()
}
func View() -> NSView {
return self
}
func SetParent(p: Control) {
self.parent = p
}
// TODO do we still need to set hugging? I think we do for stretchy controls...
// TODO try unsetting spinbox intrinsics and seeing what happens
private func relayout() {
var constraint: String
if self.controls.count == 0 {
return
}
self.removeConstraints(self.constraints)
// first collect the views
var views = [String: NSView]()
var n = 0
var firstStretchy = -1
var metrics = [String: CGFloat]()
for c in self.controls {
views["view\(n)"] = c.c.View()
var s = fittingAlignmentSize(c.c.View())
metrics["view\(n)width"] = s.width
metrics["view\(n)height"] = s.height
if firstStretchy == -1 && c.stretchy {
firstStretchy = n
}
n++
}
// if there are no stretchy controls, we must add the no-stretchy view
// if there are, we must remove it
if firstStretchy == -1 {
if self.noStretchyView.superview == nil {
self.addSubview(self.noStretchyView)
}
views["noStretchyView"] = self.noStretchyView
} else {
if self.noStretchyView.superview != nil {
self.noStretchyView.removeFromSuperview()
}
}
// next, assemble the views in the primary direction
// they all go in a straight line
constraint = "\(self.primaryDirPrefix)|"
for i in 0..<n {
if self.padded && i != 0 {
constraint += "-"
}
constraint += "[view\(i)"
// implement multiple stretchiness properly
if self.controls[i].stretchy && i != firstStretchy {
constraint += "(==view\(firstStretchy))"
}
// if the control is not stretchy, restrict it to the fitting size
if !self.controls[i].stretchy {
if self.vertical {
constraint += "(==view\(i)height)"
} else {
constraint += "(==view\(i)width)"
}
}
constraint += "]"
}
if firstStretchy == -1 { // don't space between the last control and the no-stretchy view
constraint += "[noStretchyView]"
}
constraint += "|"
var constraints = mkconstraints(constraint, metrics, views)
self.addConstraints(constraints)
// next: assemble the views in the secondary direction
// each of them will span the secondary direction
for i in 0..<n {
constraint = "\(self.secondaryDirPrefix)|[view\(i)]|"
var constraints = mkconstraints(constraint, nil, views)
self.addConstraints(constraints)
}
if firstStretchy == -1 { // and again to the no-stretchy view
constraint = "\(self.secondaryDirPrefix)|[noStretchyView]|"
var constraints = mkconstraints(constraint, nil, views)
self.addConstraints(constraints)
}
}
}

View File

@ -1,169 +0,0 @@
// 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..<n {
if self.spaced && i != 0 {
constraint += "-"
}
constraint += "[" + tAutoLayoutKey(i)
if self.children[i].stretchy {
if firstStretchy {
firstStretchy = false
nStretchy = i
} else {
constraint += "(==" + tAutoLayoutKey(nStretchy) + ")"
}
} else {
constraint += predicates[i]
}
constraint += "]"
}
constraint += "|"
self.v.addConstraints(mkconstraints(constraint, views))
// TODO do not release constraint; it's autoreleased?
// next make the views span the full other dimension
// TODO make all of these the same width/height
for i in 0..<n {
constraint = "V:|["
if self.vertical {
constraint = "H:|["
}
constraint += tAutoLayoutKey(i) + "]|"
self.v.addConstraints(mkconstraints(constraint, views))
// TODO do not release constraint; it's autoreleased?
}
// the caller needs to know if a control was stretchy
// firstStretchy is false if there was one
return !firstStretchy
}
func tRelayout() {
if self.parent != nil {
self.parent?.tRelayout()
}
}
}

View File

@ -1,30 +0,0 @@
// 31 july 2015
import Cocoa
class Button : NSButton, Control {
private var parent: Control?
init(_ text: String) {
self.parent = nil
super.init(frame: NSZeroRect)
self.title = text
self.setButtonType(NSButtonType.MomentaryPushInButton)
self.bordered = true
self.bezelStyle = NSBezelStyle.RoundedBezelStyle
self.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize))
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
func View() -> NSView {
return self
}
func SetParent(p: Control) {
self.parent = p
}
}

View File

@ -1,7 +0,0 @@
// 31 july 2015
import Cocoa
protocol Control : class {
func View() -> NSView
func SetParent(p: Control)
}

View File

@ -1,47 +0,0 @@
// 31 july 2015
import Cocoa
class Entry : NSTextField, Control {
private var parent: Control?
init() {
var cell: NSTextFieldCell
self.parent = nil
super.init(frame: NSZeroRect)
self.selectable = true
self.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize))
self.bordered = false
self.bezelStyle = NSTextFieldBezelStyle.SquareBezel
self.bezeled = true
cell = self.cell() as! NSTextFieldCell
cell.lineBreakMode = NSLineBreakMode.ByClipping
cell.scrollable = true
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
func View() -> NSView {
return self
}
func SetParent(p: Control) {
self.parent = p
}
// by default a text entry has no intrinsic content width
// in order for our layout containers to work, we need to give it one
// give it what Interface Builder uses as a default
// TODO verify against Interface Builder
override var intrinsicContentSize: NSSize {
get {
var s = super.intrinsicContentSize
s.width = 96
return s
}
}
}

View File

@ -1,38 +0,0 @@
// 31 july 2015
import Cocoa
class Label : NSTextField, Control {
private var parent: Control?
init() {
var cell: NSTextFieldCell
self.parent = nil
super.init(frame: NSZeroRect)
self.stringValue = "Label"
self.editable = false
self.selectable = false
self.drawsBackground = false
self.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize))
self.bordered = false
self.bezelStyle = NSTextFieldBezelStyle.SquareBezel
self.bezeled = false
cell = self.cell() as! NSTextFieldCell
cell.lineBreakMode = NSLineBreakMode.ByClipping
cell.scrollable = true
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
func View() -> NSView {
return self
}
func SetParent(p: Control) {
self.parent = p
}
}

View File

@ -1,49 +0,0 @@
// 8 august 2015
import Cocoa
func mkconstraints(constraint: String, metrics: [String: CGFloat]?, views: [String: NSView]) -> [AnyObject] {
return NSLayoutConstraint.constraintsWithVisualFormat(
constraint,
options: NSLayoutFormatOptions(0),
metrics: metrics,
views: views)
}
// 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
func horzHuggingPri(view: NSView) -> NSLayoutPriority {
return view.contentHuggingPriorityForOrientation(NSLayoutConstraintOrientation.Horizontal)
}
func vertHuggingPri(view: NSView) -> NSLayoutPriority {
return view.contentHuggingPriorityForOrientation(NSLayoutConstraintOrientation.Vertical)
}
func setHuggingPri(view: NSView, priority: NSLayoutPriority, orientation: NSLayoutConstraintOrientation) {
view.setContentHuggingPriority(priority, forOrientation: orientation)
}
func setHorzHuggingPri(view: NSView, priority: NSLayoutPriority) {
setHuggingPri(view, priority, NSLayoutConstraintOrientation.Horizontal)
}
func setVertHuggingPri(view: NSView, priority: NSLayoutPriority) {
setHuggingPri(view, priority, NSLayoutConstraintOrientation.Vertical)
}
// use the fitting size, not the intrinsic content size, for the case of recursive views without an intrinsic content size
func fittingAlignmentSize(view: NSView) -> NSSize {
var s = view.fittingSize
// the fitting size is for a frame rect; we need an alignment rect
var r = NSMakeRect(0, 0, s.width, s.height)
r = view.alignmentRectForFrame(r)
return r.size
}

View File

@ -1,122 +0,0 @@
// 31 july 2015
import Cocoa
var spaced = false
var firstvert = true
// keep alive
// apparently I'm not allowed to declare a variable and then assign to it first thing in a function
// it'd be great if people weren't so afraid of nil pointers
var keepAliveMainwin: Window? = nil
func appLaunched() {
var mainwin = Window()
mainwin.SetMargined(spaced)
var box = Box(vertical: firstvert, padded: spaced)
mainwin.SetControl(box)
/*
var hbox = {(entrys: Bool, buttons: Bool) -> Box in
var hbox = Box(vertical: !firstvert, padded: spaced)
hbox.Add(Entry(), entrys)
hbox.Add(Button("Button"), buttons)
return hbox
}
box.Add(hbox(true, true), false)
box.Add(hbox(true, false), false)
box.Add(hbox(false, true), false)
box.Add(hbox(false, false), false)
*/
box.Add(Spinbox(), false)
var mkhbox = {() -> Box in
Box(vertical: !firstvert, padded: spaced)
}
var hbox = mkhbox()
hbox.Add(Button("Button"), true)
hbox.Add(Button("Button"), true)
box.Add(hbox, false)
hbox = mkhbox()
hbox.Add(Button("Button"), true)
hbox.Add(Button("Button"), true)
box.Add(hbox, false)
hbox = mkhbox()
hbox.Add(Button("Button"), true)
hbox.Add(Button("A"), false)
hbox.Add(Button("BB"), false)
hbox.Add(Button("CCC"), false)
box.Add(hbox, false)
hbox = mkhbox()
hbox.Add(Spinbox(), false)
hbox.Add(Spinbox(), true)
box.Add(hbox, false)
hbox = mkhbox()
hbox.Add(Entry(), true)
hbox.Add(Entry(), false)
box.Add(hbox, false)
hbox = mkhbox()
hbox.Add(Label(), false)
box.Add(hbox, false)
hbox = mkhbox()
var vbox = Box(vertical: firstvert, padded: spaced)
vbox.Add(Button("Button"), true)
hbox.Add(vbox, false)
vbox = Box(vertical: firstvert, padded: spaced)
vbox.Add(Button("Button 2"), true)
hbox.Add(vbox, true)
box.Add(hbox, false)
hbox = Box(vertical: firstvert, padded: spaced)
vbox = mkhbox()
vbox.Add(Button("Button"), true)
hbox.Add(vbox, false)
vbox = mkhbox()
vbox.Add(Button("Button 2"), true)
hbox.Add(vbox, true)
box.Add(hbox, false)
mainwin.Show()
keepAliveMainwin = mainwin
}
class appDelegate : NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(note: NSNotification) {
appLaunched()
}
func applicationShouldTerminateAfterLastWindowClosed(app: NSApplication) -> Bool {
return true
}
}
func main() {
for arg in dropFirst(Process.arguments) {
if arg == "spaced" {
spaced = true
} else if arg == "horizontal" {
firstvert = false
} else {
fatalError("unrecognized option \(arg)")
}
}
var app = NSApplication.sharedApplication()
app.setActivationPolicy(NSApplicationActivationPolicy.Regular)
// NSApplication.delegate is weak; if we don't use the temporary variable, the delegate will die before it's used
var delegate = appDelegate()
app.delegate = delegate
app.run()
}
main()

View File

@ -1,93 +0,0 @@
// 31 july 2015
import Cocoa
var nspinbox = 0
class Spinbox : NSView, Control {
private var t: NSTextField
private var s: NSStepper
private var parent: Control?
init() {
var cell: NSTextFieldCell
self.t = NSTextField(frame: NSZeroRect)
self.t.stringValue = "\(nspinbox)"
nspinbox++
self.t.selectable = true
self.t.font = NSFont.systemFontOfSize(NSFont.systemFontSizeForControlSize(NSControlSize.RegularControlSize))
self.t.bordered = false
self.t.bezelStyle = NSTextFieldBezelStyle.SquareBezel
self.t.bezeled = true
cell = self.t.cell() as! NSTextFieldCell
cell.lineBreakMode = NSLineBreakMode.ByClipping
cell.scrollable = true
self.t.translatesAutoresizingMaskIntoConstraints = false
// make the textbox grow horizontally and vertically
setHorzHuggingPri(self.t, myNSLayoutPriorityDefaultLow)
setVertHuggingPri(self.t, myNSLayoutPriorityDefaultLow)
self.s = NSStepper(frame: NSZeroRect)
self.s.increment = 1
self.s.valueWraps = false
self.s.autorepeat = true
self.s.translatesAutoresizingMaskIntoConstraints = false
// make the spinner grow vertically but not horizontally
// TODO Required instead?
setHorzHuggingPri(self.s, myNSLayoutPriorityDefaultHigh)
setVertHuggingPri(self.s, myNSLayoutPriorityDefaultLow)
self.parent = nil
super.init(frame: NSZeroRect)
self.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(self.t)
self.addSubview(self.s)
var views = [
"t": self.t,
"s": self.s,
]
var constraints = mkconstraints("H:|[t]-[s]|", nil, views)
self.addConstraints(constraints)
constraints = mkconstraints("V:|[t]|", nil, views)
self.addConstraints(constraints)
constraints = mkconstraints("V:|[s]|", nil, views)
self.addConstraints(constraints)
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
// TODO leave only the required amount of space around the alignment rect
// TODO even with this the stepper sometimes gets cut off at the bottom *anyway*
override var alignmentRectInsets: NSEdgeInsets {
get {
return NSEdgeInsetsMake(50, 50, 50, 50)
}
}
func View() -> NSView {
return self
}
func SetParent(p: Control) {
self.parent = p
}
// TODO justify this
// TODO no really, is this height the right way to go?
// TODO in particular, why is making the NSTextField an Entry insufficient?
// TODO restrict width to the text field only?
override var intrinsicContentSize: NSSize {
get {
var s = super.intrinsicContentSize
s.width = 96
s.height = max(self.t.intrinsicContentSize.height, self.s.intrinsicContentSize.height)
return s
}
}
}

View File

@ -1,86 +0,0 @@
// 1 august 2015
import Cocoa
// auto layout helpers
func isAmbiguous(view: NSView, indent: Int) {
var s = String(count: indent, repeatedValue: " " as Character)
println("\(s) \(view.className) \(view.hasAmbiguousLayout)")
if view.hasAmbiguousLayout {
view.window?.visualizeConstraints(view.superview!.constraints)
}
for subview in view.subviews {
isAmbiguous(subview as! NSView, indent + 1)
}
}
class Window : NSWindow, Control {
private var c: Control?
private var margined: Bool
init() {
self.c = nil
self.margined = false
// we have to initialize our own instance variables first, unfortunately (thanks erica in irc.freenode.net/#swift-lang)
super.init(
contentRect: NSMakeRect(0, 0, 320, 240),
styleMask: (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask),
backing: NSBackingStoreType.Buffered,
defer: true)
self.title = "Auto Layout Test"
}
required init?(coder: NSCoder) {
fatalError("can't use this constructor, sorry")
}
func SetControl(c: Control) {
self.c = c
var contentView = self.contentView as! NSView
contentView.addSubview(self.c!.View())
self.relayout()
}
func SetMargined(m: Bool) {
self.margined = m
self.relayout()
}
func Show() {
self.cascadeTopLeftFromPoint(NSMakePoint(20, 20))
self.makeKeyAndOrderFront(self)
isAmbiguous(self.contentView as! NSView, 0)
}
func View() -> NSView {
fatalError("cannot call Window.View()")
}
func SetParent(p: Control) {
fatalError("cannot call Window.SetParent()")
}
private func relayout() {
if self.c == nil {
return
}
var contentView = self.contentView as! NSView
contentView.removeConstraints(contentView.constraints)
var views = [
"view": self.c!.View(),
]
var margin = ""
if self.margined {
margin = "-"
}
var constraint = "H:|" + margin + "[view]" + margin + "|"
var constraints = mkconstraints(constraint, nil, views)
contentView.addConstraints(constraints)
constraint = "V:|" + margin + "[view]" + margin + "|"
constraints = mkconstraints(constraint, nil, views)
contentView.addConstraints(constraints)
}
}