From 77d71ce7ed8031b1b49391aff3092a9f0257fd53 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Wed, 4 Mar 2009 03:12:46 +0000 Subject: [PATCH] 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 --- src/as/com/threerings/flash/TextFieldUtil.as | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/as/com/threerings/flash/TextFieldUtil.as b/src/as/com/threerings/flash/TextFieldUtil.as index f1c5e797..c9dfdef2 100644 --- a/src/as/com/threerings/flash/TextFieldUtil.as +++ b/src/as/com/threerings/flash/TextFieldUtil.as @@ -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" };