ラベル FeathersExample の投稿を表示しています。 すべての投稿を表示
ラベル FeathersExample の投稿を表示しています。 すべての投稿を表示

2013年3月29日金曜日

Feathers PopUpManager サンプル

PopUpManagerクラスのAPIDocumentは(リンク先へ)

実用例の動画です。

PopUpManagerはFlexにもありましたが、使用方法もほぼ一緒です。

PopUpManagerクラスを利用してみます。

PopupWindowコンポーネント

使用クラス
  protected var theme:MetalWorksMobileTheme;
  private var popUpWindow:PopUpWindow;

  private function doPopUpWindow():void
  {
   this.theme = new MetalWorksMobileTheme(this.stage);

   popUpWindow = new PopUpWindow();
   popUpWindow.addEventListener(PopUpWindow.WINDOW_CLOSE,popUpWindowCloseHandler);
   popUpWindow.width = 320;
   popUpWindow.height = 240;

   PopUpManager.addPopUp(popUpWindow);
  }

  private function popUpWindowCloseHandler(event:Event):void
  {
   PopUpManager.removePopUp(popUpWindow);
   popUpWindow.dispose();
  }

PopUpWindow.as
package controls
{
 import feathers.controls.Button;
 import feathers.core.FeathersControl;
 import feathers.display.Scale9Image;
 import feathers.textures.Scale9Textures;

 import flash.geom.Rectangle;

 import starling.animation.Transitions;
 import starling.core.Starling;
 import starling.events.Event;
 import starling.textures.Texture;

 public class PopUpWindow extends FeathersControl
 {
  [Embed(source="./assets/scale9.png")]
  private static const SCALE_9_TEXTURE:Class;

  public static const WINDOW_CLOSE:String = "windowClose";

  public function PopUpWindow()
  {
   super();
  }

  private var okButton:Button;
  private var bg:Scale9Image;

  override protected function initialize():void
  {
   var texture:Texture = Texture.fromBitmap(new SCALE_9_TEXTURE(), false);
   var textures:Scale9Textures = new Scale9Textures(texture,new Rectangle(20, 20, 20, 20));

   bg = new Scale9Image(textures, 1);
   bg.width = width;
   bg.height = height;
   bg.x = bg.pivotX = width >> 1;
   bg.y = bg.pivotY = height >> 1;
   addChild(bg);

   okButton = new Button();
   okButton.label = "Ok";
   okButton.width = 100;
   okButton.height = 48
   addChild(okButton);
   okButton.x = (bg.width >> 1) - (okButton.width >> 1);
   okButton.y = (bg.height >> 1) - (okButton.height >> 1);
   okButton.addEventListener(Event.TRIGGERED, button_triggeredHandler);

   Starling.juggler.tween(bg, 1,
    {
     transition: Transitions.EASE_OUT_BOUNCE,
     onStart:tweenStartHandler,
     onComplete:tweenCompleteHandler,
     scaleX: 1,
     scaleY: 1
    });
  }

  private function button_triggeredHandler(event:Event):void
  {
   dispatchEventWith(WINDOW_CLOSE);            
  }

  private function tweenStartHandler():void
  {
   okButton.visible = false;
   bg.scaleX = 0;
   bg.scaleY = 0;
  }

  private function tweenCompleteHandler():void
  {
   okButton.visible = true;
  }

  override public function dispose():void
  {
   bg.dispose();
   okButton.dispose();
   removeChildren();

   super.dispose();
  }

 }
}
Windowで使用する9Scale用の素材

2013年2月5日火曜日

Feathers Example ItemRendererについて

このサンプルはFeathersのサイト
「Creating custom item renderers for the Feathers List control(リンク先へ) 」
を参考にしています。
FeathersExampleのソースコード(リンク先へ)

アイテムレンダラクラスでは、ListクラスからdataProviderで設定した配列の情報を
元に1件毎に表示するリストアイテムのレイアウトを行う事ができます。
アイテムレンダラーはapache Flex(旧Adobe Flex)でも採用しています。

BasicItemRenderer.as
  override protected function initialize():void
  {
   if(!this.itemBG)
   {
    this.itemBG = new Quad(1,1,Math.floor(Math.random() * 0xffffff));
    this.addChild(this.itemBG);
   }

   if(!this.itemLabel)
   {
    this.itemLabel = new Label();
    this.addChild(this.itemLabel);
   }
  }
アイテム内のBGとラベルの初期化をします

BasicItemRenderer.as
  protected function layout():void
  {
   this.itemBG.width = this.actualWidth;
   this.itemBG.height = this.actualHeight;

   this.itemLabel.width = this.actualWidth;
   this.itemLabel.height = this.actualHeight;
   this.itemLabel.y = (this.actualHeight / 2) - (this.itemLabel.y / 2);
  }
アイテム内のBGとラベルの大きさ、配置を設定します

BasicItemRenderer.as
  protected function commitData():void
  {
   if(this._data)
   {
    this.itemLabel.text = this._data.text.toString();
   } else {
    this.itemLabel.text = "";
   }
  }
アイテム内のラベルの表示情報を設定します

Feathers Example Listについて

このサンプルはFeathersのサイト
「How to use the Feathers List component(リンク先へ) 」
を参考にしています。
FeathersExampleのソースコード(リンク先へ)

FeathersExampleを実行すると以下の画面になります

Listの表示と設定の流れ
ボタンサンプルからListサンプルへ表示を切り替える為に
exampleIndexの値を変更します。
FeathersExample.as
  private function loaderInfo_completeHandler(event:Event):void
  {
   var exampleIndex:int;
   Starling.handleLostContext = true;
   Starling.multitouchEnabled = true;

   exampleIndex = 1;
ListExample.as
   this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);

   this.theme = new MetalWorksMobileTheme(this.stage);

   var list:List = new List();
   list.width = this.stage.stageWidth;
   list.height = this.stage.stageHeight;
   this.addChild(list);

   var listData:Object;
   var listTable:Array = [];
   for(var i:int=0;i<1000;i++)
   {
    listData = { text : i.toString()+":"+"アイテム" };
    listTable.push(listData);
   }
   var groceryList:ListCollection = new ListCollection(listTable);
   list.dataProvider = groceryList;
   list.itemRendererProperties.labelField = "text";
   list.itemRendererType = BasicItemRenderer;

  • テーマの設定
  • インスタンスの作成
  • レイアウト、大きさの設定
  • 画面に対してaddChildを行う
  • リストに表示する1件単位のリストデータを作成
  • ListCollectionの作成
  • dataProviderの設定
  • labelFieldプロパティの設定
  • アイテムレンダラの設定


  • Feathers Example ボタンスキンの変更

    このサンプルはFeathersのサイト
    「Extending Feathers Themes(リンク先へ)
    を参考にしています。

    スキンの状態を赤青緑の矩形に変更してみます。


    スキン用の矩形




    FeathersThemeライブラリプロジェクトにスキン用の矩形と
    カスタムテーマExtendMetalWorksThemeを追加します。

    ExtendMetalWorksTheme.as
    package feathers.themes
    {
     import feathers.controls.Button;
     import feathers.themes.MetalWorksMobileTheme;
    
     import starling.display.DisplayObjectContainer;
     import starling.display.Image;
     import starling.textures.Texture;
    
     public class ExtendMetalWorksTheme extends MetalWorksMobileTheme
     {
      public static const ALTERNATE_NAME_MY_CUSTOM_BUTTON:String = "my-custom-button";
    
      [Embed(source="./assets/buttons/blue.png")]
      public var blueClass:Class;        
    
      [Embed(source="./assets/buttons/green.png")]
      public var greenClass:Class;        
    
      [Embed(source="./assets/buttons/red.png")]
      public var redClass:Class;        
    
      public function ExtendMetalWorksTheme(root:DisplayObjectContainer, scaleToDPI:Boolean=true)
      {
       super(root, scaleToDPI);
      }
    
      override protected function initialize():void
      {
       super.initialize();
       this.setInitializerForClass(Button, myCustomButtonInitializer, ALTERNATE_NAME_MY_CUSTOM_BUTTON);
      }        
    
      private function myCustomButtonInitializer(button:Button):void
      {
       button.defaultSkin = new Image( Texture.fromBitmap(new blueClass()) );
       button.downSkin = new Image( Texture.fromBitmap(new greenClass()) );
       button.hoverSkin = new Image( Texture.fromBitmap(new redClass()) );
    
       button.defaultLabelProperties.textFormat = this.smallUILightTextFormat;
       button.disabledLabelProperties.textFormat = this.smallUIDisabledTextFormat;
       button.selectedDisabledLabelProperties.textFormat = this.smallUIDisabledTextFormat;
      }
     }
    }
    
    FeathersThemeライブラリプロジェクトをビルドします。

    FeathersExampleプロジェクトのButtonExample.as内でカスタムテーマの変更をします。
    ButtonExample.as
    protected var theme:ExtendMetalWorksTheme;
    
       themeIndex = 2;
       switch(themeIndex)
       {
        case 0:
         //this.theme = new MetalWorksMobileTheme(this.stage);
         break;
        case 1:
         //this.theme = new AeonDesktopTheme(this.stage);
         break;
        case 2:
         this.theme = new ExtendMetalWorksTheme(this.stage);
         break;
       }
    

    Feathers Example Buttonについて

    Buttonサンプルについて
    このサンプルはFeathersのサイト
    「How to use the Feathers Button component(リンク先へ)
    を参考にしています。
    FeathersExampleのソースコード(リンク先へ)

    FeathersExampleを実行すると以下の画面になります。
    テーマの設定
    Buttonの処理を行う前にテーマを設定します。
    このサンプルでは、FeathersThemeライブラリ(リンク先へ) を利用しています。
    ButtonExample.as
        case 0:
         this.theme = new MetalWorksMobileTheme(this.stage);
         break;
    
    テーマはMetalWorksMobileThemeを使用します。

    テーマの変更
    MetalWorksMobileThemeからAeonDesktopThemeに切り替えてみます。

    ButtonExample.as
    protected var theme:AeonDesktopTheme;
    
       themeIndex = 1;
       switch(themeIndex)
       {
        case 0:
         //this.theme = new MetalWorksMobileTheme(this.stage);
         break;
        case 1:
         this.theme = new AeonDesktopTheme(this.stage);
         break;
    

    Buttonの表示と操作の流れ

    ButtonExample.as
       this.button = new Button();
       this.button.label = "クリック";
       this.button.nameList.add(ExtendMetalWorksTheme.ALTERNATE_NAME_MY_CUSTOM_BUTTON);
       this.button.defaultIcon = new Image(Texture.fromBitmapData(icon.bitmapData));
       this.button.iconPosition = Button.ICON_POSITION_TOP;
       this.button.gap = 0;
       this.button.horizontalAlign = Button.HORIZONTAL_ALIGN_LEFT;
       this.button.verticalAlign = Button.VERTICAL_ALIGN_MIDDLE;
       this.button.width = 200;
       this.button.height = 80;
    
       this.button.labelOffsetX = this.button.iconOffsetX + icon.width;
       this.button.labelOffsetY = -(this.button.height/2);
    
       this.button.addEventListener(Event.TRIGGERED, button_triggeredHandler);
       this.button.addEventListener(Event.CHANGE, button_changeHandler);
       this.addChild(this.button);
    
    • インスタンスの作成
    • labelプロパティの設定
    • レイアウト、大きさの設定
    • タッチイベントの設定
    • 画面に対してaddChildを行う

    タッチイベントハンドラーの作成 ButtonExample.as
      protected function button_triggeredHandler(event:Event):void
      {
       const label:Label = new Label();
       label.text = "Hi, I'm Feathers!\nHave a nice day.";
       Callout.show(label, this.button);
      }
    

    labelOffsetについて
    labelOffsetを利用しない場合は以下のような表示になります。
    アイコンとラベルを水平に表示させる為、labelOffsetで調整をしています。

    ButtonExample.as
       this.button.labelOffsetX = this.button.iconOffsetX + icon.width;
       this.button.labelOffsetY = -(this.button.height/2);
    

    Feathers Example プロジェクトの作成3


    プロジェクトの追加に上記3つのFlexライブラリプロジェクトを選択します。

    icon.png
    プロジェクトファイルにicon.pngを追加します。


    FeathersExample-app.xml
            
    
            direct
    
    renderMode設定をdirectに設定します。

    ビルドを行います。

    Feathers Example プロジェクトの作成2

    ListExample.as
    package
    {
     import feathers.controls.List;
     import feathers.data.ListCollection;
     import feathers.themes.MetalWorksMobileTheme;
    
     import starling.display.Sprite;
     import starling.events.Event;
    
     public class ListExample extends Sprite
     {
      public function ListExample()
      {
       this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
      }
    
      protected var theme:MetalWorksMobileTheme;
    
      protected var list:List;
    
      protected function addedToStageHandler(event:Event):void
      {
       this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    
       this.theme = new MetalWorksMobileTheme(this.stage);
    
       var list:List = new List();
       list.width = this.stage.stageWidth;
       list.height = this.stage.stageHeight;
       this.addChild(list);
    
       var listData:Object;
       var listTable:Array = [];
       for(var i:int=0;i<1000;i++)
       {
        listData = { text : i.toString()+":"+"アイテム" };
        listTable.push(listData);
       }
       var groceryList:ListCollection = new ListCollection(listTable);
       list.dataProvider = groceryList;
       list.itemRendererProperties.labelField = "text";
       list.itemRendererType = BasicItemRenderer;
      }
     }
    }
    
    BasicItemRenderer.as
    package
    {
     import feathers.controls.Label;
     import feathers.controls.List;
     import feathers.controls.Scroller;
     import feathers.controls.renderers.IListItemRenderer;
     import feathers.core.FeathersControl;
    
     import flash.geom.Point;
     import flash.text.TextFormat;
    
     import starling.display.Quad;
     import starling.events.Event;
     import starling.events.Touch;
     import starling.events.TouchEvent;
     import starling.events.TouchPhase;
    
     public class BasicItemRenderer extends FeathersControl implements IListItemRenderer
     {
      public function BasicItemRenderer()
      {
       this.addEventListener(TouchEvent.TOUCH,touchHandler);
       this.addEventListener(Event.REMOVED_FROM_STAGE,removedFromStageHandler);
      }
    
      protected var itemLabel:Label;
    
      protected var itemBG:Quad;
    
      protected var _index:int = -1;
    
      protected var touchPointID:Number;
    
      private static const HELPER_POINT:Point = new Point();
    
      protected var hasScrolled:Boolean = false;
    
      public function get index():int
      {
       return this._index;
      }
    
      public function set index(value:int):void
      {
       if(this._index == value) return;
       this._index = value;
       this.invalidate(INVALIDATION_FLAG_DATA);
      }
    
      protected var _owner:List;
    
      public function get owner():List
      {
       return List(this._owner);
      }
    
      public function set owner(value:List):void
      {
       if(this._owner == value) return;
       if(this._owner) this._owner.removeEventListener(Event.SCROLL, owner_scrollHandler);
       this._owner = value;
       if(this._owner) this._owner.addEventListener(Event.SCROLL, owner_scrollHandler);
       this.invalidate(INVALIDATION_FLAG_DATA);
      }
    
      protected var _data:Object;
    
      public function get data():Object
      {
       return this._data;
      }
    
      public function set data(value:Object):void
      {
       if(this._data == value)
       {
        return;
       }
       this._data = value;
       this.invalidate(INVALIDATION_FLAG_DATA);
      }
    
      protected var _isSelected:Boolean;
    
      public function get isSelected():Boolean
      {
       return this._isSelected;
      }
    
      public function set isSelected(value:Boolean):void
      {
       if(this._isSelected == value) return;
       this._isSelected = value;
       this.invalidate(INVALIDATION_FLAG_SELECTED);
       this.dispatchEventWith(Event.CHANGE);
      }
    
      override protected function initialize():void
      {
       if(!this.itemBG)
       {
        this.itemBG = new Quad(1,1,Math.floor(Math.random() * 0xffffff));
        this.addChild(this.itemBG);
       }
    
       if(!this.itemLabel)
       {
        this.itemLabel = new Label();
        this.addChild(this.itemLabel);
       }
      }
    
      override protected function draw():void
      {
       const dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA);
       const selectionInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SELECTED);
       var sizeInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SIZE);
    
       if(dataInvalid) this.commitData();
       sizeInvalid = this.autoSizeIfNeeded() || sizeInvalid;
       if(dataInvalid || sizeInvalid) this.layout();
      }
    
      protected function autoSizeIfNeeded():Boolean
      {
       const needsWidth:Boolean = isNaN(this.explicitWidth);
       const needsHeight:Boolean = isNaN(this.explicitHeight);
       if(!needsWidth && !needsHeight) return false;
       this.itemLabel.width = NaN;
       this.itemLabel.height = NaN;
       this.itemLabel.validate();
       var newWidth:Number = this.explicitWidth;
       if(needsWidth) newWidth = this.itemLabel.width;
       this.explicitHeight = 150;
       var newHeight:Number = this.explicitHeight;
       if(needsHeight) newHeight = this.itemLabel.height;
    
       this.itemBG.width = newWidth;
       this.itemBG.height = newHeight;
    
       return this.setSizeInternal(newWidth, newHeight, false);
      }
    
      protected function commitData():void
      {
       if(this._data)
       {
        this.itemLabel.text = this._data.text.toString();
       } else {
        this.itemLabel.text = "";
       }
      }
    
      protected function layout():void
      {
       this.itemBG.width = this.actualWidth;
       this.itemBG.height = this.actualHeight;
    
       this.itemLabel.width = this.actualWidth;
       this.itemLabel.height = this.actualHeight;
       this.itemLabel.y = (this.actualHeight / 2) - (this.itemLabel.y / 2);
      }
    
      protected function touchHandler(event:TouchEvent):void
      {
       const touches:Vector.<touch> = event.getTouches(this);
       if(touches.length == 0)
       {
        //hover has ended
        return;
       }
       if(this.touchPointID >= 0)
       {
        var touch:Touch;
        for each(var currentTouch:Touch in touches)
        {
         if(currentTouch.id == this.touchPointID)
         {
          touch = currentTouch;
          break;
         }
        }
        if(!touch)
        {
         return;
        }
        if(touch.phase == TouchPhase.ENDED)
        {
         this.touchPointID = -1;
         this.itemBG.visible = true;
         if(!this.hasScrolled)
         {                    
          touch.getLocation(this, HELPER_POINT);
          //check if the touch is still over the target
          //also, only change it if we're not selected. we're not a toggle.
          if(this.hitTest(HELPER_POINT, true) != null && !this._isSelected)
          {
           this.isSelected = true;
           trace(_index);
          }
         }
    
         return;
        }
       }
       else
       {
        for each(touch in touches)
        {
         if(touch.phase == TouchPhase.BEGAN)
         {
          this.touchPointID = touch.id;
          this.hasScrolled = false;
    
          return;
         }
        }
       }
      }
    
      protected function removedFromStageHandler(event:Event):void
      {
       this.touchPointID = -1;
      }
    
      protected function owner_scrollHandler(event:Event):void
      {
       this.hasScrolled = true;
      }        
    
     }
    }
    

    Feathers Example プロジェクトの作成1

    ボタンとリストのサンプルを作成します。
    4つのソースコードと画像を1つ用意します。
    FeathersExample.as
    package
    {
     import flash.display.Sprite;
     import flash.display.StageAlign;
     import flash.display.StageScaleMode;
     import flash.events.Event;
     import flash.geom.Rectangle;
    
     import starling.core.Starling;
     import starling.utils.HAlign;
     import starling.utils.VAlign;
    
     [SWF(width="960",height="640",frameRate="60",backgroundColor="#2f2f2f")]
     public class FeathersExample extends Sprite
     {
      public function FeathersExample()
      {
       if(this.stage)
       {
        this.stage.scaleMode = StageScaleMode.NO_SCALE;
        this.stage.align = StageAlign.TOP_LEFT;
       }
       this.mouseEnabled = this.mouseChildren = false;
       this.loaderInfo.addEventListener(Event.COMPLETE, loaderInfo_completeHandler);
      }
    
      private var _starling:Starling;
    
      private function loaderInfo_completeHandler(event:Event):void
      {
       var exampleIndex:int;
       Starling.handleLostContext = true;
       Starling.multitouchEnabled = true;
    
       exampleIndex = 0;
       switch(exampleIndex)
       {
        case 0:
         this._starling = new Starling(ButtonExample, this.stage);
         break;
        case 1:
         this._starling = new Starling(ListExample, this.stage);
         break;
       }
       this._starling.enableErrorChecking = false;
       this._starling.showStatsAt(HAlign.RIGHT,VAlign.BOTTOM,2);
       this._starling.start();
    
       this.stage.addEventListener(Event.RESIZE, stage_resizeHandler, false, int.MAX_VALUE, true);
       this.stage.addEventListener(Event.DEACTIVATE, stage_deactivateHandler, false, 0, true);
      }
    
      private function stage_resizeHandler(event:Event):void
      {
       this._starling.stage.stageWidth = this.stage.stageWidth;
       this._starling.stage.stageHeight = this.stage.stageHeight;
    
       const viewPort:Rectangle = this._starling.viewPort;
       viewPort.width = this.stage.stageWidth;
       viewPort.height = this.stage.stageHeight;
       try
       {
        this._starling.viewPort = viewPort;
       }
       catch(error:Error) {}
      }
    
      private function stage_deactivateHandler(event:Event):void
      {
       this._starling.stop();
       this.stage.addEventListener(Event.ACTIVATE, stage_activateHandler, false, 0, true);
      }
    
      private function stage_activateHandler(event:Event):void
      {
       this.stage.removeEventListener(Event.ACTIVATE, stage_activateHandler);
       this._starling.start();
      }
    
     }
    }
    

    ButtonExample.as
    package 
    {
     import feathers.controls.Button;
     import feathers.controls.Callout;
     import feathers.controls.Label;
     import feathers.themes.*;
    
     import flash.display.Bitmap;
    
     import starling.display.Image;
     import starling.display.Sprite;
     import starling.events.Event;
     import starling.textures.Texture;
    
     public class ButtonExample extends Sprite
     {
      [Embed(source='./icon.png')]
      public var ButtonIconSkin:Class;
    
      public function ButtonExample()
      {
       this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
      }
    
      protected var theme:MetalWorksMobileTheme;
    
      protected var button:Button;
    
      protected function addedToStageHandler(event:Event):void
      {
       this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    
       var icon:Bitmap = new ButtonIconSkin();
       var themeIndex:int;
    
       themeIndex = 0;
       switch(themeIndex)
       {
        case 0:
         this.theme = new MetalWorksMobileTheme(this.stage);
         break;
        case 1:
         //this.theme = new AeonDesktopTheme(this.stage);
         break;
        case 2:
         //this.theme = new ExtendMetalWorksTheme(this.stage);
         break;
       }
       this.button = new Button();
       this.button.label = "クリック";
       this.button.nameList.add(ExtendMetalWorksTheme.ALTERNATE_NAME_MY_CUSTOM_BUTTON);
       this.button.defaultIcon = new Image(Texture.fromBitmapData(icon.bitmapData));
       this.button.iconPosition = Button.ICON_POSITION_TOP;
       this.button.gap = 0;
       this.button.horizontalAlign = Button.HORIZONTAL_ALIGN_LEFT;
       this.button.verticalAlign = Button.VERTICAL_ALIGN_MIDDLE;
       this.button.width = 200;
       this.button.height = 80;
    
       this.button.labelOffsetX = this.button.iconOffsetX + icon.width;
       this.button.labelOffsetY = -(this.button.height/2);
    
       this.button.addEventListener(Event.TRIGGERED, button_triggeredHandler);
       this.button.addEventListener(Event.CHANGE, button_changeHandler);
       this.addChild(this.button);
       this.button.validate();
    
       this.button.x = (this.stage.stageWidth - this.button.width) / 2;
       this.button.y = (this.stage.stageHeight - this.button.height) / 2;
      }
    
      protected function button_triggeredHandler(event:Event):void
      {
       const label:Label = new Label();
       label.text = "Hi, I'm Feathers!\nHave a nice day.";
       Callout.show(label, this.button);
      }
    
      private function button_changeHandler(event:Event):void
      {
       var button:Button = event.currentTarget as Button;
       trace( "button.isSelected has changed:",button.isSelected);
      }
     }
    }