| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package com.adobe.linguistics.spelling.ui |
| { |
| import flash.display.Shape; |
| import flash.geom.Point; |
| import flash.geom.Rectangle; |
| |
| import mx.core.IUITextField; |
| import mx.flash.UIMovieClip; |
| |
| public class SpellingHighlighter extends UIMovieClip |
| { |
| /* |
| * offset point: |
| */ |
| private var _offsetPoint:Point; |
| |
| /* |
| * Target TextField. |
| */ |
| private var _textField:IUITextField; |
| private static var InvalidIndexValue:int = -2; |
| public function SpellingHighlighter(textField:IUITextField) { |
| super(); |
| this._textField = textField; |
| this._offsetPoint = new Point(0,0); |
| } |
| |
| public function drawSquigglyLine(firstCharIndex:int, lastCharIndex:int ):void { |
| var validFirstCharIndex:int = getValidFirstCharIndex(firstCharIndex); |
| var validLastCharIndex:int = getValidLastCharIndex(lastCharIndex); |
| if ( validFirstCharIndex == InvalidIndexValue || validLastCharIndex == InvalidIndexValue ){ |
| return; |
| } |
| /* draw squiggly line here. */ |
| if ( validFirstCharIndex <= validLastCharIndex ) { |
| var firstLine:int = _textField.getLineIndexOfChar(validFirstCharIndex); |
| var lastLine:int = _textField.getLineIndexOfChar(validLastCharIndex); |
| //only one line case. |
| if(lastLine==firstLine) |
| { |
| drawSingleSquigglyLine(validFirstCharIndex, validLastCharIndex); |
| return; |
| } |
| //more than one line. |
| //first line |
| drawSingleSquigglyLine(validFirstCharIndex, _textField.getLineOffset(firstLine)+_textField.getLineLength(firstLine)-1); |
| //middle.... |
| for(var i:int=firstLine+1;i<lastLine;i++) |
| { |
| drawSingleSquigglyLine(_textField.getLineOffset(i), _textField.getLineOffset(i)+_textField.getLineLength(i)-1); |
| } |
| //last lines. |
| drawSingleSquigglyLine(_textField.getLineOffset(lastLine), validLastCharIndex); |
| } |
| } |
| |
| public function drawSingleSquigglyLine(firstCharIndex:int, lastCharIndex:int ):void { |
| var firstLine:int = _textField.getLineIndexOfChar(firstCharIndex); |
| var lastLine:int = _textField.getLineIndexOfChar(lastCharIndex); |
| if ( firstLine != lastLine ) { |
| return; |
| }else { |
| var rect1:Rectangle = _textField.getCharBoundaries(firstCharIndex); |
| var rect2:Rectangle = _textField.getCharBoundaries(lastCharIndex); |
| var x:Number = rect1.x+_offsetPoint.x - _textField.scrollH; |
| var y:Number = rect1.y + rect1.height + 2; |
| var width:Number = rect2.x+rect2.width-rect1.x; |
| |
| // Avoid drawing outside the textField |
| if (x<0) |
| { |
| if (x+width > 0) { |
| width += x; |
| x = 0; |
| } |
| else |
| return; |
| } |
| if (x+width > _textField.width) |
| { |
| if (x < _textField.width) { |
| width = textField.width - x; |
| } |
| else |
| return; |
| } |
| |
| // The rectangle that bound the string you want |
| // actual work here. |
| var myShape:Shape = new Shape(); |
| myShape.graphics.clear(); |
| //myShape.graphics.beginFill(0x0099CC, .35); |
| myShape.graphics.lineStyle(1, 0xfa0707, .65); |
| myShape.graphics.moveTo(x, y); |
| var upDirection:Boolean = false; |
| var offset:uint = 0; |
| var stepLength:uint = 2; |
| for ( var i:uint = 1; offset <= width; i++) { |
| offset = offset + stepLength; |
| if ( upDirection ) |
| myShape.graphics.lineTo(x+offset,y); |
| else |
| myShape.graphics.lineTo(x+offset,y+stepLength); |
| upDirection = !upDirection; |
| } |
| //myShape.graphics.endFill(); |
| this.addChild(myShape); |
| } |
| } |
| |
| private function getValidFirstCharIndex(firstCharIndex:int):int{ |
| if(firstCharIndex<0 || firstCharIndex>_textField.text.length-1) |
| { |
| return InvalidIndexValue; |
| } |
| var firstLine:Number = _textField.getLineIndexOfChar(firstCharIndex); |
| |
| if(firstLine<_textField.scrollV-1) |
| { |
| firstLine = _textField.scrollV-1; |
| return _textField.getLineOffset(firstLine); |
| } |
| return firstCharIndex; |
| } |
| |
| private function getValidLastCharIndex(lastCharIndex:int):int{ |
| if(lastCharIndex<0 || lastCharIndex>_textField.text.length-1) |
| { |
| return InvalidIndexValue; |
| } |
| var lastLine:Number = _textField.getLineIndexOfChar(lastCharIndex); |
| if(lastLine>_textField.bottomScrollV-1) |
| { |
| lastLine = _textField.bottomScrollV-1; |
| return _textField.getLineOffset(lastLine)+_textField.getLineLength(lastLine)-1; |
| } |
| return lastCharIndex; |
| } |
| |
| public function set textField(tf:IUITextField):void{ |
| _textField = tf; |
| } |
| |
| public function get textField():IUITextField{ |
| return _textField; |
| } |
| |
| public function set offsetPoint(op:Point):void{ |
| _offsetPoint = op; |
| } |
| |
| public function get offsetPoint():Point{ |
| return _offsetPoint; |
| } |
| |
| |
| } |
| } |