package components { import flash.display.DisplayObject; import flash.events.Event; import flash.geom.Point; import mx.containers.Form; import mx.controls.ToolTip; import mx.core.Container; import mx.core.UIComponent; import mx.events.FlexEvent; import mx.events.ToolTipEvent; import mx.validators.IValidatorListener; import mx.core.Application; public class ExtendedForm extends Form { [Bindable] public var newElement:Boolean = false; private var invalidCounter:int = 0; private var toolTips:Array = new Array(); private function toolTipHack(event:ToolTipEvent) : void { if(event.toolTip.text != UIComponent(event.target).toolTip) { DisplayObject(event.toolTip).alpha = 0; event.toolTip.text = ""; } } private function getToolTip(component:UIComponent) : ToolTip { for each(var obj:Object in toolTips) { if(obj.component == component) { return obj.toolTip; } } return null; } private function addToolTip(event:Event) : void { var component:UIComponent = event.target as UIComponent; var myToolTip:ToolTip = getToolTip(component); if(!myToolTip) { myToolTip = new ToolTip(); myToolTip.setStyle("styleName", "errorTip"); myToolTip.setStyle("borderStyle", "errorTipBelow"); myToolTip.includeInLayout = false; addChild(myToolTip); toolTips.push({component: component, toolTip: myToolTip}); } myToolTip.text = component.errorString; moveToolTip(event); } private function moveToolTip(event:Event) : void { callLater(function() : void { for each(var obj:Object in toolTips) { var point:Point = obj.component.parent.localToGlobal( new Point(obj.component.x, obj.component.y + obj.component.height + 10)); point = globalToLocal(point); obj.toolTip.x = point.x; obj.toolTip.y = point.y; if(obj.component.height < obj.toolTip.height) { obj.toolTip.y -= (obj.toolTip.height - obj.component.height) / 2 } } }); } private function removeToolTip(event:Event) : void { var component:UIComponent = event.target as UIComponent; var myToolTip:ToolTip = getToolTip(component); if(myToolTip) { removeChild(myToolTip); for(var i:int; i < toolTips.length; i++) { if(toolTips[i].component == component) { toolTips.splice(i, 1); return; } } } } private function addToolTipListeners(component:DisplayObject) : void { component.addEventListener("toolTipShow", toolTipHack); component.addEventListener("valid", removeToolTip); component.addEventListener("invalid", addToolTip); component.addEventListener("move", moveToolTip); component.addEventListener("resize", moveToolTip); } private function addToolTipListenersToContainer(container:Container) : void { if(container is ExtendedForm) { return; } for each(var child:Object in container.getChildren()) { if(child is Container) { addToolTipListenersToContainer(child as Container); } else if(child is IValidatorListener) { addToolTipListeners(child as DisplayObject); } } } public override function addChild(child:DisplayObject) : DisplayObject { super.addChild(child); if(child is Container) { addToolTipListenersToContainer(child as Container); } else if(child is IValidatorListener) { addToolTipListeners(child); } return child; } public override function get creationPolicy() : String { return "none"; } public override function initialize() : void { super.initialize(); addEventListener(FlexEvent.INVALID, function(event:Event) : void { invalidCounter++; if(invalidCounter == 1) { setStyle("oldBorderStyle", getStyle("borderStyle")); setStyle("oldBorderColor", getStyle("borderColor")); setStyle("borderStyle", "solid"); setStyle("borderColor", getStyle("errorColor")); } else { event.stopPropagation(); } }); addEventListener(FlexEvent.VALID, function(event:Event) : void { invalidCounter--; if(invalidCounter > 0) { event.stopPropagation(); } else { setStyle("borderStyle", getStyle("oldBorderStyle")); setStyle("borderColor", getStyle("oldBorderColor")); } }); } } }