2011-06-24 8 views
0

レンダラーですが、a)キーボードショートカットは右揃えではありません b)サブメニューには多くの問題があります。のFlexメニューショートカットキーやカスタムレンダラ

私はまた、この種のメニューを描画するためにデータグリッドとパネルとその混合物を使用しようとしましたが、あまりにもうんざりです。

どのように私はこれを達成することができますか?

EDIT:追加ソースコード

Main.mxml 

<mx:Style source="assets/main.css" /> 

<mx:Script> 
    <![CDATA[ 
     import FlyOutMenuItem; 
     import FlyOutMenuRenderer; 
     import com.jusfortechies.controls.CustomMenuItemRenderer; 
     import com.jusfortechies.controls.ValueObject; 

     import mx.collections.ArrayCollection; 
     import mx.controls.Menu; 
     import mx.events.CollectionEvent; 
     import mx.events.MenuEvent; 

     [Bindable] 
     private var myMenuData:ArrayCollection = new ArrayCollection(); 

     [Bindable] 
     private var mainMenuData:ArrayCollection = new ArrayCollection(); 

     [Bindable] 
     [Embed(source="Button.png")] 
     public var Button:Class; 

     [Bindable] 
     public var state:Boolean = false; 

     [Bindable] 
     private var myMenu:Menu; 

     [Bindable] 
     private var mainMenu:Menu; 

     // Create and display the Menu control. 
     private function createAndShow():void { 

      mainMenu = Menu.createMenu(null, mainMenuData, false); 
      mainMenu.labelField="label"; 

      //myMenu.itemRenderer = new ClassFactory(CustomMenuItemRenderer); 
      mainMenu.itemRenderer = new ClassFactory(FlyOutMenuRenderer); 

      mainMenu.addEventListener(KeyboardEvent.KEY_DOWN,handleFlyOutMenuKeyStroke); 
      mainMenu.addEventListener(KeyboardEvent.KEY_UP,handleFlyOutMenuKeyStrokeUp); 
      mainMenu.addEventListener(MenuEvent.ITEM_CLICK,handleFlyOutMenuHandleClick); 

      myMenu = Menu.createMenu(mainMenu, myMenuData, false); 
      myMenu.labelField="label"; 

      //myMenu.itemRenderer = new ClassFactory(CustomMenuItemRenderer); 
      myMenu.itemRenderer = new ClassFactory(FlyOutMenuRenderer); 

      myMenu.addEventListener(KeyboardEvent.KEY_DOWN,handleFlyOutMenuKeyStroke); 
      myMenu.addEventListener(KeyboardEvent.KEY_UP,handleFlyOutMenuKeyStrokeUp); 
      myMenu.addEventListener(MenuEvent.ITEM_CLICK,handleFlyOutMenuHandleClick); 

      mainMenu.addChild(myMenu); 

      //Position the menu and show it when the button is clicked 
      mainMenu.show((this.width/2 - this.myButton.width/2), 50); 
     } 

     protected function handleFlyOutMenuKeyStrokeUp(event:KeyboardEvent):void { 
      state = false; 
     } 

     protected function handleFlyOutMenuKeyStroke(event:KeyboardEvent):void { 
      trace("target:"+event.currentTarget+"state:"+state+";keycode:"+event.keyCode); 

      // tried to check for keycode's like 2, 3 which correspond to ctrl+b and ctrl+c respectively 
      // did not work. Hence go for state based individual key check 

      if(event.keyCode == Keyboard.ESCAPE && myMenu.visible) { 
       myMenu.hide(); 
      } else if (state) { 
       if (event.keyCode >=65 && event.keyCode <= 90) { // check if any alphabet was pressed after control key 
        // A ascii code = 65. But in our data array, A starts at 1 NOT 0. So we detect 65-1 = 64 
        trace("Inside handleFlyOutMenuKeyStroke"+event.keyCode); 
       } 
      } else if(event.keyCode == Keyboard.CONTROL){ 
       state = true; 
       return; 
      } 
      state=false; 

      if(myMenu.visible) { 
       myMenu.hide(); 
      } 
     } 

     protected function handleFlyOutMenuHandleClick(event:MenuEvent):void 
     { 
      if(event.currentTarget == mainMenu){ 
       trace('MainMenu HandleClick'); 
       myMenu.show((mainMenu.x + mainMenu.width), (mainMenu.y + mainMenu.height/2)); 
       //myMenu.show((this.width/2 - this.myButton.width/2), 50); 
      } 
      trace("Inside MenuHandleClick"); 
     } 



     public function init():void { 
      /*mainMenuData.addItem(new ValueObject("MA", "MenuItem A", "menuOddItem")); 
      mainMenuData.addItem(new ValueObject("MB", "MenuItem B", "menuEvenItem")); 
      mainMenuData.addItem(new ValueObject("MC", "MenuItem C", "menuOddItem")); 
      mainMenuData.addItem(new ValueObject("MD", "MenuItem D", "menuEvenItem"));*/ 

      myMenuData.addItem(new FlyOutMenuItem("Item A", "A", "Button")); 
      myMenuData.addItem(new FlyOutMenuItem("Item B", "B", "Button")); 
      myMenuData.addItem(new FlyOutMenuItem("Item CM", "C", "Button")); 
      myMenuData.addItem(new FlyOutMenuItem("Item DE", "D", "Button")); 
     } 
    ]]> 
</mx:Script> 

<mx:VBox> 
    <!-- Define a Button control to open the menu --> 
    <mx:Button id="myButton" initialize="init()" label="Open Menu" click="createAndShow();"/> 
</mx:VBox> 

FlyOutMenuItem.as

パッケージ {[バインド可能] パブlicクラスFlyOutMenuItem { パブリック変数label:String; public var shortCut:String; public var icon:String;

public function FlyOutMenuItem(label:String, shortcut:String, icon:String) 
    { 
     this.label = label + " Ctrl+"+shortcut; 
     this.shortCut = shortcut; 
     this.icon = icon; 
    } 
} 

}

FlyOutMenuRenderer.as

パッケージ {インポートmx.controls.Label。 import mx.controls.menuClasses.MenuItemRenderer;

import spark.components.Label; 

[Bindable] 
public class FlyOutMenuRenderer extends MenuItemRenderer 
{ 
    override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void { 

     //Get the style name from Menu VO and set to the menu item 
     //this.styleName = ValueObject(this.data).styleName; 

     this.label.ignorePadding = true; 
     trace("Style.align.MenuRenderer.label:"+this.label.getStyle("textAlign")); 

     super.updateDisplayList(unscaledWidth, unscaledHeight); 
    } 

    public function FlyOutMenuRenderer() 
    { 
     super(); 
    } 
} 

}

CustomMenuItemRenderer.as/*からjustfortechies.com */

パッケージ {インポートmx.controls.menuClasses.MenuItemRendererをcom.jusfortechies.controls。

[Bindable] 
public class CustomMenuItemRenderer extends MenuItemRenderer 
{ 
    override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void { 

     //Get the style name from Menu VO and set to the menu item 
     this.styleName = ValueObject(this.data).styleName; 

     super.updateDisplayList(unscaledWidth, unscaledHeight); 
    } 
} 

}

ValueObject.as/* justfortechies.comから*/

パッケージcom.jusfortechies.controls {[バインド可能] パブリッククラスValueObject {公共VAR番号:文字列; public var label:String; public var styleName:String;

public function ValueObject(id:String, label:String, styleName:String) 
    { 
     this.id = id; 
     this.label = label; 
     this.styleName = styleName; 
    } 

} 

}

+0

はあなたのカスタムアイテムレンダラー – Neeraj

+0

Neerajのためにここにコードを追加することができます..私は、ソースコードが含まれるように私の質問を編集しました。だから私はカスタムレンダラを作成していることがわかりますし、通常のメニューのようにすべてを表示する必要があります。サブメニューがあまりうまく表示されず、イベント処理に問題があります。どのポインタも素晴らしいでしょう。 – Neo

+0

また、私はこれをMenuBarでしようとしていました。私は、ある時点でこの投稿への返信にもそのソースコードを含める予定です。私はrep <100.を持っているので、私は自分の質問に答えることができません – Neo

答えて

2

これで同じことを意図したMenuBar実験のための私のソースコード - メニューの異なる種類を表示するカスタムレンダラを使用しています。

P .:これはこの質問に対する答えではありません。この投稿は、私が取った2つのアプローチを分離するために作成されました。

FlyOutMenuItem.as

package 
{ 
    import mx.controls.Menu; 

    [Bindable] 
    public class FlyOutMenuItem extends Menu 
    { 
     public var label:String; 
     public var shortCut:String; 
     public var icon:String; 

     public function FlyOutMenuItem(label:String, shortcut:String, icon:String) 
     { 
      this.label = label + " Ctrl+"+shortcut; 
      trace("Creating new Flyoutmenuitem with label:"+this.label); 
      this.shortCut = shortcut; 
      this.icon = icon; 
     } 
    } 
} 

FlyoutMenuBar.as

package 
{ 
    import mx.controls.Menu; 
    import mx.controls.MenuBar; 
    import mx.core.ClassFactory; 

    [Bindable] 
    public class FlyoutMenuBar extends MenuBar 
    { 
     public function FlyoutMenuBar() 
     { 
      super(); 
     } 

     override public function getMenuAt(index:int) : Menu  
     { 
      var menu:Menu = super.getMenuAt(index); 
      //menu.styleName = "myMenuItemRendererStyleName"; 
      menu.itemRenderer = new ClassFactory(FlyoutMenuItemRenderer); 

      return menu; 
     } 
    } 
} 

FlyoutMenuItemRenderer.as

package 
{ 
    import mx.controls.Alert; 
    import mx.controls.menuClasses.MenuItemRenderer; 
    import mx.core.IFlexDisplayObject; 

    [Bindable] 
    public class FlyoutMenuItemRenderer extends MenuItemRenderer 
    { 
     public function FlyoutMenuItemRenderer() 
     { 
      super(); 
     } 

     [Embed(source="Button.png")] 
     public var Button:Class; 

     override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void { 
      trace("MenuRenderer.label:"+this.label.text+"; id:"+this.id); 
      super.updateDisplayList(unscaledWidth, unscaledHeight); 
     } 
    } 
} 

Main.mxml

<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         xmlns:renderers="*"> 
    <fx:Script> 
     <![CDATA[ 
      import FlyOutMenuItem; 

      import mx.collections.ArrayCollection; 
      import mx.controls.Alert; 
      import mx.controls.Menu; 
      import mx.controls.menuClasses.MenuBarItem; 
      import mx.events.FlexEvent; 

      [Bindable] 
      private var menuBarData:ArrayCollection = new ArrayCollection(); 

      protected function flyoutMenuBar_creationCompleteHandler(event:FlexEvent):void 
      { 
       //var numMenus:int = flyoutMenuBar.menus.length; 
       //var numChild:int = flyoutMenuBar.numChildren; 
       //Alert.show("numMenus:"+numMenus+"; numChild:"+numChild, "CreationComplete"); 

       flyoutMenuBar.addChild(new FlyOutMenuItem("Item A", "A", "Button")); 
       var child:Menu = flyoutMenuBar.getMenuAt(0); 
      } 

     ]]> 
    </fx:Script> 
    <fx:Declarations> 
     <!-- Place non-visual elements (e.g., services, value objects) here --> 
     <fx:XML id="mainMenuBarButtonData"> 
      <root> 
       <menuitem label="Flyout Menu"> 
        <menuitem label="ABC"/> 
        <menuitem label="DEF"> 
         <menuitem label="GHI" /> 
        </menuitem> 
       </menuitem> 
      </root> 
     </fx:XML> 
    </fx:Declarations> 
    <renderers:FlyoutMenuBar id="flyoutMenuBar" creationComplete="flyoutMenuBar_creationCompleteHandler(event)" 
       labelField="@label" dataProvider="{mainMenuBarButtonData}" showRoot="false"> 
    </renderers:FlyoutMenuBar> 

</s:WindowedApplication> 
関連する問題