スクリプトでカーソル移動可能なTextArea kacchan6 forked:1favorite:0lines:158license : see code comments modified : 2010-09-02 21:28:37 Embed Tweet <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*" creationComplete="init()"> <mx:Script> <![CDATA[ public var hoge:*; private function init():void { hoge = new MyText(); hoge.width = 300; hoge.height = 300; addChild(hoge); } ]]> </mx:Script> <mx:Button click="hoge.moveCursor(0, -1)" label="↑" focusEnabled="false"/> <mx:HBox> <mx:Button click="hoge.moveCursor(-1, 0)" label="←" focusEnabled="false"/> <mx:Button click="hoge.moveCursor(1, 0)" label="→" focusEnabled="false"/> </mx:HBox> <mx:Button click="hoge.moveCursor(0, 1)" label="↓" focusEnabled="false"/> <mx:Component className="MyText"> <mx:TextArea> <mx:Script> <![CDATA[ import mx.core.IUITextField; public function moveCursor(colOffset:int, rowOffset:int):void { //引数が全て0の場合は終了 if (colOffset === 0 && rowOffset === 0) { return; } //引数が全て0ではない場合は終了 if (colOffset !== 0 && rowOffset !== 0) { return; } //横方向への移動のみの場合 if (rowOffset === 0) { moveCursor0(colOffset); return; } //縦方向への移動 moveCursor1(rowOffset); } //カーソル位置設定 private function set caretIndex(value:int):void { textField.setSelection(value, value); } //カーソルを左右へ移動 private function moveCursor0(colOffset:int):void { //正規化 if (colOffset < -1) { colOffset = -1; } else if (colOffset > 1) { colOffset = 1; } //カーソル位置取得 var tf:IUITextField = textField; var index:int = tf.caretIndex; //オフセットを加算 index += colOffset; //境界チェック if (index < 0) { return; } else if (index > tf.length) { return; } //カーソル位置設定 caretIndex = index; } //カーソルを上下へ移動 private function moveCursor1(rowOffset:int):void { //正規化 if (rowOffset < -1) { rowOffset = -1; } else if (rowOffset > 1) { rowOffset = 1; } //カーソル位置取得 var tf:IUITextField = textField; var index:int = tf.caretIndex; //行番号取得 var rows:int = tf.numLines; var rowIndex:int = tf.getLineIndexOfChar(index); //末尾の場合は-1が返るので行数-1を設定 if (rowIndex === -1) { rowIndex = rows - 1; } //オフセットを加算 rowIndex += rowOffset; //境界チェック //先頭行で上の行が指定された場合はカーソルを先頭へ移動して終了 if (rowIndex < 0 && rowOffset === -1) { caretIndex = 0; return; } //末行で下の行が指定された場合はカーソルを末尾へ移動して終了 else if (rowIndex >= rows && rowOffset === 1) { caretIndex = tf.length; return; } //カーソル位置のXを取得 var x:Number; var rect:Rectangle = tf.getCharBoundaries(index); var textLine:TextLineMetrics; //カーソルが行末の場合はrectがnullになるので行の長さをカーソル位置とみなす if (rect === null) { textLine = tf.getLineMetrics(rowIndex - rowOffset); x = textLine.width; } else { x = rect.x; } //指定行の開始インデックスを求める var headIndex:int = tf.getLineOffset(rowIndex); //指定行のYの位置を求める rect = tf.getCharBoundaries(headIndex); //rectがnullの場合は文字がない行なのでその場所へカーソルを移動して終了 if (rect === null) { caretIndex = headIndex; return; } //X/Yからインデックスを求めて移動する var newIndex:int = tf.getCharIndexAtPoint(x, rect.y); if (newIndex === -1) { //インデックスが求められない場合 //先頭の場合はカーソルを先頭へ if (x === 0) { newIndex = headIndex; } //末尾の場合はカーソルを末尾へ else { newIndex = headIndex + tf.getLineLength(rowIndex) - 1; } } else { //移動先のXと移動元のXが被る場合、 //差分が文字幅/2を超えたときにインデックスを繰り上げる if (x - tf.getCharBoundaries(newIndex).x > rect.width / 2) { newIndex++; } } caretIndex = newIndex; } ]]> </mx:Script> </mx:TextArea> </mx:Component> <mx:Script> <![CDATA[ /* * Original */ /* package { import flash.geom.Rectangle; import flash.text.TextLineMetrics; import mx.controls.TextArea; import mx.core.IUITextField; public class MyTextArea extends TextArea { public function MyTextArea() { } public function moveCursor(colOffset:int, rowOffset:int):void { //引数が全て0の場合は終了 if (colOffset === 0 && rowOffset === 0) { return; } //引数が全て0ではない場合は終了 if (colOffset !== 0 && rowOffset !== 0) { return; } //横方向への移動のみの場合 if (rowOffset === 0) { moveCursor0(colOffset); return; } //縦方向への移動 moveCursor1(rowOffset); } //カーソル位置設定 private function set caretIndex(value:int):void { textField.setSelection(value, value); } //カーソルを左右へ移動 private function moveCursor0(colOffset:int):void { //正規化 if (colOffset < -1) { colOffset = -1; } else if (colOffset > 1) { colOffset = 1; } //カーソル位置取得 var tf:IUITextField = textField; var index:int = tf.caretIndex; //オフセットを加算 index += colOffset; //境界チェック if (index < 0) { return; } else if (index > tf.length) { return; } //カーソル位置設定 caretIndex = index; } //カーソルを上下へ移動 private function moveCursor1(rowOffset:int):void { //正規化 if (rowOffset < -1) { rowOffset = -1; } else if (rowOffset > 1) { rowOffset = 1; } //カーソル位置取得 var tf:IUITextField = textField; var index:int = tf.caretIndex; //行番号取得 var rows:int = tf.numLines; var rowIndex:int = tf.getLineIndexOfChar(index); //末尾の場合は-1が返るので行数-1を設定 if (rowIndex === -1) { rowIndex = rows - 1; } //オフセットを加算 rowIndex += rowOffset; //境界チェック //先頭行で上の行が指定された場合はカーソルを先頭へ移動して終了 if (rowIndex < 0 && rowOffset === -1) { caretIndex = 0; return; } //末行で下の行が指定された場合はカーソルを末尾へ移動して終了 else if (rowIndex >= rows && rowOffset === 1) { caretIndex = tf.length; return; } //カーソル位置のXを取得 var x:Number; var rect:Rectangle = tf.getCharBoundaries(index); var textLine:TextLineMetrics; //カーソルが行末の場合はrectがnullになるので行の長さをカーソル位置とみなす if (rect === null) { textLine = tf.getLineMetrics(rowIndex - rowOffset); x = textLine.width; } else { x = rect.x; } //指定行の開始インデックスを求める var headIndex:int = tf.getLineOffset(rowIndex); //指定行のYの位置を求める rect = tf.getCharBoundaries(headIndex); //rectがnullの場合は文字がない行なのでその場所へカーソルを移動して終了 if (rect === null) { caretIndex = headIndex; return; } //X/Yからインデックスを求めて移動する var newIndex:int = tf.getCharIndexAtPoint(x, rect.y); if (newIndex === -1) { //インデックスが求められない場合 //先頭の場合はカーソルを先頭へ if (x === 0) { newIndex = headIndex; } //末尾の場合はカーソルを末尾へ else { newIndex = headIndex + tf.getLineLength(rowIndex) - 1; } } else { //移動先のXと移動元のXが被る場合、 //差分が文字幅/2を超えたときにインデックスを繰り上げる if (x - tf.getCharBoundaries(newIndex).x > rect.width / 2) { newIndex++; } } caretIndex = newIndex; } } } */ ]]> </mx:Script> </mx:Application> Code Fullscreen Preview Fullscreen TextArea TextField caretIndex caretIndex getCharBoundaries width getLineIndexOfChar numLines getLineOffset getLineMetrics getLineLength getCharIndexAtPoint setSelection length Number int sort new page view favorite forked pv0 forked from: スクリプトでカーソル移動可能なTe.. s.0samu0320 forked:0 favorite:0lines:159 (diff:1)