Converted box.m to Swift. Now to test the build!
This commit is contained in:
parent
3709e3fb0a
commit
de4156122f
|
@ -1,177 +0,0 @@
|
||||||
// 31 july 2015
|
|
||||||
#import "osxaltest.h"
|
|
||||||
|
|
||||||
// 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
|
|
||||||
@interface tBoxContainer : NSView
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation tBoxContainer
|
|
||||||
|
|
||||||
- (NSEdgeInsets)alignmentRectInsets
|
|
||||||
{
|
|
||||||
return NSEdgeInsetsMake(50, 50, 50, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation tBox {
|
|
||||||
NSView *v;
|
|
||||||
NSMutableArray *children;
|
|
||||||
NSMutableArray *stretchy;
|
|
||||||
BOOL vertical;
|
|
||||||
id<tControl> parent;
|
|
||||||
BOOL spaced;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO rename to padded
|
|
||||||
- (id)tInitVertical:(BOOL)vert spaced:(BOOL)sp
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
if (self) {
|
|
||||||
self->v = [[tBoxContainer alloc] initWithFrame:NSZeroRect];
|
|
||||||
[self->v setTranslatesAutoresizingMaskIntoConstraints:NO];
|
|
||||||
self->children = [NSMutableArray new];
|
|
||||||
self->stretchy = [NSMutableArray new];
|
|
||||||
self->vertical = vert;
|
|
||||||
self->parent = nil;
|
|
||||||
self->spaced = sp;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)tAddControl:(id<tControl>)c stretchy:(BOOL)s
|
|
||||||
{
|
|
||||||
[c tSetParent:self addToView:self->v relayout:NO];
|
|
||||||
[self->children addObject:c];
|
|
||||||
[self->stretchy addObject:[NSNumber numberWithBool:s]];
|
|
||||||
[self tRelayout];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)tSetParent:(id<tControl>)p addToView:(NSView *)sv relayout:(BOOL)relayout
|
|
||||||
{
|
|
||||||
self->parent = p;
|
|
||||||
[sv addSubview:self->v];
|
|
||||||
if (relayout)
|
|
||||||
[self tRelayout];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO make the other dimension not hug (as an experiment)
|
|
||||||
- (void)tFillAutoLayout:(tAutoLayoutParams *)p
|
|
||||||
{
|
|
||||||
NSMutableDictionary *views;
|
|
||||||
__block uintmax_t i, n;
|
|
||||||
__block tAutoLayoutParams pp;
|
|
||||||
NSMutableString *constraint;
|
|
||||||
BOOL firstStretchy;
|
|
||||||
uintmax_t nStretchy;
|
|
||||||
NSLayoutConstraintOrientation orientation;
|
|
||||||
__block NSMutableArray *predicates;
|
|
||||||
|
|
||||||
if ([self->children count] == 0)
|
|
||||||
goto selfOnly;
|
|
||||||
|
|
||||||
[self->v removeConstraints:[self->v constraints]];
|
|
||||||
|
|
||||||
orientation = NSLayoutConstraintOrientationHorizontal;
|
|
||||||
if (self->vertical)
|
|
||||||
orientation = NSLayoutConstraintOrientationVertical;
|
|
||||||
|
|
||||||
views = [NSMutableDictionary new];
|
|
||||||
n = 0;
|
|
||||||
predicates = [NSMutableArray new];
|
|
||||||
[self->children enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
|
|
||||||
id<tControl> c;
|
|
||||||
NSNumber *isStretchy;
|
|
||||||
NSLayoutPriority priority;
|
|
||||||
|
|
||||||
c = (id<tControl>) obj;
|
|
||||||
isStretchy = (NSNumber *) [self->stretchy objectAtIndex:n];
|
|
||||||
pp.nonStretchyWidthPredicate = @"";
|
|
||||||
pp.nonStretchyHeightPredicate = @"";
|
|
||||||
// this also resets the hugging priority
|
|
||||||
// TODO do this when adding and removing controls instead
|
|
||||||
[c tFillAutoLayout:&pp];
|
|
||||||
priority = NSLayoutPriorityDefaultHigh; // forcibly hug; avoid stretching out
|
|
||||||
if ([isStretchy boolValue])
|
|
||||||
priority = NSLayoutPriorityDefaultLow; // do not forcibly hug; freely stretch out
|
|
||||||
if (self->vertical)
|
|
||||||
[predicates addObject:pp.nonStretchyHeightPredicate];
|
|
||||||
else
|
|
||||||
[predicates addObject:pp.nonStretchyWidthPredicate];
|
|
||||||
[pp.view setContentHuggingPriority:priority forOrientation:orientation];
|
|
||||||
[views setObject:pp.view forKey:tAutoLayoutKey(n)];
|
|
||||||
n++;
|
|
||||||
}];
|
|
||||||
|
|
||||||
// first string the views together
|
|
||||||
if (self->vertical)
|
|
||||||
constraint = [NSMutableString stringWithString:@"V:|"];
|
|
||||||
else
|
|
||||||
constraint = [NSMutableString stringWithString:@"H:|"];
|
|
||||||
firstStretchy = YES;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
NSNumber *isStretchy;
|
|
||||||
|
|
||||||
if (self->spaced && i != 0)
|
|
||||||
[constraint appendString:@"-"];
|
|
||||||
[constraint appendString:@"["];
|
|
||||||
[constraint appendString:tAutoLayoutKey(i)];
|
|
||||||
isStretchy = (NSNumber *) [self->stretchy objectAtIndex:i];
|
|
||||||
if ([isStretchy boolValue])
|
|
||||||
if (firstStretchy) {
|
|
||||||
firstStretchy = NO;
|
|
||||||
nStretchy = i;
|
|
||||||
} else {
|
|
||||||
[constraint appendString:@"(=="];
|
|
||||||
[constraint appendString:tAutoLayoutKey(nStretchy)];
|
|
||||||
[constraint appendString:@")"];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
[constraint appendString:[predicates objectAtIndex:i]];
|
|
||||||
[constraint appendString:@"]"];
|
|
||||||
}
|
|
||||||
[constraint appendString:@"|"];
|
|
||||||
[self->v addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraint options:0 metrics:nil views: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 = 0; i < n; i++) {
|
|
||||||
if (self->vertical)
|
|
||||||
constraint = [NSMutableString stringWithString:@"H:|["];
|
|
||||||
else
|
|
||||||
constraint = [NSMutableString stringWithString:@"V:|["];
|
|
||||||
[constraint appendString:tAutoLayoutKey(i)];
|
|
||||||
[constraint appendString:@"]|"];
|
|
||||||
[self->v addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraint options:0 metrics:nil views:views]];
|
|
||||||
// TODO do not release constraint; it's autoreleased?
|
|
||||||
}
|
|
||||||
|
|
||||||
[predicates release];
|
|
||||||
[views release];
|
|
||||||
|
|
||||||
// and now populate for self
|
|
||||||
selfOnly:
|
|
||||||
p->view = self->v;
|
|
||||||
p->attachLeft = YES;
|
|
||||||
p->attachTop = YES;
|
|
||||||
// don't attach to the end if there weren't any stretchy controls
|
|
||||||
// firstStretchy is NO if there was at least one stretchy control
|
|
||||||
if (self->vertical) {
|
|
||||||
p->attachRight = YES;
|
|
||||||
p->attachBottom = !firstStretchy;
|
|
||||||
} else {
|
|
||||||
p->attachRight = !firstStretchy;
|
|
||||||
p->attachBottom = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)tRelayout
|
|
||||||
{
|
|
||||||
if (self->parent != nil)
|
|
||||||
[self->parent tRelayout];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
// 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 func alignmentRectInsets() -> NSEdgeInsets {
|
||||||
|
return NSEdgeInsetsMake(50, 50, 50, 50)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tBoxChild {
|
||||||
|
var c: tControl
|
||||||
|
var stretchy: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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, v addToView: NSView) {
|
||||||
|
self.parent = p
|
||||||
|
v.addSubview(self.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
if self.children.count == 0 {
|
||||||
|
goto selfOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
self.v.removeConstraints(self.v.constraints)
|
||||||
|
|
||||||
|
orientation = NSLayoutConstraintOrientationHorizontal
|
||||||
|
if self.vertical {
|
||||||
|
orientation = NSLayoutConstraintOrientationVertical
|
||||||
|
}
|
||||||
|
|
||||||
|
var views = [String: NSView]()
|
||||||
|
n = 0
|
||||||
|
var predicates = [String]()
|
||||||
|
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 = NSLayoutPriorityDefaultHigh // forcibly hug; avoid stretching out
|
||||||
|
if child.stretchy {
|
||||||
|
priority = NSLayoutPriorityDefaultLow // do not forcibly hug; freely stretch out
|
||||||
|
}
|
||||||
|
if self.vertical {
|
||||||
|
predicates.append(pp.nonStretchyHeightPredicate)
|
||||||
|
} else {
|
||||||
|
predicates.append(pp.nonStretchyWidthPredicate)
|
||||||
|
}
|
||||||
|
pp.view.setContentHuggingPriority(priority, orientation:orientation)
|
||||||
|
views[tAutoLayoutKey(n)] = pp.view
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
|
||||||
|
// first string the views together
|
||||||
|
var constraint = "H:"
|
||||||
|
if self.vertical {
|
||||||
|
constraint = "V:"
|
||||||
|
}
|
||||||
|
var firstStretchy: true
|
||||||
|
for i = 0; i < n; i++ {
|
||||||
|
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(NSLayoutConstraint(
|
||||||
|
visualFormat: constraint,
|
||||||
|
options: 0,
|
||||||
|
metrics: nil,
|
||||||
|
views: 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 = 0; i < n; i++ {
|
||||||
|
constraint = "V:|["
|
||||||
|
if self->vertical {
|
||||||
|
constraint = "H:|["
|
||||||
|
}
|
||||||
|
constraint += tAutoLayoutKey(i) + "]|"
|
||||||
|
self.v.addConstraints(NSLayoutConstraint(
|
||||||
|
visualFormat: constraint,
|
||||||
|
options: 0,
|
||||||
|
metrics: nil,
|
||||||
|
views: views))
|
||||||
|
// TODO do not release constraint; it's autoreleased?
|
||||||
|
}
|
||||||
|
|
||||||
|
// and now populate for self
|
||||||
|
selfOnly:
|
||||||
|
p.view = self.v
|
||||||
|
p.attachLeft = true
|
||||||
|
p.attachTop = true
|
||||||
|
// don't attach to the end if there weren't any stretchy controls
|
||||||
|
// firstStretchy is false if there was at least one stretchy control
|
||||||
|
if self.vertical {
|
||||||
|
p.attachRight = true
|
||||||
|
p.attachBottom = !firstStretchy
|
||||||
|
} else {
|
||||||
|
p.attachRight = !firstStretchy
|
||||||
|
p.attachBottom = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tRelayout() {
|
||||||
|
if self->parent != nil {
|
||||||
|
self.parent.tRelayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue