My scenario was loading images from a directory on the server and placing them inside a canvas in a rectangular array fashion. When I set autoLayout to true the images would show without me sizing the canvas to the height/width of the total contents, but when I set autoLayout to false, I had to set the total height/width of the canvas to match it's contents. I thought it was strange. I read in blog somewhere that easing would not work correctly on moving a canvas that had autoLayout set to true.. I was finding that to be the case, so that's why I set autoLayout to false.
On Tue, Sep 2, 2008 at 7:43 PM, Richard Rodseth <[EMAIL PROTECTED]> wrote: > I'd really love some review of the code below. I made one correction in > red: the target of the move() call should be "this" rather than _content. > > Some refactoring might be in order. The dance between the contentholder and > the ScaledContent parent due to the _allowInvalidateSize issue is a bit > clunky. > > But my main concern now is that while it scales and centers as desired, it > only does it if the contents have an explicit width and height. Not sure if > that calls into question the whole approach, or is just a missing > invalidation. > > Thanks. > > On Tue, Sep 2, 2008 at 11:59 AM, Richard Rodseth <[EMAIL PROTECTED]>wrote: > >> I'm returning to a component I was trying to write earlier, that would >> scale and center a single child (or ideally children), such that the >> contents fit within the bounds of the container, and aspect ratio is >> preserved. The solution at the end of this post does the scaling of one >> child fine (including aspect ratio) but I haven't figured out how to >> incorporate the centering. Just setting horizontalCenter on the content >> holder didn't work, and nor did my efforts to add a move() call as shown in >> the code below: >> >> A couple of notes. >> - If the measure() implementations returned content dimensions rather than >> 0, I got scroll bars and 1400 was passed into updateDisplayList(). >> - allowInvalidateSize is because otherwise setting scale triggers >> re-measuring. >> >> Any advice about the centering would be much appreciated. Here's the code: >> >> Test case: >> >> <mx:Canvas width="90%" height="90%" horizontalCenter="0" >> verticalCenter="0" borderStyle="solid" > >> <comp:ScaledContent width="100%" height="100%" borderStyle="solid" > >> <mx:Button label="Big" width="1400" height="1400" >> cornerRadius="50"/> >> </comp:ScaledContent> >> </mx:Canvas> >> >> ScaledContent.mxml: >> >> <?xml version="1.0" encoding="utf-8"?> >> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comp="comp.*" >> horizontalScrollPolicy="off" verticalScrollPolicy="off" >> > >> >> <mx:Metadata> >> [DefaultProperty("contents")] >> >> </mx:Metadata> >> >> <mx:Script> >> <![CDATA[ >> import mx.core.UIComponent; >> >> private var _contents:UIComponent; >> private var _contentsChanged:Boolean = false; >> >> public function set contents(value:UIComponent):void { >> _contents = value; >> _contentsChanged = true; >> this.invalidateProperties(); >> } >> >> override protected function commitProperties():void { >> super.commitProperties(); >> >> if (_contentsChanged) { >> contentHolder.content = _contents; >> _contentsChanged = false; >> } >> } >> >> >> override protected function measure():void { >> super.measure(); >> minWidth = measuredWidth = 0; // >> _contents.getExplicitOrMeasuredWidth(); >> minHeight = measuredHeight = 0; // >> _contents.getExplicitOrMeasuredHeight(); >> } >> >> override protected function >> updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { >> super.updateDisplayList(unscaledWidth, unscaledHeight); >> contentHolder.scaleContentToFit(unscaledWidth, >> unscaledHeight); >> contentHolder.setActualSize(unscaledWidth, >> unscaledHeight); >> } >> ]]> >> </mx:Script> >> >> <comp:ScaledContentHolder id="contentHolder" > >> </comp:ScaledContentHolder> >> >> </mx:Canvas> >> >> ScaledContentHolder.as >> >> public class ScaledContentHolder extends UIComponent >> { >> public function ScaledContentHolder() >> { >> } >> >> private var _allowInvalidateSize:Boolean = true; >> private var _content:UIComponent; >> private var _contentChanged:Boolean = false; >> >> override protected function measure():void >> { >> super.measure(); >> minWidth = measuredWidth = 0; // >> _content.getExplicitOrMeasuredWidth(); >> minHeight = measuredHeight = 0; >> //_content.getExplicitOrMeasuredHeight(); >> } >> >> public function set content(value:UIComponent):void { >> _content = value; >> _contentChanged = true; >> this.invalidateProperties(); >> } >> >> override protected function commitProperties():void { >> super.commitProperties(); >> if (_contentChanged) { >> this.removeAllChildren(); >> this.addChild(_content); >> _contentChanged = false; >> } >> } >> >> >> private function removeAllChildren():void >> { >> while (numChildren> 0) >> { >> removeChildAt(0); >> } >> } >> >> >> override public function invalidateSize():void >> { >> if (_allowInvalidateSize) >> super.invalidateSize(); >> } >> >> public function scaleContentToFit(unscaledWidth:Number, >> unscaledHeight:Number):void { >> var contentWidth:Number = >> _content.getExplicitOrMeasuredWidth(); >> var contentHeight:Number = >> _content.getExplicitOrMeasuredHeight(); >> >> var xScale:Number = (unscaledWidth / contentWidth); >> var yScale:Number = (unscaledHeight / contentHeight); >> var finalScale:Number = Math.min(xScale, yScale); // Preserve >> aspect ratio >> >> _allowInvalidateSize = false; >> this.scaleX = finalScale; >> this.scaleY = finalScale; >> _allowInvalidateSize = true; >> >> var scaledContentWidth:Number = contentWidth * finalScale; >> var scaledContentHeight:Number = contentHeight * finalScale; >> >> this.move(unscaledWidth/2 - scaledContentWidth/2 , >> unscaledHeight/2 - scaledContentHeight/2); >> >> } >> >> override protected function >> updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void >> { >> super.updateDisplayList(unscaledWidth, unscaledHeight); >> } >> >> > > -- Jamie
