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