3
import flash.events.MouseEvent;
7
* Simplifies creation of drag-and-drop operations by handling the common functionality.
9
class DragMaster extends AnimatedWidget
11
static var singleton : DragMaster;
13
public var filtersBad : Array<flashx.filter.Filter>;
14
public var filtersGood : Array<flashx.filter.Filter>;
15
public var dragStart : Int; //how much the mouse must move before the drag actually starts
18
* Starts dragging a particular object. This object will be added to the stage at the current
19
* mouse location with the offset applied. It is assumed to have the correct size. It will
20
* be allowed to be dragged around the stage and dropped on a target which can
23
* @param object [in,keep] the object to drag around
24
* @param offset [in] how far the top-left/origin of the object should be positioned relative to the mouse
25
* @param controller [in] the interface used to decide how to handle the dragging
26
* @param data [in,keep] custom data passed back to the controller
28
static public function startDrag( controller : DragController, data : Dynamic )
30
ASSERT_NULL( singleton );
32
singleton = new DragMaster( controller, data );
33
flash.Lib.current.stage.addChild( singleton );
34
singleton.origPos = Point2.at( singleton.stage.mouseX, singleton.stage.mouseY );
35
ui.Events.captureMouse( singleton );
37
return singleton; //allows setting options
41
* Cancels any drag operation currently in progress.
43
static public function cancelDrag()
45
if( singleton == null )
53
ctl.dragAbort( data );
59
ctl.dragCancel( data );
65
ui.Events.endCapture( this );
66
flash.Lib.current.stage.removeChild( singleton );
69
object.getNative().filters = origFilters;
75
var ctl : DragController;
76
var cancelIn : Null<Float>;
77
var origFilters : Array<Dynamic>;
82
function new( ctl, data )
89
dragStart = 0; //start on any move by default
93
addEventListener( MouseEvent.MOUSE_UP, onMouseUp );
94
addEventListener( MouseEvent.MOUSE_MOVE, onMouseMove );
95
addEventListener( MouseEvent.MOUSE_OVER, onMouseOver );
96
addEventListener( MouseEvent.MOUSE_OUT, onMouseOut );
100
* Actually starts the dragging operation. Up until this point it was rather
101
* tentative with minimal work done in case dragging is not actually to be performed.
103
function startDragNow( sp : Point2 )
106
var d = ctl.dragStart( data, sp );
109
origFilters = object.getNative().filters;
111
singleton.addChild( object.getNative() );
112
singleton.positionObject();
115
function onMouseMove( ev : MouseEvent )
119
//check if we've moved far enough to start
120
var sp = Point2.at( stage.mouseX, stage.mouseY );
121
if( sp.distanceTo( origPos ) < dragStart )
128
function onMouseUp( ev : MouseEvent )
130
//if we haven't started allow the event to propogate normally and we simply abord the drag
133
Events.captureContProp = true;
138
//check if we can accept here and then accept or cancel
139
var sp = Point2.at( stage.mouseX, stage.mouseY );
140
var loc = sp.add( offset );
142
if( !ctl.dragCanAccept( data, sp, loc ) )
146
//it could still be rejected now
147
if( !ctl.dragAccept( data, sp, loc ) )
154
function onMouseOver( ev : MouseEvent )
156
//if we come back to our window and the mouse isn't down, cancel the drag
161
function onMouseOut( ev : MouseEvent )
163
//if we are out of bounds too long then we simply cancel the drag
167
function positionObject()
169
var sp = Point2.at( stage.mouseX, stage.mouseY );
170
var loc = sp.add( offset );
171
object.move( loc.x, loc.y );
173
//apply filters based on accept at this point
174
if( ctl.dragCanAccept( data, sp, loc ) )
175
object.getNative().filters = filtersGood;
177
object.getNative().filters = filtersBad;
180
override function _animate( elapsed : Float )
182
//run the cancellation timeout
183
if( cancelIn != null )
194
public function enableFullStage()
200
override function _resize( w : Float, h : Float )
202
//not awlays needed, so only do if requested (efficiency)
205
//full area to ensure mouse events capture
206
gfx.use( draw.Brush.clear() );
207
gfx.drawRect( 0, 0, w, h );