Merge branch 'unstable' into touch-support
authorMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Aug 2011 21:00:14 +0000 (14:00 -0700)
committerMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Aug 2011 21:00:14 +0000 (14:00 -0700)
Conflicts:
src/main/resources/mouse.js

1  2 
src/main/resources/mouse.js

   *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
- function GuacamoleMouse(element) {
-       /*****************************************/
-       /*** Mouse Handler                     ***/
-       /*****************************************/
-     var mouseIndex = 0;
-     var mouseLeftButton   = 0;
-     var mouseMiddleButton = 0;
-     var mouseRightButton  = 0;
-     var mouseX = 0;
-     var mouseY = 0;
-     var absoluteMouseX = 0;
-     var absoluteMouseY = 0;
-     function getMouseState(up, down) {
-         var mouseState = new MouseEvent(mouseX, mouseY,
-                 mouseLeftButton, mouseMiddleButton, mouseRightButton, up, down);
-         return mouseState;
-     }
+ // Guacamole namespace
+ var Guacamole = Guacamole || {};
+ /**
+  * Provides cross-browser mouse events for a given element. The events of
+  * the given element are automatically populated with handlers that translate
+  * mouse events into a non-browser-specific event provided by the
+  * Guacamole.Mouse instance.
+  * 
+  * Touch event support is planned, but currently only in testing (translate
+  * touch events into mouse events).
+  * 
+  * @constructor
+  * @param {Element} element The Element to use to provide mouse events.
+  */
+ Guacamole.Mouse = function(element) {
+     /**
+      * Reference to this Guacamole.Mouse.
+      * @private
+      */
+     var guac_mouse = this;
+     /**
+      * The current mouse state. The properties of this state are updated when
+      * mouse events fire. This state object is also passed in as a parameter to
+      * the handler of any mouse events.
+      * 
+      * @type Guacamole.Mouse.State
+      */
+     this.currentState = new Guacamole.Mouse.State(
+         0, 0, 
+         false, false, false, false, false
+     );
+     /**
+      * Fired whenever the user presses a mouse button down over the element
+      * associated with this Guacamole.Mouse.
+      * 
+      * @event
+      * @param {Guacamole.Mouse.State} state The current mouse state.
+      */
+       this.onmousedown = null;
+     /**
+      * Fired whenever the user releases a mouse button down over the element
+      * associated with this Guacamole.Mouse.
+      * 
+      * @event
+      * @param {Guacamole.Mouse.State} state The current mouse state.
+      */
+       this.onmouseup = null;
+     /**
+      * Fired whenever the user moves the mouse over the element associated with
+      * this Guacamole.Mouse.
+      * 
+      * @event
+      * @param {Guacamole.Mouse.State} state The current mouse state.
+      */
+       this.onmousemove = null;
  
 -    // Block context menu so right-click gets sent properly
 -    element.oncontextmenu = function(e) {
 -        return false;
 -    };
 +    function moveMouse(pageX, pageY) {
  
-         absoluteMouseX = pageX;
-         absoluteMouseY = pageY;
-         mouseX = absoluteMouseX - element.offsetLeft;
-         mouseY = absoluteMouseY - element.offsetTop;
 -    element.onmousemove = function(e) {
 -
 -        e.stopPropagation();
 -
 -        var absoluteMouseX = e.pageX;
 -        var absoluteMouseY = e.pageY;
 -
 -        guac_mouse.currentState.x = absoluteMouseX - element.offsetLeft;
 -        guac_mouse.currentState.y = absoluteMouseY - element.offsetTop;
++        guac_mouse.currentState.x = pageX - element.offsetLeft;
++        guac_mouse.currentState.y = pageY - element.offsetTop;
  
          // This is all JUST so we can get the mouse position within the element
          var parent = element.offsetParent;
          while (parent) {
              if (parent.offsetLeft && parent.offsetTop) {
-                 mouseX -= parent.offsetLeft;
-                 mouseY -= parent.offsetTop;
+                 guac_mouse.currentState.x -= parent.offsetLeft;
+                 guac_mouse.currentState.y -= parent.offsetTop;
              }
              parent = parent.offsetParent;
          }
  
-         movementHandler(getMouseState(0, 0));
+         if (guac_mouse.onmousemove)
+             guac_mouse.onmousemove(guac_mouse.currentState);
  
 +    }
 +
 +
 +    // Block context menu so right-click gets sent properly
-     element.oncontextmenu = function(e) {return false;};
++    element.oncontextmenu = function(e) {
++        return false;
++    };
 +
 +    element.onmousemove = function(e) {
 +
 +        e.stopPropagation();
 +
 +        moveMouse(e.pageX, e.pageY);
 +
 +    };
 +
 +    element.ontouchend = function(e) {
 +        
 +        e.stopPropagation();
 +        e.preventDefault();
 +
 +        // Release all buttons (FIXME: for now...)
 +        if (mouseLeftButton || mouseMiddleButton || mouseRightButton) {
 +            mouseLeftButton = 0;
 +            mouseMiddleButton = 0;
 +            mouseRightButton = 0;
 +
 +            buttonReleasedHandler(getMouseState(0, 0));
 +        }
 +
 +    }
 +
 +    element.ontouchstart = function(e) {
 +
 +        e.stopPropagation();
 +        e.preventDefault();
 +
 +        if (e.touches.length == 1)
 +            element.ontouchmove(e);
 +
 +        else {
 +            
 +            var button = e.touches[0];
 +            var pointer = e.touches[1];
 +
 +            if (pointer.pageX < button.pageX)
 +                mouseLeftButton = 1;
 +            else
 +                mouseRightButton = 1;
 +
 +            buttonPressedHandler(getMouseState(0, 0));
 +        }
 +
 +    };
 +
 +    element.ontouchmove = function(e) {
 +
 +        e.stopPropagation();
 +        e.preventDefault();
 +
 +        var touch = e.touches[0];
 +        moveMouse(touch.pageX, touch.pageY);
 +
      };
  
  
  
          switch (e.button) {
              case 0:
-                 mouseLeftButton = 1;
+                 guac_mouse.currentState.left = true;
                  break;
              case 1:
-                 mouseMiddleButton = 1;
+                 guac_mouse.currentState.middle = true;
                  break;
              case 2:
-                 mouseRightButton = 1;
+                 guac_mouse.currentState.right = true;
                  break;
          }
  
-         buttonPressedHandler(getMouseState(0, 0));
+         if (guac_mouse.onmousedown)
+             guac_mouse.onmousedown(guac_mouse.currentState);
      };
  
  
  
          switch (e.button) {
              case 0:
-                 mouseLeftButton = 0;
+                 guac_mouse.currentState.left = false;
                  break;
              case 1:
-                 mouseMiddleButton = 0;
+                 guac_mouse.currentState.middle = false;
                  break;
              case 2:
-                 mouseRightButton = 0;
+                 guac_mouse.currentState.right = false;
                  break;
          }
  
-         buttonReleasedHandler(getMouseState(0, 0));
+         if (guac_mouse.onmouseup)
+             guac_mouse.onmouseup(guac_mouse.currentState);
      };
  
      element.onmouseout = function(e) {
          e.stopPropagation();
  
          // Release all buttons
-         if (mouseLeftButton || mouseMiddleButton || mouseRightButton) {
-             mouseLeftButton = 0;
-             mouseMiddleButton = 0;
-             mouseRightButton = 0;
+         if (guac_mouse.currentState.left
+             || guac_mouse.currentState.middle
+             || guac_mouse.currentState.right) {
  
-             buttonReleasedHandler(getMouseState(0, 0));
+             guac_mouse.currentState.left = false;
+             guac_mouse.currentState.middle = false;
+             guac_mouse.currentState.right = false;
+             if (guac_mouse.onmouseup)
+                 guac_mouse.onmouseup(guac_mouse.currentState);
          }
  
      };
  
          // Up
          if (delta < 0) {
-             buttonPressedHandler(getMouseState(1, 0));
-             buttonReleasedHandler(getMouseState(0, 0));
+             if (guac_mouse.onmousedown) {
+                 guac_mouse.currentState.up = true;
+                 guac_mouse.onmousedown(guac_mouse.currentState);
+             }
+             if (guac_mouse.onmouseup) {
+                 guac_mouse.currentState.up = false;
+                 guac_mouse.onmouseup(guac_mouse.currentState);
+             }
          }
  
          // Down
          if (delta > 0) {
-             buttonPressedHandler(getMouseState(0, 1));
-             buttonReleasedHandler(getMouseState(0, 0));
+             if (guac_mouse.onmousedown) {
+                 guac_mouse.currentState.down = true;
+                 guac_mouse.onmousedown(guac_mouse.currentState);
+             }
+             if (guac_mouse.onmouseup) {
+                 guac_mouse.currentState.down = false;
+                 guac_mouse.onmouseup(guac_mouse.currentState);
+             }
          }
  
          if (e.preventDefault)
  
      element.onmousewheel = function(e) {
          handleScroll(e);
-     }
-       var buttonPressedHandler = null;
-       var buttonReleasedHandler = null;
-       var movementHandler = null;
-       this.setButtonPressedHandler  = function(mh) {buttonPressedHandler = mh;};
-       this.setButtonReleasedHandler = function(mh) {buttonReleasedHandler = mh;};
-       this.setMovementHandler = function(mh) {movementHandler = mh;};
-     this.getX = function() {return mouseX;};
-     this.getY = function() {return mouseY;};
-     this.getLeftButton = function() {return mouseLeftButton;};
-     this.getMiddleButton = function() {return mouseMiddleButton;};
-     this.getRightButton = function() {return mouseRightButton;};
- }
- function MouseEvent(x, y, left, middle, right, up, down) {
-     this.getX = function() {
-         return x;
-     };
-     this.getY = function() {
-         return y;
-     };
-     this.getLeft = function() {
-         return left;
-     };
-     this.getMiddle = function() {
-         return middle;
      };
  
-     this.getRight = function() {
-         return right;
-     };
-     this.getUp = function() {
-         return up;
-     };
-     this.getDown = function() {
-         return down;
-     };
+ };
+ /**
+  * Simple container for properties describing the state of a mouse.
+  * 
+  * @constructor
+  * @param {Number} x The X position of the mouse pointer in pixels.
+  * @param {Number} y The Y position of the mouse pointer in pixels.
+  * @param {Boolean} left Whether the left mouse button is pressed. 
+  * @param {Boolean} middle Whether the middle mouse button is pressed. 
+  * @param {Boolean} right Whether the right mouse button is pressed. 
+  * @param {Boolean} up Whether the up mouse button is pressed (the fourth
+  *                     button, usually part of a scroll wheel). 
+  * @param {Boolean} down Whether the down mouse button is pressed (the fifth
+  *                       button, usually part of a scroll wheel). 
+  */
+ Guacamole.Mouse.State = function(x, y, left, middle, right, up, down) {
+     /**
+      * The current X position of the mouse pointer.
+      * @type Number
+      */
+     this.x = x;
+     /**
+      * The current Y position of the mouse pointer.
+      * @type Number
+      */
+     this.y = y;
+     /**
+      * Whether the left mouse button is currently pressed.
+      * @type Boolean
+      */
+     this.left = left;
+     /**
+      * Whether the middle mouse button is currently pressed.
+      * @type Boolean
+      */
+     this.middle = middle
+     /**
+      * Whether the right mouse button is currently pressed.
+      * @type Boolean
+      */
+     this.right = right;
+     /**
+      * Whether the up mouse button is currently pressed. This is the fourth
+      * mouse button, associated with upward scrolling of the mouse scroll
+      * wheel.
+      * @type Boolean
+      */
+     this.up = up;
+     /**
+      * Whether the down mouse button is currently pressed. This is the fifth 
+      * mouse button, associated with downward scrolling of the mouse scroll
+      * wheel.
+      * @type Boolean
+      */
+     this.down = down;
+     
+ };
  
- }