webui-aria2/js/libs/dojox/geo/charting/MouseInteractionSupport.js.uncompressed.js
2012-05-01 19:52:07 +08:00

336 lines
9.7 KiB
JavaScript

//>>built
define("dojox/geo/charting/MouseInteractionSupport", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/event",
"dojo/_base/connect","dojo/_base/window","dojo/_base/html","dojo/dom","dojo/_base/sniff"],
function(lang, declare, event, connect, win, html, dom, has) {
return declare("dojox.geo.charting.MouseInteractionSupport", null, {
// summary:
// class to handle mouse interactions on a dojox.geo.charting.Map widget
// tags:
// private
_map : null,
_mapClickLocation : null,
_screenClickLocation: null,
_mouseDragListener: null,
_mouseUpListener: null,
_mouseUpClickListener: null,
_mouseDownListener: null,
_mouseMoveListener: null,
_mouseWheelListener: null,
_currentFeature: null,
_cancelMouseClick: null,
_zoomEnabled: false,
_panEnabled: false,
_onDragStartListener: null,
_onSelectStartListener: null,
mouseClickThreshold: 2,
constructor : function(/* Map */map,/*boolean*/options) {
// summary:
// Constructs a new _MouseInteractionSupport instance
// map: dojox.geo.charting.Map
// the Map widget this class provides touch navigation for.
// options: object
// to enable panning and mouse wheel zooming
this._map = map;
this._mapClickLocation = {x: 0,y: 0};
this._screenClickLocation = {x: 0,y: 0};
this._cancelMouseClick = false;
if (options) {
this._zoomEnabled = options.enableZoom;
this._panEnabled = options.enablePan;
if (options.mouseClickThreshold && options.mouseClickThreshold > 0) {
this.mouseClickThreshold = options.mouseClickThreshold;
}
}
},
setEnableZoom: function(enable){
// summary:
// enables mouse zoom on the map
if (enable && !this._mouseWheelListener) {
// enable
var wheelEventName = !has("mozilla") ? "onmousewheel" : "DOMMouseScroll";
this._mouseWheelListener = this._map.surface.connect(wheelEventName, this, this._mouseWheelHandler);
} else if (!enable && this._mouseWheelListener) {
// disable
connect.disconnect(this._mouseWheelListener);
this._mouseWheelListener = null;
}
this._zoomEnabled = enable;
},
setEnablePan: function(enable){
// summary:
// enables mouse panning on the map
this._panEnabled = enable;
},
connect: function() {
// summary:
// connects this mouse support class to the Map component
// install mouse listeners
this._mouseMoveListener = this._map.surface.connect("onmousemove", this, this._mouseMoveHandler);
this._mouseDownListener = this._map.surface.connect("onmousedown", this, this._mouseDownHandler);
if (has("ie")) {
_onDragStartListener = connect.connect(win.doc,"ondragstart",this,event.stop);
_onSelectStartListener = connect.connect(win.doc,"onselectstart",this,event.stop);
}
this.setEnableZoom(this._zoomEnabled);
this.setEnablePan(this._panEnabled);
},
disconnect: function() {
// summary:
// disconnects any installed listeners
// store zoomPan state
var isZoom = this._zoomEnabled;
// disable zoom (disconnects listeners..)
this.setEnableZoom(false);
// restore value
this._zoomEnabled = isZoom;
// disconnect remaining listeners
if (this._mouseMoveListener) {
connect.disconnect(this._mouseMoveListener);
this._mouseMoveListener = null;
connect.disconnect(this._mouseDownListener);
this._mouseDownListener = null;
}
if (this._onDragStartListener) {
connect.disconnect(this._onDragStartListener);
this._onDragStartListener = null;
connect.disconnect(this._onSelectStartListener);
this._onSelectStartListener = null;
}
},
_mouseClickHandler: function(mouseEvent) {
// summary:
// action performed on the map when a mouse click was performed
// mouseEvent: the mouse event
// tags:
// private
var feature = this._getFeatureFromMouseEvent(mouseEvent);
if (feature) {
// call feature handler
feature._onclickHandler(mouseEvent);
} else {
// unselect all
for (var name in this._map.mapObj.features){
this._map.mapObj.features[name].select(false);
}
this._map.onFeatureClick(null);
}
},
_mouseDownHandler: function(mouseEvent){
// summary:
// action performed on the map when a mouse down was performed
// mouseEvent: the mouse event
// tags:
// private
event.stop(mouseEvent);
this._map.focused = true;
// set various status parameters
this._cancelMouseClick = false;
this._screenClickLocation.x = mouseEvent.pageX;
this._screenClickLocation.y = mouseEvent.pageY;
// store map location where mouse down occurred
var containerBounds = this._map._getContainerBounds();
var offX = mouseEvent.pageX - containerBounds.x,
offY = mouseEvent.pageY - containerBounds.y;
var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
this._mapClickLocation.x = mapPoint.x;
this._mapClickLocation.y = mapPoint.y;
// install drag listener if pan is enabled
if (!has("ie")) {
this._mouseDragListener = connect.connect(win.doc,"onmousemove",this,this._mouseDragHandler);
this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
this._mouseUpListener = connect.connect(win.doc,"onmouseup",this, this._mouseUpHandler);
} else {
var node = dom.byId(this._map.container);
this._mouseDragListener = connect.connect(node,"onmousemove",this,this._mouseDragHandler);
this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
this._mouseUpListener = this._map.surface.connect("onmouseup", this, this._mouseUpHandler);
this._map.surface.rawNode.setCapture();
}
},
_mouseUpClickHandler: function(mouseEvent) {
if (!this._cancelMouseClick) {
// execute mouse click handler
this._mouseClickHandler(mouseEvent);
}
this._cancelMouseClick = false;
},
_mouseUpHandler: function(mouseEvent) {
// summary:
// action performed on the map when a mouse up was performed
// mouseEvent: the mouse event
// tags:
// private
event.stop(mouseEvent);
this._map.mapObj.marker._needTooltipRefresh = true;
// disconnect listeners
if (this._mouseDragListener) {
connect.disconnect(this._mouseDragListener);
this._mouseDragListener = null;
}
if (this._mouseUpClickListener) {
connect.disconnect(this._mouseUpClickListener);
this._mouseUpClickListener = null;
}
if (this._mouseUpListener) {
connect.disconnect(this._mouseUpListener);
this._mouseUpListener = null;
}
if (has("ie")) {
this._map.surface.rawNode.releaseCapture();
}
},
_getFeatureFromMouseEvent: function(mouseEvent) {
// summary:
// utility function to return the feature located at this mouse event location
// mouseEvent: the mouse event
// returns: dojox.geo.charting.Feature
// the feature found if any, null otherwise.
// tags:
// private
var feature = null;
if (mouseEvent.gfxTarget && mouseEvent.gfxTarget.getParent) {
feature = this._map.mapObj.features[mouseEvent.gfxTarget.getParent().id];
}
return feature;
},
_mouseMoveHandler: function(mouseEvent) {
// summary:
// action performed on the map when a mouse move was performed
// mouseEvent: the mouse event
// tags:
// private
// do nothing more if dragging
if (this._mouseDragListener && this._panEnabled) {
return;
}
// hover and highlight
var feature = this._getFeatureFromMouseEvent(mouseEvent);
// set/unset highlight
if (feature != this._currentFeature) {
if (this._currentFeature) {
// mouse leaving component
this._currentFeature._onmouseoutHandler();
}
this._currentFeature = feature;
if (feature)
feature._onmouseoverHandler();
}
if (feature)
feature._onmousemoveHandler(mouseEvent);
},
_mouseDragHandler: function(mouseEvent){
// summary:
// action performed on the map when a mouse drag was performed
// mouseEvent: the mouse event
// tags:
// private
// prevent browser interaction
event.stop(mouseEvent);
// find out if this the movement discards the "mouse click" gesture
var dx = Math.abs(mouseEvent.pageX - this._screenClickLocation.x);
var dy = Math.abs(mouseEvent.pageY - this._screenClickLocation.y);
if (!this._cancelMouseClick && (dx > this.mouseClickThreshold || dy > this.mouseClickThreshold)) {
// cancel mouse click
this._cancelMouseClick = true;
if (this._panEnabled) {
this._map.mapObj.marker.hide();
}
}
if (!this._panEnabled)
return;
var cBounds = this._map._getContainerBounds();
var offX = mouseEvent.pageX - cBounds.x,
offY = mouseEvent.pageY - cBounds.y;
// compute map offset
var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
var mapOffsetX = mapPoint.x - this._mapClickLocation.x;
var mapOffsetY = mapPoint.y - this._mapClickLocation.y;
// adjust map center
var currentMapCenter = this._map.getMapCenter();
this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY);
},
_mouseWheelHandler: function(mouseEvent) {
// summary:
// action performed on the map when a mouse wheel up/down was performed
// mouseEvent: the mouse event
// tags:
// private
// prevent browser interaction
event.stop(mouseEvent);
// hide tooltip
this._map.mapObj.marker.hide();
// event coords within component
var containerBounds = this._map._getContainerBounds();
var offX = mouseEvent.pageX - containerBounds.x,
offY = mouseEvent.pageY - containerBounds.y;
// current map point before zooming
var invariantMapPoint = this._map.screenCoordsToMapCoords(offX,offY);
// zoom increment power
var power = mouseEvent[(has("mozilla") ? "detail" : "wheelDelta")] / (has("mozilla") ? - 3 : 120) ;
var scaleFactor = Math.pow(1.2,power);
this._map.setMapScaleAt(this._map.getMapScale()*scaleFactor ,invariantMapPoint.x,invariantMapPoint.y,false);
this._map.mapObj.marker._needTooltipRefresh = true;
}
});
});