PushButton の雛形

次のような感じだと思う。
PushButton の状態には、up, over, down ともうひとつ、ボタン押したままでボタンの枠外にマウスが外れたときの状態 (downout?) が必要。なんというかボタンごときでなんでこんなに複雑なんだろ。
http://park.geocities.jp/mxmlc/misc/PushButtonTest.html

// PushButton.as

package {
  import flash.display.*;
  import flash.text.*;
  import flash.events.*;

  public class PushButton extends Sprite {

    private var _state:int;
    private static const UP:int = 0;
    private static const OVER:int = 1;
    private static const DOWN:int = 2;
    private static const DOWNOUT:int = 3;

    public function PushButton():void {
      graphics.beginFill(0xFF8888, 1.0);
      graphics.drawRoundRect(0, 0, 100, 20, 4,4);
      graphics.endFill();

      state = UP;
      addEventListener(MouseEvent.ROLL_OVER, onRollOver);
      addEventListener(MouseEvent.ROLL_OUT, onRollOut);
      addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
      addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    }
    private function onMouseDown(ev:MouseEvent):void {
      state = DOWN;
    }
    private function stageMouseUp(ev:MouseEvent):void {
      if (state == DOWNOUT) {
        stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
      }
      state = UP;
    }
    private function onMouseUp(ev:MouseEvent):void {
      state = OVER;
    }
    private function onRollOver(ev:MouseEvent):void {
      if (ev.buttonDown) {
        if (state == DOWNOUT) {
          state = DOWN;
          stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
        } else {
          state = UP;
        }
      } else {
        state = OVER;
      }
    }
    private function onRollOut(ev:MouseEvent):void {
      if (state == DOWN) {
        state = DOWNOUT;
        stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
      } else {
        state = UP;
      }
    }

    private function set state(val:int):void {

      import flash.filters.*;
      var gf_up:Array = [new GlowFilter(0x888888, 0.3, 1,1, 3)];
      var gf_over:Array = [new GlowFilter(0x888888, 0.3, 4,4, 6)];
      var gf_down:Array = [new GlowFilter(0xFF0000, 0.5, 8,8, 2)];
      var gf_downout:Array = [new GlowFilter(0xFF0000, 0.5, 4,4, 2)];
      _state = val;
      switch (val) {
        case UP:
          filters = gf_up;
          break;
        case OVER:
            filters = gf_over;
          break;
        case DOWN:
            filters = gf_down;
          break;
        case DOWNOUT:
            filters = gf_downout;
          break;
      }
    }
    private function get state():int { return _state; }
  }
}