Actionscript – TextLayoutFramework and exact location of mouse events

 If you want beautiful text and to have close user interaction, the TextLayoutFramework is the thing.

This required Adobe Flex 4 or the corresponding Actionscript version with the Open Source compiler.  I’m using “Burrito” the newest beta version of the Flash Builder, because I need some of the newest TextLayoutFramework features.  This includes the ability to include inline graphics in a text chunk.

 You’ll see some references to tr.*.  Debug stuff that you can ignore.

 The critical part for detecting user events, of course, is:

richText.addEventListener(FlowElementMouseEvent.CLICK,mouseEvent);

 and then catching the event and using the selectionState to find the characters of text.

var selectionState:SelectionState = textFlow.interactionManager.getSelectionState();
var start:int = selectionState.absoluteStart;
var end:int = selectionState.absoluteEnd;

 The values absoluteStart and absoluteEnd are indices into the text, which you can get with

var textString:String = richText.text;

 

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

            xmlns:s="library://ns.adobe.com/flex/spark"

            xmlns:mx="library://ns.adobe.com/flex/mx"

                   

            preinitialize="onPreinitialize()"        

            applicationComplete="initApplication()"

                   

            name="4D Text Hero"

            pageTitle="4D Text Hero (loading 11012)"

            backgroundColor="0xFFFFFF"

            scriptTimeLimit="60"

            minWidth="955" minHeight="600">

     

<fx:Script>

      <![CDATA[

     

            import flash.text.engine.TextLine;

            import flashx.textLayout.elements.*;

            import flashx.textLayout.events.*;

            import mx.managers.BrowserManager;

            import mx.managers.IBrowserManager;

            import spark.utils.TextFlowUtil;

 

            private var cN:String = "4D Text Hero";

            private var bm:IBrowserManager;

           

            private function onPreinitialize():void

            {

                  var mN:String = cN + ".onPreinitialize ";

                 

                  bm = BrowserManager.getInstance();            

                  bm.setTitle(cN);

                 

                  if (tr.traceStartup) tr.output(cN+".onPreinitialize");

            }

           

           

            private var textFlow:TextFlow;

           

            private function initApplication():void {

                  var mN:String = cN + ".initApplication ";

                  tr.output(mN);

                 

                  var textString:String;

                 

                  textString = "<div color=\"#444444\" fontFamily=\"Times New Roman\" fontSize=\"20\" paragraphSpaceAfter=\"15\" textIndent=\"10\" >" +

                       

                                    "<p>" +

                                      "<span>" +

                                          "Alice, really, was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do:  once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, \`and what is the use of a book,\' thought Alice \`without pictures or conversation?\'" +

                                      "</span>" +

                                    "</p>" +

                                   

                                    "<p>" +

                                          "<img source=\"assets/images/White Rabbit.png\" height=\"auto\" width=\"auto\" float=\"left\" paddingRight=\"10\" />" +

                                          "<span>So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.</span>" +

                                    "</p>" +

 

                                    "<p>" +

                                      "<span>" +

                                          "There was nothing so VERY remarkable in that; nor did Alice think it so VERY much out of the way to hear the Rabbit say to itself, \`Oh dear!  Oh dear!  I shall be late!\'  (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge." +

                                      "</span>" +

                                    "</p>" +

                                "</div>";

                 

 

                  richText.width = 800;

                 

                  richText.editable = false;

                  richText.selectable = true;

//                richText.addEventListener(FlowElementMouseEvent.MOUSE_MOVE,mouseEvent);

                  richText.addEventListener(FlowElementMouseEvent.MOUSE_DOWN,mouseEvent);

                  richText.addEventListener(FlowElementMouseEvent.MOUSE_UP,mouseEvent);

                  richText.addEventListener(FlowElementMouseEvent.CLICK,mouseEvent);

                 

                  textFlow = TextFlowUtil.importFromString(textString);

     

                  richText.textFlow = textFlow;

            }

           

            private function statusChangeHandler(event:Event):void

            {

                  var mN:String = cN + ".statusChangeHandler " + tr.enquoteEvent(event.type);

                  tr.output(mN);

            }                

           

            import flashx.textLayout.edit.SelectionManager;

            import flashx.textLayout.edit.SelectionState;

           

            private function mouseEvent(event:MouseEvent):void {

                  var mN:String = cN + ".mouseEvent " + tr.enquoteEvent(event.type);

                 

                  var selectionState:SelectionState = textFlow.interactionManager.getSelectionState();

                  var start:int = selectionState.absoluteStart;

                  var end:int = selectionState.absoluteEnd;

                  tr.output(mN + tr.selectionToString(start,end) + tr.locationToString(event.stageX,event.stageY) + tr.getClassShort(event.target));

//                tr.output(mN + tr.locationToString(event.localX,event.localY) + event.target);

            }

           

      ]]>

</fx:Script>    

     

     

<s:BorderContainer width="95%" height="95%" x="20" y="20">

      <s:Group>

            <s:RichEditableText id="richText">

                 

            </s:RichEditableText>

      </s:Group>

</s:BorderContainer>

</s:Application>