views:

1128

answers:

2

Is it possible (if so how) to find out what word the cursor/mouse is over when it is moving over a < mx:Text > component? So for example as the user moves the mouse along a sentence (inside text component), each word will highlight as they go (I know you can highlight while pressing the mouse button down - but that not how I wish to do it).

Thanks for any info.

A: 

You need to use the TextSnapshot class. You can grab it from your text control from the textSnapshot property. TextSnapshot has a hitTestTextNearPos() function that you can use to determine which character the user's mouse is near.

...
var startIndex:Number;
...

private function textMouseMoveHandler(event:MouseEvent):void
{
    var snapshot:TextSnapshot = text.textSnapshot;
    var index = snapshot.hitTestTextNearPos(event.x, event.y);

    snapshot.setSelected(startIndex, index, true);
}

// I do not know how you want to begin the selection, so I put it here in the MouseEnter event.
private function textMouseEnterHandler(event:MouseEvent):void
{

    var snapshot:TextSnapshot = text.textSnapshot;
    startIndex = snapshot.hitTestTextNearPos(event.x, event.y);
}

Not sure how you want to handle starting the selection, but something like that should work.

CookieOfFortune
thats sounds like just the job, going to do some reg-ex stuff on the words to get what i'm after. cheers.
kenneth
Looks like this isn't the answer after all :(The docs say the following 'The following example works only in the Flash authoring environment. Flex does not include any ways of adding static text to a file.'When trying it in flex there isn't anything inside the snapshot so you always get an index of -1.
kenneth
Hmmm... you may have to just use the height and width of the text and interpolate... not a very easy thing to do but doable. Reply to me if you want me to help you out on it, but I don't have a Flex development environment available right now.
CookieOfFortune
+2  A: 

Here's one way to do it: you need to create your own component that extends the mx:Text component. I used MyText in this example. Here's the full code for MyText:

<?xml version="1.0" encoding="utf-8"?>
<mx:Text xmlns:mx="http://www.adobe.com/2006/mxml" mouseMove="onMouseMove(event)" initialize="init()">
    <mx:Script>
     <![CDATA[

      // Text formats
      private var normalTextFormat:TextFormat;
      private var highlightTextFormat:TextFormat;

      // Saved word start and end indexes
      private var wordStartIndex:int = -1;
      private var wordEndIndex:int = -1;

      private function init():void
      {
       normalTextFormat = textField.getTextFormat();
       normalTextFormat.color = 0;
       highlightTextFormat = textField.getTextFormat();
       highlightTextFormat.color = 0xFF0000;
      }

      private function onMouseMove(event:MouseEvent):void
      {
       // Clear previous word highlight
       textField.setTextFormat(normalTextFormat, wordStartIndex, wordEndIndex);

       var charIndexUnderMouse:int = textField.getCharIndexAtPoint(event.localX, event.localY);
       wordStartIndex = charIndexUnderMouse;
       wordEndIndex = charIndexUnderMouse;

       // Find start of word
       while (text.charAt(wordStartIndex) != " " && wordStartIndex > 0)
       {
        wordStartIndex--;
       }

       // Find end of word
       while (text.charAt(wordEndIndex) != " " && wordEndIndex < text.length)
       {
        wordEndIndex++;
       }

       // Highlight character
       textField.setTextFormat(highlightTextFormat, wordStartIndex, wordEndIndex);
      }
     ]]>
    </mx:Script>

</mx:Text>

It works by accessing methods of the TextField object inside the Text component, finding the character index under the mouse coordinates and then finding the word the character belongs to. This is a quick example, you probably need to make it more elaborate for real world use.

Niko Nyman
I've just tried this an this does it. I did have to add the following 2 lines at the start of the onMouseMove function to make it work without throwing errors through.wordStartIndex = -1;wordEndIndex = -1;Thanks. Text is a bit of an odd thing in flash, the format goes a bit 'funny' when highlighting some parts! Haven't really tried the new text engine in flash 10, hopefully its better.
kenneth
You can set the index vars in the onMouseMove function, but theoretically you could save a little memory by having them outside. Defining vars in an MXML script block is a bit funky. The example would make more sense if you made it an ActionScript component.
Niko Nyman