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

第6回 ウィンドウの操作

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

ウィンドウの移動/リサイズ

システムクロームやFlexクロームを使っている場合には,特別な設定をしなくてもタイトルバーを掴んでウィンドウを移動したり,エッジを掴んでリサイズしたりできます。ですが,カスタムクロームでそういった動作を行うには,対応する処理を組み込む必要があります。下記はそのサンプルです。タイトルバーとリサイズボックスの代わりとして2つのHBoxコンポーネントを使っています。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			private function onTitleBarPress(evt:MouseEvent):void {
				stage.window.startMove();
			}
			private function onResizeBoxPress(evt:MouseEvent):void {
				stage.window.startResize(NativeWindowResize.BOTTOM_RIGHT);
			}
		]]>
	</mx:Script>
	<mx:HBox width="100%" height="20" backgroundColor="#666666" mouseDown="onTitleBarPress(event)"/>
	<mx:HBox width="20" height="20" backgroundColor="#666666" mouseDown="onResizeBoxPress(event)" right="0" bottom="0"/>
</mx:Application>

ウィンドウをドラッグして移動するには,mouseDownイベントをきっかけにstartMove()メソッドを呼び出します。するとマウスボタンを押している間はウィンドウをドラッグできます。マウスボタンを放すと自動的に移動停止します。停止用のメソッドはありません。

リサイズの場合も同様で,mouseDownイベントをきっかけにstartResize()メソッドを呼び出します。startResize()メソッドには,引数としてリサイズする方向を指定します。指定できる値はNativeWindowResizeクラスの定数として定義されています。サンプルではリサイズボックスを右下に配置しているので,NativeWindowResize.BOTTOM_RIGHTを指定しています。

NativeWindowResize.TOP
NativeWindowResize.BOTTOM
NativeWindowResize.LEFT
NativeWindowResize.RIGHT
NativeWindowResize.TOP_LEFT左上
NativeWindowResize.TOP_RIGHT右上
NativeWindowResize.BOTTOM_LEFT左下
NativeWindowResize.BOTTOM_RIGHT右下
NativeWindowResize.NONEリサイズしない

マウスドラッグによる操作以外に,NativeWindowクラスのプロパティを直接指定して位置やサイズを変更できます。位置を指定するにはx,yプロパティを,サイズを指定するにはwidth,heightプロパティを使います。

var appWin:NativeWindow = stage.window;
appWin.x = 100;
appWin.y = 100;
appWin.width = 640;
appWin.height = 480;

また,boundsプロパティを使えば位置とサイズを同時に指定できます。値はRectangle型です。

stage.window.bounds = new Rectangle(100, 100, 640, 480);

なお,カスタムクロームではウィンドウとステージのサイズが一致しますが,システムクロームの場合はウィンドウからクロームの領域を除いた範囲がステージになるので注意してください。

ウィンドウのサイズには上限と下限があり,それぞれmaxSize,minSizeプロパティに設定されています。値はPoint型です。この値を上書きしてリサイズ可能な範囲を設定できます。

var appWin:NativeWindow = stage.window;
appWin.minSize = new Point(320, 240);
appWin.maxSize = new Point(640, 480);

ウィンドウの状態を知る

現在のウィンドウの状態(通常/最小化/最大化)は,NativeWindowクラスのdisplayStateプロパティで調べることができます。各状態を表す値は,NativeWindowDisplayStateクラスの定数として定義されています。

NativeWindowDisplayState.MAXIMIZED最大化された状態
NativeWindowDisplayState.MINIMIZED最小化された状態
NativeWindowDisplayState.NORMAL通常の状態

次のステートメントはウィンドウが通常の状態であれば最大化し,そうでなければ元に戻します。

var appWin:NativeWindow = stage.window;
if (appWin.displayState == NativeWindowDisplayState.NORMAL) {
	appWin.maximize();
} else {
	appWin.restore();
}

ウィンドウの状態が変わる直前や変わった直後に処理を行いたい場合は,NativeWindowクラスのイベントを利用します。定義されているイベントには次の種類があります。

NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING最小化や最大化が行われる直前
NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE最小化や最大化が行われた
NativeWindowBoundsEvent.MOVING移動される直前
NativeWindowBoundsEvent.MOVE移動された
NativeWindowBoundsEvent.RESIZINGリサイズされる直前
NativeWindowBoundsEvent.RESIZEリサイズされた
Event.ACTIVATEアクティブになった
Event.DEACTIVATE非アクティブになった
Event.CLOSING閉じられる直前
Event.CLOSE閉じられた

NativeWindowDisplayStateEventクラスにはbeforeDisplayStateとafterDisplayStateプロパティがあり,イベント受信時に変更前と変更後の状態を知ることができます。同様に,NativeWindowBoundsEventクラスには変更前と変更後の位置やサイズを知るためのbeforeBounds,afterBoundsプロパティがあります。下記はサイズ変更時や移動時のイベントを受け取るサンプルです。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
	<mx:Script>
		<![CDATA[
			private function init():void {
				var appWin:NativeWindow = stage.window;
				appWin.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, onDisplayStateChange);
				appWin.addEventListener(NativeWindowBoundsEvent.MOVE, onBoundsChange);
				appWin.addEventListener(NativeWindowBoundsEvent.RESIZE, onBoundsChange);
			}
			private function onDisplayStateChange(evt:NativeWindowDisplayStateEvent):void {
				trace(evt.type, evt.beforeDisplayState, evt.afterDisplayState);
			}
			private function onBoundsChange(evt:NativeWindowBoundsEvent):void {
				trace(evt.type, evt.beforeBounds, evt.afterBounds);
			}
		]]>
	</mx:Script>
</mx:WindowedApplication>

NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGINGとEvent.CLOSINGについては,システムクロームまたはFlexクロームを使っている場合に配信されます。また,NativeWindowBoundsEvent.MOVINGとNativeWindowBoundsEvent.RESIZINGは,マウスドラッグによる操作の場合に配信されます。これらイベント名にINGのつくものは,その後に行われるデフォルト動作をキャンセルすることができます。下記のサンプルでは,ウィンドウが閉じられる直前にpreventDefault()メソッドでキャンセルしています。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
	<mx:Script>
		<![CDATA[
			private function init():void {
				stage.window.addEventListener(Event.CLOSING, onClosing);
			}
			private function onClosing(evt:Event):void {
				evt.preventDefault();
				trace("クローズイベントをキャンセルしました");
			}
		]]>
	</mx:Script>
</mx:WindowedApplication>

著者プロフィール

タナカヤスヒロ

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

URLhttp://labs.anthill.jp/

著書