1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview This class implements a mouse-drag event. It registers for
7 * mousedown events, and when it sees one, starts capturing mousemove events
8 * until it gets a mousup event. It manufactures three drag events: the
9 * DRAG_START, DRAG and DRAG_END.
15 * Constructor for the Dragger. Register for mousedown events that happen on
16 * |opt_target|. If |opt_target| is null or undefined, then this object
17 * observes mousedown on the whole document.
18 * @param {?Element} opt_target The event target. Defaults to the whole
22 tumbler.Dragger = function(opt_target) {
28 this.target_ = opt_target || document;
31 * The array of objects that get notified of drag events. Each object in
32 * this array get sent a handleStartDrag(), handleDrag() and handleEndDrag()
34 * @type {Array.<Object>}
40 * Flag to indicate whether the object is in a drag sequence or not.
44 this.isDragging_ = false;
47 * The function objects that get attached as event handlers. These are
48 * cached so that they can be removed on mouse up.
52 this.boundMouseMove_ = null;
53 this.boundMouseUp_ = null;
55 this.target_.addEventListener('mousedown',
56 this.onMouseDown.bind(this),
61 * The ids used for drag event types.
64 tumbler.Dragger.DragEvents = {
65 DRAG_START: 'dragstart', // Start a drag sequence
66 DRAG: 'drag', // Mouse moved during a drag sequence.
67 DRAG_END: 'dragend' // End a drag sewquence.
71 * Add a drag listener. Each listener should respond to thhree methods:
72 * handleStartDrag(), handleDrag() and handleEndDrag(). This method assumes
73 * that |listener| does not already exist in the array of listeners.
74 * @param {!Object} listener The object that will listen to drag events.
76 tumbler.Dragger.prototype.addDragListener = function(listener) {
77 this.listeners_.push(listener);
81 * Handle a mousedown event: register for mousemove and mouseup, then tell
82 * the target that is has a DRAG_START event.
83 * @param {Event} event The mousedown event that triggered this method.
85 tumbler.Dragger.prototype.onMouseDown = function(event) {
86 this.boundMouseMove_ = this.onMouseMove.bind(this);
87 this.boundMouseUp_ = this.onMouseUp.bind(this);
88 this.target_.addEventListener('mousemove', this.boundMouseMove_);
89 this.target_.addEventListener('mouseup', this.boundMouseUp_);
90 this.isDragging_ = true;
91 var dragStartEvent = { type: tumbler.Dragger.DragEvents.DRAG_START,
92 clientX: event.offsetX,
93 clientY: event.offsetY };
95 for (i = 0; i < this.listeners_.length; ++i) {
96 this.listeners_[i].handleStartDrag(this.target_, dragStartEvent);
101 * Handle a mousemove event: tell the target that is has a DRAG event.
102 * @param {Event} event The mousemove event that triggered this method.
104 tumbler.Dragger.prototype.onMouseMove = function(event) {
105 if (!this.isDragging_)
107 var dragEvent = { type: tumbler.Dragger.DragEvents.DRAG,
108 clientX: event.offsetX,
109 clientY: event.offsetY};
111 for (i = 0; i < this.listeners_.length; ++i) {
112 this.listeners_[i].handleDrag(this.target_, dragEvent);
117 * Handle a mouseup event: un-register for mousemove and mouseup, then tell
118 * the target that is has a DRAG_END event.
119 * @param {Event} event The mouseup event that triggered this method.
121 tumbler.Dragger.prototype.onMouseUp = function(event) {
122 this.target_.removeEventListener('mouseup', this.boundMouseUp_, false);
123 this.target_.removeEventListener('mousemove', this.boundMouseMove_, false);
124 this.boundMouseUp_ = null;
125 this.boundMouseMove_ = null;
126 this.isDragging_ = false;
127 var dragEndEvent = { type: tumbler.Dragger.DragEvents.DRAG_END,
128 clientX: event.offsetX,
129 clientY: event.offsetY};
131 for (i = 0; i < this.listeners_.length; ++i) {
132 this.listeners_[i].handleEndDrag(this.target_, dragEndEvent);