source: Dev/trunk/src/client/dojox/drawing/manager/Mouse.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 13.5 KB
Line 
1define(["dojo", "../util/oo", "../defaults"],
2function(dojo, oo, defaults){
3
4//dojox.drawing.manager.Mouse =
5return oo.declare(
6        function(/* Object */options){
7                this.util = options.util;
8                this.keys = options.keys;
9                this.id = options.id || this.util.uid("mouse");
10                this.currentNodeId = "";
11                this.registered = {};
12        },
13       
14        {
15                // summary:
16                //              Master object (instance) that tracks mouse
17                //              events. A new instance is created for each
18                //              Drawing object.
19                // description:
20                //              You could connect to any method or event in this
21                //              class, but it is designed to have the object
22                //              'registered'. All objects with the current event
23                //              will be called directly.
24                //
25                //              Custom events are used often. In addition to
26                //              standard events onDown, onUp, onDrag, etc, if
27                //              a certain object is clicked upon (or dragged, etc),
28                //              that object's drawingType will create the custom event,
29                //              such as onAnchorDown, or onStencilDown.
30
31
32                // doublClickSpeed: Number
33                //              Milliseconds between clicks to
34                //              register as for onDoubleClick
35                doublClickSpeed:400,
36               
37                // private properties
38               
39                _lastx:0,
40                _lasty:0,
41                __reg:0,
42                _downOnCanvas:false,
43               
44                /*=====
45                CustomEventMethod: {
46                        // summary:
47                        //              The custom event methods that an Object that has
48                        //              registered with manager.Mouse can receive.
49                        //              Can contain any or all of the following methods
50                        //              and they will be called on mouse events. All events
51                        //              will be sent a EventObject event object.
52                        //
53                        //              NOTE:
54                        //              Events happen anywhere in the document unless
55                        //              otherwise noted.
56
57                        // onMove: Function
58                        //              Fires on mousemove when mouse is up
59                        // onDown: Function
60                        //              Fires on mousedown *on the canvas*
61                        // onDrag: Function
62                        //              Fires on mousemove when mouse is down
63                        // onUp: Function
64                        //              Fires on mouseup, anywhere in the document
65                        // onStencilDown: Function
66                        //              Fired on mousedown on a Stencil
67                        // onStencilDrag: Function
68                        //              Fired when mouse moves and mose is down on a Stencil
69                        // onStencilUp: Function
70                        //              Fired on mouseup off of a Stencil
71                        // on[Custom]Up|Down|Move: Function
72                        //              Custom events can bet set and fired by setting a
73                        //              different drawingType on a Stencil, or by calling
74                        //              setEventMode(customEventName)
75                },
76                EventObject: function(){
77                        // summary:
78                        //              The custom event object that is sent to registered objects
79                        //              and their respective methods.
80                        //
81                        //              NOTE: Most event objects are the same with the exception
82                        //              of the onDown events, which have fewer.
83
84                        // id: String
85                        //              Id of the focused object (included in onDown)
86                        // pageX: Number
87                        //              The X coordinate of the mouse from the left side of
88                        //              the document. (included in onDown)
89                        // pageY: Number
90                        //              The Y coordinate of the mouse from the top of
91                        //              the document. (included in onDown)
92                        // x: Number
93                        //              The X coordinate of the mouse from the left side
94                        //              of the canvas (included in onDown)
95                        // y: Number
96                        //              The Y coordinate of the mouse from the top
97                        //              of the canvas (included in onDown)
98
99                        // last:        Object
100                        //              The x and y coordinates of the last mousemove
101                        //              relative to the canvas (not included in onDown)
102                        // move: Object
103                        //              The x and y amounts the mouse moved since the last event
104                        //              (not included in onDown)
105                        // orgX:        Number
106                        //              The left side of the canvas from the side of the document (not included in onDown)
107                        // orgY:        Number
108                        //              The top of the canvas from the top of the document (not included in onDown)
109                        // scroll: Object
110                        //              The 'top' and 'left' scroll amounts of the canvas. (not included in onDown)
111                        // start:       Object
112                        //              The x and y coordinates of the mousedown event (not included in onDown)
113                        // withinCanvas: Boolean
114                        //              Whether the event happened within the Canvas or not (not included in onDown)
115                },
116                =====*/
117                       
118                init: function(/* HTMLNode*/node){
119                        // summary:
120                        //              Internal. Initializes mouse.
121
122                        this.container = node;
123                        this.setCanvas();
124                        var c;
125                        var _isDown = false;
126                        dojo.connect(this.container, "rightclick", this, function(evt){
127                                console.warn("RIGHTCLICK")
128                        });
129                       
130                        dojo.connect(document.body, "mousedown", this, function(evt){
131                                //evt.preventDefault();
132                                //dojo.stopEvent(evt);
133                        });
134                       
135                        dojo.connect(this.container, "mousedown", this, function(evt){
136                                this.down(evt);
137                                // Right click shouldn't trigger drag
138                                if(evt.button != dojo.mouseButtons.RIGHT){
139                                        _isDown = true;
140                                        c = dojo.connect(document, "mousemove", this, "drag");
141                                }
142                        });
143                        dojo.connect(document, "mouseup", this, function(evt){
144                                dojo.disconnect(c);
145                                _isDown = false;
146                                this.up(evt);
147                        });
148                        dojo.connect(document, "mousemove", this, function(evt){
149                                if(!_isDown){
150                                        this.move(evt);
151                                }
152                        });
153                        dojo.connect(this.keys, "onEsc", this, function(evt){
154                                this._dragged = false;
155                        });
156                },
157               
158                setCanvas: function(){
159                        // summary:
160                        //              Internal. Sets canvas position
161                        var pos = dojo.position(this.container.parentNode);
162                        this.origin = dojo.clone(pos);
163                },
164               
165                scrollOffset: function(){
166                        // summary:
167                        //      Gets scroll offset of canvas
168                        return {
169                                top:this.container.parentNode.scrollTop,
170                                left:this.container.parentNode.scrollLeft
171                        }; // Object
172                },
173
174                resize: function(width,height){
175                        if(this.origin){
176                                this.origin.w=width;
177                                this.origin.h=height;
178                        }
179                },
180
181                register: function(/* CustomEventMethod*/scope){
182                        // summary:
183                        //              All objects (Stencils) should register here if they
184                        //              use mouse events. When registering, the object will
185                        //              be called if it has that method.
186                        //              See: CustomEventMethod and EventObject
187                        // scope:
188                        //              The object to be called
189                        // returns: handle
190                        //              Keep the handle to be used for disconnection.
191
192                        var handle = scope.id || "reg_"+(this.__reg++);
193                        if(!this.registered[handle]){ this.registered[handle] = scope; }
194                        return handle; // String
195                },
196                unregister: function(handle){
197                        // summary:
198                        //              Disconnects object. Mouse events are no longer
199                        //              called for it.
200                        if(!this.registered[handle]){ return; }
201                        delete this.registered[handle];
202                },
203               
204                _broadcastEvent:function(strEvt, obj){
205                        // summary:
206                        //              Fire events to all registered objects.
207
208                        //console.log("mouse.broadcast:", strEvt, obj)
209                        for(var nm in this.registered){
210                                if(this.registered[nm][strEvt]) this.registered[nm][strEvt](obj);
211                        }
212                },
213               
214                onDown: function(obj){
215                        // summary:
216                        //              Create on[xx]Down event and send to broadcaster.
217                        //              Could be connected to.
218                       
219                        //console.info("onDown:", this.eventName("down"))
220                        this._broadcastEvent(this.eventName("down"), obj);
221                },
222               
223                onDrag: function(obj){
224                        // summary:
225                        //              Create on[xx]Drag event and send to broadcaster.
226                        //              Could be connected to.
227
228                        var nm = this.eventName("drag");
229                        if(this._selected && nm == "onDrag"){
230                                nm = "onStencilDrag"
231                        }
232                        this._broadcastEvent(nm, obj);
233                },
234               
235                onMove: function(obj){
236                        // summary:
237                        //              Create onMove event and send to broadcaster.
238                        //              Could be connected to.
239                        //              Note: onMove never uses a custom event
240                        //              Note: onMove is currently not enabled in the app.
241
242                        this._broadcastEvent("onMove", obj);
243                },
244               
245                overName: function(obj,evt){
246                        var nm = obj.id.split(".");
247                        evt = evt.charAt(0).toUpperCase() + evt.substring(1);
248                        if(nm[0] == "dojox" && (defaults.clickable || !defaults.clickMode)){
249                                return "onStencil"+evt;
250                        }else{
251                                return "on"+evt;
252                        }
253                       
254                },
255               
256                onOver: function(obj){
257                        this._broadcastEvent(this.overName(obj,"over"), obj);
258                },
259               
260                onOut: function(obj){
261                        this._broadcastEvent(this.overName(obj,"out"), obj);
262                },
263               
264                onUp: function(obj){
265                        // summary:
266                        //              Create on[xx]Up event and send to broadcaster.
267                        //              Could be connected to.
268                       
269                        //      blocking first click-off (deselect), largely for TextBlock
270                        //      TODO: should have param to make this optional?
271                        var nm = this.eventName("up");
272                       
273                        if(nm == "onStencilUp"){
274                                this._selected  = true;
275                        }else if(this._selected && nm == "onUp"){ //////////////////////////////////////////
276                                nm = "onStencilUp";
277                                this._selected = false;
278                        }
279                       
280                        console.info("Up Event:", this.id, nm, "id:", obj.id);
281                        this._broadcastEvent(nm, obj);
282                       
283                        // Silverlight double-click handled in Silverlight class
284                        if(dojox.gfx.renderer == "silverlight"){ return; }
285                       
286                        // Check Double Click
287                        // If a double click is detected, the onDoubleClick event fires,
288                        // but does not replace the normal event. They both fire.
289                        this._clickTime = new Date().getTime();
290                        if(this._lastClickTime){
291                                if(this._clickTime-this._lastClickTime<this.doublClickSpeed){
292                                        var dnm = this.eventName("doubleClick");
293                                        console.warn("DOUBLE CLICK", dnm, obj);
294                                        this._broadcastEvent(dnm, obj);
295                                }else{
296                                        //console.log("    slow:", this._clickTime-this._lastClickTime)
297                                }
298                        }
299                        this._lastClickTime = this._clickTime;
300                       
301                },
302               
303                zoom: 1,
304                setZoom: function(zoom){
305                        // summary:
306                        //              Internal. Sets the mouse zoom percentage to
307                        //              that of the canvas
308                        this.zoom = 1/zoom;
309                },
310               
311                setEventMode: function(mode){
312                        // summary:
313                        //              Sets the mouse mode s that custom events can be called.
314                        //              Also can 'disable' events by using a bogus mode:
315                        // |    mouse.setEventMode("DISABLED")
316                        //              (unless any object subscribes to this event,
317                        //              it is effectively disabled)
318
319                        this.mode = mode ? "on" + mode.charAt(0).toUpperCase() + mode.substring(1) :  "";
320                },
321               
322                eventName: function(name){
323                        // summary:
324                        //              Internal. Determine the event name
325
326                        name = name.charAt(0).toUpperCase() + name.substring(1);
327                        if(this.mode){
328                                if(this.mode == "onPathEdit"){
329                                        return "on"+name;
330                                }
331                                if(this.mode == "onUI"){
332                                        //return "on"+name;
333                                }
334                                return this.mode + name;
335                        }else{
336                                //Allow a mode where stencils aren't clickable
337                                if(!defaults.clickable && defaults.clickMode){return "on"+name;}
338                                var dt = !this.drawingType || this.drawingType=="surface" || this.drawingType=="canvas" ? "" : this.drawingType;
339                                var t = !dt ? "" : dt.charAt(0).toUpperCase() + dt.substring(1);
340                                return "on"+t+name;
341                        }
342                },
343               
344                up: function(evt){
345                        // summary:
346                        //              Internal. Create onUp event
347
348                        this.onUp(this.create(evt));
349                },
350               
351                down: function(evt){
352                        // summary:
353                        //              Internal. Create onDown event
354
355                        this._downOnCanvas = true;
356                        var sc = this.scrollOffset();
357                        var dim = this._getXY(evt);
358                        this._lastpagex = dim.x;
359                        this._lastpagey = dim.y;
360                        var o = this.origin;
361                        var x = dim.x - o.x + sc.left;
362                        var y = dim.y - o.y + sc.top;
363                       
364                        var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
365                        x*= this.zoom;
366                        y*= this.zoom;
367                       
368                        o.startx = x;
369                        o.starty = y;
370                        this._lastx = x;
371                        this._lasty = y;
372                       
373                        this.drawingType = this.util.attr(evt, "drawingType") || "";
374                        var id = this._getId(evt);
375                        //console.log("DOWN:", this.id, id, withinCanvas);
376                        //console.log("this.drawingType:", this.drawingType);
377                       
378                        if(evt.button == dojo.mouseButtons.RIGHT && this.id == "mse"){
379                                //Allow right click events to bubble for context menus
380                        }else{
381                                evt.preventDefault();
382                                dojo.stopEvent(evt);
383                        }
384                        this.onDown({
385                                mid:this.id,
386                                x:x,
387                                y:y,
388                                pageX:dim.x,
389                                pageY:dim.y,
390                                withinCanvas:withinCanvas,
391                                id:id
392                        });
393                       
394                },
395                over: function(obj){
396                        // summary:
397                        //              Internal.
398
399                        this.onOver(obj);
400                },
401                out: function(obj){
402                        // summary:
403                        //              Internal.
404
405                        this.onOut(obj);
406                },
407                move: function(evt){
408                        // summary:
409                        //              Internal.
410
411                        var obj = this.create(evt);
412                        if(this.id=="MUI"){
413                                //console.log("obj.id:", obj.id, "was:", this.currentNodeId)
414                        }
415                        if(obj.id != this.currentNodeId){
416                                // TODO: I wonder if an ID is good enough
417                                //      that would avoid the mixin
418                                var outObj = {};
419                                for(var nm in obj){
420                                        outObj[nm] = obj[nm];
421                                }
422                                outObj.id = this.currentNodeId;
423                                this.currentNodeId && this.out(outObj);
424                                obj.id && this.over(obj);
425                                this.currentNodeId = obj.id;
426                        }
427                        this.onMove(obj);
428                },
429                drag: function(evt){
430                        // summary:
431                        //              Internal. Create onDrag event
432                        this.onDrag(this.create(evt, true));
433                },
434                create: function(evt, squelchErrors){
435                        // summary:
436                        //              Internal. Create EventObject
437
438                        var sc = this.scrollOffset();
439                        var dim = this._getXY(evt);
440                       
441                        var pagex = dim.x;
442                        var pagey = dim.y;
443                       
444                        var o = this.origin;
445                        var x = dim.x - o.x + sc.left;
446                        var y = dim.y - o.y + sc.top;
447
448                        var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
449                        x*= this.zoom;
450                        y*= this.zoom;
451                       
452                        var id = withinCanvas ? this._getId(evt, squelchErrors) : "";
453                        var ret = {
454                                mid:this.id,
455                                x:x,
456                                y:y,
457                                pageX:dim.x,
458                                pageY:dim.y,
459                                page:{
460                                        x:dim.x,
461                                        y:dim.y
462                                },
463                                orgX:o.x,
464                                orgY:o.y,
465                                last:{
466                                        x: this._lastx,
467                                        y: this._lasty
468                                },
469                                start:{
470                                        x: this.origin.startx, //+ sc.left,
471                                        y: this.origin.starty //+ sc.top
472                                },
473                                move:{
474                                        x:pagex - this._lastpagex,
475                                        y:pagey - this._lastpagey
476                                },
477                                scroll:sc,
478                                id:id,
479                                withinCanvas:withinCanvas
480                        };
481                       
482                        //console.warn("MSE LAST:", x-this._lastx, y-this._lasty)
483                        this._lastx = x;
484                        this._lasty = y;
485                        this._lastpagex = pagex;
486                        this._lastpagey = pagey;
487                        dojo.stopEvent(evt);
488                        return ret; //Object
489                },
490                _getId: function(evt, squelchErrors){
491                        // summary:
492                        //              Internal. Gets ID of focused node.
493                        return this.util.attr(evt, "id", null, squelchErrors); // String
494                },
495                _getXY: function(evt){
496                        // summary:
497                        //              Internal. Gets mouse coords to page.
498                        return {x:evt.pageX, y:evt.pageY}; // Object
499                },
500               
501                setCursor: function(cursor,/* HTMLNode*/node){
502                        // summary:
503                        //              Sets the cursor for  a given node.  If no
504                        //              node is specified the containing node is used.
505                        if(!node){
506                                dojo.style(this.container, "cursor", cursor);
507                        }else{
508                                dojo.style(node, "cursor", cursor);
509                        }
510                }
511        }
512);
513});
Note: See TracBrowser for help on using the repository browser.