以下、面倒なんでドラッグ&ドロップ(Drag and Drop)をDDと略します。
まず。ドラッグして移動するアイテムをfromオブジェクト、fromオブジェクトを格納する先をtoオブジェクトと仮に呼称しておきます(なんか正式名称あったら速攻切り替えますw)。
双オブジェクトとも、mx.core.UIComponentの派生クラスならOKなようです。
で…まず、仕様によらない、DDの考察を。
fromオブジェクト
・マウスをクリック(ダウン)して
・そのままの状態でマウスが移動:オブジェクトが移動する
toオブジェクト
・移動中のfromオブジェクトがtoオブジェクトの上空にいる
・その状態でマウスアップ(クリックの指を外す)が発生する
・fromオブジェクトを受け入れる準備が整ったので「かも〜ん」
こんな感じでげしょか?
とりあえず、雑に領域を用意してみましょう。fromオブジェクトにはボタンを、toオブジェクトにはパネルを用意します。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="onComplete()"> <!-- ********************************** --> <mx:Script source="base.as" /> <!-- ********************************** --> <mx:Panel> <mx:Panel id="p1" > </mx:Panel> <mx:Button id="bt1" label="●" /> </mx:Panel> </mx:Application>
…デザイン? なにそれおいしい?
おいといて。
では。まず「fromオブジェクトをふらふらと動かせる」ようにしてみませう。
fromオブジェクトでは、マウスをクリック(mouseDown)、マウス移動(mouseMove)のほかに。マウスのクリックで手を離してしまった時用にマウスアップ(mouseUp)のイベントを捕捉します。
private function onComplete():void{ // マウスダウンを捕捉 bt1.addEventListener(MouseEvent.MOUSE_DOWN, m_down); // マウスアップを捕捉 bt1.addEventListener(MouseEvent.MOUSE_UP, m_up); // マウス移動を捕捉 bt1.addEventListener(MouseEvent.MOUSE_MOVE, m_move); } // マウスダウン private function m_down(e:MouseEvent):void{ Alert.show("mouse_doun"); } // マウスアップ private function m_up(e:MouseEvent):void{ Alert.show("mouse_up"); } // マウス移動 private function m_move(e:MouseEvent):void{ Alert.show("mouse_move"); }
一応動くけど…いやまぁ反応よくて面倒(苦笑
traceにしたほうが、多分試しやすいです。…moveとか凄い量になりそうだけど。
んで。イベントに反応して「実際に動かしてみたい」ので。
ちと小細工します。
動かすので、中核になるのはmoveイベント。
moveイベント内で「マウスダウンが発生したらフラグ立てて動けるようにして、マウスアップを検出したらフラグを寝かせる」ようにします…ので、先にフラグの実装から。
import flash.events.MouseEvent; import mx.controls.Alert; private function onComplete():void{ // マウスダウンを捕捉 bt1.addEventListener(MouseEvent.MOUSE_DOWN, m_down); // マウスアップを捕捉 bt1.addEventListener(MouseEvent.MOUSE_UP, m_up); // マウス移動を捕捉 bt1.addEventListener(MouseEvent.MOUSE_MOVE, m_move); } // マウスダウン private function m_down(e:MouseEvent):void{ this.m_flg_ = true; } // マウスアップ private function m_up(e:MouseEvent):void{ this.m_flg_ = false; } // マウス移動 private function m_move(e:MouseEvent):void{ Alert.show("mouse_move"); } //private private var m_flg_:Boolean = false; // マウスダウンでtrueにする
で…動かすには、DragManagerという子にお願いをする必要があるようです。DragManagerのdoDrag()メソッドが必要なようなので…まずは仕様の確認。
public static function doDrag(dragInitiator:IUIComponent, dragSource:DragSource, mouseEvent:MouseEvent, dragImage:IFlexDisplayObject = null, xOffset:Number = 0, yOffset:Number = 0, imageAlpha:Number = 0.5, allowMove:Boolean = true):void
ドラッグ & ドロップ操作を開始します。
パラメータ
dragInitiator:IUIComponent ― ドラッグを開始するコンポーネントを指定する IUIComponent です。
dragSource:DragSource ― ドラッグされているデータを含む DragSource オブジェクトです。
mouseEvent:MouseEvent ― ドラッグを開始するためのマウス情報を含む MouseEvent です。
dragImage:IFlexDisplayObject (default = null) ― ドラッグするイメージ。この引数はオプションです。省略した場合、ドラッグ & ドロップ操作時には標準的なドラッグ長方形が使用されます。イメージを指定する場合は、イメージの高さと幅を明示的に設定しないとイメージが表示されません。
xOffset:Number (default = 0) ― dragImage の x オフセットをピクセル単位で指定する数値です。この引数はオプションです。これを省略すると、ドラッグプロキシはドラッグイニシエータの左上隅に表示されます。このオフセットは、ドラッグプロキシの左端からドラッグイニシエータの左端までのピクセル数として表され、通常は負の数値になります。
yOffset:Number (default = 0) ― dragImage の y オフセットをピクセル単位で指定する数値です。この引数はオプションです。これを省略すると、ドラッグプロキシはドラッグイニシエータの左上隅に表示されます。このオフセットは、ドラッグプロキシの上端からドラッグイニシエータの上端までのピクセル数として表され、通常は負の数値になります。
imageAlpha:Number (default = 0.5) ― dragImage に使用されるアルファ値を指定する数値です。この引数はオプションです。省略した場合のデフォルトのアルファ値は 0.5 です。値が 0.0 の場合、イメージは透明であることを示します。値が 1.0 の場合、イメージは完全な不透明であることを示します。
allowMove:Boolean (default = true)
まず第一パラメタはfromオブジェクトであるbt1を。
第二パラメタは…DragSource って、なんじゃらほい?
DragSource クラスには、ドラッグされるデータが格納されます。このデータには複数の形式が使用されます。たとえば、テキストコンポーネントにはプレーンテキスト、リッチテキスト、HTML データが入ります。
はぁ…つまり「移動させるブツそのものが入る」でよいのかしらん?
いくつか、余所様のサイトから、これに関連するあたりを引っかけてみる。
var ds:DragSource = new DragSource(); ds.addData(ddbox, "canvas");
// DragSource オブジェクトを作成します。 var ds:DragSource = new DragSource(); // オブジェクトにデータを追加します。 ds.addData(text, format);
これ↑はdragIt(event, 'red', 'color')とcallされてる。
//ドラッグされるデータを作成 var dragSource:DragSource = new DragSource(); dragSource.addData(image.source, "img");
第二引数が…よぉわからん。で、調べる。
addData () メソッド
public function addData(data:Object, format:String):voidデータ、および対応する形式のストリングをドラッグソースに追加します。このメソッドは値を返しません。
パラメータ
data:Object ― ドラッグデータを指定するオブジェクトです。String、DataProvider など、任意のオブジェクトを使用できます。
format:String ― このデータの形式を記述するラベルを指定するストリングです。
なるほどようはハンドル名らしい。
で…やってみた。
// import flash.events.MouseEvent; import mx.core.DragSource; import mx.managers.DragManager; private function onComplete():void{ // マウスダウンを捕捉 bt1.addEventListener(MouseEvent.MOUSE_DOWN, m_down); // マウスアップを捕捉 bt1.addEventListener(MouseEvent.MOUSE_UP, m_up); // マウス移動を捕捉 bt1.addEventListener(MouseEvent.MOUSE_MOVE, m_move); } // マウスダウン private function m_down(e:MouseEvent):void{ this.m_flg_ = true; } // マウスアップ private function m_up(e:MouseEvent):void{ this.m_flg_ = false; } // マウス移動 private function m_move(e:MouseEvent):void{ if (true == this.m_flg_) { var ds:DragSource = new DragSource; ds.addData(bt1, "bt1"); DragManager.doDrag(bt1, ds, e); } } //private private var m_flg_:Boolean = false; // マウスダウンでtrueにする
をを動く!!
で…このままだと固定値が多くていやなので。
マウスイベントで情報取れないかなぁ…おもってたらついでに一案。マウスダウンだけで実装できね?
まず。マウスイベントは…その中にcurrentTargetってのがあるです。
っつわけで、調査。
// マウスダウン private function m_down(e:MouseEvent):void{ trace( e.currentTarget ); trace( e.currentTarget.className ); }
DD2_0.Panel4.bt1
Button
ふむり。んでは…がりごりっとテスト実装。
// マウスダウン private function m_down(e:MouseEvent):void{ //DragManager.doDrag(bt1, ds, e); var ds:DragSource = new DragSource(); ds.addData(e.currentTarget, "test"); DragManager.doDrag(e.currentTarget, ds, e); }
あれ? エラーが出る。どうやら、本当はButton型なのに「やってきたのがObject型だから僕Object型としてしか見なさないモン」と言ってるらしい…融通のきかない orz
とりあえずButtonクラスにキャストしてみる。
// マウスダウン
private function m_down(e:MouseEvent):void{
var b:Button;
b = e.currentTarget as Button;
var ds:DragSource = new DragSource();
ds.addData(e.currentTarget, "test");
DragManager.doDrag(b, ds, e);
}
無問題。で…余所で見たんだけど…DragSourceがどうもいらないくさい。実験くん。
// マウスダウン private function m_down(e:MouseEvent):void{ var b:Button; b = e.currentTarget as Button; DragManager.doDrag(b, new DragSource(), e); }
よしいける!!
問題がなきゃこのままいきまっしょ。
現状のソース。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="onComplete()"> <!-- ********************************** --> <mx:Script source="base.as" /> <!-- ********************************** --> <mx:Panel> <mx:Panel id="p1" > </mx:Panel> <mx:Button id="bt1" label="●" /> </mx:Panel> </mx:Application>
Script
// import flash.events.MouseEvent; import mx.containers.Box; import mx.controls.Button; import mx.core.DragSource; import mx.managers.DragManager; private function onComplete():void{ // マウスダウンを捕捉 bt1.addEventListener(MouseEvent.MOUSE_DOWN, m_down); } // マウスダウン private function m_down(e:MouseEvent):void{ var b:Button; b = e.currentTarget as Button; DragManager.doDrag(b, new DragSource(), e); } //private