Question

I'd like to do fancy things the selection indicator. How do I get the bounding box for the currently selected characters?

Was it helpful?

Solution

This was non-trivial. First, a selection may require more than one rectangle. Next, there's no convenient way to do it.

Here's what I had to do:

        var start:int = op.activePosition < op.anchorPosition ? op.activePosition : op.anchorPosition;
        var end:int = op.activePosition > op.anchorPosition ? op.activePosition : op.anchorPosition;

        var textFlow:TextFlow = this.textFlow;
        var rectangles:Dictionary = new Dictionary();

        // For each selected character, make a box
        for( var i:int=start; i < end; i++) {

            var flowLine:TextFlowLine = textFlow.flowComposer.findLineAtPosition( i, true );

            if( rectangles[ flowLine.absoluteStart ] == null ) {
                rectangles[ flowLine.absoluteStart ] = new Rectangle();
                (rectangles[ flowLine.absoluteStart ] as Rectangle).x = 0xffffff;
                (rectangles[ flowLine.absoluteStart ] as Rectangle).right = 0;
            }
            var currentRect:Rectangle = rectangles[ flowLine.absoluteStart ];

            var textLine:TextLine = flowLine.getTextLine(true);
            var atomIndex:int = textLine.getAtomIndexAtCharIndex( i );
            if( atomIndex >= 0) {
                var atomBounds:Rectangle = textLine.getAtomBounds( atomIndex );

                var pt:Point = this.globalToLocal( textLine.localToGlobal( new Point( atomBounds.left, atomBounds.top ) ) );                    
                if( pt.x <= currentRect.left ) {
                    currentRect.left = pt.x;
                    currentRect.top = pt.y;
                }

                pt = this.globalToLocal( textLine.localToGlobal( new Point( atomBounds.right, atomBounds.bottom) ) );
                if( pt.x >= currentRect.right ) {
                    currentRect.right = pt.x;
                    currentRect.bottom = pt.y;
                }                   
            }
        } 
        return rectangles;

OTHER TIPS

I don't believe there's a trivial way to get total control over this, from looking around at the docs a bit I saw this: http://opensource.adobe.com/wiki/display/flexsdk/Spark+Text+Primitives#SparkTextPrimitives-FTE

[Style(name="focusedTextSelectionColor", type="uint", format="Color", inherit="yes")]

[Style(name="inactiveTextSelectionColor", type="uint", format="Color", inherit="yes")]

[Style(name="unfocusedTextSelectionColor", type="uint", format="Color", inherit="yes")]

also to note:

anchor position - A character index specifying the end of the selection that stays fixed when you extend the selection with the arrow keys.

active position - A character index specifying the end of the selection that moves when you extend the selection with the arrow keys.

Since these are all only colors (or indices) I don't know if they'll get at all the fanciness you'd like to do. I'd worked on something in Flex 3 to deal with custom text selection controls and ended up using an "off screen buffer" of sorts where I put a TextField offscreen with the same properties as the one on screen then dump the characters 1 by 1 until I got to the desired width then I could figure out where in the characters the control was dropped(kind of like android selection).

I would suggest searching for the above styles in the SDK you have (particularly in RichEditableText and its super classes, I would do this but there's quite a few versions out there now and don't know which one your using, TLF and FTE are both a bit in flux it seems). Once you find where these styles are used you'll probably be in the vicinity of the selection indicator drawing code and will likely need to extend from whatever class that is in order to override the appropriate methods.

Sorry I can't give you a straight answer but hopefully this helps or someone else is able to chime in if there's an easier way.

Shaun

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top