Adobe AIRで作るデスクトップアプリケーション

第13回 メニューの実装

この記事を読むのに必要な時間:およそ 5 分

様々なタイプのメニュー

冒頭で紹介したように,アプリケーションメニューやウィンドウメニュー以外でも同様のメニューを表示できます。先のサンプルのアサイン部分だけを変更して確認してみましょう。Mac OS XのDockアイコンメニューとWindowsのシステムトレイアイコンメニューに表示するには,次のように変更します。

if (Shell.supportsDockIcon) {
  var dockIcon:DockIcon = Shell.shell.icon as DockIcon;
  dockIcon.menu = rootMenu;
} else if (Shell.supportsSystemTrayIcon) {
  var sysTrayIcon:SystemTrayIcon = Shell.shell.icon as SystemTrayIcon;
  sysTrayIcon.bitmaps = [new BitmapData(16, 16, false, 0xff0000)];
  sysTrayIcon.menu = rootMenu;
}

どちらの場合も結果的にはShell.shell.icon.menuプロパティにアサインするのですが,サポートしているアイコンのタイプによってShell.shell.iconプロパティの値が異なる点に注意してください。Dockアイコンの場合はDockIcon.menuプロパティ,システムトレイアイコンの場合はSystemTrayIcon.menuプロパティにメニューをアサインすることになります。この判別にはShell.supportsDockIconプロパティとShell.supportsSystemTrayIconプロパティを使います。前者がtrueの場合はDockアイコンをサポートしており,後者がtrueの場合はシステムトレイアイコンをサポートしています。なお,ここではシステムトレイアイコンのイメージとして16×16の赤い矩形を指定しています。

Mac OS XのDockアイコンメニューとWindowsのシステムトレイアイコンメニュー

Mac OS XのDockアイコンメニューとWindowsのシステムトレイアイコンメニュー

コンテキストメニューとして使いたい場合は,任意のインタラクティブオブジェクトのcontextMenuプロパティにアサインするだけです。すると,そのオブジェクト上でコンテキストメニューを表示したときに指定のメニューが表示されるようになります。

myMovieClip.contextMenu = rootMenu;

ポップアップメニューとして使いたい場合はこれまでと異なり,NativeMenu.display()メソッドを使います。第1パラメータにはメニューを表示するステージを,第2/第3パラメータにはステージを基準としたメニューの座標を指定します。

rootMenu.display(stage, 32, 32);

ただし,確認した範囲ではMac版での座標指定は無視され,マウス座標に表示されます。

セパレータの挿入

メニューのアイテムの間にはセパレータを挿入できます。セパレータもNativeMenuItemオブジェクトです。NativeMenuItemコンストラクタの第2パラメータにtrueを指定すると,そのアイテムはセパレータになります。

var separator:NativeMenuItem = new NativeMenuItem("", true);
fileMenu.submenu.addItem(separator);

メニュー選択時のイベント

ここまでメニューの表示について見てきましたが,表示するだけではメニューの役割を果たしません。選択されたときに発生するイベントを受けて,何らかのアクションを起こす必要があります。メニューの選択に関するイベントは次の2つがあります(flash.eventsパッケージ)⁠

イベント発生タイミング
Event.DISPLAYINGメニューが表示される直前
Event.SELECTメニューが選択された時

Event.DISPLAYINGは,ユーザがメニューをクリックして表示しようとした時に発生しますが,まだメニューは表示されていない状態です。例えば,⁠最近開いたドキュメント」のように動的に内容を変更したいメニューに利用できます。実際に選択された時はEvent.SELECTが発生します。次のサンプルは,[File]メニューから[Exit]を選択するとアプリケーションを終了します。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="buildMenu()">
  <mx:Script>
    <![CDATA[
      private function buildMenu():void {
        var rootMenu:NativeMenu = new NativeMenu();
        var fileMenu:NativeMenuItem = rootMenu.addSubmenu(new NativeMenu(), "File");
        var exitMenu:NativeMenuItem = new NativeMenuItem("Exit");
        exitMenu.addEventListener(Event.SELECT, selectExitHandler);
        fileMenu.submenu.addItem(exitMenu);
        if (Shell.supportsMenu) {
          Shell.shell.menu = rootMenu;
        } else if (NativeWindow.supportsMenu) {
          stage.nativeWindow.menu = rootMenu;
        }
      }
      private function selectExitHandler(e:Event):void {
        Shell.shell.exit();
      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

メニューのオン/オフ

NativeMenuItemクラスには,checkedプロパティとenabledプロパティがあります。前者はメニューのアイテムがチェックされているかどうかを示すもので,trueにするとアイテムにチェックマークが付きます。後者はメニューのアイテムが現在選択可能かどうかを示すもので,falseにするとアイテムがグレーアウトの状態になります。

次のサンプルは,先のコードに[Lock]メニューを追加しています。[Lock]メニューを選択する度にチェックの有無が切り替わり,チェックが付いているときは[Exit]メニューを無効にします。

確認した範囲では,Windowsで一旦chekedプロパティを設定するとその後値が変更できません。
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="buildMenu()">
  <mx:Script>
    <![CDATA[
      private var _exitMenu:NativeMenuItem;
      private function buildMenu():void {
        var rootMenu:NativeMenu = new NativeMenu();
        var fileMenu:NativeMenuItem = rootMenu.addSubmenu(new NativeMenu(), "File");
        var lockMenu:NativeMenuItem = new NativeMenuItem("Lock");
        lockMenu.addEventListener(Event.SELECT, selectLockHandler);
        fileMenu.submenu.addItem(lockMenu);
        _exitMenu = new NativeMenuItem("Exit");
        _exitMenu.addEventListener(Event.SELECT, selectExitHandler);
        fileMenu.submenu.addItem(_exitMenu);
        if (Shell.supportsMenu) {
          Shell.shell.menu = rootMenu;
        } else if (NativeWindow.supportsMenu) {
          stage.nativeWindow.menu = rootMenu;
        }
      }
      private function selectLockHandler(e:Event):void {
        e.target.checked = !e.target.checked;
        _exitMenu.enabled = !e.target.checked;
      }
      private function selectExitHandler(e:Event):void {
        Shell.shell.exit();
      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

メニューのチェックや無効化が可能

メニューのチェックや無効化が可能

メニューにデータを設定する

NativeMenuItemクラスのdataプロパティを使うと,メニューアイテムに任意の値を持たせることができます。次のサンプルでは[Help]メニューの下に[LiveDocs]メニューを設け,そのdataプロパティにURLを持たせてあります。[LiveDocs]メニューが選択されると,dataプロパティからURLを取得してページにジャンプします。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="buildMenu()">
  <mx:Script>
    <![CDATA[
      private function buildMenu():void {
        var rootMenu:NativeMenu = new NativeMenu();
        var helpMenu:NativeMenuItem = rootMenu.addSubmenu(new NativeMenu(), "Help");
        var docMenu:NativeMenuItem = new NativeMenuItem("LiveDocs");
        docMenu.data = "http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/";
        docMenu.addEventListener(Event.SELECT, selectDocHandler);
        helpMenu.submenu.addItem(docMenu);
        if (Shell.supportsMenu) {
          Shell.shell.menu = rootMenu;
        } else if (NativeWindow.supportsMenu) {
          stage.nativeWindow.menu = rootMenu;
        }
      }
      private function selectDocHandler(e:Event):void {
        navigateToURL(new URLRequest(e.target.data));
      }
    ]]>
  </mx:Script>
</mx:WindowedApplication>

dataプロパティには様々なオブジェクトを設定できるので,例えばドキュメントに関するメニューにFileオブジェクトを設定しておくといった使い方ができます。

著者プロフィール

タナカヤスヒロ

早稲田大学卒業後,DTP業務を経てマルチメディア系制作会社へ。Macromedia Directorにのめり込む。フリーランスとなりFlashにシフトしてからもデスクトップ絡みの仕事が絶えず,Apolloにも勝手に縁を感じている。現在株式会社antsに所属。ants Lab.にも記事を上げている。

URLhttp://labs.anthill.jp/

著書

コメント

コメントの記入