source: Dev/branches/rest-dojo-ui/client/dojo/dnd/Mover.js @ 263

Last change on this file since 263 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 3.9 KB
Line 
1define(["../main", "../Evented", "../touch", "./common", "./autoscroll"], function(dojo, Evented, touch) {
2        // module:
3        //              dojo/dnd/Mover
4        // summary:
5        //              TODOC
6
7
8dojo.declare("dojo.dnd.Mover", [Evented], {
9        constructor: function(node, e, host){
10                // summary:
11                //              an object which makes a node follow the mouse, or touch-drag on touch devices.
12                //              Used as a default mover, and as a base class for custom movers.
13                // node: Node
14                //              a node (or node's id) to be moved
15                // e: Event
16                //              a mouse event, which started the move;
17                //              only pageX and pageY properties are used
18                // host: Object?
19                //              object which implements the functionality of the move,
20                //              and defines proper events (onMoveStart and onMoveStop)
21                this.node = dojo.byId(node);
22                this.marginBox = {l: e.pageX, t: e.pageY};
23                this.mouseButton = e.button;
24                var h = (this.host = host), d = node.ownerDocument;
25                this.events = [
26                        // At the start of a drag, onFirstMove is called, and then the following two
27                        // connects are disconnected
28                        dojo.connect(d, touch.move, this, "onFirstMove"),
29
30                        // These are called continually during the drag
31                        dojo.connect(d, touch.move, this, "onMouseMove"),
32
33                        // And these are called at the end of the drag
34                        dojo.connect(d, touch.release,   this, "onMouseUp"),
35
36                        // cancel text selection and text dragging
37                        dojo.connect(d, "ondragstart",   dojo.stopEvent),
38                        dojo.connect(d.body, "onselectstart", dojo.stopEvent)
39                ];
40                // notify that the move has started
41                if(h && h.onMoveStart){
42                        h.onMoveStart(this);
43                }
44        },
45        // mouse event processors
46        onMouseMove: function(e){
47                // summary:
48                //              event processor for onmousemove/ontouchmove
49                // e: Event
50                //              mouse/touch event
51                dojo.dnd.autoScroll(e);
52                var m = this.marginBox;
53                this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
54                dojo.stopEvent(e);
55        },
56        onMouseUp: function(e){
57                if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
58                                e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
59                        this.destroy();
60                }
61                dojo.stopEvent(e);
62        },
63        // utilities
64        onFirstMove: function(e){
65                // summary:
66                //              makes the node absolute; it is meant to be called only once.
67                //              relative and absolutely positioned nodes are assumed to use pixel units
68                var s = this.node.style, l, t, h = this.host;
69                switch(s.position){
70                        case "relative":
71                        case "absolute":
72                                // assume that left and top values are in pixels already
73                                l = Math.round(parseFloat(s.left)) || 0;
74                                t = Math.round(parseFloat(s.top)) || 0;
75                                break;
76                        default:
77                                s.position = "absolute";        // enforcing the absolute mode
78                                var m = dojo.marginBox(this.node);
79                                // event.pageX/pageY (which we used to generate the initial
80                                // margin box) includes padding and margin set on the body.
81                                // However, setting the node's position to absolute and then
82                                // doing dojo.marginBox on it *doesn't* take that additional
83                                // space into account - so we need to subtract the combined
84                                // padding and margin.  We use getComputedStyle and
85                                // _getMarginBox/_getContentBox to avoid the extra lookup of
86                                // the computed style.
87                                var b = dojo.doc.body;
88                                var bs = dojo.getComputedStyle(b);
89                                var bm = dojo._getMarginBox(b, bs);
90                                var bc = dojo._getContentBox(b, bs);
91                                l = m.l - (bc.l - bm.l);
92                                t = m.t - (bc.t - bm.t);
93                                break;
94                }
95                this.marginBox.l = l - this.marginBox.l;
96                this.marginBox.t = t - this.marginBox.t;
97                if(h && h.onFirstMove){
98                        h.onFirstMove(this, e);
99                }
100
101                // Disconnect onmousemove and ontouchmove events that call this function
102                dojo.disconnect(this.events.shift());
103        },
104        destroy: function(){
105                // summary:
106                //              stops the move, deletes all references, so the object can be garbage-collected
107                dojo.forEach(this.events, dojo.disconnect);
108                // undo global settings
109                var h = this.host;
110                if(h && h.onMoveStop){
111                        h.onMoveStop(this);
112                }
113                // destroy objects
114                this.events = this.node = this.host = null;
115        }
116});
117
118return dojo.dnd.Mover;
119});
Note: See TracBrowser for help on using the repository browser.