/ru/volgogradetzzz/text/VMultilineText.as
http://fte-text-controls.googlecode.com/ · ActionScript · 1011 lines · 648 code · 122 blank · 241 comment · 120 complexity · a4fdc76beece03c1c5e90d3e2c89f7eb MD5 · raw file
- package ru.volgogradetzzz.text
- {
- import flash.display.Graphics;
- import flash.display.Shape;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.events.MouseEvent;
- import flash.geom.Point;
- import flash.geom.Rectangle;
- import flash.text.engine.BreakOpportunity;
- import flash.text.engine.ElementFormat;
- import flash.text.engine.FontDescription;
- import flash.text.engine.FontLookup;
- import flash.text.engine.FontPosture;
- import flash.text.engine.FontWeight;
- import flash.text.engine.RenderingMode;
- import flash.text.engine.TextBaseline;
- import flash.text.engine.TextBlock;
- import flash.text.engine.TextElement;
- import flash.text.engine.TextLine;
- import flash.ui.Mouse;
- import flash.ui.MouseCursor;
- import flash.utils.getQualifiedClassName;
-
- /**
- * VMultilineText can contain multiply text lines. Text can set it's width automatically if autoWidth set to true,
- * and height if autoHeight set to true. In other cases text is wraps or trunkates if string width is greater then
- * explicitly setted width or string height is greater then explicitly setted height. Text can be formatted.
- * Whole text change it's style when new format applied.
- *
- * @author Volgogradetzzz
- */
- public class VMultilineText extends Sprite implements IFTEVText
- {
- //--------------------------------------
- // Private fields
- //--------------------------------------
-
- /**
- * Auxiliary property.
- */
- private var _textElement:TextElement = new TextElement();
- /**
- * Indicates that text control can be selected or not.
- */
- private var _selectable:Boolean = false;
- /**
- * Holds atom index.
- */
- private var _startInd:int = -1;
- /**
- * Holds atom center respective to mouse position.
- */
- private var _startMouseAtomPos:String;
- /**
- * Mouse position in the place of click.
- */
- private var _startMousePosX:Number;
- /**
- * Atom info object that contains atom center respective to mouse position and atom index.
- */
- private var _atomInfo:Object = new Object();
- /**
- * Start index of selection.
- */
- private var _startIndForClipboard:int = -1;
- /**
- * End index of selection.
- */
- private var _endIndForClipboard:int = -1;
-
- //--------------------------------------
- // Protected fields
- //--------------------------------------
-
- /**
- * Text to display.
- */
- protected var _text:String = '';
- /**
- * Auxiliary property.
- */
- protected var _block:TextBlock = new TextBlock(_textElement);
- /**
- * Delays control updating until 'update' called manually.
- */
- protected var _updateLater:Boolean = false;
- /**
- * Text format.
- */
- protected var _textFormat:VTextFormat = new VTextFormat();
- /**
- * Hold text lines
- */
- protected var _linesCont:Sprite = new Sprite();
- /**
- * Array of lines.
- */
- protected var _allLines:Vector.<TextLine> = new Vector.<TextLine>();
- /**
- * Shape for correct width/height getting
- */
- protected var _bg:Shape = new Shape();
- /**
- * Text control width.
- */
- protected var _w:Number = 100;
- /**
- * Text control height.
- */
- protected var _h:Number = 100;
- /**
- * Allows to VMultilineText instance to 'grow' or 'shrink' automatically in horizontal direction.
- */
- protected var _autoWidth:Boolean = false;
- /**
- * Allows to VMultilineText instance to 'grow' or 'shrink' automatically in vertical direction.
- */
- protected var _autoHeight:Boolean = false;
- /**
- * Total atoms in text control. Can be less than supplied string because text can be trunkated.
- */
- protected var _totalAtoms:int;
-
- //--------------------------------------
- // Constructor
- //--------------------------------------
-
- /**
- * Creates new instance of VMultilineText.
- */
- public function VMultilineText()
- {
- super();
-
- var g:Graphics = _bg.graphics;
- g.beginFill(0x000000, 0.0);
- g.drawRect(0, 0, 100, 100);
- g.endFill();
- _bg.width = _w;
- _bg.height = _h;
- addChild(_bg);
-
- addChild(_linesCont);
-
- doubleClickEnabled = true;
-
- text = _text;
-
- addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
- addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
- }
-
- //--------------------------------------
- // Public methods
- //--------------------------------------
-
- /**
- * Method recreates lines and set 'updateLater' property to false.
- * You should call it if 'updateLater' was set to 'true'.
- */
- public function update():void
- {
- _updateLater = false;
- createLines();
- }
-
- /**
- * Sets selection in specified interval.
- * @param startInd Start index of selection
- * @param endInt End index of selection.
- */
- public function setSelection(startInd:int, endInt:int):void
- {
- _startMouseAtomPos = 'left';
- drawSelection(startInd, endInt)
- }
-
- /**
- * Removes any selection.
- */
- public function clearSelection():void
- {
- graphics.clear();
- _startIndForClipboard = -1;
- _endIndForClipboard = -1;
- }
-
- //--------------------------------------
- // Public properties
- //--------------------------------------
-
- /**
- * Gets start index of selection. If no selection made -1 returned.
- */
- public function get selectionBeginIndex():int
- {
- return _startIndForClipboard;
- }
-
- /**
- * Gets end index of selection. If no selection made -1 returned.
- */
- public function get selectionEndIndex():int
- {
- return _endIndForClipboard;
- }
-
- /**
- * Gets or sets text message for VMultilineText instance. VMultilineText can contain multiply text lines.
- * If width is not enougth to hold the whole string then string is wraps. If height is not enougth to hold the
- * whole string then string is trunkates and property returns trunkated text.
- * To get full text use 'fullText' property.
- */
- public function get text():String { return _text.substr(0, _totalAtoms); }
- /**
- * @private
- */
- public function set text(value:String):void
- {
- _text = value;
-
- var fontWeight:String = _textFormat.bold ? FontWeight.BOLD : FontWeight.NORMAL;
- var fontStyle:String = _textFormat.italic ? FontPosture.ITALIC : FontPosture.NORMAL;
- var embedFont:String = _textFormat.embedFont ? FontLookup.EMBEDDED_CFF : FontLookup.DEVICE;
-
- var fontDesc:FontDescription = new FontDescription(_textFormat.font, fontWeight, fontStyle, embedFont, RenderingMode.NORMAL);
- var format:ElementFormat = new ElementFormat(fontDesc, _textFormat.size, _textFormat.color);
- format.breakOpportunity = BreakOpportunity.AUTO;
-
- _textElement.text = _text;
- _textElement.elementFormat = format;
-
- if(!_updateLater) createLines();
- }
-
- /**
- * Returns full text. If 'autoWidth' is true then 'text' and 'fullText' are same.
- */
- public function get fullText():String { return _text };
-
- /**
- * Gets or sets width of VMultilineText instance. If autoWidth is true then setting width nave no effect
- * and getting width returns actual width - not width that was setted explicitly. So to set width be sure
- * to set false to autoWidth property.
- */
- override public function get width():Number { return _w; }
- /**
- * @private
- */
- override public function set width(value:Number):void
- {
- _w = value < 0 ? 0 : value;
-
- if(!_updateLater) createLines();
- }
-
- /**
- * Gets or sets height of VMultilineText instance. If autoHeight is true then setting height nave no effect
- * and getting height returns actual height - not height that was setted explicitly. So to set height be sure
- * to set false to autoHeight property.
- */
- override public function get height():Number { return _h; }
- /**
- * @private
- */
- override public function set height(value:Number):void
- {
- _h = value < 0 ? 0 : value;
-
- if(!_updateLater) createLines();
- }
-
- /**
- * Allows to VMultilineText instance to 'grow' or 'shrink' automatically in horizontal direction
- * when new text entered.
- */
- public function get autoWidth():Boolean { return _autoWidth; }
- /**
- * @private
- */
- public function set autoWidth(value:Boolean):void
- {
- _autoWidth = value;
-
- if(!_updateLater) createLines();
- }
-
- /**
- * Allows to VMultilineText instance to 'grow' or 'shrink' automatically in vertical direction
- * when new text entered.
- */
- public function get autoHeight():Boolean { return _autoHeight; }
- /**
- * @private
- */
- public function set autoHeight(value:Boolean):void
- {
- _autoHeight = value;
-
- if(!_updateLater) createLines();
- }
-
- /**
- * Sets new text format. VMultilineText supports align, bold, italic, color, font, size and embedFont properties.
- */
- public function get textFormat():VTextFormat { return _textFormat; }
- /**
- * @private
- */
- public function set textFormat(value:VTextFormat):void
- {
- _textFormat = value;
- text = _text;
- }
-
- /**
- * Most of properties of VMultilineText cause to recreate lines when that property change. For example,
- * you can change 'width' and 'height' and for every property lines would be recreated. But it would be better
- * to commit all that properties at once and update control only one time. You can do it by setting 'updateLater'
- * to 'true', changing neccesary properties and than calling 'update' method.
- */
- public function get updateLater():Boolean { return _updateLater; }
- /**
- * @private
- */
- public function set updateLater(value:Boolean):void
- {
- _updateLater = value;
- }
-
- /**
- * Indicates that text control can be selected or not.
- */
- public function get selectable():Boolean { return _selectable; }
- /**
- * @private
- */
- public function set selectable(value:Boolean):void
- {
- _selectable = value;
- }
-
- /**
- * Gets characters number in VMultilineText instance. If width is not enougth to hold whole string
- * then string is trunkates and property returns trunkated text length.
- * To get full text length use 'fullLength' property.
- */
- public function get length():int { return _totalAtoms };
-
- /**
- * Gets characters number of full text in VMultilineText instance. If 'autoWidth' is true
- * then 'length' and 'fullLength' are same.
- */
- public function get fullLength():int { return _text.length };
-
- //--------------------------------------
- // Private methods
- //--------------------------------------
-
- /**
- * @private Create lines and aligns them horizontally and vertically.
- */
- protected function createLines():void
- {
- _allLines.length = 0;
- _totalAtoms = 0;
-
- //if lines exists - remove them.
- var numLines:int = _linesCont.numChildren;
- while (--numLines > -1)
- {
- _linesCont.removeChildAt(numLines);
- }
-
- //if text was created before - release it's data for garbage collection.
- if (_block)
- {
- var firstLine:TextLine = _block.firstLine;
- var lastLine:TextLine = _block.lastLine;
- if (firstLine) _block.releaseLines(firstLine, lastLine);
- }
-
- var w:Number = _autoWidth ? 1000000 : _w;
- var line:TextLine = _block.createTextLine(null, w);
- var lastLineDescent:Number = 0;
-
- var isFirstLineFit:Boolean = true;
-
- if (line)
- {
- line.y = line.height;
- lastLineDescent = Math.ceil(line.getBaselinePosition(TextBaseline.DESCENT));
- line.doubleClickEnabled = true;
-
- if (_autoHeight)
- {
- _linesCont.addChild(line);
- _allLines.push(line);
- _totalAtoms += line.atomCount;
- }
- else
- {
- if (line.y + lastLineDescent < _h)
- {
- _linesCont.addChild(line);
- _allLines.push(line);
- _totalAtoms += line.atomCount;
- }
- else
- {
- isFirstLineFit = false;
- }
- }
- }
-
- while (line && isFirstLineFit)
- {
- line = _block.createTextLine(line, w);
-
- if (line)
- {
- line.y = _linesCont.height + line.height + _textFormat.lineSpace;
- lastLineDescent = Math.ceil(line.getBaselinePosition(TextBaseline.DESCENT));
- line.doubleClickEnabled = true;
-
- if (_autoHeight)
- {
- _linesCont.addChild(line);
- _allLines.push(line);
- _totalAtoms += line.atomCount;
- }
- else
- {
- if (line.y + lastLineDescent < _h)
- {
- _linesCont.addChild(line);
- _allLines.push(line);
- _totalAtoms += line.atomCount;
- }
- else
- {
- break;
- }
- }
- }
- }
-
- if (_autoWidth)
- {
- _w = _linesCont.width;
- }
-
- if (_autoHeight)
- {
- _h = _linesCont.height + lastLineDescent;
- }
-
- numLines = _linesCont.numChildren;
- if (_textFormat.horizontalAlign == VTextAlign.LEFT)
- {
- while (--numLines > -1)
- {
- line = _linesCont.getChildAt(numLines) as TextLine;
- line.x = 0;
- }
- }
- else if (_textFormat.horizontalAlign == VTextAlign.CENTER)
- {
- while (--numLines > -1)
- {
- line = _linesCont.getChildAt(numLines) as TextLine;
- line.x = (_w - line.width) >> 1;
- }
- }
- else if (_textFormat.horizontalAlign == VTextAlign.RIGHT)
- {
- while (--numLines > -1)
- {
- line = _linesCont.getChildAt(numLines) as TextLine;
- line.x = _w - line.width;
- }
- }
-
- numLines = _linesCont.numChildren;
- if (_textFormat.verticalAlign == VTextAlign.TOP)
- {
- for (var i:int = 0; i < numLines; i++)
- {
- line = _linesCont.getChildAt(i) as TextLine;
- line.y = i == 0 ? line.height : _linesCont.getChildAt(i - 1).y + line.height + _textFormat.lineSpace;
- }
- }
- else if (_textFormat.verticalAlign == VTextAlign.MIDDLE)
- {
- for (i = 0; i < numLines; i++)
- {
- line = _linesCont.getChildAt(i) as TextLine;
- line.y = i == 0 ? ((_h - _linesCont.height - lastLineDescent) >> 1) + line.height : _linesCont.getChildAt(i - 1).y + line.height + _textFormat.lineSpace;
- }
- }
- else if (_textFormat.verticalAlign == VTextAlign.BOTTOM)
- {
- for (i = numLines - 1; i > -1; i--)
- {
- line = _linesCont.getChildAt(i) as TextLine;
- line.y = i == numLines - 1 ? _h - lastLineDescent : _linesCont.getChildAt(i + 1).y - line.height - _textFormat.lineSpace;
- }
- }
-
- _bg.width = _w;
- _bg.height = _h;
- }
-
- /**
- * Adds nesessary listeners if instance added to stage.
- * @param event
- */
- private function addedToStageHandler(event:Event = null):void
- {
- addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
- addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
- addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
- addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
- stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
- stage.addEventListener(MouseEvent.MOUSE_DOWN, stageMouseDownHandler);
- }
-
- /**
- * Removes listeners if instance removed from stage.
- * @param event
- */
- private function removedFromStageHandler(event:Event = null):void
- {
- removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
-
- removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
- removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
- removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
- removeEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
- stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
- stage.removeEventListener(MouseEvent.MOUSE_DOWN, stageMouseDownHandler);
- }
-
- /**
- * Handles mouse over.
- * @param event
- */
- private function mouseOverHandler(event:MouseEvent = null):void
- {
- if(_selectable) Mouse.cursor = MouseCursor.IBEAM;
- }
-
- /**
- * Handles mouse out.
- * @param event
- */
- private function mouseOutHandler(event:MouseEvent = null):void
- {
- if(_selectable) Mouse.cursor = MouseCursor.ARROW;
- }
-
- /**
- * Handles mouse down.
- * @param event
- */
- private function mouseDownHandler(event:MouseEvent = null):void
- {
- clearSelection();
-
- if (!_selectable) return;
-
- if (_text.length == 0) return;
-
- var atomInfo:Object = getIndexUnderMouse();
-
- _startMousePosX = stage.mouseX;
- _startInd = atomInfo.index;
- _startMouseAtomPos = atomInfo.mouseAtomPos;
-
- addEventListener(Event.ENTER_FRAME, enterFrameHandler);
- }
-
- /**
- * Handles double click - selects word under mouse.
- * @param event
- */
- private function doubleClickHandler(event:MouseEvent = null):void
- {
- if (!_selectable) return;
-
- if (_text.length == 0) return;
-
- var atomInfo:Object = getIndexUnderMouse();
- var indInBlock:int = atomInfo.index;
- var indInLine:int = indInBlock - atomInfo.textLine.textBlockBeginIndex;
-
- var selectedChar:String = _text.substr(indInBlock, 1);
- if (selectedChar == ' ' || selectedChar == '\n')
- {
- var wordStartInd:int = indInBlock;
- var wordEndInd:int = indInBlock - 1;
-
- for (var i:int = indInBlock - 1; i > -1; i--)
- {
- selectedChar = _text.substr(i, 1);
- if (selectedChar != ' ' && selectedChar != '\n')
- {
- break;
- }
- else
- {
- wordStartInd = i;
- }
- }
-
- for (i = indInBlock; i < _totalAtoms; i++)
- {
- selectedChar = _text.substr(i, 1);
- if (selectedChar != ' ' && selectedChar != '\n')
- {
- break;
- }
- else
- {
- wordEndInd = i;
- }
- }
- }
- else if(atomInfo.textLine.getAtomWordBoundaryOnLeft(indInLine))
- {
- wordStartInd = indInBlock;
- wordEndInd = _block.findNextWordBoundary(indInBlock) - 1;
-
- if (wordEndInd > _totalAtoms - 1)
- {
- wordEndInd = _totalAtoms - 1;
- }
-
- for (i = wordEndInd + 1; i < _totalAtoms; i++)
- {
- selectedChar = _text.substr(i, 1);
- if (selectedChar != ' ' && selectedChar != '\n')
- {
- break;
- }
- else
- {
- wordEndInd = i;
- }
- }
- }
- else
- {
- wordStartInd = _block.findPreviousWordBoundary(indInBlock);
- wordEndInd = _block.findNextWordBoundary(indInBlock) - 1;
-
- if (wordEndInd > _totalAtoms - 1)
- {
- wordEndInd = _totalAtoms - 1;
- }
-
- for (i = wordEndInd + 1; i < _totalAtoms; i++)
- {
- selectedChar = _text.substr(i, 1);
- if (selectedChar != ' ' && selectedChar != '\n')
- {
- break;
- }
- else
- {
- wordEndInd = i;
- }
- }
- }
-
- _startMouseAtomPos = 'left';
- //if (wordEndInd == _totalAtoms) wordEndInd--;
-
- drawSelection(wordStartInd, wordEndInd);
- }
-
- /**
- * Handles stage mouse up.
- * @param event
- */
- private function stageMouseUpHandler(event:MouseEvent = null):void
- {
- removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
- }
-
- /**
- * Handles stage mouse down. Removes any selection.
- * @param event
- */
- private function stageMouseDownHandler(event:MouseEvent = null):void
- {
- clearSelection();
- }
-
- /**
- * Gets atom index under mouse. Lines are choses based on mouse Y position.
- * If mouse not over line - nearest up line selects.
- * If mouse above all lines - first line selects.
- * @return
- */
- private function getIndexUnderMouse():Object
- {
- var upLine:TextLine;
-
- var atomInfo:Object = new Object();
- atomInfo.index = -1;
-
- var numLines:int = _allLines.length;
- for (var i:int = 0; i < numLines; i++)
- {
- var line:TextLine = _allLines[i];
-
- if (line.mouseY >= -line.height && line.mouseY <= 0)
- {
- atomInfo = getIndexAtLine(line);
- atomInfo.textLine = line;
- break;
- }
-
- if (this.mouseY > line.y)
- {
- upLine = line;
- }
- }
-
- if (atomInfo.index == -1)
- {
- if (upLine)
- {
- atomInfo = getIndexAtLine(upLine);
- atomInfo.textLine = upLine;
- }
- else
- {
- atomInfo = getIndexAtLine(_allLines[0]);
- atomInfo.textLine = _allLines[0];
- }
- }
-
- return atomInfo;
- }
-
- /**
- * Gets atom index in line based on mouse X position.
- * If mouse is on the right of line - last index selects.
- * If mouse is on the left of line - first index selects.
- * @param line Line to select index from.
- * @return
- */
- private function getIndexAtLine(line:TextLine):Object
- {
- var atomInfo:Object = new Object();
-
- var lineLocalPoint:Point = new Point(line.mouseX, 0);
- var lineGlobalPoint:Point = line.localToGlobal(lineLocalPoint);
- var lastAtomBounds:Rectangle = line.getAtomBounds(line.atomCount - 1);
-
- if (this.mouseX >= line.x + lastAtomBounds.x + lastAtomBounds.width)
- {
- atomInfo.index = line.textBlockBeginIndex + line.atomCount - 1;
- atomInfo.mouseAtomPos = 'right';
- }
- else if (this.mouseX <= line.x)
- {
- atomInfo.index = line.textBlockBeginIndex;
- atomInfo.mouseAtomPos = 'left';
- }
- else
- {
- var indInLine:int = line.getAtomIndexAtPoint(lineGlobalPoint.x, lineGlobalPoint.y);
- atomInfo.index = line.textBlockBeginIndex + indInLine;
-
- if (line.getAtomCenter(indInLine) > line.mouseX)
- {
- atomInfo.mouseAtomPos = 'left';
- }
- else
- {
- atomInfo.mouseAtomPos = 'right';
- }
- }
-
- return atomInfo;
- }
-
- /**
- * Manages selection drawing.
- * @param event
- */
- private function enterFrameHandler(event:Event = null):void
- {
- var prevEndInd:int = _atomInfo.index;
- var prevEndMouseAtomPos:String = _atomInfo.mouseAtomPos;
-
- _atomInfo = getIndexUnderMouse();
- var endInd:int = _atomInfo.index;
- var endMouseAtomPos:String = _atomInfo.mouseAtomPos;
-
- if (endInd == prevEndInd && endMouseAtomPos == prevEndMouseAtomPos) return;
-
- if (_startInd == endInd)
- {
- if (_startMouseAtomPos != endMouseAtomPos)
- {
- drawSelection(_startInd, endInd);
- }
- else
- {
- clearSelection();
- }
- }
- else
- {
- if (_startMouseAtomPos == 'right')
- {
- if (_startInd + 1 < _totalAtoms)
- {
- drawSelection(_startInd, endInd);
- }
- else
- {
- drawSelection(_startInd, endInd);
- }
- }
- else
- {
- drawSelection(_startInd, endInd);
- }
- }
- }
-
- /**
- * Draws selection based on incoming first and last indicies.
- * @param startInd
- * @param endInd
- */
- private function drawSelection(startInd:int, endInd:int):void
- {
- clearSelection();
-
- if (startInd < endInd)
- {
- _startIndForClipboard = startInd;
- _endIndForClipboard = endInd;
- }
- else
- {
- _startIndForClipboard = endInd;
- _endIndForClipboard = startInd;
- }
-
- var lineToStartFrom:TextLine = _block.getTextLineAtCharIndex(startInd);
- var lineToEndTo:TextLine = _block.getTextLineAtCharIndex(endInd);
-
- var start:int = startInd - lineToStartFrom.textBlockBeginIndex;
- var end:int = endInd - lineToEndTo.textBlockBeginIndex;
-
- var startBounds:Rectangle = lineToStartFrom.getAtomBounds(start);
- var endBounds:Rectangle = lineToEndTo.getAtomBounds(end);
-
- var rects:Vector.<Rectangle> = new Vector.<Rectangle>();
- var rect:Rectangle = new Rectangle();
-
- if (lineToStartFrom == lineToEndTo)
- {
- if (start == end)
- {
- rect.x = lineToStartFrom.x + startBounds.x;
- rect.y = lineToStartFrom.y + startBounds.y;
- rect.width = endBounds.x + endBounds.width - startBounds.x;
- rect.height = lineToStartFrom.height;
- }
- else if (start < end)
- {
- rect.x = lineToStartFrom.x + startBounds.x;
- rect.y = lineToStartFrom.y + startBounds.y;
- rect.width = endBounds.x + endBounds.width - startBounds.x;
- rect.height = lineToStartFrom.height;
-
- if (_startMouseAtomPos == 'right')
- {
- rect.x += startBounds.width;
- rect.width -= startBounds.width;
- }
- }
- else
- {
- rect.x = lineToStartFrom.x + startBounds.x;
- rect.y = lineToStartFrom.y + startBounds.y;
- rect.width = endBounds.x - startBounds.x;
- rect.height = lineToStartFrom.height;
-
- if (_startMouseAtomPos == 'right')
- {
- rect.x += startBounds.width;
- rect.width -= startBounds.width;
- }
- }
-
- rects.push(rect);
- }
- else
- {
- if (startInd < endInd)
- {
- var startRect:Rectangle = new Rectangle();
- var lastCharBounds:Rectangle = lineToStartFrom.getAtomBounds(lineToStartFrom.atomCount - 1);
-
- startRect.x = lineToStartFrom.x + startBounds.x;
- startRect.y = lineToStartFrom.y + startBounds.y;
- startRect.width = lastCharBounds.x + lastCharBounds.width - startBounds.x;
- startRect.height = lineToStartFrom.height;
-
- if (_startMouseAtomPos == 'right')
- {
- startRect.x += startBounds.width;
- startRect.width -= startBounds.width;
- }
-
- rects.push(startRect);
-
- //do middle lines
- var startLineInd:int = _allLines.indexOf(lineToStartFrom);
- var endLineInd:int = _allLines.indexOf(lineToEndTo);
- for (var i:int = startLineInd + 1; i < endLineInd; i++)
- {
- var midLine:TextLine = _allLines[i];
- var midLineFirstCharBounds:Rectangle = midLine.getAtomBounds(0);
- var midLineLastCharBounds:Rectangle = midLine.getAtomBounds(midLine.atomCount - 1);
- var midRect:Rectangle = new Rectangle();
- midRect.x = midLine.x + midLineFirstCharBounds.x;
- midRect.y = midLine.y + midLineFirstCharBounds.y;
- midRect.width = midLineLastCharBounds.x + midLineLastCharBounds.width - midLineFirstCharBounds.x;
- midRect.height = midLine.height;
-
- rects.push(midRect);
- }
-
- var endRect:Rectangle = new Rectangle();
- var firstCharBounds:Rectangle = lineToEndTo.getAtomBounds(0);
-
- endRect.x = lineToEndTo.x + firstCharBounds.x;
- endRect.y = lineToEndTo.y + firstCharBounds.y;
- endRect.width = endBounds.x + endBounds.width - firstCharBounds.x;
- endRect.height = lineToEndTo.height;
-
-
- rects.push(endRect);
- }
- else
- {
- startRect = new Rectangle();
- firstCharBounds = lineToStartFrom.getAtomBounds(0);
-
- startRect.x = lineToStartFrom.x + startBounds.x;
- startRect.y = lineToStartFrom.y + startBounds.y;
- startRect.width = firstCharBounds.x - startBounds.x;
- startRect.height = lineToStartFrom.height;
-
- if (_startMouseAtomPos == 'right')
- {
- startRect.x += startBounds.width;
- startRect.width -= startBounds.width;
- }
-
- rects.push(startRect);
-
- //do middle lines
- startLineInd = _allLines.indexOf(lineToStartFrom);
- endLineInd = _allLines.indexOf(lineToEndTo);
- for (i = startLineInd - 1; i > endLineInd; i--)
- {
- midLine = _allLines[i];
- midLineFirstCharBounds = midLine.getAtomBounds(0);
- midLineLastCharBounds = midLine.getAtomBounds(midLine.atomCount - 1);
- midRect = new Rectangle();
- midRect.x = midLine.x + midLineFirstCharBounds.x;
- midRect.y = midLine.y + midLineFirstCharBounds.y;
- midRect.width = midLineLastCharBounds.x + midLineLastCharBounds.width - midLineFirstCharBounds.x;
- midRect.height = midLine.height;
-
- rects.push(midRect);
- }
-
- endRect = new Rectangle();
- lastCharBounds = lineToEndTo.getAtomBounds(lineToEndTo.atomCount - 1);
-
- endRect.x = lineToEndTo.x + endBounds.x;
- endRect.y = lineToEndTo.y + endBounds.y;
- endRect.width = lastCharBounds.x + lastCharBounds.width - endBounds.x;
- endRect.height = lineToEndTo.height;
-
- rects.push(endRect);
- }
- }
-
- for each(rect in rects)
- {
- graphics.beginFill(0x003399, 0.25);
- graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
- graphics.endFill();
- }
- }
- }
- }