hi!

131 views
Skip to first unread message

Ken Ferry

unread,
Feb 22, 2014, 2:00:53 PM2/22/14
to overcon...@googlegroups.com
Hi! 

Someone on twitter happened to link to this, and I thought I'd say hello.

I did the original auto layout implementation at Apple. I'm happy to discuss decisions we made, if that's useful. 

(Hi Greg!)

-ken

Greg Badros

unread,
Feb 22, 2014, 2:11:48 PM2/22/14
to overcon...@googlegroups.com

Hey Ken... hope your new thing is going well! (And guys, Ken knows Cassowary really well too...)

--
You received this message because you are subscribed to the Google Groups "overconstrained" group.
To unsubscribe from this group and stop receiving emails from it, send an email to overconstrain...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Dan Tocchini IV

unread,
Feb 24, 2014, 2:44:42 PM2/24/14
to overcon...@googlegroups.com
Ken, there's so much to discuss... Where to start?  Interested in your thoughts on this thread about default strength.  Why auto layout's default priority level was required?  As with CCSS, I made weak the default strength in GSS.  Also, how & why does NSLayoutPriority differ from Cassowary's strength & weight. 

Thanks!
Dan

Ken Ferry

unread,
Feb 24, 2014, 5:15:43 PM2/24/14
to overcon...@googlegroups.com
On Feb 24, 2014, at 11:44 AM, Dan Tocchini IV <d...@thegrid.io> wrote:

Ken, there's so much to discuss... Where to start?  Interested in your thoughts on this thread about default strength.  Why auto layout's default priority level was required?  

Yup! That's true.

Consider this UI:

MailLayout.mov
PastedGraphic-3.png
PastedGraphic-4.png
PastedGraphic-5.tiff

Ken Ferry

unread,
Feb 24, 2014, 5:23:47 PM2/24/14
to overcon...@googlegroups.com
By the way, if you'd like an overview of how Cocoa thinks about this stuff, I'd recommend the talk "Cocoa Autolayout" at <https://developer.apple.com/videos/wwdc/2011>.

It requires an Apple dev account, but it's free.

-ken



Here's a simplified version recreated in Cocoa's dev tools, with lines denoting constraints.



It behaves like this:

If you look at that, you see that all the constraints are expected to always hold, with one exception, and that's that the delete button is only preferentially aligned with the messages pane (which is denoted in the UI builder as a dashed line). 

And you can see that that's kind of a special case. Strength is absolutely wonderful to have when you need it, but still, it seems like almost all relationships you make you intend to always hold.

The system can help you debug better if you express constraints that should always hold as required:  If you make constraints required and they conflict, there is enough information in the solver to show the developer the mutually exclusive constraints. If they're non-required, you'll get wrong layout with no assistance. What Cocoa does in the case of conflicting required constraints is to log them out, optionally tell the involved constraints to start displaying themselves on the screen as lines like in the above diagrams, and then it selects one of the conflicting constraints and lowers its priority to make it optional so that the UI can still be laid out. This last bit is because it's easier to debug the system when it still functions. (It also throws and catches an exception, which is useful in Cocoa because developers often set a breakpoint on all exception throwing. I don't know if that has a web analog.)

Also, a required constraint is also easier to reason about, because it requires less contextual knowledge of the system as a whole. If something's required, you can just say "this will happen, no ifs ands or buts".

As with CCSS, I made weak the default strength in GSS.  Also, how & why does NSLayoutPriority differ from Cassowary's strength & weight. 

NSLayoutPriority is the same as strength, except that it's a floating point number between 0 and 1000 instead of one of (weak, medium, strong, required). Weight is not a concept. (I think when Greg and Alan Borning were visiting, they explained that weight is a much more useful concept with a non-linear solver, like http://en.wikipedia.org/wiki/Qoca. Did I get that right Greg?)

Implementation wise, this stuff corresponds to coefficients of variables in the objective expression in the solver. In Cassowary you can think of the coefficients as being triples of floats,
 
(strongWeight, mediumWeight, weakWeight)

Where when you say "a medium constraint with weight 2" you're giving the triple (0, 2, 0).

Ok. Another data representation for "a medium constraint with weight 2" could be to say 

enum {
Strong: 300
  Medium: 200
Weak: 100
}

and then represent "a medium constraint with weight 2" as ( (200, 2) ). That is, as a list of pairs, where the first el of each pair is the strength and the second is the weight.

Once you're using that representation, you can have arbitrary floating point strengths. In Cocoa, "priority 600" corresponds to the objective expression coefficient ( (600, 1) ).

If you're looking for a case where you'd need multiple levels of priority, consider this:



If I grab the splitter where the mouse is and pull to the left or to the right, the split panes should close in the given order. In Cocoa, that'd be implemented with constraints of differing priorities that are created when you mouse down on a split divider, and destroyed when you mouse up.

Cocoa itself ended up needing to define 7 prebaked priority levels for OS X, and 4 for iOS (fewer on iOS 'cause no resizable windows!)

-ken

Alex Russell

unread,
Feb 28, 2014, 12:30:50 AM2/28/14
to overcon...@googlegroups.com
Lots for me to process in this, but I just wanted to say thanks so much for sharing your experience with us! I'd be especially curious to know what areas you found Cassowary (the API or the algorithm) frustrating in trying to achieve layouts. I'm noticing that many CSS-like layouts generate a large number of constraints and that the system (as I've got it right now) isn't particularly good about GC-ing Tableau rows. Were those challenges for you as well?

Ken Ferry

unread,
Feb 28, 2014, 5:19:52 AM2/28/14
to overcon...@googlegroups.com
On Feb 27, 2014, at 9:30 PM, Alex Russell <sligh...@gmail.com> wrote:

> Lots for me to process in this, but I just wanted to say thanks so much for sharing your experience with us!

No problem!

> I'm noticing that many CSS-like layouts generate a large number of constraints and that the system (as I've got it right now) isn't particularly good about GC-ing Tableau rows. Were those challenges for you as well?

There need to be at least as many constraints as variables for each var to get a value. Since a rectangle needs a minX, minY, width, height, the average number of constraints per block to be laid out should be a bit over 4. Are you seeing much more than that?

We did try pretty hard to minimize memory usage and churn. That helps with speed too. Cocoa isn't garbage collected, so getting things freed up promptly is not a problem.

> I'd be especially curious to know what areas you found Cassowary (the API or the algorithm) frustrating in trying to achieve layouts.

The API layering we used isn't really the same. I'm not sure what to say specifically, but happy to answer questions.

Not much complaint re: expressive power! Probably the most important thing there is that Cocoa's engine integrates with imperative trapdoors. For example, if you have a minesweeper view that always needs to be a multiple of 10 points wide, you can hook into the layout process, make it so, and your information gets propagated back into the solver.

There are a few things that are handled awkwardly. The most important is multiline text areas that need be tightly sized to their content. The relationship between width and height of a paragraph is not linear (the height is a step-function of the width, when stuff wraps to a new line), so it requires more hand holding from the developer than one would like. The situation is more rare than you might think, though. Looking through OS X Mail, I don't see any text areas like that.

That said, visualization, transparency, debuggability, understandability, and other UI issues were (and are) much more of a concern than expressive power. The vast majority of UI relationships are some variation on "this aligns with that".

-ken
Reply all
Reply to author
Forward
0 new messages