Menu

Baseline Alignment in Horizontal Layout

SourceForge Editorial Staff

Functional and Design Specification


Glossary

Baseline Position - Element's layout metric. Typically the y position of the base of the first line of text in a component.
Baseline - A virtual horizontal line in a container. All elements that align to baseline are positioned such that their baseline position (first line of text) lands on the baseline.

Summary and Background

This feature extends the verticalAlign option for HGroup/HorizontalLayout. It allows elements in a HGroup/HorizontalLayout to be positioned such that their text aligns. There are a number of settings the developer can use to fine-tweak the baseline alignment.

The feature works only in non-virtualized HorizontalLayout/HGroup.

Usage Scenarios

  • Jane is building UI in Flex, she has a few components - a Button, a Label, a CheckBox. She wants to lay them out horizontally and have their text align. Jane wraps the components in a HGroup and sets the verticalAlign property to "baseline". Delightful.

    <s:HGroup verticalAlign="baseline">
        <s:CheckBox id="checkBox" label="One check box" />
        <s:Label id="label" text="...and some random text..." />
        <s:Button id="button" label="and a Button!"/>
    </s:HGroup>
    
  • John takes Jane's work and wants to add a red line to visualize where the group's baseline is. He binds to the HGroup's "actualAlignmentBaseline" property. That property gets updated with the value of the HGroup's baseline and fires an event, so binding works fine. Splendid.

    <s:Line x="0" width="{g.width}" y="{1 + g.actualAlignmentBaseline}" includeInLayout="false">
        <s:stroke>
            <s:SolidColorStroke color="0xFF0000"/>
        </s:stroke>
    </s:Line>
    
    <s:HGroup verticalAlign="baseline" id="g">
        <s:CheckBox id="checkBox" label="One check box" />
        <s:Label id="label" text="...and some random text..." />
        <s:Button id="button" label="and a Button!"/>
    </s:HGroup>
    
  • Jack takes over Jane's work and wants to tweak a little bit the HGroup's baseline. He wants to nudge it up one pixel from the calculated value. After reading the ASDoc for the alignmentBaseline property, he sets it to "maxAscent:-1". Wonderful.

    <s:HGroup verticalAlign="baseline" alignmentBaseline="maxAscent:-1">
        <s:CheckBox id="checkBox" label="One check box" />
        <s:Label id="label" text="...and some random text..." />
        <s:Button id="button" label="and a Button!"/>
    </s:HGroup>
    
  • James takes over John's work, but doesn't like it. He wants the HGroup's baseline to not be calculated from the elements but to be an absolute value. He sets the "alignmentBaseline" property to an explicit number. Then he wants to nudge down the Button by 1 pixel, but leave everything else the same. He sets the Button's "baseline" constraint to 1. Nice!

    <s:HGroup verticalAlign="baseline" alignmentBaseline="100">
        <s:CheckBox id="checkBox" label="One check box" />
        <s:Label id="label" text="...and some random text..." />
        <s:Button id="button" label="and a Button!" baseline="1"/>
    </s:HGroup>
    

Detailed Description

  • VerticalAlign.BASELINE = "baseline"
    • A new "baseline" enum value supported by the HGroup and HorizontalLayout verticalAlign.
    • baseline alignment is only in effect when HorizontalLayout is not virtualized.
    • When measuring, the HGroup/HorizontalLayout with baseline alignment will measure just enough height to fit in all the children + any padding.
    • Measured size is always a whole number.
  • A new HGroup/HorizontalLayout property - "baseline"
    • The property supports either "maxAscent:Number" or a plain Number format (similarly to the ConstraintRow's baseline property).
    • When the property is set to a Number, then the container's baseline is that number.
    • When the property is set to "maxAscent:Number", then the container's baseline is calculated when the layout runs.
    • actualAlignmentBaseline = paddingTop + max(element.baselinePosition + element.baseline) + Number;
    • actualAlignmentBaseline is not rounded, since if rounded, text will not align visually.
    • This property defaults to "maxAscent:0"
  • A new HGroup/HorizontalLayout proeprty - "actualBaseline"
    • The property's value is the calculated baseline of the container.
    • The property is read-only.
    • The property is bindable.
    • The property gets updated when layout runs.

API Description

public class HGroup extends Group
{

    //----------------------------------
    //  actualBaseline
    //----------------------------------

    <a href="Bindable%28%26quot%3BpropertyChange%26quot%3B%29">Bindable("propertyChange")</a>
    <a href="Inspectable%28category%3D%26quot%3BGeneral%26quot%3B%29">Inspectable(category="General")</a>

    /**
     *  The computed base line, in pixels, relative to the top edge
     *  of the group.
     *
     *  The value is computed in the group's <code>updateDisplayList()</code>
     *  and is based on the <code>alignmentBaseline</code> property as well as the <code>baselinePosition</code>
     *  and <code>baseline</code> properties of the group's elements.
     *
     *  Note that <code>actualAlignmentBaseline</code> is computed only when <code>verticalAlign</code>
     *  is set to "baseline".
     *
     *  @see #baseline
     *  @see #verticalAlign
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get actualAlignmentBaseline():Number

    //----------------------------------
    //  baseline
    //----------------------------------

    <a href="Inspectable%28category%3D%26quot%3BGeneral%26quot%3B%29">Inspectable(category="General")</a>

    /**
     *  The baseline of the layout, in pixels, either relative to the top edge
     *  of the container or to the max ascent of the elements.
     *
     *  Note that <code>baseline</code> has an effect only when <code>verticalAlign</code>
     *  is set to "baseline".
     *
     *  @default "maxAscent:0"
     *  @see #verticalAlign
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get alignmentBaseline():Object
    public function set alignmentBaseline(value:Object):void
}

public class HorizontalLayout extends LayoutBase
{
    //----------------------------------
    //  actualAlignmentBaseline
    //----------------------------------

    <a href="Bindable%28%26quot%3BpropertyChange%26quot%3B%29">Bindable("propertyChange")</a>
    <a href="Inspectable%28category%3D%26quot%3BGeneral%26quot%3B%29">Inspectable(category="General")</a>

    /**
     *  The computed <code>alignmentBaseline</code> of the layout, in pixels, relative to the top edge
     *  of the container.
     *
     *  The <code>actualAlignmentBaseline</code> is computed in the layout's <code>updateDisplayList()</code>
     *  and is based on the <code>alignmentBaseline</code> property as well as the <code>baselinePosition</code>
     *  and <code>baseline</code> properties of the layout elements.
     *
     *  Note that <code>actualAlignmentBaseline</code> is computed only when <code>verticalAlign</code>
     *  is set to "baseline".
     *
     *  @see #alignmentBaseline
     *  @see #verticalAlign
     *
     */
    public function get actualAlignmentBaseline():Number
    private function setActualAlignmentBaseline(value:Number):void

    //----------------------------------
    //  alignmentBaseline
    //----------------------------------

    <a href="Inspectable%28category%3D%26quot%3BGeneral%26quot%3B%29">Inspectable(category="General")</a>

    /**
     *  The base line of the layout, in pixels, either relative to the top edge
     *  of the container or to the max ascent of the elements.
     *
     *  Note that <code>alignmentBaseline</code> has an effect only when <code>verticalAlign</code>
     *  is set to "baseline".
     *
     *  @default "maxAscent:0"
     *  @see #verticalAlign
     *
     */
    public function get alignmentBaseline():Object
    public function set alignmentBaseline(value:Object):void

    //----------------------------------
    //  verticalAlign
    //----------------------------------

    <a href="Inspectable%28category%3D%26quot%3BGeneral%26quot%3B%2C%20enumeration%3D%26quot%3Btop%2Cbottom%2Cmiddle%2Cjustify%2CcontentJustify%2Cbaseline%26quot%3B%2C%20defaultValue%3D%26quot%3Btop%26quot%3B%29">Inspectable(category="General", enumeration="top,bottom,middle,justify,contentJustify,baseline", defaultValue="top")</a>

    /**
     *  The vertical alignment of layout elements.
     *
     *  <p>If the value is <code>"bottom"</code>, <code>"middle"</code>,
     *  or <code>"top"</code> then the layout elements are aligned relative
     *  to the container's <code>contentHeight</code> property.</p>
     *
     *  <p>If the value is <code>"contentJustify"</code> then the actual
     *  height of the layout element is set to
     *  the container's <code>contentHeight</code> property.
     *  The content height of the container is the height of the largest layout element.
     *  If all layout elements are smaller than the height of the container,
     *  then set the height of all the layout elements to the height of the container.</p>
     *
     *  <p>If the value is <code>"justify"</code> then the actual height
     *  of the layout elements is set to the container's height.</p>
     *
     *  <p>If the value is <code>"baseline"</code> then the elements are baseline
     *  aligned to the <code>alignmentBaseline</code> of the layout.
     *
     *  <p>This property does not affect the layout's measured size.</p>
     *
     *  @default "top"
     *
     */
    public function get verticalAlign():String
    public function set verticalAlign(value:String):void

}

/**
 *  The VerticalAlign class defines the possible values for the
 *  <code>verticalAlign</code> property of the HorizontalLayout class.
 *
 *  @see HorizontalLayout#verticalAlign
 *
 */
public final class VerticalAlign
{
   ....

    /**
     *  Vertically align the children to the baseline of the container.
     */
    public static const BASELINE:String = "baseline";
}

Additional Implementation Details

Compiler Work

Backwards Compatibility

Performance

No performance impact on non-baseline aligned HGroup/HorizontalLayout or virtualized HorizontalLayout expected.

Globalization

N/A

Localization

N/A

Cross-Platform Considerations

N/A

Issues and Recommendations


Related

Wiki: Flex 4.5

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.