开发者

Flex TextArea - how to highlight the row/line under the cursor?

There is a TextArea, and I can find the line index via textField.getLineIndexAtPoint(event.localX, event.localY). How can I set the background color of the selected l开发者_如何学编程ine? Sort of a row/line highlight. Thanks!


Okay, this is most probably not exactly the solution you are looking for, because my solution is targetted at the standard flash core TextField class, not some specific Flex compontent. But I guess by looking at the code you should be able to understand what happens and transfer that to the component as well.

Basically what I did is that I always check where the current cursor is using the selection, then I get the responding lines and draw some kind of highlight in the background that highlights the current rows. Note that I did it rather easy by simply basing on a single font, so the line height will always be the same. You could however make that work for different fonts within a single text field, by using the TextLineMetrics class and calculating the actual offsets more accurately. As this is a lot more work, and the highlight probably only makes sense for a single font environment, I left it out. My example below uses Courier, but it should automatically work with any font at any size.

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;
            }
        }
    }
}

You can also see this solution on Wonderfl, along with a working demo.


Assuming you are using the Spark component, define a textAreaFormat, set the backgroundColor property on that. Apply the format to the defined range on your text area.

var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
textLayoutFormat.fontSize = 12;
textLayoutFormat.color = 0xFF0000;
textLayoutFormat.backgroundColor = 0xFF00FF;
myRET.setFormatOfRange(textLayoutFormat,begin,end);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜