diff --git a/.flexLibProperties b/.flexLibProperties index 05b7bde..e4dcb9e 100644 --- a/.flexLibProperties +++ b/.flexLibProperties @@ -76,6 +76,7 @@ + diff --git a/src/main/as/flashbang/objects/Dragger.as b/src/main/as/flashbang/objects/Dragger.as new file mode 100644 index 0000000..fb813ea --- /dev/null +++ b/src/main/as/flashbang/objects/Dragger.as @@ -0,0 +1,129 @@ +// +// Flashbang - a framework for creating Flash games +// Copyright (C) 2008-2012 Three Rings Design, Inc., All Rights Reserved +// http://github.com/threerings/flashbang +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library. If not, see . + +package flashbang.objects { + +import com.threerings.util.Preconditions; +import com.threerings.util.Registration; + +import flash.events.MouseEvent; +import flash.geom.Point; + +import flashbang.GameObject; +import flashbang.input.MouseListener; + +public class Dragger extends GameObject +{ + public function get dragging () :Boolean + { + return _dragReg != null; + } + + public function startDrag (e :MouseEvent) :void + { + Preconditions.checkState(!this.dragging, "already dragging"); + _listener = new DragListener(new Point(e.stageX, e.stageY), this.onDragged, + function (current :Point, start :Point) :void { + // stop the drag before calling onDragEnd, to allow safe destruction of the + // dragger from within onDragEnd + stopDrag(true); + onDragEnd(current, start); + }); + _dragReg = this.mode.mouseInput.registerListener(_listener); + } + + public function cancelDrag () :void + { + stopDrag(false); + } + + override protected function removedFromMode () :void + { + cancelDrag(); + super.removedFromMode(); + } + + protected function stopDrag (dragCompleted :Boolean) :void + { + if (_dragReg != null) { + _dragReg.cancel(); + _dragReg = null; + if (!dragCompleted) { + var start :Point = _listener.start; + var current :Point = _listener.current; + _listener = null; + onDragCanceled(current != null ? current : start, start); + } + } + } + + protected function onDragStart (start :Point) :void {} + protected function onDragged (current :Point, start :Point) :void {} + protected function onDragEnd (current :Point, start :Point) :void {} + protected function onDragCanceled (last :Point, start :Point) :void {} + + protected var _listener :DragListener; + protected var _dragReg :Registration; +} +} + +import flash.events.MouseEvent; +import flash.geom.Point; + +import flashbang.input.MouseReactor; +import flashbang.objects.Dragger; + +class DragListener extends MouseReactor +{ + public function DragListener (start :Point, onMouseMove :Function, onMouseUp :Function) + { + _start = start; + _onMouseMove = onMouseMove; + _onMouseUp = onMouseUp; + } + + public function get start () :Point + { + return _start; + } + + public function get current () :Point + { + return _current; + } + + override public function onMouseMove (e :MouseEvent) :Boolean + { + _current = new Point(e.stageX, e.stageY); + _onMouseMove(_current, _start); + return true; + } + + override public function onMouseUp (e :MouseEvent) :Boolean + { + _current = new Point(e.stageX, e.stageY); + _onMouseUp(_current, _start); + return true; + } + + protected var _start :Point; + protected var _current :Point; + + protected var _onMouseMove :Function; + protected var _onMouseUp :Function; +}