forked from: TextFieldを改行とTab入力できるようにした
forked from TextFieldを改行とTab入力できるようにした (diff: 215)
ActionScript3 source code
/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wwEM
*/
// forked from tepe's TextFieldを改行とTab入力できるようにした
package {
import flash.display.*;
import flash.text.*;
import flash.system.*;
import flash.events.*;
public class FlashTest extends Sprite {
private var s:Sprite = new Sprite();
private var editer:TextEditer = new TextEditer();
private var words:Array = new Array();
private var txt1:TextField = new TextField();
private var word:Array = new Array();
private var txt2:TextField = new TextField();
private var newFormat:TextFormat = new TextFormat();
public function FlashTest() {
//適用するフォーマットの設定
newFormat.size = 20;
newFormat.font = "Arial";
newFormat.color = 0xff0000;
newFormat.italic = true;
txt2.x = 300;
txt2.height =400;
txt2.border =true;
txt2.type = "input";
txt1.x = 100;
txt1.y=430;
txt1.text = "aaa";
txt1.textColor = 0xff0000;
addChild(txt1);
addChild(s);
s.tabChildren = false;//タブ入力に対応するためには全体でtab移動を無効にする必要がある。
editer.width = 400;
editer.height = 400;
editer.border = true;
s.addChild(editer);
s.addChild(txt2);
//IME.conversionMode = "JAPANESE_HIRAGANA";
//IME.conversionMode = "ALPHANUMERIC_FULL";
//IME.conversionMode = "KOREAN";
//editer.text = IME.conversionMode;
addEventListener(KeyboardEvent.KEY_UP,onKey);
addEventListener(MouseEvent.CLICK,function():void{
//stage.displayState = StageDisplayState.FULL_SCREEN;//フルスクリーンモード
});
}
//テキストをトークンに分割
private function func12(source:String):Array{
var obj:Object = new Object();
var re:RegExp = /[ \!\"\#\$\%\&\'\(\)\-\=\+\*\;\:\~\^\|\[\]\{\}\,\.\<\>\?\n\r\t\/\\]/gsm;
var re2:RegExp = /[a]/gsm;
var token:String;
var ar:Array = new Array();
var cnt:int = 0;
var index:int = 0;
while(1){
obj = re2.exec(source);
if(obj == null)break;
ar.push(obj.input);
cnt++;
if(100<cnt)break;
}
return ar;
}
//英数字のみで構成された文字列を取得
private function func03(str:String):Array{
var re:RegExp = /[^a-zA-Z0-9_.]/;
var ar:Array;
ar = str.split(re);
return ar;
}
//コメント除外
private function func09(source:String):String{
var out:String = "";
var index:int = 0;
var stIndex:int;
var endIndex:int;
var comSt1:RegExp = /\/\//g;//一行コメント開始位置
var comEnd1:RegExp = /[\n\r]/g;// 一行コメント終了位置
var comSt2:RegExp = /\/\*/gsm;//複数行コメント開始位置
var comEnd2:RegExp = /\*\//gsm;//複数コメント終了位置
var st1:Object = new Object();
var st2:Object = new Object();
var end:Object = new Object();
var cnt:int = 0;
var a:int,b:int;
while(1){
st1 = comSt1.exec(source);
if(st1 == null)a=source.length;
else a = st1.index;
st2 = comSt2.exec(source);
if(st2 == null)b=source.length;
else b = st2.index;
if(a == b){//走査終了
out+=source.substring(index,source.length);
break;
}
else if(a < b){//一行コメント
comEnd1.lastIndex = a;
end = comEnd1.exec(source);
if(end == null)endIndex = source.length;
else endIndex = end.index;
stIndex = a;
out += source.substring(index,stIndex);
}
else{//複数行コメント
comEnd2.lastIndex = b;
end = comEnd2.exec(source);
if(end == null)endIndex = source.length;
else endIndex = end.index+2;
stIndex = b;
out += source.substring(index,stIndex);
}
index = endIndex;
comSt1.lastIndex = comSt2.lastIndex = index;
cnt++;
if(100<cnt)break;
}
return out;
}
//コメントリスト取得
private function func11(source:String):Array{
var obj:Object;
var index:int = 0;
var stIndex:int;
var endIndex:int;
var ar:Array = new Array();
var comSt1:RegExp = /\/\//g;//一行コメント開始位置
var comEnd1:RegExp = /[\n\r]/g;// 一行コメント終了位置
var comSt2:RegExp = /\/\*/gsm;//複数行コメント開始位置
var comEnd2:RegExp = /\*\//gsm;//複数コメント終了位置
var st1:Object = new Object();
var st2:Object = new Object();
var end:Object = new Object();
var cnt:int = 0;
var a:int,b:int;
while(1){
st1 = comSt1.exec(source);
if(st1 == null)a=source.length;
else a = st1.index;
st2 = comSt2.exec(source);
if(st2 == null)b=source.length;
else b = st2.index;
if(a == b){//走査終了
break;
}
else if(a < b){//一行コメント
comEnd1.lastIndex = a;
end = comEnd1.exec(source);
if(end == null)endIndex = source.length;
else endIndex = end.index;
stIndex = a;
obj = new Object();
obj.text = source.substring(stIndex+2,endIndex);
obj.index = stIndex;
obj.lastIndex = endIndex;
ar.push(obj);
}
else{//複数行コメント
comEnd2.lastIndex = b;
end = comEnd2.exec(source);
if(end == null)endIndex = source.length;
else endIndex = end.index+2;
stIndex = b;
obj = new Object();
obj.text = source.substring(stIndex+2,endIndex-2);
obj.index = stIndex;
obj.lastIndex = endIndex;
ar.push(obj);
}
index = endIndex;
comSt1.lastIndex = comSt2.lastIndex = index;
cnt++;
if(100<cnt)break;
}
return ar;
}
private function onKey(e:Event):void{
//txt2.text = func09(editer.text);
var ar1:Array = new Array();
//ar1 = func11(editer.text);
ar1 = func12(editer.text);
txt1.text = "";
for(var i:int=0;i<ar1.length;i++){
txt2.appendText(ar1[i].text);
txt2.appendText("\n");
}
}
}
}
////////////////////////////////////////////////////////////////////////
// TextEditer class
////////////////////////////////////////////////////////////////////////
import flash.text.*;
import flash.ui.*;
import flash.events.*;
import flash.net.*;
import flash.system.*;
class TextEditer extends TextField {
private var file:FileReference;
private var prevText:Object;
private var nextText:Object;
public function TextEditer():void {
System.useCodePage = true;//UNICODE以外のテキストファイルをロードする場合 true
this.type = "input";//入力可能
this.mouseWheelEnabled = false;//デフォルトではホイールスクロールOFF
//this.tabEnabled = true;
this.selectable = false;
this.addEventListener(KeyboardEvent.KEY_DOWN, onKey);
addEventListener(MouseEvent.CLICK, onFocus);
addEventListener(MouseEvent.MOUSE_WHEEL,onWheel);
//コンテキストメニュー@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
var menu1:ContextMenuItem = new ContextMenuItem("ファイルを開く");
menu1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void {
//txt.appendText("menu");
load();
});
var menu2:ContextMenuItem = new ContextMenuItem("ファイルを保存");
menu2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void {
save();
});
contextMenu = new ContextMenu();
contextMenu.hideBuiltInItems();
contextMenu.customItems = [menu1,menu2];
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
private function onWheel(e:MouseEvent):void{
e.stopPropagation();
}
//改行コードの統一 (CR+LF or CR) → LF
private function unifyLineFeedCode(str:String):String {
var CR:String = String.fromCharCode(13);
var LF:String = String.fromCharCode(10);
str = str.split(CR+LF).join(LF);
str = str.split(CR).join(LF);
return str;
}
//セーブ
public function save():void {
var fileRef:FileReference = new FileReference();
fileRef.save(this.text, this.name);
}
//ファイルロード
public function load():void {//ファイル選択 ①
file = new FileReference();
file.addEventListener(Event.COMPLETE, onLoaded);
file.addEventListener(Event.SELECT, onSelect);
file.browse();
}
private function onSelect(e:Event):void{//ロード開始 ②
file.load();
}
private function onLoaded(e:Event):void {//ロード完了 ③
this.name = file.name;
var byte:int = file.data.length;
var byte2:uint;
//txt.text = String(file.data);
this.text = unifyLineFeedCode(file.data.toString());//改行コード統一
file.removeEventListener(Event.COMPLETE, onLoaded);
file.removeEventListener(Event.SELECT, onSelect);
}
//編集モード終了
private function outFocus(e:FocusEvent):void {
this.selectable = false;
removeEventListener(FocusEvent.FOCUS_OUT, outFocus);
removeEventListener(MouseEvent.MOUSE_DOWN, dragCansel);
addEventListener(MouseEvent.MOUSE_DOWN, onFocus);
//this.appendText(" Out ");
}
//編集モード開始
private function onFocus(e:MouseEvent):void {
this.selectable = true;
addEventListener(FocusEvent.FOCUS_OUT, outFocus);
removeEventListener(MouseEvent.MOUSE_DOWN, onFocus);
addEventListener(MouseEvent.MOUSE_DOWN, dragCansel);
//this.appendText(" In ");
//e.stopPropagation();
}
private function dragCansel(e:MouseEvent):void {
e.stopPropagation();
}
//キー入力
private function onKey(e:KeyboardEvent):void {
var sw:Boolean;
var str1:String;
var str2:String;
// エンターキーの状態
if (e.keyCode == 13) sw = true;
else if (e.keyCode == 108) sw = true;
else sw = false;
//キャレット位置に改行文字を挿入
if(sw == true){
str1 = this.text.substring(0, this.caretIndex);
str2 = this.text.substring(this.caretIndex, this.length);
this.text = str1;
this.appendText("\n");//キャレット位置で改行
//インデント構造(タブ&スペースの構成)を調べる
var indent:int=0;
var prevReturn:int = this.text.lastIndexOf('\r', this.caretIndex-1);//前回の改行位置
//一つ前の改行直後に続くタブコードの数=インデント深度
for (var j:int = prevReturn+1; j < this.caretIndex; j++) {
if (this.text.charAt(j) == '\t' || this.text.charAt(j) == ' ' ) indent++;
else break;
}
//上の行のインデントに従う
var indentStr:String = this.text.slice(prevReturn + 1, prevReturn + 1 + indent);
this.appendText(indentStr);//インデント
this.text += str2;//結合
//キャレット位置をインクリメント
this.setSelection(this.caretIndex +indent + 1, this.caretIndex +indent + 1);
return;
}
//tab
if (e.keyCode == 9) {
str1 = this.text.substring(0, this.caretIndex);
str2 = this.text.substring(this.caretIndex, this.length);
this.text = str1 + '\t' + str2;
//キャレット位置をインクリメント
this.setSelection(this.caretIndex + 1, this.caretIndex + 1);
return;
}
}
}