As we all know, Xojo supports “Lock” parameters for most controls, this set the behaviour of an embedded control, when its parent moves or changes size.
I am attempting to create a Swift framework, and am trying to figure out the best way to replicate a similar behaviour. I have come up with a few ideas, and don’t really like any of them
Add Autolayout constraints when would be turned on/off . So far this is messy, and I can’t quite make it work properly
Add an extension to the base object (NSVIEW) which would somehow determine what changes to the controls frame need to be made… Not tested, but feels just as messy
forget about it entirely, and leave it as a manual exercise for the developer using this framework
Anyone have an idea what Xojo does behind the scenes? I doubt it is the AL method, as AL is new and macOS only…
The Xojo locks are roughly an autolayout constraint from the control to a permanently fixed distance from the left, right, top and bottom edges of the containing item
I think that would get you to the same thing as Xojo locks
I think I figured it out (but not tested it yet)
First I had to add properties to superclass of ALL controls… This is something that Swift doesn’t do in a straight forward manner… but I think I got it to work… this was the LOCKxxx direction flags
Then for each “container” type control… if its frame changed, it will pass the old and new frame sizes to a function that will examine the lock flags on each child control, and alter its frame based on its lockflags and how its parent frame changed…
for those interested :
extension NSView {
// nested structure
private struct lockKeys {
static var leftKey : Bool = false
static var topKey : Bool = false
static var rightKey : Bool = false
static var bottomKey : Bool = false
}
var lockLeft: Bool {
get { return getAssociated(associatedKey: &lockKeys.leftKey) }
set { setAssociated(value: newValue, associatedKey: &lockKeys.leftKey) }
}
var lockTop: Bool {
get { return getAssociated(associatedKey: &lockKeys.topKey) }
set { setAssociated(value: newValue, associatedKey: &lockKeys.topKey) }
}
var lockRight: Bool {
get { return getAssociated(associatedKey: &lockKeys.rightKey) }
set { setAssociated(value: newValue, associatedKey: &lockKeys.rightKey) }
}
var lockBottom: Bool {
get { return getAssociated(associatedKey: &lockKeys.bottomKey) }
set { setAssociated(value: newValue, associatedKey: &lockKeys.bottomKey) }
}
}
IMHO AutoLayout constraints are quite a complex thing for what AutoResizingMask does perfectly. I built myself a method that creates a mask from the locks of a Xojo control when I embed a custom declared subclass and that works quite nicely.