ec4c7b1a2b77070248df38252a0b577c2cdd9450
[guacamole-common-js.git] / src / main / resources / mouse.js
1
2 /*
3  *  Guacamole - Clientless Remote Desktop
4  *  Copyright (C) 2010  Michael Jumper
5  *
6  *  This program is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU Affero General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Affero General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Affero General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 // Guacamole namespace
21 var Guacamole = Guacamole || {};
22
23 Guacamole.Mouse = function(element) {
24
25     var guac_mouse = this;
26
27     var mouseLeftButton   = 0;
28     var mouseMiddleButton = 0;
29     var mouseRightButton  = 0;
30
31     var mouseX = 0;
32     var mouseY = 0;
33
34     var absoluteMouseX = 0;
35     var absoluteMouseY = 0;
36
37
38     function getMouseState(up, down) {
39         var mouseState = new MouseEvent(mouseX, mouseY,
40                 mouseLeftButton, mouseMiddleButton, mouseRightButton, up, down);
41
42         return mouseState;
43     }
44
45
46     // Block context menu so right-click gets sent properly
47     element.oncontextmenu = function(e) {return false;};
48
49     element.onmousemove = function(e) {
50
51         e.stopPropagation();
52
53         absoluteMouseX = e.pageX;
54         absoluteMouseY = e.pageY;
55
56         mouseX = absoluteMouseX - element.offsetLeft;
57         mouseY = absoluteMouseY - element.offsetTop;
58
59         // This is all JUST so we can get the mouse position within the element
60         var parent = element.offsetParent;
61         while (parent) {
62             if (parent.offsetLeft && parent.offsetTop) {
63                 mouseX -= parent.offsetLeft;
64                 mouseY -= parent.offsetTop;
65             }
66             parent = parent.offsetParent;
67         }
68
69         if (guac_mouse.onmousemove)
70             guac_mouse.onmousemove(getMouseState(0, 0));
71     };
72
73
74     element.onmousedown = function(e) {
75
76         e.stopPropagation();
77
78         switch (e.button) {
79             case 0:
80                 mouseLeftButton = 1;
81                 break;
82             case 1:
83                 mouseMiddleButton = 1;
84                 break;
85             case 2:
86                 mouseRightButton = 1;
87                 break;
88         }
89
90         if (guac_mouse.onmousedown)
91             guac_mouse.onmousedown(getMouseState(0, 0));
92     };
93
94
95     element.onmouseup = function(e) {
96
97         e.stopPropagation();
98
99         switch (e.button) {
100             case 0:
101                 mouseLeftButton = 0;
102                 break;
103             case 1:
104                 mouseMiddleButton = 0;
105                 break;
106             case 2:
107                 mouseRightButton = 0;
108                 break;
109         }
110
111         if (guac_mouse.onmouseup)
112             guac_mouse.onmouseup(getMouseState(0, 0));
113     };
114
115     element.onmouseout = function(e) {
116
117         e.stopPropagation();
118
119         // Release all buttons
120         if (mouseLeftButton || mouseMiddleButton || mouseRightButton) {
121             mouseLeftButton = 0;
122             mouseMiddleButton = 0;
123             mouseRightButton = 0;
124
125             if (guac_mouse.onmouseup)
126                 guac_mouse.onmouseup(getMouseState(0, 0));
127         }
128
129     };
130
131     // Override selection on mouse event element.
132     element.onselectstart = function() {
133         return false;
134     };
135
136     // Scroll wheel support
137     function handleScroll(e) {
138
139         var delta = 0;
140         if (e.detail)
141             delta = e.detail;
142         else if (e.wheelDelta)
143             delta = -event.wheelDelta;
144
145         // Up
146         if (delta < 0) {
147             if (guac_mouse.onmousedown)
148                 guac_mouse.onmousedown(getMouseState(1, 0));
149
150             if (guac_mouse.onmouseup)
151                 guac_mouse.onmouseup(getMouseState(0, 0));
152         }
153
154         // Down
155         if (delta > 0) {
156             if (guac_mouse.onmousedown)
157                 guac_mouse.onmousedown(getMouseState(0, 1));
158             
159             if (guac_mouse.onmouseup)
160                 guac_mouse.onmouseup(getMouseState(0, 0));
161         }
162
163         if (e.preventDefault)
164             e.preventDefault();
165
166         e.returnValue = false;
167     }
168
169     element.addEventListener('DOMMouseScroll', handleScroll, false);
170
171     element.onmousewheel = function(e) {
172         handleScroll(e);
173     }
174
175         guac_mouse.onmousedown = null;
176         guac_mouse.onmouseup = null;
177         guac_mouse.onmousemove = null;
178
179     guac_mouse.getX = function() {return mouseX;};
180     guac_mouse.getY = function() {return mouseY;};
181     guac_mouse.getLeftButton = function() {return mouseLeftButton;};
182     guac_mouse.getMiddleButton = function() {return mouseMiddleButton;};
183     guac_mouse.getRightButton = function() {return mouseRightButton;};
184
185 }
186
187 function MouseEvent(x, y, left, middle, right, up, down) {
188
189     this.getX = function() {
190         return x;
191     };
192
193     this.getY = function() {
194         return y;
195     };
196
197     this.getLeft = function() {
198         return left;
199     };
200
201     this.getMiddle = function() {
202         return middle;
203     };
204
205     this.getRight = function() {
206         return right;
207     };
208
209     this.getUp = function() {
210         return up;
211     };
212
213     this.getDown = function() {
214         return down;
215     };
216
217 }