2
* This file is part of Checkbox
4
* Copyright 2015 Canonical Ltd.
7
* - Maciej Kisielewski <maciej.kisielewski@canonical.com>
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; version 3.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
import Ubuntu.Components 1.3
24
/*! \brief Helper for delegating keypresses
27
This component helps to register keystroke handlers in a human-friendly
28
manner. Once handler is assigned to a given keystroke, the next time
29
keyPress will be called with event matching the key combination expressed
30
as registered keystroke, the supplied handler will be called.
31
There are two kinds of handlers: owned (normal), and 'global'.
32
Owned are registered with 'owner' parameter, that owner must match the top
33
of the 'activeStack' in order for the handler to be called.
34
Global handlers are handler regardless of what's on activeStack.
35
Note that owned handlers take precedence over global ones. I.e. if you have
36
registered two handlers for the same keystroke and the owner of the owned
37
one is on activeStack, ONLY that one will be called.
42
Keys.onPressed: keysDelegator.keyPress(event)
44
kd.setGlobalHandler('ctrl+q', Qt.quit);
45
kd.setHandler('ctrl+y', yesButton.clicked);
51
Gets signalled when no handler was found for given keystroke.
53
signal keyPressed(var event);
56
Handle a keyboard event.
57
This is intended to be called as a handler for Keys.onPressed in your MainView.
59
function keyPress(event) {
60
// build the keystroke string
62
if (event.modifiers & Qt.AltModifier) keystroke += 'alt+';
63
if (event.modifiers & Qt.ControlModifier) keystroke += 'ctrl+';
64
if (event.modifiers & Qt.ShiftModifier) keystroke += 'shift+';
65
keystroke += String.fromCharCode(event.key).toLowerCase();
67
var ownedHandlerHit = false;
68
// get the object this keystroke should be processed for
69
if (activeStack.length > 0) {
70
var candidate = activeStack[activeStack.length - 1];
71
if (candidate in _handlers) {
72
if (keystroke in _handlers[candidate]) {
73
_handlers[candidate][keystroke]();
74
ownedHandlerHit = true;
78
if (!ownedHandlerHit) {
79
if (keystroke in _globalHandlers) {
80
_globalHandlers[keystroke]();
82
// no handlers set, forwarding as keyPressed signal
89
Make given page receive all (yet) unhandled keystrokes while it's visible.
90
Note, page must have its own KeysDelegator exposed as 'keys'.
92
function forwardPressesWhileVisible(page) {
93
var handler = function() {
94
if (page.visible == true) {
95
root.onKeyPressed.connect(page.keys.keyPress);
97
root.onKeyPressed.disconnect(page.keys.keyPress);
100
page.onVisibleChanged.connect(handler);
101
page.Component.onDestruction.connect(function() {
102
page.onVisibleChanged.disconnect(handler);
107
Set handler for given keystroke.
108
This function stores `handler` as the function that is to be called if
109
`keystroke` is processed and owner is on the top of the activeStack.
110
`keystroke` is in form of [<mod_key>+...]<key>, E.g. 'ctrl+x'
112
If called with the keystroke that's already in the registry, it will
113
overwrite the previous handler.
115
function setHandler(keystroke, owner, handler) {
116
if (!(owner in _handlers)) {
117
_handlers[owner] = [];
120
_handlers[owner][_normalizeKeystroke(keystroke)] = handler;
124
Unset handler for a given keystroke for a given owner.
126
It silently ignores keystroke entries that are not in the registry
128
function unsetHandler(keystroke, owner) {
129
if (!(owner in _handlers)) {
132
delete _handlers[owner][_normalizeKeystroke(keystroke)];
136
Unset handlers owned by the given owner.
138
function unsetHandlersByOwner(owner) {
139
_handlers[owner] = [];
145
function unsetAllHandlers() {
150
Set global handler for a keystroke.
152
function setGlobalHandler(keystroke, handler) {
153
_globalHandlers[_normalizeKeystroke(keystroke)] = handler;
157
Unset global handler for a given keystroke.
158
NOTE: owned handlers will not be affected
160
function unsetGlobalHandler(keystroke) {
161
delete _globalHandlers[_normalizeKeystroke(keystroke)];
165
Unset all global handlers.
166
NOTE: owned handlers will not be affected
168
function unsetAllGlobalHandlers() {
169
_globalHandlers = [];
172
property var activeStack: []
174
property var _handlers : []
176
property var _globalHandlers : []
179
Validate and normalize keystroke description.
181
This function 'repairs' strings that depict keystroke to match following template:
184
* `mod_key`is one of the modifier keys defined as `allowedModifiers` below
185
* given `mod_key` is supplied at most once
186
* `key` is an lowercase alphanumeric character - [a-z0-9]
187
* supplied `mod_key`s occur in alphabetic order
190
_normalizeKeystroke('ctrl+alt+K') -> 'alt+ctrl+k'
191
_normalizeKeystroke('Q') -> 'q'
192
_normalizeKeystroke('shift+W') -> 'shift+w'
194
Returns normalized keystroke
195
Throws an `Error` when parsing of keystroke string failed
197
function _normalizeKeystroke(keystroke) {
198
var allowedModifiers = ['alt', 'ctrl', 'shift'];
199
var parts = keystroke.toLowerCase().split('+');
202
throw new Error('Missing key in the keystroke. Got: "%1"'.arg(keystroke));
204
if (!k.match(/^[a-z0-9]$/)) {
205
throw new Error('Picked key "%1" is not an alphanumeric. Got: "%2"'.arg(k).arg(keystroke));
210
while (parts.length > 0) {
211
var modifier = parts.shift();
212
if (allowedModifiers.indexOf(modifier) < 0) {
213
throw new Error('Unknown modifier key "%1". Allowed modifiers: %2'.arg(modifier).arg(allowedModifiers));
215
modifiers[modifier] = true;
217
var normalizedKeystroke = '';
218
for (var i in allowedModifiers) {
219
if (allowedModifiers[i] in modifiers) {
220
normalizedKeystroke += allowedModifiers[i] + '+';
223
normalizedKeystroke += k;
224
return normalizedKeystroke;