setSelection (no scroll)
/**
* Copyright 9re ( http://wonderfl.net/user/9re )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/W6CP
*/
// forked from 9re's show caret index
// forked from 9re's MyCaretIndex, selectionBeginIndex, selectionEndIndex
package {
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.geom.Rectangle;
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldType;
public class TextField_caretIndex extends Sprite {
private var outputField:TextField;
private var tf:MyTextField;
protected var caret:MyCaret;
public function TextField_caretIndex() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addChild(outputField = createCustomTextField(10, 200, 100, 100));
tf = new MyTextField;
tf.trace = trace;
tf.selectionColor = 0xff4040;
tf.defaultTextFormat = new TextFormat('_typewriter');
tf.x = 10;
tf.y = 10;
tf.width = 120;
addChild(tf);
tf.text = "Click or select this text field. Caret will move to the position you click and the selected area is marked red.";
//tf.addEventListener(MouseEvent.CLICK, printCursorPosition);
tf.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
//tf.selectable = false;0
}
public function trace(...arguments:Array):void {
outputField.appendText(arguments + "\n");
outputField.scrollV = outputField.maxScrollV;
outputField.width = outputField.textWidth + 4;
}
private function printCursorPosition(event:MouseEvent):void {
var tf:TextField = TextField(event.target);
trace("caretIndex:", tf.caretIndex);
}
private function createCustomTextField(x:Number, y:Number, width:Number, height:Number):TextField {
var result:TextField = new TextField();
result.x = x;
result.y = y;
result.width = width;
result.height = height;
addChild(result);
return result;
}
}
}
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.setTimeout;
// jp.psyark.psycode.controls.UIControl
class UIControl extends Sprite {
private var _width:Number = 100;
private var _height:Number = 100;
/**
* コントロールの幅と高さ設定します。
*/
public function setSize(width:Number, height:Number):void {
if (_width != width || _height != height) {
_width = width;
_height = height;
updateSize();
}
}
/**
* コントロールの幅を取得または設定します。
*/
public override function get width():Number {
return _width;
}
/**
* @private
*/
public override function set width(value:Number):void {
if (_width != value) {
_width = value;
updateSize();
}
}
/**
* コントロールの高さを取得または設定します。
*/
public override function get height():Number {
return _height;
}
/**
* @private
*/
public override function set height(value:Number):void {
if (_height != value) {
_height = value;
updateSize();
}
}
/**
* コントロールのサイズを更新します。
*/
protected function updateSize():void {
}
}
class MyCaret extends Sprite {
private var _height:Number;
private var _width:Number;
private var _color:int;
private var _count:int;
private var _hide:Boolean = false;
private const INTERVAL:int = 30;
public function MyCaret($h:int, $color:uint) {
_color = $color;
setSize(2, $h);
addEventListener(Event.ENTER_FRAME, updateCaret);
}
private function updateCaret(e:Event):void
{
if (_hide) return;
_count = ++_count % INTERVAL;
visible = _count < (INTERVAL >> 1);
}
public function setSize(w:Number, h:Number):void {
_width = w;
_height = h;
draw();
}
public function show():void {
_count = 0;
_hide = false;
}
public function hide():void {
_hide = true;
visible = false;
}
private function draw():void {
graphics.clear();
graphics.beginFill(_color);
graphics.drawRect(0, 0, _width, _height);
graphics.endFill();
show();
}
}
class MyTextField extends UIControl {
private var _textField:TextField;
private var _caret:MyCaret;
private var _caretIndex:int;
private var _selectionBeginIndex:int;
private var _selectionEndIndex:int;
private var _mouseDownIndex:int;
private var _caretPos:Point;
private var _selectionColor:uint = 0xffffff;
public function MyTextField () {
_textField = new TextField;
//_textField.background = true;
_textField.selectable = false;
_textField.mouseEnabled = _textField.mouseWheelEnabled = false;
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
addChild(_textField);
addChild(_caret = new MyCaret(13, 0));
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
}
private function onMouseLeave(e:Event):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
public function set defaultTextFormat(value:TextFormat):void {
_textField.defaultTextFormat = value;
setZeroPos();
}
private function setZeroPos():void {
var str:String = _textField.text;
_textField.text = 'A';
var rect:Rectangle = _textField.getCharBoundaries(0);
_caret.x = rect.x;
_caret.y = rect.y + 2;
_textField.text = str;
}
public function getCharIndexFromMousePoint():int {
var i:int = _textField.getCharIndexAtPoint(mouseX, mouseY);
var line:int;
if (i < 0) {
line = _textField.getLineIndexAtPoint(mouseX, mouseY);
if (line < 0) return -1;
i = _textField.getLineOffset(line) + _textField.getLineLength(line) - 1;
if (i == _textField.length - 1)
i = _textField.length;
}
return i;
}
public function set text(value:String):void {
_textField.wordWrap = true;
_textField.text = value;
_textField.height = _textField.textHeight + 4;
}
public function set selectionColor(value:uint):void
{
_selectionColor = value;
}
public var trace:Function;
private function onMouseDown(e:MouseEvent):void {
_mouseDownIndex = getCharIndexFromMousePoint();
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseUp(e:MouseEvent):void {
onMouseMove(null);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseMove(e:MouseEvent):void
{
setSelection(_mouseDownIndex, getCharIndexFromMousePoint());
}
public function setSelection($selectionBeginIndex:int, $selectionEndIndex:int):void {
var b:int, bb:Rectangle;
var e:int, eb:Rectangle;
graphics.clear();
if ($selectionBeginIndex == $selectionEndIndex) {
showCaret($selectionBeginIndex);
return;
}
//_caret.hide();
if ($selectionBeginIndex < $selectionEndIndex) {
b = $selectionBeginIndex;
e = $selectionEndIndex;
} else {
b = $selectionEndIndex;
e = $selectionBeginIndex;
}
_selectionBeginIndex = b;
_selectionEndIndex = _caretIndex = e;
bb = getCaretBoundary(b);
eb = getCaretBoundary(e);
trace("selection", b, e);
e = (e == _textField.length) ? --e : e;
b = _textField.getLineIndexOfChar(b);
e = _textField.getLineIndexOfChar(e);
trace("line offsets", b, e);
graphics.beginFill(_selectionColor);
// assert b <= e
if (b < e) {
graphics.drawRect(bb.x, bb.y, width - bb.x, bb.height);
graphics.drawRect(0, bb.y + bb.height, width, eb.y - bb.y - bb.height);
graphics.drawRect(0, eb.y, eb.x, eb.height);
} else { // b == c
graphics.drawRect(bb.x, bb.y, eb.x - bb.x, bb.height);
}
showCaret(_caretIndex);
}
private function getCaretBoundary(i:int):Rectangle {
var rect:Rectangle;
i = (i < 0) ? 0 : i;
if (i < _textField.length) {
rect = _textField.getCharBoundaries(i);
} else {
trace('getCaretBoundary: else:');
rect = _textField.getCharBoundaries(_textField.length - 1);
rect.x += rect.width + 2;
}
return rect;
}
private function getCaretPos(i:int):Point {
return getCaretBoundary(i).topLeft;
}
private function showCaret(i:int):void
{
var pos:Point = getCaretPos(i);
_caret.x = pos.x;
_caret.y = pos.y + 2;
_caret.show();
}
override protected function updateSize():void
{
_textField.width = width;
_textField.height = height;
}
}