flash.display.DisplayObject#localToGlobal(point:Point):Point - Adobe Flex 3.2 リファレンスガイド によると「point オブジェクトを表示オブジェクトの (ローカル) 座標からステージ (グローバル) 座標に変換します。」とかいう機能を提供してくれるこのメソッド。その出番は何時なのか。
まずは、試しにこんな感じに絶対座標でコンポーネントを配置してみる。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.controls.Menu; import mx.collections.ArrayCollection; import mx.controls.Alert; private function menuButtonClickHandler(event:MouseEvent):void { Alert.show("x=" + menuButton.x + ":y=" + menuButton.y);//x=10:y=60 と表示; } ]]> </mx:Script> <mx:Canvas x="60" y="40" width="200" height="120"> <mx:Button id="menuButton" x="10" y="60" label="ボタン" click="menuButtonClickHandler(event)"/> </mx:Canvas> </mx:Application>
コード中のコメントにあるとおり menuButton の x と y は 10,60 と表示される。これは親コンポーネントである Canvas を基準にした座標なことがわかる……とまぁ、x,y のプロパティは親となるコンテナコンポーネントから見ての座標なわけです。なお Flex の座標系の用語については Flex の座標系 - MouseEvent#localX と Canvas#contentMouseX のちがい - kagamihogeのblog を参照。
これだと困るケースというのは、たとえば、 みたいにボタンの下にメニューを表示したい、というとき。ボタン(この例では menuButton のこと)の x,y をそのまま使うと、Flex アプリケーション全体から見た絶対座標の位置で表示されてしまう。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.controls.Menu; import mx.collections.ArrayCollection; import mx.controls.Alert; private function menuButtonClickHandler(event:MouseEvent):void { var myMenu:Menu; myMenu = Menu.createMenu(null, [{label:"メニュー1"},{label:"メニュー2"}]); myMenu.show( menuButton.x, menuButton.y + menuButton.height); //10,60の位置にメニューが表示される! } ]]> </mx:Script> <mx:Canvas x="60" y="40" width="200" height="120"> <mx:Button id="menuButton" x="10" y="60" label="ボタン" click="menuButtonClickHandler(event)"/> </mx:Canvas> </mx:Application>
こんな感じのコードを実行すると、下図のようにわけのわからん位置にメニューが表示される。x=10,y=60 の位置に表示しているから、わけのわからない位置に見える、という話なのだけども。
というわけで。こういう事態に対処する場合に localToGlobal を使用する。コードは↓みたいな感じ。localToGlobal のターゲットとなるオブジェクトは親コンポーネントを使うのがミソといえばミソだろうか。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.controls.Menu; import mx.collections.ArrayCollection; import mx.controls.Alert; private function menuButtonClickHandler(event:MouseEvent):void { var localPoint:Point = new Point(menuButton.x, menuButton.y); var globalPoint:Point = hogeCanvas.localToGlobal(localPoint); Alert.show("x=" + globalPoint.x + ":y=" + globalPoint.y);//x=70:y=100 と表示 var myMenu:Menu; myMenu = Menu.createMenu(null, [{label:"メニュー1"},{label:"メニュー2"}]); myMenu.show( globalPoint.x, globalPoint.y + menuButton.height); } ]]> </mx:Script> <mx:Canvas id="hogeCanvas" x="60" y="40" width="200" height="120"> <mx:Button id="menuButton" x="10" y="60" label="ボタン" click="menuButtonClickHandler(event)"/> </mx:Canvas> </mx:Application>