Menu

Enhanced Constraints Specification

SourceForge Editorial Staff

Enhanced Constraints Specification

PLEASE NOTE THAT THIS SPECIFICATION MAY BE OUT OF DATE, DOCUMENTATION PROVIDED WITH THE RELEASE SUPERCEDES ANYTHING IN THIS SPEC.

Summary of Feature

The goal of this feature is to expand upon the current constraint-based layout system to accomodate sibling-relative layouts. With this functionality added in, designers will be able to use the Canvas container to create complex layouts that aligns children in both the horizontal and vertical directions, constrains child controls to each other as well as the parent Canvas edges, and stretches and reflows as the parent Canvas container resizes. The Grid container and its associated classes will be deprecated in favor of the new Canvas container to avoid redundancy of behavior. Documention and FlexBuilder UI will promote the usage of the new Canvas container to achieve resizable table layouts. Application and Panel will also support the new constraint functionality built into the Canvas container the same as before (by simple specifying layout="absolute" in the Application or Panel tag).

The current constraint-based layout system allows for only parent-child constraints to be defined. We will expand the current system so that sibling-relative layouts can be achieved easily with our constraints system without resorting to complex databinding expressions or nested containers. Additionally, we will add the ability to constrain controls along a shared baseline.

We will add the concept of constraint regions that can be created in the horizontal or vertical direction. Constraint regions are non-UI elements that are added to Canvas containers. Users will be able to design layouts that align controls in multiple constraint regions which enables flexible resizing behavior at runtime. Constraint regions are sized by 1 of 3 sizing options: fixed size, percentage size and content size. Fixed size means that the region is sized to a fixed pixel value. Percentage size means that the region is sized to a percentage of its parent Canvas. Content size means that the region is sized by the content contained in it. As the Canvas container grows or shrinks in space, the change in space is redistributed based on the sizing option each constraint region has adopted.

Controls are added such that they occupy individual constraint regions or span multiple constraint regions. Controls specify which constraint regions they are bounded by and this defines the area which the control "lives" in, ie: their content area. Constraints can be set relative to this content area. If a Canvas contains no constraint regions, controls are contained within the space defined by the parent Canvas container and any constraints set are evaluated relative to the parent Canvas edges.

Usage Scenario

Marisa is a visual designer who uses Photoshop and Illustrator to layout complex, large-scale user interfaces. Her company moves over to Flex and she is now encouraged to use FlexBuilder to create her UIs. Marisa opens up FlexBuilder and imports her content into Design View. She is able to easily create her complex layouts by defining constraint columns and constraint rows and setting constraint styles so that as the application resizes, the excess space is shared as desired by the original designer. By adding constraints and specifying which constraint regions are percentage sized, fixed sized or content sized, Marissa has added reflowing capabilities to her UI upon resizing.

Detailed Description

ConstraintColumn and ConstraintRow

A designer will use FlexBuilder's Design View to partition a Canvas into constraint columns and constraint rows and this will result in auto-generated mxml. Two properties will be added to Canvas: constraintColumns and constraintRows. Both properties will contain an array of ConstraintColumn or ConstraintRow objects which are faceless objects. ConstraintColumns and ConstraintRows are laid out with respect to an origin - the top/left corner of the Canvas. So ConstraintRows are laid out top to bottom in the order that they were defined and ConstraintColumns are laid out left to right in the order that they were defined.

<mx:Canvas>
  <mx:constraintColumns>
    <mx:ConstraintColumn id="nav" width="212" />
    <mx:ConstraintColumn id="column1" width="100%" />
  </mx:constraintColumns>
  <mx:constraintRows>
    <mx:ConstraintRow id="row1" height="80%" />
    <mx:ConstraintRow id="footer" height="20%" />
  </mx:constraintRows>
</mx:Canvas>

It is ok to have space in the Canvas unallocated to a constraint region. For example, this layout:

<mx:Canvas width="100%" height="100%">
  <mx:constraintColumns>
    <mx:ConstraintColumn id="col1" width="20%" />
  </mx:constraintColumns>
</mx:Canvas>

Produces a Canvas with a single constraint column that consumes 20% of the overall Canvas size.

Constraint columns/rows have 3 sizing options available to them: fixed size, percentage size, and content size. These sizing options dictate the position of the constraint region and the amount of space it takes up in the parent Canvas. Fixed size means that the space taken up by that region is a fixed pixel size, ie: <mx:constraintcolumn id="nav" width="212"></mx:constraintcolumn>. Percentage size means that the space taken up by that region is a percentage of the overall space available to the parent Canvas, ie: <mx:constraintrow id="footer" height="20%"></mx:constraintrow>. Content size means that the space taken up by that region is dictated by the content contained in that space. As the size of the content changes, so does the size of the region. An example of a content sized constraint row is: <mx:constraintrow id="footer"></mx:constraintrow> - one can infer this is a content sized constraint row since the height property is not set. As space is added or removed from the parent Canvas, space is distributed to each ConstraintColumn and ConstraintRow instance according to its sizing option.

Constraint columns/rows will be able to set minimum and maximum sizes to control how much they grow or shrink. This is useful in percentage-sized constraint regions. As a constraint region shrinks below its minimum size, the parent Canvas will sprout scrollbars to show hidden content.

Constraints

Controls are placed within, or can span across, the constraint regions which partition the main Canvas. A control identifies its content area by specifying the constraint region or parent border which it is bounded by on the left, right, top and bottom. This identification happens by the value passed into the original constraint styles defined in UIComponent: left, right, top and bottom. A micro-language is used to specify the constraint region and the pixel offset. The pixel offset is evaluated relative to that constraint region. For example, this mxml:

<mx:Canvas>
  <mx:constraintColumns>
    <mx:ConstraintColumn id="nav" width="212" />
    <mx:ConstraintColumn id="column1" width="100%" />
  </mx:constraintColumns>
  <mx:constraintRows>
    <mx:ConstraintRow id="row1" height="80%" />
    <mx:ConstraintRow id="footer" height="20%" />
  </mx:constraintRows>

  <mx:List left="nav:10" right="nav:10" top="row1:10" bottom="row1:10" />

</mx:Canvas>

defines a List control which is bounded by the ConstraintColumn on the left with id="nav", the ConstraintColumn on the right with id="nav", the ConstraintRow on top with id="row1" and the ConstraintRow below with id="row2". The List is placed such that it is 10 pixels offset from the left and right edges of the "nav" ConstraintColumn and 10 pixels offset from the top and bottom of the "row1" ConstraintRow. The List will stretch to consume the space defined. If the main Canvas is resized horizontally, the List will not grow since it lives in the fixed "nav" ConstraintColumn. If the main Canvas is resized vertically, the List will grow to always consume 80% of the total height of the Canvas.

To specify that a control's content area is bounded by a parent Canvas border, the original syntax is used. An pffset without a ConstraintColumn or ConstraintRow id implies that the offset is relative to the parent border. For example, in this mxml:

<mx:Canvas id="main">
  <mx:constraintColumns>
    <mx:ConstraintColumn id="nav" width="212" />
    <mx:ConstraintColumn id="column1" width="100%" />
  </mx:constraintColumns>
  <mx:constraintRows>
    <mx:ConstraintRow id="row1" height="80%" />
    <mx:ConstraintRow id="footer" height="20%" />
  </mx:constraintRows>

  <mx:List left="10" right="nav:10" top="row1:10" bottom="row1:10" />

</mx:Canvas>

There are some rules, which are hopefully obvious, that dictate how a control behaves based on what constraint regions are set to define its content area. When using DesignView to create constraint regions and apply constraints, we will auto-generate mxml that follows these rules.

*Unset constraint regions default to the appropriate Canvas edge border. IE: <mx:List left="10" right="nav:10" top="row1:10" bottom="row1:10" /> the left constraint is evaluated relative to the Canvas' left edge.

*If neither of the paired constraint regions are set (ie: left and right are evaluated relative to the Canvas' left and right edges), and a control is defined that spans multiple existing constraint columns, those constraint columns do not take that control into account when evaluating their reflow behavior. (ie: if those constraint columns are content sized columns, they do not count that control as content they care about).

*If a control's boundary is set to an invalid constraint region (ie: left references a ConstraintRow id, left references a non-existant or misspelled constraint region), we will throw an error. This is the downside of not having databinding in specifying the constraint boundary expressions. Additionally, we may chose to emit RTE's for other errors in the micro-language used to specify a constraint boundary and offset.

Below are some simple examples showing a variety of constraint regions and constraint permutations and the expected behavior in those situations.

<mx:Button id="btn" left="col1:20" right="col1"/>

<!--Evaluates to a Button's left edge constrained 20 pixels in from the left edge of the 
constraint column with id="col1" and flush against the right border of the 
constraint column with id="col1". Basically the Button spans only col1 -->



<mx:Button id="btn" left="col1:20" right="col4:0"/>

<!--The Button spans 4 constraint columns. The Button assumes its 
preferred size (lets say 200 pixels) and the 4 columns are made to 
equally divide that area. So, col 1, 2, 3 and 4 will be 50 pixels each. 
The Button is then placed 20 pixels in from the left edge of col1. As the 
Button changes in size, the 4 columns will shrink or grow equally 
(ie: share the new space equally or subtract the space taken away equally). -->



<mx:Button id="btn" left="20" right="20" />

<!--The Button is placed such that it is 20 pixels from the left edge of 
the parent Canvas and 20 pixels from the right 
edge of the parent Canvas. If the control spans constraint columns (ie: 
constraint columns exist), those constraint columns do not take 
the Button into account when figuring out their reflow behavior. -->



<mx:Button id="btn" left="col1:20" right="col2:20" />

<!--The Button is placed such that its left edge is 20 pixels in from col1 and 
its right edge is 20 pixels in from col2. Constraint columns 1 and 2 take 
the Button's size into account when figuring out their reflow behavior. For 
example, col2 is a content-sized constraint column. 
If the Button's label grows, col2 will grow to accomodate the wider Button and 
the right edge of the Button will be 20 pixels in from 
the edge of col2. -->

Center Constraints

If the horizontalCenter or verticalCenter constraint is set, that constraint is evaluated relative to the constraint region specified, or the center of the parent container if no constraint region is specified. In specifying constraint regions, horizontalCenter constraints require a ConstraintColumn to evaluate off of and verticalCenter constraints require a ConstraintRow to evaluate off of. Examples are included below.

<mx:Button horizontalCenter="col1:0" />

<!-- The Button is placed directly in the center of the 
ConstraintColumn with id="col1" -->



<mx:Button verticalCenter="row1:0" />

<!-- The Button is placed directly in the center of the 
ConstraintRow with id="row1" -->



<mx:Button horizontalCenter="col1:20" />

<!-- The Button is placed 20 pixels down from the center of the 
ConstraintColumn with id="col1" -->



<mx:Button verticalCenter="20" />

<!--The Button lives in a region defined by the Canvas edges. The 
Button is placed 20 pixels down from the center 
of the Canvas. -->

Baseline Constraint

We would like to add the ability to constrain controls along a baseline. A new baseline constraint style will be added to UIComponent to accomplish this.

Setting the baseline constraint means that the user is specifying an offset from the top edge of constraint region or parent border and the control's baseline. By offering a baseline constraint style, we can now allow multiple components to be constrained along a single shared baseline. Examples are included below.

<mx:Button baseline="row2:0" />

<!--The Button is placed such that its baseline is flush with 
the top edge of row2. -->



<mx:Button baseline="20" />

<!-- The Button's top edge is the top Canvas border. The Control 
is placed such that its baseline is 20 pixels offset from the 
top of the Canvas edge. -->



<mx:Button baseline="row1:0" />
<mx:Label baseline="row1:0" />
<mx:LinkButton  baseline="row1:0" />

<!--The 3 controls are all baseline constrained to the same 
constraint row so they will all line up along the shared baseline correctly. -->

Solving Constraints

We will write a new layout algorithm that a Canvas uses whenever it has constraint regions specified. If no constraint regions are specified, the old layout algorithm will be used. The new layout algorithm is very similar to the old layout algorithm. The description below is written with respect to horizontal coordinates.

Step 1. Given the current size of the parent Canvas, decipher pixel values for all the ConstraintColumns.

1a. Fixed ConstraintColumns honor their pixel values.

1b. Content sized ConstraintColumns figure out if they have content that spans multiple columns or not (ie: all the content in that ConstraintColumn is contained solely in that ConstraintColumn or spans that ConstraintColumn plus other ConstraintColumns).

*Content is contained solely in that ConstraintColumn means the ConstraintColumn assumes the width of the widest child.

*Content spans multiple columns:

  • (1) Sort the children by order of how many columns they are spanning (least to most)
  • (2) For children spanning a single column, make each column as wide as the preferred size of the child
  • (3) Work through the next set of children (ie: those spanning 2 columns) and divide the remainder space equally between shared columns
    • We might want to consider sorting the children in each column-span set by size and evaluate remainder space in order of smallest to largest.

Note: This means content-sized column widths are decided in order of children encountered from top to bottom

1c. The remaining space is divided up between the percentage sized ConstraintColumns and pixel values are assigned for them.

Step 2. Determine the size and position of children in each ConstraintColumn (pretty much the same as the existing layout algorithm).

2a. If both left and right anchors are specified, the actual width is determined by them, relative to the constraint column width. However, the actual width is subject to the child's minWidth.

2b. Otherwise, if a percentWidth was specified, this percentage is applied to the constraint column's width (the widest specified point of content, or the width of the constraint column, whichever is greater). The actual width is subject to the child's minWidth and maxWidth.

2c. Otherwise, if an explicitWidth was specified, this is used as the actual width.

2d. Otherwise, the measuredWidth is used as the actual width.

Step 3. Then the x coordinate of the child is determined.

-Note: If we were working on the vertical plan and trying to determine the y coordinate of a child, the following step would be added:
3a. If a baseline constraint is specified, the center of the child is placed relative to the top constraint row or the top edge of the parent if the top constraint row is not set.-

3a. If a horizonalCenter constraint is specified, the center of the child is placed relative to the center of the content area.

3b. Otherwise, if a left constraint is specified, the left edge of the child is placed there.

3c. Otherwise, if a right constraint is specified, the right edge of the child is placed there.

3d. Otherwise, the child is left at its previously set x coordinate.

Step 4. If the child's width is a percentage, try to make sure it doesn't overflow the constraint column width (while still honoring minWidth). We need to wait until after the x coordinate is set to test this.

Creating Sibling Relative Layouts

With the addition of ConstraintColumns and ConstraintRows along with constraints, it should now be easy for visual designers to create sibling-relative layouts. For example, a common requirement is something like: "let the OK button be its natural size, and put the cancel button next to it and let the cancel button take up no more then 100 pixels."

That can be achieved like so:

<mx:Canvas>
  <mx:constraintColumns>
    <mx:ConstraintColumn id="col1" /> <!--content sized column-->
    <mx:ConstraintColumn id="col2" width="100"/> <!-- fixed sized column -->
  </mx:constraintColumns>

  <mx:Button label="OK" left="col1:0" right="col1:0" />
  <mx:Button label="Cancel" left="col2:0" right="col2:0"/>
</mx:Canvas>

If the OK button grows and shrinks, the Cancel button is always anchored 0 pixels from the OK button's right edge.

If the Canvas has a fixed size, ie: 500 pixels, like so:

<mx:Canvas width="500">
  <mx:constraintColumns>
    <mx:ConstraintColumn id="col1" /> <!--content sized column-->
    <mx:ConstraintColumn id="col2" width="100"/> <!-- fixed sized column -->
  </mx:constraintColumns>

  <mx:Button label="OK" left="col1:0" right="col1:0" />
  <mx:Button label="Cancel" left="col2:0" right="col2:0" />
</mx:Canvas>

The behavior would be the same. Now, if the OK button grows so that its larger then 400 pixels a scrollbar will sprout on the Canvas such that the user can scroll and see the rest of the Button.

Terminology

Why did we chose constraint terminology (column/rows with a width/height) instead of guides with an x/y location? Well - it was hotly debated but in the end we decided this was a layout feature where perhaps controls were being anchored to guides, but fundamentally we were concerned with the space that was being managed by those guides. And that space contains columns and rows, leading to a constraint-like terminology. The way people primarily understand the feature will be how we author it, and the key is to make the API readable and easy to understandand. The FlexBuilder UI will make the idea of constraint rows and columns easy to understand and visualize.

API Description
The following classes will be added to the package: mx.containers.utilityClasses

package mx.containers.utilityClasses
{

/**
 *  IConstraintLayout is a marker interface that indicates a container
 *  is capable of a constraint layout. Those containers in the 
 *  framework that support a constraint layout are Canvas, Application
 *  and Panel. To utilize the constraint layout in these containers, 
 *  set the <code>layout</code> property to "absolute" and create
 *  constraint regions. 
 * 
 *  @see mx.containers.Canvas
 *  @see mx.containers.Panel
 *  @see mx.core.Application
 *  @see mx.containers.utilityClasses.ConstraintColumn;
 *  @see mx.containers.utilityClasses.ConstraintRow;
 */
public interface IConstraintLayout
{
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  constraintColumns
    //----------------------------------

    /**
     *  The ConstraintColumn objects partitioning this Canvas. The ConstraintColumn
     *  at index 0 is the left-most column and indices increase to the
     *  right. 
     * 
     *  @default []
     */
    function get constraintColumns():Array;

    /**
     *  @private
     */
    function set constraintColumns(value:Array):void;

    //----------------------------------
    //  constraintRows
    //----------------------------------

    /**
     *  The ConstraintRow objects partitioning this Canvas. The ConstraintRow
     *  at index 0 is the top-most row and indices increase to the
     *  bottom.
     * 
     *  @default []
     */
    function get constraintRows():Array;

    /**
     *  @private
     */
    function set constraintRows(value:Array):void;
}

}




package mx.containers.utilityClasses
{

/**
 *  ConstraintColumns are used to partition a Canvas in the vertical plane. 
 * 
 *  ConstraintColumns have 3 sizing options available to them: fixed size, 
 *  percentage size, and content size. These sizing options dictate 
 *  the position of the constraint column, the amount of space the constraint column 
 *  takes up in the Canvas and how the constraint column deals with a change in size
 *  of the Canvas. 
 */
public class ConstraintColumn implements IMXMLObject
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function ConstraintColumn()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  The unique id for this ConstraintColumn. 
     */     
    public function get id():String;
    public function set id(value:String):void;

    /**
     *  The width of this ConstraintColumn. The ConstraintColumn can be either 
     *  a fixed size ConstraintColumn (width = pixel value), a 
     *  percentage sized ConstraintColumn (width = percentage) or
     *  a content sized ConstraintColumn (width property is unset). 
     */     
    public function get width():Number;
    public function set width(value:Number):void;

    public function get minWidth():Number;
    public function set minWidth():Number;

    public function get maxWidth():Number;
    public function set maxWidth():Number;

}

}





package mx.containers.utilityClasses
{

/**
 *  ConstraintRows are used to partition a Canvas in the horizontal plane. 
 * 
 *  ConstraintRows have 3 sizing options available to them: fixed size, 
 *  percentage size, and content size. These sizing options dictate 
 *  the position of the constraint row, the amount of space the constraint row 
 *  takes up in the Canvas and how the constraint row deals with a change in size
 *  of the Canvas. 
 */
public class ConstraintRow implements IMXMLObject
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function ConstraintRow()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  The unique id for this ConstraintRow. 
     */     
    public function get id():String;
    public function set id(value:String):void;

    /**
     *  The height of this ConstraintRow. The ConstraintRow can be either 
     *  a fixed size ConstraintRow (height = pixel value), a 
     *  percentage sized ConstraintRow (height = percentage) or
     *  a content sized ConstraintRow (height property is unset). 
     */     
    public function get height():Number;
    public function set height(value:Number):void;

    public function get minHeight():Number;
    public function set minHeight():Number;

    public function get maxHeight():Number;
    public function set maxHeight():Number;


}

}

Canvas, Application and Panel will be made to implement IConstraintLayout and the following properties will be added:

    /**
     *  Returns an array of the ConstraintColumn objects partitioning
     *  this Canvas. 
     */
    public function get constraintColumns():Array

    /**
     *  @private
     *  Sets the ConstraintColumn objects partitioning this Canvas. 
     */
    public function set constraintColumns(value:Array):void

    /**
     *  Returns an array of the ConstraintRow objects partitioning
     *  this Canvas. 
     */
    public function get constraintRows():Array

    /**
     *  @private
     *  Sets the ConstraintRow objects partitioning this Canvas. 
     */
    public function set constraintRows(value:Array):void

Additions to AnchorStyles.as

/**
 *  The vertical distance in pixels from the top edge of a control's 
 *  content area and the baseline of the component.
 *  
 *  If this style is set, the baseline of the component is
 *  anchored to the top edge of its top ConstraintRow, or the top of the
 *  parent container if no top ConstraintRow is set; when its container
 *  is resized, the two edges maintain their separation.
 * 
 *  <p>This style only has an effect when used on a component in a Canvas container, 
 *  or when used on a component in a Panel or Application container that has the 
 *  <code>layout</code> property set to <code>absolute</code>.</p> 
 * 
 *  <p>The default value is <code>undefined</code>, which means it is not set.</p>
 */
<a href="Style%28name%3D%26quot%3Bbaseline%26quot%3B%2C%20format%3D%26quot%3BLength%26quot%3B%2C%20inherit%3D%26quot%3Bno%26quot%3B%29">Style(name="baseline", format="Length", inherit="no")</a>

Flex Builder Integration

A quick description of the FlexBuilder UI in lieu of mockups. A Canvas will look as it does in FlexBuilder's Design View. A header (like a track runner) will be visible above and to the left of the Canvas. You can mouse over the header and press down to create a constraint line at that point. That will divide the Canvas into a ConstraintColumn or ConstraintRow.

When you create a new column or row, a lightweight visual cue is offered to set that column/row's sizing option. Either through an icon or through a dialogue window. By default, those icons indicating a column/row's sizing option is not visible. It will be visible when an individual constraint region is selected.

We will have an in-place UI to indicate a constraint and the value of that constraint. The UI will extend from the control to the constraint boundary it is constrained to.

Backwards Compatibility

The Grid container will be deprecated in favor of the new, robust Canvas container with constraint capabilities.

Flex 2.0 users will not be required to add in constraint regions to their existing constraint-based layouts unless they want to incorporate sibling relative layouts. Only by adding in constraint regions will the new layout algorithm be used.

Users can utilize the new baseline constraint style without adding in constraint regions to their Canvas; the baseline constraint will be evaluated relative to the top edge of the Canvas.

Performance

Performance testing of the layout algorithm is key. We need to ensure that:

as the number of ConstraintColumns and ConstraintRows increase in a Canvas, the performance of the layout algorithm does not degrade. as the number of overall constraints set in a Canvas increases, the performance of the layout algorithm does not degrade. *as layout properties are set on constrained controls (min/maxWidth, etc), the performance of the layout algorithm does not degrade.

B Features

  1. States

We want to make sure the new constraint system can be used correctly with states. What happens when a state change results in constraint columns/rows being added or removed from the base state? When a state change results in a new constraint column being added, what tag is used to capture that change?

We could add new tags to the mx.states package, <mx:addconstraintcolumn>, <mx:removeconstraintcolumn>, <mx:addconstraintrow>, and <mx:removeconstraintrow>. Since constraint columns and rows are identified by a unique id, we do not need to do any re-jiggering of indices but the Canvas layout will need to be re-evaluated. The Add tags will need to be able to indicate where in the constraint column/row sequence the new constraint region should be added. This could be similar to the AddChild position property, where AddConstraintColumn and AddConstraintRow have an index property indicating where the new constraint region should be added.</mx:removeconstraintrow></mx:addconstraintrow></mx:removeconstraintcolumn></mx:addconstraintcolumn>

AddConstraintColumn.as:

    /**
     *  Constructor.
     *
     *  @param relativeTo The Canvas which the ConstraintColumn is being added to. 
     *
     *  @param target The ConstraintColumn object being added.
     *
     *  @param index The location in the display list of the <code>target</code>
     *  relative to the <code>relativeTo</code> component. Must be a number within 
     *  the range of constraint columns existing in the Canvas, or 0
     *  if this is the only constraint column in the Canvas. 
     */
     public function AddConstraintColumn(relativeTo:UIComponent = null, target:ConstraintColumn = null, index:Number = 0);

RemoveConstraintColumn.as:

   /**
     *  Constructor.
     *
     *  @param target The ConstraintColumn object being removed
     *
     *  @param relativeTo The Canvas which the ConstraintColumn is being removed from. 
     */
     public function RemoveConstraintColumn(relativeTo:UIComponent = null, target:ConstraintColumn= null)

The same API would be used for AddConstraintRow and RemoveConstraintRow.

  1. Reuse the refactoring features built into FlexBuilder so that at authoring time if a constraint region's id is changed, constraint expressions referencing that constraint region are changed throughout the application.

QA

A few things to think about while testing:

*Test effects where a control moves from one constraint region to another (ie: its content area changes). Transitions calculate toValue and fromValue and we should be able to do the same with constraint columns/rows such that the animation is smooth.

*Test the new constraint column/row layouts with states extensively. Ie: states where constraint regions are added or removed from the base state.


Related

Wiki: Flex 3.0 Planning

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.