forked from: TextFieldを改行とTab入力できるようにした

by tepe forked from TextFieldを改行とTab入力できるようにした (diff: 215)
♥0 | Line 284 | Modified 2012-05-20 10:55:06 | MIT License
play

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;
            }
            

        }

    }