My thought was that applyCSS could for now just call impl_processCSS(true) -- so it is "Thor's Hammer" and will just hammer everything to be updated. Not necessarily fast. Then in subsequent releases we could maybe tune it up. Do we *need* the boolean? I know it is sometimes false (TreeView, TableView, etc) and other times true. But is the "true" usage really needed or was it just to cover up errors we were seeing? I remember having done this but don't remember if it was truly needed or not?
Richard On Jul 12, 2013, at 9:03 AM, David Grieve <david.gri...@oracle.com> wrote: > I hesitate to mention Node#impl_processCSS(boolean) which is very very close > to your notion of applyCss(); impl_processCSS(boolean) is a thorn in my side, > but is used in certain places in controls code to ensure CSS is applied > before layout in order to ascertain a node's dimensions. What it does is > walk up the tree to find the closest parent who's cssFlag is other than clean > and then calls processCSS from that node on down. The flag says whether to > simply update css or to reapply css (reapply involves figuring out what > styles apply to a node). > > impl_processCSS is also used by SceneBuilder. They created > https://javafx-jira.kenai.com/browse/RT-21206 asking to make > impl_processCSS(boolean) public. > > It should also be mentioned that pseudo-class state matters, including the > state of the parents, so depending on when you call applyStyle(), you might > get different results. The applyStyle() method can't really ignore > pseudo-class state since things like orientation (horizontal/vertical) are > kind of important. > > On Jul 12, 2013, at 11:32 AM, Richard Bair <richard.b...@oracle.com> wrote: > >>>> Is there any reason why I might want to measure a node independent of the >>>> layout of its parent? If I have a Button in a StackPane, is there a time I >>>> might want to measure the Button independent of the StackPane? I suppose >>>> so, if for example I wanted to get snapshots of it at its min size, max >>>> size, and pref size, regardless of what the layout container might do with >>>> the button. That seems reasonable. >>> Yes, maybe. But that would require a completely different API. >> >> In what way? Just having applyCSS exposed allows me to do this? >> >>>>> The concept of layout roots is not documented well in the API ( we use >>>>> the term in few place, but never define it) and people would have to know >>>>> how to identify the layout root and also know that they need to start >>>>> from the layout root. Also, there's no way to check which Node is the >>>>> layout root, although you can identify it using managedProperty(), it's >>>>> parent and/or sub scene. >>>> Hmmm. OK, so today suppose I have a scene graph with a root node and >>>> someplace down in the hierarchy is an unmanaged node. If I call layout() >>>> on the root node, then it will layout everything except for the unmanaged >>>> node. If i wanted to get a list of all the dirty layout roots, well, there >>>> is no public API to do so. >>>> >>>> After your change, the semantics of layout would be the same -- calling >>>> layout on the root node isn't going to cause the unmanaged node to be laid >>>> out. So for what Steve and I are proposing to make sense (just expose >>>> applyCSS), we also have to expose either another method >>>> (layoutEverythingForTheLove) that will force everything in the tree to be >>>> laid out, or we have to have another method (getLayoutRoots) which will >>>> accumulate the layout roots so that you can then call layout() on them all >>>> manually. >>> Actually, calling layout() on scene root will layout everything in the root >>> after my changes (as the flags must always be set up to the root, so we can >>> find the way to all dirty layout roots), currently this doesn't work as the >>> scene root doesn't know whether there are other dirty layout roots in the >>> scene. So if you have (Sub)Scene, you can just call getRoot().layout() and >>> everything should be laid-out correctly (if you also called CSS before). >>> But this would re-layout much more then is needed for some specific Node. >> >> If that's the case then it seems like all you need is applyCSS. Because from >> any node you get getScene().getRoot().layout(), or in the worst case walk up >> to the root and then fire off the applyCSS / layout. >> >> In this case, applyCSS becomes the essential API, and "validate" or whatever >> it would be called becomes the convenience API. In this case I would suggest >> adding the essential API and adding the convenience API subsequently when >> the pain is clearly felt and understood. >> >> Richard >