source: Dev/branches/rest-dojo-ui/client/dojo/dnd/Manager.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: 5.6 KB
Line 
1define(["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) {
2        // module:
3        //              dojo/dnd/Manager
4        // summary:
5        //              TODOC
6
7
8var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
9        // summary:
10        //              the manager of DnD operations (usually a singleton)
11        constructor: function(){
12                this.avatar  = null;
13                this.source = null;
14                this.nodes = [];
15                this.copy  = true;
16                this.target = null;
17                this.canDropFlag = false;
18                this.events = [];
19        },
20
21        // avatar's offset from the mouse
22        OFFSET_X: 16,
23        OFFSET_Y: 16,
24
25        // methods
26        overSource: function(source){
27                // summary:
28                //              called when a source detected a mouse-over condition
29                // source: Object
30                //              the reporter
31                if(this.avatar){
32                        this.target = (source && source.targetState != "Disabled") ? source : null;
33                        this.canDropFlag = Boolean(this.target);
34                        this.avatar.update();
35                }
36                dojo.publish("/dnd/source/over", [source]);
37        },
38        outSource: function(source){
39                // summary:
40                //              called when a source detected a mouse-out condition
41                // source: Object
42                //              the reporter
43                if(this.avatar){
44                        if(this.target == source){
45                                this.target = null;
46                                this.canDropFlag = false;
47                                this.avatar.update();
48                                dojo.publish("/dnd/source/over", [null]);
49                        }
50                }else{
51                        dojo.publish("/dnd/source/over", [null]);
52                }
53        },
54        startDrag: function(source, nodes, copy){
55                // summary:
56                //              called to initiate the DnD operation
57                // source: Object
58                //              the source which provides items
59                // nodes: Array
60                //              the list of transferred items
61                // copy: Boolean
62                //              copy items, if true, move items otherwise
63                this.source = source;
64                this.nodes  = nodes;
65                this.copy   = Boolean(copy); // normalizing to true boolean
66                this.avatar = this.makeAvatar();
67                dojo.body().appendChild(this.avatar.node);
68                dojo.publish("/dnd/start", [source, nodes, this.copy]);
69                this.events = [
70                        dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
71                        dojo.connect(dojo.doc, "onmouseup",   this, "onMouseUp"),
72                        dojo.connect(dojo.doc, "onkeydown",   this, "onKeyDown"),
73                        dojo.connect(dojo.doc, "onkeyup",     this, "onKeyUp"),
74                        // cancel text selection and text dragging
75                        dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
76                        dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
77                ];
78                var c = "dojoDnd" + (copy ? "Copy" : "Move");
79                dojo.addClass(dojo.body(), c);
80        },
81        canDrop: function(flag){
82                // summary:
83                //              called to notify if the current target can accept items
84                var canDropFlag = Boolean(this.target && flag);
85                if(this.canDropFlag != canDropFlag){
86                        this.canDropFlag = canDropFlag;
87                        this.avatar.update();
88                }
89        },
90        stopDrag: function(){
91                // summary:
92                //              stop the DnD in progress
93                dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
94                dojo.forEach(this.events, dojo.disconnect);
95                this.events = [];
96                this.avatar.destroy();
97                this.avatar = null;
98                this.source = this.target = null;
99                this.nodes = [];
100        },
101        makeAvatar: function(){
102                // summary:
103                //              makes the avatar; it is separate to be overwritten dynamically, if needed
104                return new dojo.dnd.Avatar(this);
105        },
106        updateAvatar: function(){
107                // summary:
108                //              updates the avatar; it is separate to be overwritten dynamically, if needed
109                this.avatar.update();
110        },
111
112        // mouse event processors
113        onMouseMove: function(e){
114                // summary:
115                //              event processor for onmousemove
116                // e: Event
117                //              mouse event
118                var a = this.avatar;
119                if(a){
120                        dojo.dnd.autoScrollNodes(e);
121                        //dojo.dnd.autoScroll(e);
122                        var s = a.node.style;
123                        s.left = (e.pageX + this.OFFSET_X) + "px";
124                        s.top  = (e.pageY + this.OFFSET_Y) + "px";
125                        var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
126                        if(this.copy != copy){
127                                this._setCopyStatus(copy);
128                        }
129                }
130        },
131        onMouseUp: function(e){
132                // summary:
133                //              event processor for onmouseup
134                // e: Event
135                //              mouse event
136                if(this.avatar){
137                        if(this.target && this.canDropFlag){
138                                var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))),
139                                params = [this.source, this.nodes, copy, this.target, e];
140                                dojo.publish("/dnd/drop/before", params);
141                                dojo.publish("/dnd/drop", params);
142                        }else{
143                                dojo.publish("/dnd/cancel");
144                        }
145                        this.stopDrag();
146                }
147        },
148
149        // keyboard event processors
150        onKeyDown: function(e){
151                // summary:
152                //              event processor for onkeydown:
153                //              watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
154                // e: Event
155                //              keyboard event
156                if(this.avatar){
157                        switch(e.keyCode){
158                                case dojo.keys.CTRL:
159                                        var copy = Boolean(this.source.copyState(true));
160                                        if(this.copy != copy){
161                                                this._setCopyStatus(copy);
162                                        }
163                                        break;
164                                case dojo.keys.ESCAPE:
165                                        dojo.publish("/dnd/cancel");
166                                        this.stopDrag();
167                                        break;
168                        }
169                }
170        },
171        onKeyUp: function(e){
172                // summary:
173                //              event processor for onkeyup, watching for CTRL for copy/move status
174                // e: Event
175                //              keyboard event
176                if(this.avatar && e.keyCode == dojo.keys.CTRL){
177                        var copy = Boolean(this.source.copyState(false));
178                        if(this.copy != copy){
179                                this._setCopyStatus(copy);
180                        }
181                }
182        },
183
184        // utilities
185        _setCopyStatus: function(copy){
186                // summary:
187                //              changes the copy status
188                // copy: Boolean
189                //              the copy status
190                this.copy = copy;
191                this.source._markDndStatus(this.copy);
192                this.updateAvatar();
193                dojo.replaceClass(dojo.body(),
194                        "dojoDnd" + (this.copy ? "Copy" : "Move"),
195                        "dojoDnd" + (this.copy ? "Move" : "Copy"));
196        }
197});
198
199// dojo.dnd._manager:
200//              The manager singleton variable. Can be overwritten if needed.
201dojo.dnd._manager = null;
202
203Manager.manager = dojo.dnd.manager = function(){
204        // summary:
205        //              Returns the current DnD manager.  Creates one if it is not created yet.
206        if(!dojo.dnd._manager){
207                dojo.dnd._manager = new dojo.dnd.Manager();
208        }
209        return dojo.dnd._manager;       // Object
210};
211
212return Manager;
213});
Note: See TracBrowser for help on using the repository browser.