package { import flash.display.DisplayObject; import flash.events.Event; import mx.core.EdgeMetrics; import mx.core.ScrollControlBase; import mx.events.ScrollEvent; import mx.events.ScrollEventDetail; public class ScrollingImage extends ScrollControlBase { public function ScrollingImage() { super(); this.horizontalScrollPolicy = "auto"; } private var imageClassChanged:Boolean = true; protected var currentImage:DisplayObject; protected var _imageClass:Class; public function get imageClass():Class { return this._imageClass; } public function set imageClass(imageClass:Class):void { this._imageClass = imageClass; this.imageClassChanged = true; this.invalidateProperties(); this.invalidateSize(); this.invalidateDisplayList(); } override protected function commitProperties():void { super.commitProperties(); if(this.imageClassChanged) { this.imageClassChanged = false; if(this.currentImage) { // Clear our old image if any. this.removeChild(this.currentImage); this.currentImage = null; } if(this.imageClass) { // We have a new image, so load it up. this.currentImage = new this.imageClass(); // Make it invisible for now until it's properly positioned. this.currentImage.visible = false; this.currentImage.mask = this.maskShape; // Finally, add it to our display list. this.addChild(this.currentImage); } } } override protected function measure():void { super.measure(); var edgeMetrics:EdgeMetrics = this.viewMetrics; var width:Number = edgeMetrics.left + edgeMetrics.right; var height:Number = edgeMetrics.top + edgeMetrics.bottom; if(this.currentImage) { // We have a real image, so get its dimensions. width += this.currentImage.width * this.currentImage.scaleX; height += this.currentImage.height * this.currentImage.scaleY; } else { // No image, so just set it to our edgeMetrics, with an added default size of 40x40 var defaultSize:Number = 40; width += defaultSize; height += defaultSize; } this.measuredWidth = width; this.measuredHeight = height; } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); if(!this.currentImage) return; var edgeMetrics:EdgeMetrics = this.viewMetrics; this.currentImage.x = edgeMetrics.left + -this.horizontalScrollPosition; this.currentImage.y = edgeMetrics.top + -this.verticalScrollPosition; // Make the image visible. this.currentImage.visible = true; this.setScrollBarProperties( this.currentImage.width, unscaledWidth - edgeMetrics.left - edgeMetrics.right, this.currentImage.height, unscaledHeight - edgeMetrics.top - edgeMetrics.bottom ); } override protected function scrollHandler(event:Event):void { // Immediately return if there's no image. if(!this.currentImage) return; // Return if it's not a ScrollEvent. This is for TextField scroll events bubbling up that // we wouldn't understand. if(!(event is ScrollEvent)) return; // And finally, if we're not liveScrolling, and we're in the middle of scrolling, return. if (!liveScrolling && ScrollEvent(event).detail == ScrollEventDetail.THUMB_TRACK) return; super.scrollHandler(event); this.currentImage.x = this.viewMetrics.left + -this.horizontalScrollPosition; this.currentImage.y = this.viewMetrics.top + -this.verticalScrollPosition; } } }