1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
//>>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);
}
}
});
});
|