以下、面倒なんでドラッグ&ドロップ(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