Sounds like a plan.
I'll retarget RT-31133 ("validate") to Van Ness in case it would be
required later.
I will change the layout processing so that it uses flags instead of
dirty root lists. That way, getRoot().layout() will trigger a complete
layout pass or both Scenes and SubScenes.
Means the only API change that we need is "applyCSS", which is covered
by RT-21206.
Regards,
-Martin
On 07/12/2013 06:33 PM, Richard Bair wrote:
I'm thinking applyCSS would just call impl_processCSS(true) and then we should
work towards removing impl_processCSS(boolean) if possible, so that we're all
just using applyCSS() all the time (once impl_processCSS(boolean) can be
removed and all bugs sorted out, then we could just move impl_processCSS() guts
into applyCSS, methinks).
Its OK with me if we make the transition over time.
Richard
On Jul 12, 2013, at 9:19 AM, David Grieve <david.gri...@oracle.com> wrote:
There is Node#impl_processCSS() that is the normal css processing path (Scene#doCSSPass
-> Node#processCSS -> Node#impl_processCSS() ->
CssStyleHelper#transitionToState) .
impl_processCSS(boolean) was left in because it is a way of forcing the reapply in cases
where CSS was needed to be processed before the next pulse but has become the panacea for
covering up errors, i.e. "this doesn't display right, try
impl_processCSS(true)."
On Jul 12, 2013, at 12:06 PM, Richard Bair <richard.b...@oracle.com> wrote:
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