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
|
<!--
-- Copyright 2013 The Chromium Authors. All rights reserved.
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.
-->
<polymer-element name="kb-modifier-key" class="unlocked dark" extends="kb-key"
on-pointerout="{{out}}">
<script>
(function () {
/**
* The possible states of the key.
* @const
* @type {Enum}
*/
var KEY_STATES = {
PRESSED: "pressed", // Key-down.
UNLOCKED: "unlocked", // Default state.
TAPPED: "tapped", // Key-down followed by key-up.
CHORDING: "chording", // Chording mode.
};
/**
* A map of the state of all modifier keys.
* @type {Object}
*/
var states = {};
Polymer('kb-modifier-key', {
up: function(event) {
if (this.state == KEY_STATES.PRESSED)
this.state = KEY_STATES.TAPPED;
else
this.state = KEY_STATES.UNLOCKED;
this.super([event]);
},
down: function(event) {
// First transition state so that populateDetails generates
// correct data.
switch (this.state) {
case KEY_STATES.UNLOCKED:
this.state = KEY_STATES.PRESSED;
break;
case KEY_STATES.TAPPED:
this.state = KEY_STATES.UNLOCKED;
break;
case KEY_STATES.PRESSED:
case KEY_STATES.CHORDING:
// We pressed another key at the same time,
// so ignore second press.
return;
default:
console.error("Undefined key state: " + state);
break;
}
this.super([event]);
},
/**
* Returns whether the modifier for this key is active.
* @return {boolean}
*/
isActive: function() {
return this.state != KEY_STATES.UNLOCKED;
},
/**
* Notifies key that a non-control keyed down.
* A control key is defined as one of shift, control or alt.
*/
onNonControlKeyDown: function() {
switch(this.state) {
case (KEY_STATES.PRESSED):
this.state = KEY_STATES.CHORDING;
break;
}
},
/**
* Notifies key that a non-control keyed was typed.
* A control key is defined as one of shift, control or alt.
*/
onNonControlKeyTyped: function() {
switch(this.state) {
case (KEY_STATES.TAPPED):
this.state = KEY_STATES.UNLOCKED;
break;
}
},
/**
* Called on a pointer-out event. Ends chording.
* @param {event} event The pointer-out event.
*/
out: function(event) {
// TODO(rsadam): Add chording event so that we don't reset
// when shift-chording.
if (this.state == KEY_STATES.CHORDING) {
this.state = KEY_STATES.UNLOCKED;
}
},
/*
* Overrides the autoRelease function to enable chording.
*/
autoRelease: function() {
},
populateDetails: function(caller) {
var detail = this.super([caller]);
if (this.state != KEY_STATES.UNLOCKED)
detail.activeModifier = this.charValue;
return detail;
},
/**
* Resets the modifier key state.
*/
reset: function() {
this.state = KEY_STATES.UNLOCKED;
},
get state() {
var key = this.charValue;
if (!key)
console.error("missing key for kb-modifier-key state: " + this);
// All keys default to the unlock state.
if (!(key in states))
states[key] = KEY_STATES.UNLOCKED;
return states[key];
},
set state(value) {
var key = this.charValue;
states[key] = value;
}
});
})();
</script>
</polymer-element>
|