Skip to main content
Inspiring
April 28, 2010
Answered

Has text selection changed?

  • April 28, 2010
  • 1 reply
  • 4434 views

I'm not sure if it's just me going mad, but....

Imagine a container with the following 2 TextLines, the vertical pipes (|) are meant to represent the bounds of the container so please assume these are aligned:

|Line one is longer|

|Line two             |

In my code I set the interactionManager to allow editing of the text.

When I move my mouse over any of the text I get the text caret cursor, I can click to drag select text, right click to get the relevant context menu ("select all" etc). When I move my mouse in the blank area to the right of the text "Line two", you get no text caret cursor, the TextLine's bounds simply don't extend into this area so the "edit" context menu is not applied.

This makes text selection very awkward, now you have to find the 1 pixel wide point after the last character to begin to select all the previous text.

Has something changed recently? 

This topic has been closed for replies.
Correct answer rdermer

Not that I'm aware of.  This doesn't duplicate in our testing.

TLF does rely on drawing a transparent background into the Sprite.graphics.  Are you clearing that?

Richard

1 reply

rdermerCorrect answer
Adobe Employee
April 29, 2010

Not that I'm aware of.  This doesn't duplicate in our testing.

TLF does rely on drawing a transparent background into the Sprite.graphics.  Are you clearing that?

Richard

Inspiring
April 30, 2010

That is spot on... I have implemented Squiggly for my "pure TLF" text inputs, calling clear before I run through and underline the misspelled words.

Just in case anyone finds this thread when searching for Squiggly, the way I did it was:

  • Find TextRanges for misspelled words:
    • Get the first Paragraph using textFlow.getFirstLeaf().getParagraph()
    • Loop through all Paragraphs using para.getNextParagraph()
    • For each, run a Regex match (/\b\w+\b/) on para.getText()
    • Spellcheck each result using Squiggly, and for bad words store a TextRange: TextRange(textFlow, para.getAbsoluteStart()+index, para.getAbsoluteStart()+index+word.length-1); where index is incremented to the position proceeding the end of each word (match or no match).

  • Spellcheck class:
    • Created a static SpellCheck class which loads language dictionary (downloaded from OpenOffice website) and a UserDictionary (stored as a simple text file)
    • Added methods for checkTextFlow(textFlow:TextFlow):Array which returns an array of "bad" TextRanges, a method for getSuggestions(word:String):Array and methods for checkWord() and addUserWord().

  • Context menu:
    • Extend ContainerController and override menuSelectHandler()... use an instance of my CustomContainerController when creating the TextFlow:
    •   textFlow.flowComposer.addController( new CustomContainerController() );  
    • Loop through flowComposer.numLines, obtain each TextFlowLine from flowComposer and therefore each TextLine.
    • Determine if textLine.getBounds(container).container(container.mouseX, container.mouseY) to find the line they right-clicked.
    • Get the "raw text" for the line: textLine.textBlock.content.rawText.substr(textLine.textBlockBeginIndex);
    • Find the atom clicked: textLine.getAtomIndexAtPoint(container.stage.mouseX, container.stage.mouseY).
    • Find the starting atom of the word (reverse lookup for word boundary i.e.. " " or first char in raw text).
    • Determine the word itself by using regex to find the first word from this starting point (/\b\w+\b/).
    • Add ContextMenuItems for "add to dictionary" and suggested words (for the latter also store start/end atoms in ContextMenuItem.data).
    • When user clicks a suggested word, use (interactionManager as EditManager).selectRange(data.start, data.end); (interactionManager as EditManager).insertText(data.word) where "data" is the data property of the clicked ContextMenuItem.

  • In my "EditableTextField" class, I call my SpellCheck.checkTextFlow() to get the bad TextRanges and...
    •   Loop through the badRanges array.
    •   Loop from range.absoluteStart to range.absoluteEnd for each TextRange.
    •   Find TextFlowLine for "i" in this loop, and therefore the TextLine: containerController.flowComposer.findLineAtPosition(i); textFlowLine.getTextLine();
    •   Find atom bounds using textLine.getAtomBounds(charIndex); where charIndex is: i - textFlowLine.absoluteStart.
    •   Underline... drawRect( bounds.x + textLine.x, bounds.y + textLine.y + bounds.height - textLine.descent - 1, bounds.width, 3)

I'm sure there is a more elegant way, but this seems to work. I believe I read Adobe are working on Squiggly for pure TLF, if not, I hope this helps somebody get on the right track.

I'd paste the code but as this is for a client I can't paste the full contents of the class-files without permission or sufficient modification first.

Thanks again, Richard

Message was edited by: richardleggettmk added bullets

Participant
December 17, 2010

Nice implementation... here's another implementation I have done for using with TLF and openning a popup to spell check and returning the the results while keeping all the TLF properties:

http://elromdesign.com/blog/2010/12/16/implementing-squiggly-spell-check-for-tlf-text-layout-framework-text-inputs/