Home Contact

[September 12, 2005]

I Gotcha ToolTip Right Heah

Filed under: ActionScript — @ 4:01 pm

I was glad to see the latest in Lee Brimelow’s great series of video Flash tutorials, this one on making tooltips in Flash. I’d been meaning to implement tooltips in my current project for a while, and this got me going. But you know I always prefer to do it in code that I can reuse anywhere, and not depend on library assets if I can help it. And tooltip is a prime candidate for implementation with a Singleton class, so…


import ascb.util.Proxy;

class com.nodename.utils.ToolTip
{
static var version:String = "$Id: ToolTip.as,v 1.9 2006/03/26 18:14:15 ashaw Exp $";

public static function setBoxSize(wd:Number, ht:Number):Void
{
	ToolTip._boxWidth = wd;
	ToolTip._boxHeight = ht;
}

public static function setPointSize(ps:Number):Void
{
	ToolTip._pointSize = ps;
}

/*
 *
 * @function	create
 * @param	tipTarget	the object over which the tooltip is to be shown:
 * 				MovieClip, MCComposite, or Button
 * @param	tip		the text to be displayed in the ToolTip
 *
 */
public static function create(tipTarget, tip:String):Void
{
	tipTarget.onRollOver = Proxy.create(ToolTip, ToolTip.showToolTip, tip);
	tipTarget.onRollOut = tipTarget.onDragOut = ToolTip.hideToolTip;
}

/////////////////////////////////////////
//                                     //
//       End of public interface       //
//                                     //
/////////////////////////////////////////

private static var theOnlyToolTip:ToolTip;

private static function showToolTip(tip:String):Void
{
	if (theOnlyToolTip == undefined)
	{
		theOnlyToolTip = new ToolTip();
	}
	theOnlyToolTip.p_showToolTip(tip);
}

private static function hideToolTip():Void
{
	if (theOnlyToolTip == undefined)
	{
		theOnlyToolTip = new ToolTip();
	}
	theOnlyToolTip.p_hideToolTip();
}

private var _mc:MovieClip;
private var _tf:TextField;
private var _tFormat:TextFormat;

private static var _boxWidth:Number = 150;
private static var _boxHeight:Number = 50;

private static var _pointSize:Number = 10;

private var _tailLeft:Number;		// distance from left edge of box to left edge of tail
private var _tailWidth:Number;
private var _tailHeight:Number;
private var _tailTipOffset:Number;	// tip of tail is this far above registration point
private var _textSideMargin:Number;

private var topY:Number;
private var leftX:Number;

private function ToolTip()
{
	_tailLeft = .40 * ToolTip._boxHeight;
	_tailWidth = .40 * ToolTip._boxHeight;
	_tailHeight = .60 * ToolTip._boxHeight;
	_tailTipOffset = 5;
	_textSideMargin = 5;

	var trueParent:MovieClip = _level0;	// it has to live somewhere...

	this._mc = trueParent.createEmptyMovieClip("nodenameToolTip", trueParent.getNextHighestDepth());

	this._mc._visible = false;

	leftX = -this._tailLeft;
	topY  = -ToolTip._boxHeight - this._tailHeight - this._tailTipOffset;

	this.draw(leftX, topY, ToolTip._boxWidth, ToolTip._boxHeight, this._tailWidth, this._tailTipOffset);

	this.makeTextField(leftX, topY, ToolTip._boxWidth, ToolTip._boxHeight);
}

private function draw(leftX:Number, topY:Number, boxWidth:Number, boxHeight:Number,
			tailWidth:Number, tailTipOffset:Number):Void
{
// TODO:	make rounded corners

	var rightX:Number	= leftX + boxWidth;
	var bottomY:Number	= topY + boxHeight;

	with (this._mc)
	{
		moveTo(leftX, topY);
		lineStyle(1, 0x000000, 100); // black
		beginGradientFill(
				"linear",
				[0xfff3d9, 0xfffbf2],	// colors
				[100, 100],		// alphas
				[0, 255],		// ratios
				{
					matrixType:"box",
					x: leftX, y: topY,
					w: boxWidth, h: boxHeight,
					r: Math.PI/2	// 90 degrees: vertical gradient
				}
				);
		lineTo(rightX, topY);
		lineTo(rightX, bottomY);
		lineTo(tailWidth, bottomY);
		lineTo(0, -tailTipOffset);	// tip of tail
		lineTo(0, bottomY);
		lineTo(leftX, bottomY);
		lineTo(leftX, topY);
		endFill();
	}
}

private function makeTextField(leftX:Number, topY:Number, boxWidth:Number, boxHeight:Number):Void
{
	this._mc.createTextField("_tf", this._mc.getNextHighestDepth(),
				leftX, topY, boxWidth, boxHeight);
	this._tf = this._mc._tf;
	this._tFormat = new TextFormat("_sans", ToolTip._pointSize, 0×000000);
	this._tFormat.align = "center";
	this._tFormat.leftMargin = this._tFormat.rightMargin = this._textSideMargin;
	this._tf.setNewTextFormat(this._tFormat);
	this._tf.wordWrap = true;
	this._tf.autoSize = "none";
}

private var _toolTipIntervalID:Number;
private var _toolTipDelay:Number = 500; // milliseconds

private function p_showToolTip(tip:String):Void
{
	this._toolTipIntervalID = setInterval(this, "reallyShowToolTip", this._toolTipDelay, tip);
}

private function reallyShowToolTip(tip:String):Void
{
	clearInterval(this._toolTipIntervalID);

	this._tf.text = tip;
	updateToolTip();
	this._mc._visible = true;

	this._mc.onMouseMove = Proxy.create(this, updateToolTip);
}

private function updateToolTip():Void
{
	setFlip();

	this._mc._x = this._mc._parent._xmouse;
	this._mc._y = this._mc._parent._ymouse;

	updateAfterEvent();
}

public function setFlip():Void
{
	var loc:Object = {x: this._mc._xmouse, y: this._mc._ymouse};
	this._mc.localToGlobal(loc);
	if (loc.y + topY < 5)
	{
		flipY();
	}
	else
	{
		unflipY();
	}
	if (loc.x + leftX + ToolTip._boxWidth > Stage.width - 5)
	{
		flipX();
	}
	else
	{
		unflipX();
	}
}

private function flipY():Void
{
	this._mc._yscale = -100;
	this._tf._yscale = -100;
	this._tf._y = topY + ToolTip._boxHeight;
}

private function unflipY():Void
{
	this._mc._yscale = 100;
	this._tf._yscale = 100;
	this._tf._y = topY;
}

private function flipX():Void
{
	this._mc._xscale = -100;
	this._tf._xscale = -100;
	this._tf._x = leftX + ToolTip._boxWidth;
}

private function unflipX():Void
{
	this._mc._xscale = 100;
	this._tf._xscale = 100;
	this._tf._x = leftX;
}

private function p_hideToolTip():Void
{
	clearInterval(this._toolTipIntervalID);
	this._mc._visible = false;
	delete this._mc.onMouseMove;
}

}

Contents copyright © Alan Shaw 2005-2008

25 queries. 0.234 seconds. Powered by WordPress version 2.5.1