デフォルトでドラッグ&ドロップをサポートしていないコントロールに、新たにドラッグ&ドロップ機能を追加する場合や、異なるコントロール間で行う場合には、“DragManager”を利用します。
まずは、サンプルを見てみましょう。
このサンプルは画像を下部の桃色のエリアにドラッグすると、その画像がエリアに追加されるサンプルです。
サンプル3 画像をドラッグして追加する |
少し長くなりますが、ソースコードも確認してみましょう。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> <mx:Script> <![CDATA[ import mx.events.DragEvent; import mx.core.UIComponent; import mx.core.IFlexDisplayObject; import mx.core.DragSource; import mx.managers.DragManager; private function mouseDownHandler(event:MouseEvent):void{ //ドラッグされるデータを作成 var dragSource:DragSource = new DragSource(); dragSource.addData(image.source, "img"); //ドラッグ中のイメージを作成 var imageProxy:UIComponent = new UIComponent(); var bitmap:Bitmap = new Bitmap(); var bitmapData:BitmapData = new BitmapData(image.width, image.height); bitmapData.draw(image); bitmap.bitmapData = bitmapData; imageProxy.addChild(bitmap); //ドラッグを開始 DragManager.doDrag(image, dragSource, event, imageProxy); } private function dragEnterHandler(event:DragEvent):void{ DragManager.acceptDragDrop(vbox); } private function dragOverHandler(event:DragEvent):void{ vbox.setStyle("borderStyle", "solid"); } private function dragExitHandler(event:DragEvent):void{ vbox.setStyle("borderStyle", "none"); } private function dragDropHandler(event:DragEvent):void{ var dropImage:Image = new Image(); dropImage.source = event.dragSource.dataForFormat("img"); vbox.addChild(dropImage); } private function dragCompleteHandler(event:DragEvent):void{ vbox.setStyle("borderStyle", "none"); } ]]> </mx:Script> <mx:Image id="image" source="img.png" mouseDown="mouseDownHandler(event)" dragComplete="dragCompleteHandler(event)" /> <mx:VBox id="vbox" width="300" height="200" borderColor="0x0000FF" backgroundColor="0xFFCCCC" borderStyle="none" horizontalAlign="center" dragEnter="dragEnterHandler(event)" dragOver="dragOverHandler(event)" dragExit="dragExitHandler(event)" dragDrop="dragDropHandler(event)" /> </mx:Application>
ドラッグ&ドロップという操作は、マウスを押下したとき、マウスがコンポーネント上に来たとき、コンポーネントにドロップされたとき、などの一連のイベントの流れがあります。
それぞれのタイミングで発生するイベントと処理の手順は以下のとおりになります。
ここでは、ドロップターゲットに渡されるデータとそのフォーマット、およびドラッグ中のイメージを作成し、ドラッグを開始します。
まず、DragSourceを作成します。DragSource.addData()で、ドロップターゲットに渡すデータとフォーマットを指定します。ここでは参照元の画像へのパスを「img」というフォーマットとして渡します。フォーマットは任意の名前です。後で、この名前で渡したデータを取得します。
次に、ドラッグ中のイメージを作成します。ここでは画像のビットマップデータを取得し、imageProxyとして作成します。
最後に、DragManager.doDrag()を実行します。ここでは上記で作成したデータを渡します。
ドロップターゲットにドラッグされたときにdragEnterイベントが発生します。ここでは、渡されたデータによって、ドラッグを受け付けるかどうかを判断し、ドロップターゲットでドロップを受け付けられる状態にします。
今回は、特に渡されたデータの判断はしていませんが、通常はdragEnterイベントのdragSourceからドラッグで渡されたデータが、受け付けられるデータかどうかをフォーマットから判断します。これは複数のコントロールで異なるドラッグデータを扱う際に必要になります。
ドロップターゲットでドロップを許可するには、DragManager.acceptDragDrop()に対象のコントロールを渡します。この時点で、マウスカーソルがドロップ可能なアイコンに変化します。
ドロップターゲットでドロップが許可された後、ドロップターゲットにマウスを移動した際にdragOverイベントが発生します。
このイベントはオプションであり、特に指定しなくても構いませんが、ここではドロップターゲットの枠線のスタイルを変更して、ドロップができる状態であることを視覚化しています。
ドロップターゲットでドロップが許可された後、ドロップターゲットからマウスが離れた際にdragExitイベントが発生します。
このイベントはオプションであり、特に指定しなくても構いませんが、ここではドロップターゲットの枠線のスタイルを変更して、ドロップできる状態ではなくなったことを視覚化しています。
ドロップターゲットでドロップが許可された後、マウスをリリースしてドロップ操作が実行されたときにdragDropイベントが発生します。
ここでは、ドラッグイニシエータから渡されたDragSourceを基にImageを作成し、ドロップターゲットに追加する処理を行っています。
ドラッグ&ドロップ操作が正しく実行されたときに、ドラッグイニシエータでdragCompleteイベントが発生します。
ここでは、操作完了後のクリーンアップを行います。また、データのコピーではなく移動を行う場合は、この段階で元データを削除します。
ドラッグ&ドロップでは直感的な操作が可能になりますが、ドラッグ&ドロップ操作ができるのかどうかをユーザーに伝えることがいささか困難であることと、ドラッグ&ドロップの操作自体がユーザーに比較的精密な操作を要求する点に注意が必要です。
またAIRでは、AIRアプリケーションとOS間でのドラッグ&ドロップをサポートしているため、さまざまな利用方法が実現できます。詳しくは「AIRアプリはドラッグ&ドロップでこんなことまで!」を参照してください。
次回は、データグリッドおよびリスト系コンポーネントの使用方法の解説をします。
成瀬 勉(なるせ つとむ)
クラスメソッド株式会社 エンタープライズサービス部門アーキテクト
Macromedia FLASH MX 2004 Developer認定技術者
FlashエンジニアとしてWeb製作を経たのちWebアプリケーション開発に携わる。FlexやWPFなどのRIA開発および技術調査を日々行っている。
クラスメソッド株式会社での主な開発実績は、旭化成の電子ファイリングシステム、ひまわり証券のオンライントレードシステム、ベルシステム24の営業支援システムなど。
ブログ(C:\narun)も更新中。
Copyright © ITmedia, Inc. All Rights Reserved.