apache-flexricheditabletext

How do I get a bounding box for the current selection?


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


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;