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

145 lines
4.6 KiB
JavaScript

//>>built
define("dojox/geo/charting/KeyboardInteractionSupport", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/event","dojo/_base/connect",
"dojo/_base/html","dojo/dom","dojox/lang/functional","dojo/keys"],
function(lang, declare, event, connect, html, dom, functional, keys) {
return declare("dojox.geo.charting.KeyboardInteractionSupport", null, {
// summary:
// class to handle keyboard interactions on a dojox.geo.charting.Map widget
//
// The sections on the leading edge should receive the focus in response to a TAB event.
// Then use cursor keys to the peer sections. The cursor event should go the adjacent section
// in that direction. With the focus, the section zooms in upon SPACE. The map should zoom out
// on ESC. Finally, while it has the focus, the map should lose the focus on TAB.
// tags:
// private
_map: null,
_zoomEnabled: false,
constructor: function(map, options){
// summary:
// Constructs a new _KeyboardInteractionSupport instance
// map: dojox.geo.charting.Map
// the Map widget this class provides touch navigation for.
this._map = map;
if(options){
this._zoomEnabled = options.enableZoom;
}
},
connect: function(){
// summary:
// connects this keyboard support class to the Map component
var container = dom.byId(this._map.container);
// tab accessing enable
html.attr(container, {
tabindex: 0,
role: "presentation",
"aria-label": "map"
});
// install listeners
this._keydownListener = connect.connect(container, "keydown", this, "keydownHandler");
this._onFocusListener = connect.connect(container, "focus", this, "onFocus");
this._onBlurListener = connect.connect(container, "blur", this, "onBlur");
},
disconnect: function(){
// summary:
// disconnects any installed listeners
connect.disconnect(this._keydownListener);
this._keydownListener = null;
connect.disconnect(this._onFocusListener);
this._onFocusListener = null;
connect.disconnect(this._onBlurListener);
this._onBlurListener = null
},
keydownHandler: function(e){
switch(e.keyCode){
case keys.LEFT_ARROW:
this._directTo(-1,-1,1,-1);
break;
case keys.RIGHT_ARROW:
this._directTo(-1,-1,-1,1);
break;
case keys.UP_ARROW:
this._directTo(1,-1,-1,-1);
break;
case keys.DOWN_ARROW:
this._directTo(-1,1,-1,-1);
break;
case keys.SPACE:
if(this._map.selectedFeature && !this._map.selectedFeature._isZoomIn && this._zoomEnabled){
this._map.selectedFeature._zoomIn();
}
break;
case keys.ESCAPE:
if(this._map.selectedFeature && this._map.selectedFeature._isZoomIn && this._zoomEnabled){
this._map.selectedFeature._zoomOut();
}
break;
default:
return;
}
event.stop(e);
},
onFocus: function(e){
// select the leading region at the map center
if(this._map.selectedFeature || this._map.focused){return;}
this._map.focused = true;
var leadingRegion,
needClick = false;
if(this._map.lastSelectedFeature){
leadingRegion = this._map.lastSelectedFeature;
}else{
var mapCenter = this._map.getMapCenter(),
minDistance = Infinity;
// find the region most closing to the map center
functional.forIn(this._map.mapObj.features, function(feature){
var distance = Math.sqrt(Math.pow(feature._center[0] - mapCenter.x, 2) + Math.pow(feature._center[1] - mapCenter.y, 2));
if(distance < minDistance){
minDistance = distance;
leadingRegion = feature;
}
});
needClick = true;
}
if(leadingRegion){
if(needClick) {
leadingRegion._onclickHandler(null);
}else{
}
this._map.mapObj.marker.show(leadingRegion.id);
}
},
onBlur: function(){
this._map.lastSelectedFeature = this._map.selectedFeature;
},
_directTo: function(up,down,left,right){
var currentSelected = this._map.selectedFeature,
centerX = currentSelected._center[0],
centerY = currentSelected._center[1],
minMargin = Infinity,
nextSelected = null;
functional.forIn(this._map.mapObj.features, function(feature){
var paddingX = Math.abs(centerX - feature._center[0]),
paddingY = Math.abs(centerY - feature._center[1]),
paddingSum = paddingX + paddingY;
if((up - down) * (centerY - feature._center[1]) > 0){
if(paddingX < paddingY && minMargin > paddingSum){
minMargin = paddingSum;
nextSelected = feature;
}
}
if((left - right) * (centerX - feature._center[0]) > 0){
if(paddingX > paddingY && minMargin > paddingSum){
minMargin = paddingSum;
nextSelected = feature;
}
}
});
if(nextSelected){
this._map.mapObj.marker.hide();
nextSelected._onclickHandler(null);
this._map.mapObj.marker.show(nextSelected.id);
}
}
});
});