package { import flash.events.Event; import mx.containers.VBox; import mx.controls.Image; import mx.controls.sliderClasses.SliderDataTip; import mx.core.ScrollPolicy; import mx.core.UITextField; import mx.core.mx_internal; import mx.core.EdgeMetrics; import mx.skins.RectangularBorder; use namespace mx_internal; import ResourceManager; public class AlbumPreviewToolTip extends SliderDataTip { private var vbox:VBox; private var img:Image; private var imageSource:Object; private var imageIsStale:Boolean; public function AlbumPreviewToolTip() { super(); } public function get image():Image { if (!img) { if (this.source) { img= ResourceManager.getInstance().getRegisteredAsset(String(this.source)); } else { img =new Image(); } } return img; } public function get field():UITextField { return textField; } //[Bindable] public function get source():Object { return imageSource; } public function set source(o:Object):void { imageIsStale =true; imageSource =o; //a bit of hackery, where we want the vbox to reuse the registered asset if (image.source && vbox) { vbox.removeChild(image); img =vbox.addChild(ResourceManager.getInstance().getRegisteredAsset(String(o))) as Image; imageIsStale =false; } if (imageIsStale) { invalidateProperties(); } invalidateDisplayList(); } protected function get borderMetrics():EdgeMetrics { if (mx_internal::border is RectangularBorder) return RectangularBorder(mx_internal::border).borderMetrics; return EdgeMetrics.EMPTY; } override protected function commitProperties():void { super.commitProperties(); if (imageIsStale) { this.image.source =imageSource; imageIsStale =false; } } override protected function createChildren():void { super.createChildren(); vbox =this.addChild(new VBox()) as VBox; vbox.horizontalScrollPolicy =ScrollPolicy.OFF; vbox.verticalScrollPolicy =ScrollPolicy.OFF; //reparent the textfield to the box vbox.addChild(textField); vbox.addChild(image) as Image; } override protected function measure():void { super.measure(); var bm:EdgeMetrics = borderMetrics; var leftInset:Number = bm.left + getStyle("paddingLeft"); var topInset:Number = bm.top + getStyle("paddingTop"); var rightInset:Number = bm.right + getStyle("paddingRight"); var bottomInset:Number = bm.bottom + getStyle("paddingBottom"); measuredWidth = (vbox.measuredWidth +leftInset +rightInset); measuredHeight = (vbox.measuredHeight +topInset +bottomInset); } //note we're not calling super here since we don't want the field inset from the box, so we set the field size here override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { var bm:EdgeMetrics = borderMetrics; var leftInset:Number = bm.left + getStyle("paddingLeft"); var topInset:Number = bm.top + getStyle("paddingTop"); var rightInset:Number = bm.right + getStyle("paddingRight"); var bottomInset:Number = bm.bottom + getStyle("paddingBottom"); border.setActualSize(unscaledWidth, unscaledHeight); textField.setActualSize(unscaledWidth - leftInset -rightInset, unscaledHeight - topInset -bottomInset); vbox.move(leftInset, topInset); vbox.setActualSize(image.getExplicitOrMeasuredWidth(), image.getExplicitOrMeasuredHeight() +field.measuredHeight); } } }