Hacktastic support for making a TextField only mouseEnabled when the mouse

is over a link. Similar in concept to some code that lived in msoy,
but that special code was tied into the RoomView, which just ain't right
for the chat system, and made it not work the same in games.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@778 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Ray Greenwell
2009-03-04 03:12:46 +00:00
parent 1b14473f25
commit 77d71ce7ed
@@ -24,6 +24,7 @@ package com.threerings.flash {
import com.threerings.util.StringUtil;
import com.threerings.util.Util;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
@@ -32,6 +33,7 @@ import flash.system.System;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.Dictionary;
public class TextFieldUtil
{
@@ -177,6 +179,22 @@ public class TextFieldUtil
textField.setSelection(0, 0);
}
/**
* Install listeners on the specified TextField such that the mouseEnabled property
* is only true when the mouse is over a link.
*/
public static function trackOnlyLinksMouseable (textField :TextField, on :Boolean = true) :void
{
if (on) {
_mouseables[textField] = true;
// always add the listener, seems easier than checking to see.
_frameDispatcher.addEventListener(Event.ENTER_FRAME, handleTrackMouseable);
} else {
delete _mouseables[textField];
}
}
/**
* Internal method related to tracking a single selectable TextField.
*/
@@ -199,6 +217,27 @@ public class TextFieldUtil
}
}
/**
* Checks every damn frame to see if we should make a TextField mouse-enabled.
*/
protected static function handleTrackMouseable (event :Event) :void
{
var seen :Boolean = false;
for (var f :* in _mouseables) {
var field :TextField = f; // fucking hack of a language doesn't iterate non-string keys
seen = true;
if (field.stage != null) {
var charIndex :int = field.getCharIndexAtPoint(field.mouseX, field.mouseY);
field.mouseEnabled = (charIndex >= 0) && (charIndex < field.length) &&
!StringUtil.isBlank(field.getTextFormat(charIndex).url);
}
}
if (!seen) {
// try to remove the listener as soon as we can
_frameDispatcher.removeEventListener(Event.ENTER_FRAME, handleTrackMouseable);
}
}
/**
* Process the selection.
*/
@@ -246,6 +285,10 @@ public class TextFieldUtil
/** The last tracked TextField to be selected. */
protected static var _lastSelected :TextField;
protected static var _mouseables :Dictionary = new Dictionary(true); // weak keys
protected static const _frameDispatcher :Sprite = new Sprite();
protected static const MASK_FIELD_PROPS :Object = { outlineColor: true };
protected static const DEFAULT_FORMAT_PROPS :Object = { size: 18, font: "_sans" };