HighlightedTextField

by poke
In response to StackOverflow question: Flex TextArea - how to highlight the row/line under the cursor?”
http://stackoverflow.com/questions/6075630//6083247#6083247
♥0 | Line 69 | Modified 2011-05-22 02:14:17 | GPLv3 License
play

ActionScript3 source code

/**
 * Copyright poke ( http://wonderfl.net/user/poke )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/uFrv
 */

/*
 * In response to StackOverflow question:
 * “Flex TextArea - how to highlight the row/line under the cursor?”
 * http://stackoverflow.com/questions/6075630//6083247#6083247
 */
package
{
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    import flash.text.TextLineMetrics;
    
    public class HighlightedTextField extends Sprite
    {
        private var textField:TextField;
        private var highlighter:Shape;
        private var metrics:TextLineMetrics;        
        private var selectionBegin:int = -1;
        private var selectionEnd:int = -1;
        private var lineBegin:int = -1;
        private var lineEnd: int = -1;
        
        public function HighlightedTextField()
        {
            this.graphics.beginFill( 0xEEEEEE );
            this.graphics.drawRect( 5, 5, 290, 290 );
            this.graphics.endFill();

            // construct text field            
            textField = new TextField();
            textField.width = 280;
            textField.height = 280;
            textField.x = 10;
            textField.y = 10;
            textField.background = false;
            textField.selectable = true;
            textField.multiline = true;
            textField.defaultTextFormat = new TextFormat( 'Courier', 12 );
            textField.type = TextFieldType.INPUT;
            
            // construct line highlighter
            highlighter = new Shape();
            highlighter.graphics.beginFill( 0xCCCCCC );
            highlighter.graphics.drawRect( 0, 0, textField.width, 1 );
            highlighter.x = textField.x;
            highlighter.y = textField.y;
            
            this.addChild( highlighter );
            this.addChild( textField );
            this.addEventListener( Event.ENTER_FRAME, setHighlighter );
                        
            // get line metrics and initialize highlight
            metrics = textField.getLineMetrics( 0 );
            setHighlighter( null );
        }
        
        private function setHighlighter ( event:Event ):void
        {
            var changed:Boolean = false;
                        
            // cache checks to make sure that the selection has changed
            if ( selectionBegin != textField.selectionBeginIndex )
            {
                selectionBegin = textField.selectionBeginIndex;
                lineBegin = textField.getLineIndexOfChar( selectionBegin );
                
                // when the caret is at the end of the text, getLineIndexOfChar will return -1
                lineBegin = lineBegin != -1 ? lineBegin : textField.numLines - 1;
                
                changed = true;
            }
            
            // same as above
            if ( selectionEnd != textField.selectionEndIndex )
            {
                selectionEnd = textField.selectionEndIndex;
                lineEnd = textField.getLineIndexOfChar( selectionEnd );
                lineEnd = lineEnd != -1 ? lineEnd : textField.numLines - 1;
                changed = true;
            }
            
            // only move the highlight when something has changed
            if ( changed )
            {
                highlighter.y = textField.y + metrics.height * lineBegin + 2;
                highlighter.height = textField.y + metrics.height * ( lineEnd + 1 ) + 2 - highlighter.y;
            }
        }
    }
}