ActionScript3でUIコンポーネントを作ってみる

ActionScript3からFlexのUIって使えないんですか!そんな・・・

仕方がないので勉強も兼ねて自分で作るさ作るさ。
めちゃめちゃリファレンスとにらめっこしたお。
AdobeのLiveDocs重いからリファレンス本買おうかな。。。

まずは、何はともあれリンクテキストですよね!

  • LinkText.as
package jp.cheesepie.ui {
  import flash.display.Sprite;
  import flash.text.TextField;
  import jp.cheesepie.ui.view.ViewLinkText;
  import jp.cheesepie.ui.ctrl.ControlLinkText;

  public class LinkText extends Sprite {
    private var tf:ViewLinkText;
    private var txtFormats:Array;
    private var colors:Array;

    public function LinkText(txt:String="", txtSize:Number=18, txtColor:uint=0x0033CC, onHoverColor:uint=0xff3333, txtFont:String="_ゴシック", underline:Boolean=true, bold:Boolean=false, italic:Boolean=false) {
      txtFormats = [txt, txtSize, txtColor, txtFont, underline, bold, italic];
      colors = [onHoverColor, txtColor];
      init(txtFormats);
    }

    private function init(txtFormats:Array):void {
      tf = new ControlLinkText(new ViewLinkText(txtFormats), colors).setEvents();
      addChild(tf);
    }
  }
}

後でいろいろ変えやすいように、見た目はViewLinkText.asで、イベントやら何やらの設定はControlLinkText.asで定義することにした。

  • ViewLinkText.as
package jp.cheesepie.ui.view {
  import flash.display.Sprite;
  import flash.text.*;

  public class ViewLinkText extends Sprite {
    public var txtF:TextField;

    public function ViewLinkText(txtFormats:Array) {
      txtF = new TextField();
      txtF.text = txtFormats[0];
      txtF.width = txtF.textWidth + 10;
      txtF.height = txtF.textHeight + 3;
      txtF.setTextFormat(textFormat(txtFormats));
      txtF.mouseEnabled = false;
      this.buttonMode = true;
      addChild(txtF);
    }

    private function textFormat(arr:Array):TextFormat {
      var format:TextFormat = new TextFormat();
      format.font = arr[3];
      format.color = arr[2];
      format.underline = arr[4];
      format.bold = arr[5];
      format.italic = arr[6];
      return format;
    }
  }
}

引数で受け取った設定を突っ込んでるだけ。
ただ、リンクなのでマウス乗せたときにカーソルをポインターにしようと思って

txtF.useHandCursor = true;

ってやってもカーソルが変わらないのでググったら、mouseEnabledにtrue入れればよかったんですね。。。

  • ControlLinkText.as
package jp.cheesepie.ui.ctrl {
  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.events.MouseEvent;
  import jp.cheesepie.ui.view.ViewLinkText;

  public class ControlLinkText {
    private var vtb:ViewLinkText;
    private var colors:Array;

    public function ControlLinkText(vtb:ViewLinkText, colors:Array) {
      this.vtb = vtb;
      this.colors = colors;
      init(vtb);
    }

    private function init(vtb:ViewLinkText):void {
      setEvents();
    }

    public function setEvents():ViewLinkText {
      vtb.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
      vtb.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
      return vtb;
    }

    private function onMouseOver(event:MouseEvent):void {
      vtb.txtF.textColor = colors[0];
    }

    private function onMouseOut(event:MouseEvent):void {
      vtb.txtF.textColor = colors[1];
    }
  }
}

リンクテキストなので、マウスを乗せたらテキストの色を変える。

動作確認用

  • TextLinkText.as
package {
  import flash.display.Sprite;
  import jp.cheesepie.ui.LinkText;

  public class TestLinkText extends Sprite {
    private var linktext:LinkText;

    public function TestLinkText() {
      init();
    }

    private function init():void {
      linktext = new LinkText("HogeHoge");
      linktext.x = 100;
      linktext.y = 50;
      addChild(linktext);
    }
  }
}


続いてテキストボックス!

  • TextBox.as
package jp.cheesepie.ui {
  import flash.display.Sprite;
  import flash.text.TextField;
  import jp.cheesepie.ui.view.ViewTextBox;
  import jp.cheesepie.ui.ctrl.ControlTextBox;

  public class TextBox extends Sprite {
    private var tf:ViewTextBox;
    private var txtFormats:Array;
    private var colors:Array;

    public function TextBox(tfSize:Number=200, color:uint=0x333333, txtSize:Number=18, txtFont:String="_ゴシック", bold:Boolean=false, italic:Boolean=false, activeColor:uint=0xffffff, bgColor:uint=0xdddddd, borderColor:uint=0x999999) {
      txtFormats = [tfSize, txtFont, txtSize, color, bold, italic, bgColor, borderColor];
      colors = [activeColor, bgColor];
      init(txtFormats);
    }

    private function init(txtFormats:Array):void {
      tf = new ControlTextBox(new ViewTextBox(txtFormats), colors).setEvents();
      addChild(tf);
    }
  }
}

ほとんどリンクテキストと変わらない・・あとでまとめられるところまとめようかな。

  • ViewTextBox.as
package jp.cheesepie.ui.view {
  import flash.display.Sprite;
  import flash.text.*;

  public class ViewTextBox extends Sprite {
    public var txtF:TextField;

    public function ViewTextBox(labelArr:Array) {
      txtF = new TextField();
      txtF.width = labelArr[0];
      txtF.height = 22;
      txtF.background = true;
      txtF.backgroundColor = labelArr[6];
      txtF.border = true;
      txtF.borderColor = labelArr[7];
      txtF.type = TextFieldType.INPUT;
      txtF.setTextFormat(textFormat(labelArr));
      addChild(txtF);
    }

    private function textFormat(arr:Array):TextFormat {
      var format:TextFormat = new TextFormat();
      format.font = arr[1];
      format.size = arr[2];
      format.color = arr[3];
      format.bold = arr[4];
      format.italic = arr[5];
      return format;
    }
  }
}

TextFieldType.INPUTをtypeに指定すると、テキストフィールドが編集可能になる。
テキストフィールドに1文字分の高さを設定すればテキストボックスのできあがり!
ちなみに、「txtF.multiline = true;」を指定すると、複数行編集可能になるので高さ(rowsに相当)を増やせばテキストエリアになりますね。

  • ControlTextBox.as
package jp.cheesepie.ui.ctrl {
  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.events.FocusEvent;
  import jp.cheesepie.ui.view.ViewTextBox;

  public class ControlTextBox {
    private var vtb:ViewTextBox;
    private var colors:Array;

    public function ControlTextBox(vtb:ViewTextBox, colors:Array) {
      this.vtb = vtb;
      this.colors = colors;
      init(vtb);
    }

    private function init(vtb:ViewTextBox):void {
      setEvents();
    }

    public function setEvents():ViewTextBox {
      vtb.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
      vtb.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
      return vtb;
    }

    private function onFocusIn(event:FocusEvent):void {
      vtb.txtF.backgroundColor = colors[0];
    }

    private function onFocusOut(event:FocusEvent):void {
      vtb.txtF.backgroundColor = colors[1];
    }
  }
}

フォーカスが当たると背景色変わります。見た目アクティブっぽくしてみました。

動作確認用
TestTextBox.as

package {
  import flash.display.Sprite;
  import jp.cheesepie.ui.TextBox;

  public class TestTextBox extends Sprite {
    private var textbox:TextBox;

    public function TestTextBox() {
      init();
    }

    private function init():void {
      textbox = new TextBox(200);
      textbox.x = 100;
      textbox.y = 50;
      addChild(textbox);
    }
  }
}