HI,

I've got an application I'm trying to implement a custom layout.  I'm trying
to get move and resize effects to work on the children but it doesn't seem
to work. Have I missed something obvious?

Also...

When I'm extending Canvas am I changing the correct method to recalculate
the size and position of the children.

Should this ignore canvas and instead extend Container?

Please note that this is a WIP.

Would anyone like me to post the completed version when its done?

*Application.mxml*
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; layout="absolute"
xmlns:icarus="com.icarus.*">
    <mx:Script>
        <![CDATA[
            private function
widgetAddButtonClickHandler(event:MouseEvent):void
            {
                widgetContainer.addChildAt(new Panel(),0);
            }

            private function
widgetRemoveButtonClickHandler(event:MouseEvent):void
            {
                widgetContainer.removeChildAt(0);
            }
        ]]>
    </mx:Script>
    <icarus:WidgetContainer right="10" left="10" bottom="10"
id="widgetContainer" top="51" borderStyle="solid" borderThickness="1"
borderColor="#585A5C" backgroundColor="#CCDCEA">
     <icarus:moveEffect>
         <mx:Parallel>
             <mx:Move duration="250" />
             <mx:Resize duration="250" />
         </mx:Parallel>
     </icarus:moveEffect>
        <mx:Panel move="trace('moved')" x="5"/>
    </icarus:WidgetContainer>
    <mx:ApplicationControlBar top="10" left="10" right="10" height="33">
        <mx:Button label="Add Item" id="widgetAddButton"
click="widgetAddButtonClickHandler(event)"/>
        <mx:Button label="Remove Item" id="widgetRemoveButton"
click="widgetRemoveButtonClickHandler(event)" />
    </mx:ApplicationControlBar>
</mx:Application>

*WidgetContainer.as*
package com.icarus
{
    import mx.containers.Canvas;
    import mx.core.UIComponent;

    public class WidgetContainer extends Canvas
    {
        private var positions:Array;

        public var numCols:int = 3;
        private var paddingLeft:int = 10;
        private var paddingRight:int = 10;
        private var paddingTop:int = 10;
        private var paddingBottom:int = 10;
        private var itemSpacing:int =10;
        private var itemMinHeight:int = 200;

        public function WidgetContainer()
        {
            super();
        }

        private function calculatePositions(width:int, height:int):void
        {
            var children:Array = getChildren();
            var numChildren:int = children.length;
            var availableHeight:int = height - (paddingTop + paddingBottom);
            availableHeight = availableHeight - (viewMetrics.bottom +
viewMetrics.top);
            var availableWidth:int = width; - (paddingLeft + paddingRight);
            availableWidth = availableWidth - (viewMetrics.top +
viewMetrics.bottom);
            availableWidth = availableWidth - ((verticalScrollBar ===
null)?0:verticalScrollBar.width)
            var numFirstRowChildren:int = (numChildren -1) % numCols +1;

            var numRows:int = Math.ceil(numChildren / numCols);
            var rowHeight:int = availableHeight -(paddingTop
+paddingBottom);
            var firstRowWidth:int = availableWidth - ((numFirstRowChildren
-1) * itemSpacing);
            firstRowWidth = firstRowWidth / numFirstRowChildren;
            var otherRowWidth:int = availableWidth - ((numCols-1) *
itemSpacing);
            otherRowWidth = otherRowWidth /numCols;
            rowHeight = availableHeight - ((numRows-1) * itemSpacing);
            rowHeight = Math.max(rowHeight / numRows, itemMinHeight);
            positions = new Array();
            for (var i:int=0; i<numChildren; i++)
            {
                positions[i] = new Position();
                //Height always remains the same.
                positions[i].height = rowHeight;

                //First Row
                if (i<numFirstRowChildren)
                {
                    positions[i].y = paddingTop;
                    positions[i].width = firstRowWidth;
                } else {
                    //final item of previous row;
                    var previousRowFinalItem:int = i -
((i-numFirstRowChildren) % numCols) - 1;
                    positions[i].y = positions[previousRowFinalItem].y +
positions[previousRowFinalItem].height + itemSpacing;
                    positions[i].width = otherRowWidth;
                }
                //First Column
                if (i == 0 || (i-numFirstRowChildren) % numCols == 0)
                {
                    positions[i].x = paddingLeft;
                } else {
                    //Subsequent columns.
                    positions[i].x = positions[i-1].x + positions[i-1].width
+ itemSpacing;
                }
            }
        }

        override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
        {
            calculatePositions(unscaledWidth, unscaledHeight);
            var children:Array = getChildren();
            for (var i:int = 0; i < children.length; i++)
            {
                var child:UIComponent = UIComponent(children[i]);
                child.move(positions[i].x, positions[i].y);
                children[i].width = positions[i].width;
                children[i].height = positions[i].height;
            }
            super.updateDisplayList(unscaledWidth, unscaledHeight);
        }



    }
}

class Position
{
    public var x:int;
    public var y:int;
    public var height:int;
    public var width:int;
}

Regards,
Wes

Reply via email to