Flex tool tip allows show and hide effect defining. However, hide effect works only for timeout happening (when mouse stays not moved for a long time, tool tip hides after some time).
This solution shows how you can define custom tool tip class that supports hide effect for any tool tip hiding event (mouse out or move to other item etc.). It is tested well and works well also for lists, quick mouse movement etc.
Below is implementation code for custom tool tip that supports hide effect for any tool tip hiding event. See comments inside of it to get an idea how it is working. The main problem was that tool tip manager removes tool tip instance from parent container before hiding effect played, and this effect playing was not visible even if you force your custom effect playing manually. Below solution solves this completely.
package
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import mx.controls.ToolTip;
import mx.core.UIComponent;
import mx.effects.EffectInstance;
import mx.effects.IEffect;
import mx.events.EffectEvent;
public class EffectToolTip extends ToolTip
{
public static var hideEffect:IEffect;
private static var allEffects:Array = [];
private var _skipEventsHandling:Boolean = false;
public function EffectToolTip()
{
super();
this.addEventListener(Event.REMOVED, meRemoved);
// when we show this tool tip, end effect playing for others so no 2 tool tips stay on screen at the same time
callLater(endOthersEffects);
}
private function meRemoved(event:Event):void {
if (_skipEventsHandling) {
return;
}
var target:DisplayObject = event.target as DisplayObject;
if (target && target is UIComponent) {
var parent:DisplayObjectContainer = target.parent as DisplayObjectContainer;
if (parent) {
var ndx:int = parent.getChildIndex(target);
if (ndx >= 0) {
// allow manager time to remove this tool tip from parent
(target as UIComponent).callLater(playHideEffect, [target, parent]);
}
}
}
}
private function playHideEffect(target:DisplayObject, parent:DisplayObjectContainer) : void{
// if this tool tip instance is re-displayed (for example, for list items), skip hide effect
if (!hideEffect || target.parent) {
return;
}
// at this point, manager removed tool tip from parent, so now we re-add it and play effect
// without this sequence of events/actions, hide effect is not playing because this
// instance is not in the parent
_skipEventsHandling = true;
// a bit of hack to force tool tip to be added back into container so it is visible for duration of
// hide effect playing
parent.parent.addChild(target);
// Play hide effect.
var instances: Array = hideEffect.play([target]);
for (var i:int = 0; i<instances.length; i++) {
(instances[i] as EffectInstance).addEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
}
allEffects = allEffects.concat(instances);
_skipEventsHandling = false;
}
private function handleEffectEnd(event:EffectEvent):void {
_skipEventsHandling = true;
(event.effectInstance as EffectInstance).removeEventListener(EffectEvent.EFFECT_END, handleEffectEnd);
(event.effectInstance as EffectInstance).end();
// remove myself from parent after re-adding in playFadeEffect method
parent.removeChild(this);
_skipEventsHandling = false;
}
private function endOthersEffects():void {
for (var i:int = 0; i<allEffects.length; i++) {
(allEffects[i] as EffectInstance).end();
}
allEffects = [];
}
}
}
Below is example how you can use effects for tool tip with new class. In example, we use Fade effect, though you can use your any effects for it.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.managers.ToolTipManager;
private function initApp() : void {
ToolTipManager.toolTipClass = EffectToolTip;
ToolTipManager.hideEffect = fadeOut;
ToolTipManager.showEffect = fadeIn;
EffectToolTip.hideEffect = fadeOut;
}
]]>
</mx:Script>
<mx:Fade id="fadeIn" alphaFrom="0.3" alphaTo="1.0" duration="500" />
<mx:Fade id="fadeOut" alphaFrom="1.0" alphaTo="0.3" duration="500" />
<mx:Button label="Button1" toolTip="This is tool tip 1" />
<mx:Button label="Button2" toolTip="Tool Tip 2" />
</mx:Application>