You may be right. Aligning a wrapped, vertically-aligned label to a
baseline doesn't seem like a very common requirement, but the baseline
of a FlowPane, for example, could easily change as its width
constraint changes: different components may comprise the first row,
which would ultimately define the flow pane's baseline for that width.
Since FlowPanes are likely to be used as fields in a form (which may
have the "fill" style set to true), this could happen fairly often.
The problem is that calculating a baseline in these cases will be
computationally intensive. It will require the component to basically
perform the same math twice - once to calculate its preferred size,
and again to determine the baseline given a size. The logic will need
to be applied again during layout.
If we do go ahead and include both width and height arguments to
getBaseline(), we'll probably want to cache the values in Component
like we do for preferred size. We can probably hook into the existing
mechanism pretty easily.
One alternative would be to drop the width argument for now, and
introduce both width and height arguments in a later update. The
existing signature could then potentially delegate to the two-argument
signature, passing -1 for each to indicate an unconstrained value.
This way, we wouldn't break backwards compatibility.
On Nov 5, 2009, at 4:14 PM, Todd Volkert wrote:
I thought of a case where both the width & height would come into
play in a
baseline calculation. Let's imagine a Label with a vertical
alignment of
CENTER and wrapText set to true. Here are some baselines that it
should
report:
1. If it's asked for its baseline given its preferred size, it
doesn't
need to wrap, and the vertical alignment isn't in play. It
reports the
baseline of its single line if text.
2. If it's asked for its baseline given its preferred width and
more than
its preferred height, it doesn't wrap, but it does need to center
itself
vertically. It reports the baseline of its single line of text,
plus its
vertical offset due to the vertical alignment.
3. If it's asked for its baseline given less than its preferred
width and
more than its preferred height, it needs to both wrap its text and
center
itself vertically. It reports the baseline of its first line of
text, plus
the vertical offset due to the vertical alignment. In this case,
the
vertical offset will be less than in #2 because there are more
lines of
text.
If we dropped the width argument and went with just the height
argument, we
wouldn't satisfy #3 above.
Thus, I think the correct thing to do is to pass both a width and
height
argument to getBaseline().
-T
On Wed, Nov 4, 2009 at 3:49 PM, Greg Brown <[email protected]> wrote:
I can't think of one. I think a height argument would be sufficient
(even
if we don't update the FlowPane and Form skins to take it into
account right
away).
On Wednesday, November 04, 2009, at 03:42PM, "Todd Volkert" <
[email protected]> wrote:
It's certainly more comprehensive that having getBaseline() take no
arguments. We don't really want to suffer from a design flaw
years down
the
road, so better to cover our bases now. In this aspect, I agree.
The
only
question is what value a width argument could possibly provide...
-T
On Wed, Nov 4, 2009 at 2:16 PM, Greg Brown <[email protected]> wrote:
Apparently, the AWT Component#getBaseline() method takes a width
and a
height. I don't think both are necessary, but it might be good to
include
the height argument, because this will allow a container to
determine
its
preferred size based on the baselines of its children.
Take FlowPane, for example - FlowPaneSkin#getPreferredSize()
might ask
each
subcomponent for its preferred size and then determine its own
preferred
height using the size/position of the subcomponents relative to the
baseline
(it doesn't currently do this, but it probably should). It would
call
getBaseline(preferredHeight) on each subcomponent to determine the
baseline
value, then calculate its preferred height as the difference
between the
components whose top and bottom are farthest apart.
TerraFormSkin might do something similar. Rather than assuming
that a
field
row is simply the max. value of the label and field heights, it
could
take
the baselines into account and determine the row height based on
their
relative positions.
Thoughts?
On Wednesday, November 04, 2009, at 01:11PM, "Greg Brown" <
[email protected]>
wrote:
After some additional thought, it does seem as though
eliminating the
width argument to getBaseline() might be a good idea. Baselines are
primarily a layout construct - they don't generally have any
bearing on
preferred size calculations (and, after thinking about it a bit,
I'm not
even sure that they can). As a result, getBaseline() probably
doesn't
need a
width constraint.
G
On Wednesday, November 04, 2009, at 10:22AM, "Todd Volkert" <
[email protected]> wrote:
Actually, I'm starting to think your original assertion may be
correct.
I
looked deeper into the problem with push button's baseline
calculation
as
it
pertains to PIVOT-338, and the buttons in the component
explorer that
don't
report their baselines correctly aren't even given an aspect
ratio --
*they're
given an explicit preferred size*. The design of the existing
baseline
calculation method implicitly assumes that you'll be given your
preferred
size.
Example: <PushButton wtkx:id="button" buttonData="foo"
preferredHeight="100"
/>
button.getBaseline(-1) will return something like 10, when in
fact the
baseline will end up being something like 55.
Perhaps my assertion that a component's baseline may affect the
preferred
size of its parent caters to an edge case condition that we
really
shouldn't
worry about. I think I'm leaning towards re-defining the
method to be
getBaseline(), and having it pertain to the existing size of the
component.
Thoughts?
-T
On Tue, Nov 3, 2009 at 8:06 AM, Greg Brown <[email protected]>
wrote:
Ah, yes, I think that may be true. Containers must calculate
their
preferred size before they are actually given a size and
called to
lay
out.
It stands to reason that baseline alignment may factor into that
calculation, so you are right that we can't simplify it in
this way.
On Nov 3, 2009, at 7:56 AM, Todd Volkert wrote:
Containers that can align to baseline may need to know the
baselines
of
their child components when calculating preferred size (where
it's
going
to
place the children may affect the preferred size of the
container).
Since
the container has may have a width constraint in mind when it
asks
its
children for their preferred size, it stands to reason that the
same
width
constraint will apply when it asks the children for their
baselines.
Thus,
I think the baseline calculation has to take a width
constraint.
From a high level, it seems like this should be OK, since
baseline
alignment
isn't so much about setting size as it is aligning things
after
their
sizes
have been set.
I think what I'm saying above is that this assumption may not
be
correct.
Is it possible that a child's baseline will need to be
calculated
during
the
preferred size calculation of its parent (and would affect the
preferred
size of the parent)? I want to say we have to assume yes,
but I'm
not
100%
sure.
-T