ドラッグ&ドロップテスト改造

先日、AIRでドラッグ&ドロップのサンプルプログラムを動かしましたが、改造してみました。
やったのは、画面に表示したイメージオブジェクトを、ドラッグで動かせるようにするというもの。
こんな感じ↓(つっても、動いてないとわかりづらい・・・)


最初、ドロップした位置に画像が移動しませんでした。
なぜか、最初にイメージをつかんだ所に移動するんですよね。
どうやら、ドロップした時のマウス位置を取ったつもりだったが、AIRはイメージ(を持っているSprite)のマウス位置を保持し続けていたようです。
ドロップしたウィンドウ上の位置を取得するには、NativeDragEventのstageX/stageYというパラメータを取る必要があったみたい。
今回は、画面いっぱいにSpriteを置いて動かしたのでこれでOKでしたが、もしかしたらlocalX/localYというパラメータを使う必要があったのかもしれません。(今回は両者とも同じ値になっていました)


ソースはこんな感じ。

package {
    import flash.desktop.*;
    import flash.display.*;
    import flash.events.*;
    import flash.filesystem.*;
    import flash.geom.*;
    import flash.net.*;
    import flash.text.*;

    //ドラッグ&ドロップ
    public class DragDropEx2 extends Sprite {
        [Embed(source='text.gif')]
        private var TextImage:Class;
        [Embed(source='sample.gif')]
        private var SampleImage:Class;

        //private var dragTextField:TextField;//ドラッグテキストフィールド
        private var dragImage:Sprite;       //ドラッグイメージ
        private var dropField:Sprite;   //ドラッグテキストフィールド

        //コンストラクタ
        public function DragDropEx2() {
            //ドロップテキストフィールドの生成
            dropField=makeSpriteField(
                0, 0, 320, 320, 0xFFFFFF);
            dropField.addEventListener(
                NativeDragEvent.NATIVE_DRAG_ENTER, onDragEnter);
            dropField.addEventListener(
                NativeDragEvent.NATIVE_DRAG_DROP,  onDragDrop);
            addChild(dropField);

            //ドラッグイメージの生成
            dragImage=new Sprite();
            dragImage.x=10;
            dragImage.y=10;
            dragImage.addChild(new SampleImage());
            dragImage.addEventListener(
                MouseEvent.MOUSE_DOWN, onDragStart);
            dropField.addChild(dragImage);
            addChild(dragImage);
        }

        //テキストフィールドの生成
        private function makeSpriteField(x:int,
                                         y:int,
                                         width:int,
                                         height:int,
                                         color:int):Sprite {

            var sprite:Sprite=new Sprite();
            sprite.graphics.beginFill(color);
            sprite.graphics.drawRect(x, y, width, height);
            sprite.graphics.endFill();

            return sprite;
        }

        //ドラッグ開始イベントの処理
        private function onDragStart(evt:MouseEvent):void {
            trace("in :onDragStart()");
            
            var image :BitmapData;
            var offset:Point;
            var bitmap:Bitmap;

            //クリップボードオブジェクトの生成
            var cb:Clipboard=new Clipboard();

            //ドラッグイメージのデータ指定
            if (evt.target==dragImage) {
                bitmap=Bitmap(dragImage.getChildAt(0));
                cb.setData(ClipboardFormats.BITMAP_FORMAT, bitmap.bitmapData);
                image =bitmap.bitmapData;
                offset=new Point(-image.width/2, -image.height/2);
            }

            //ドラッグオプションの生成
            var options:NativeDragOptions=new NativeDragOptions();
            options.allowLink=true;

            //ドラッグの開始処理
            NativeDragManager.doDrag(this, cb, image, offset, options);
            
            trace("out:onDragStart()");
        }

        //ドラッグエンターイベントの処理
        public function onDragEnter(evt:NativeDragEvent):void {
            trace("in :onDragEnter()");
            //クリップボードの取得
            var cb:Clipboard=evt.clipboard;

            //ドラッグ可能かどうかのチェック
            if (cb.hasFormat(ClipboardFormats.BITMAP_FORMAT)) {
                //ドロップの許可
                NativeDragManager.acceptDragDrop(dropField);
                trace("    drag accepted");
            }
            trace("out:onDragEnter()");
        }

        //ドラッグドロップイベントの処理
        public function onDragDrop(evt:NativeDragEvent):void {
            trace("in :onDragDrop()");
            trace("    " + evt);
            //クリップボードの取得
            var cb:Clipboard=evt.clipboard;

            //ビットマップのドロップ
            if (cb.hasFormat(ClipboardFormats.BITMAP_FORMAT)) {
                var bitmap:Bitmap=new Bitmap(cb.getData(
                    ClipboardFormats.BITMAP_FORMAT) as BitmapData);
                
                // ドロップした位置にイメージを移動させる
                // →ドロップイベントからドロップ位置を取得して決定する
                dragImage.x = evt.stageX - (bitmap.width  / 2);
                dragImage.y = evt.stageY - (bitmap.height / 2);
                
                // 移動後の位置をターゲット範囲内に調整する
                if (dragImage.x < 0) {
                    dragImage.x = 0;
                }
                if (dragImage.x + bitmap.width >= dropField.width) {
                    dragImage.x = dropField.width - bitmap.width - 1;
                }
                
                if (dragImage.y < 0) {
                    dragImage.y = 0;
                }
                if (dragImage.y + bitmap.height >= dropField.height) {
                    dragImage.y = dropField.height - bitmap.height - 1;
                }
                trace("    dragImage --> (" + dragImage.x + ", " + dragImage.y + ")");
            }
            trace("out:onDragDrop()");
        }
    }
}