• Skip to content
  • Skip to link menu
KDE API Documentation - VirtualKeyboard.qml Source File (GCompris-qt)
  • KDE Home
  • Contact Us
 

GCompris-qt

  • src
  • core
VirtualKeyboard.qml
1 /* GCompris - VirtualKeyboard.qml
2  *
3  * Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
4  *
5  * Authors:
6  * Holger Kaelberer <holger.k@elberer.de>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
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.
17  *
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/>.
20  */
21 import QtQuick 2.0
22 import GCompris 1.0
23 
36 Item {
37  id: keyboard
38 
39  /* Public interface: */
40 
47  readonly property var qwertyLayout:
48  [ [ { label: "1", shiftLabel: "!" },
49  { label: "2", shiftLabel: "@" },
50  { label: "3", shiftLabel: "#" },
51  { label: "4", shiftLabel: "$" },
52  { label: "5", shiftLabel: "%" },
53  { label: "6", shiftLabel: "^" },
54  { label: "7", shiftLabel: "&" },
55  { label: "8", shiftLabel: "*" },
56  { label: "9", shiftLabel: "(" },
57  { label: "0", shiftLabel: ")" },
58  { label: "-", shiftLabel: "_" },
59  { label: "=", shiftLabel: "+" } ],
60 
61  [ { label: "q", shiftLabel: "Q" },
62  { label: "w", shiftLabel: "W" },
63  { label: "e", shiftLabel: "E" },
64  { label: "r", shiftLabel: "R" },
65  { label: "t", shiftLabel: "T" },
66  { label: "y", shiftLabel: "Y" },
67  { label: "u", shiftLabel: "U" },
68  { label: "i", shiftLabel: "I" },
69  { label: "o", shiftLabel: "O" },
70  { label: "p", shiftLabel: "P" } ],
71 
72  [ { label: "a", shiftLabel: "A" },
73  { label: "s", shiftLabel: "S" },
74  { label: "d", shiftLabel: "D" },
75  { label: "f", shiftLabel: "F" },
76  { label: "g", shiftLabel: "G" },
77  { label: "h", shiftLabel: "H" },
78  { label: "j", shiftLabel: "J" },
79  { label: "k", shiftLabel: "K" },
80  { label: "l", shiftLabel: "L" } ],
81 
82  [ { label: "z", shiftLabel: "Z" },
83  { label: "x", shiftLabel: "X" },
84  { label: "c", shiftLabel: "C" },
85  { label: "v", shiftLabel: "V" },
86  { label: "b", shiftLabel: "B" },
87  { label: "n", shiftLabel: "N" },
88  { label: "m", shiftLabel: "M" } ]]
89 
94  readonly property string backspace: "\u2190"
95 
100  readonly property string shiftUpSymbol: "\u21E7"
101 
106  readonly property string shiftDownSymbol: "\u21E9"
107 
147  property var layout: null
148 
153  property bool shiftKey: false
154 
155  // property bool ctrlKey: false;
156  // ...
157 
163  property int rowSpacing: 5 * ApplicationInfo.ratio
164 
170  property int keySpacing: 3 * ApplicationInfo.ratio
171 
177  property int keyHeight: 45 * ApplicationInfo.ratio
178 
184  property int margin: 5 * ApplicationInfo.ratio
185 
194  property bool hide
195 
201  signal keypress(string text)
202 
203 
208  signal error(string msg)
209 
210 
211 
212  opacity: 0.9
213 
214  visible: !hide && ApplicationSettings.isVirtualKeyboard && priv.initialized
215  enabled: visible
216 
217  z: 9999
218  width: parent.width
219  height: visible ? priv.cHeight : 0
220  anchors.bottom: parent.bottom
221  anchors.horizontalCenter: parent.horizontalCenter
222 
223  property int modifiers: Qt.NoModifier; // currently active key modifiers, internal only
224 
225  // private properties:
226  QtObject {
227  id: priv
228 
229  readonly property int cHeight: numRows * keyboard.keyHeight +
230  (numRows + 1) * keyboard.rowSpacing
231  property int numRows: 0
232  property bool initialized: false
233  }
234 
235 
236  function populateKeyboard(a)
237  {
238  var nRows;
239  var maxButtons = 0;
240 
241  // validate layout syntax:
242  if (!Array.isArray(a) || a.length < 1) {
243  error("VirtualKeyboard: Invalid layout, array of length > 0");
244  return;
245  }
246  nRows = a.length;
247  // if we need special keys, put them in a separate row at the bottom:
248  if (keyboard.shiftKey) {
249  a.push([ {
250  label : keyboard.shiftUpSymbol + " Shift",
251  shiftLabel: keyboard.shiftDownSymbol + " Shift",
252  specialKeyValue: Qt.Key_Shift } ]);
253  }
254  var i
255  var seenLabels = [];
256  for (i = 0; i < a.length; i++) {
257  if (!Array.isArray(a[i])) {
258  error("VirtualKeyboard: Invalid layout, expecting array of arrays of keys");
259  return;
260  }
261  if (a[i].length > maxButtons)
262  maxButtons = a[i].length;
263  for (var j = 0; j < a[i].length; j++) {
264  if (undefined === a[i][j].label) {
265  error("VirtualKeyboard: Invalid layout, invalid key object");
266  return;
267  }
268  if (undefined === a[i][j].specialKeyValue)
269  a[i][j].specialKeyValue = 0;
270  var label = a[i][j].label;
271  // if we have a shift key lowercase all labels:
272  if (shiftKey && label == label.toLocaleUpperCase())
273  label = label.toLocaleLowerCase();
274  // drop duplicates (this alters keyboard layout, though!):
275  if (seenLabels.indexOf(label) !=-1) {
276  a[i].splice(j, 1);
277  j--;
278  continue;
279  }
280  a[i][j].label = label;
281  seenLabels.push(label);
282  if (keyboard.shiftKey && undefined === a[i][j].shiftLabel)
283  a[i][j].shiftLabel = a[i][j].label.toLocaleUpperCase();
284  }
285  }
286 
287  // populate
288  for (i = 0; i < a.length; i++) {
289  var row = a[i];
290  var offset = 0;
291  rowListModel.append({ rowNum: i,
292  offset: offset,
293  keys: row});
294  }
295  priv.numRows = i;
296  priv.initialized = (priv.numRows > 0);
297  }
298 
299  function handleVirtualKeyPress(virtualKey) {
300  if (virtualKey.specialKey == Qt.Key_Shift)
301  keyboard.modifiers ^= Qt.ShiftModifier;
302 // else if (virtualKey.specialKey == Qt.Key_Alt)
303 // keyboard.modifiers ^= Qt.AltModifier;
304  else
305  keyboard.keypress(virtualKey.text);
306  }
307 
308  onLayoutChanged: {
309  rowListModel.clear();
310  priv.initialized = false;
311  if (layout != null)
312  populateKeyboard(layout);
313  }
314 
315  ListModel {
316  id: rowListModel
317  /* Currently expects the following
318  * ListElement {
319  * rowNum: 1
320  * keys: [ { label: "a", shiftLabel: "A" },
321  * { label: "b", shiftLabel: "B" },
322  * { label: "Shift", shiftLabel: "Shift", special },
323  * ...}
324  * ]
325  * }
326  */
327  }
328 
329  Behavior on height {
330  NumberAnimation {
331  duration: 500
332  easing.type: Easing.OutCubic
333  }
334  }
335 
336  Rectangle {
337  id: background
338 
339  width: parent.width
340  height: keyboard.height
341  color: "#8C8F8C"
342  opacity: keyboard.opacity
343 
344  ListView {
345  id: rowList
346 
347  anchors.top: parent.top
348  anchors.topMargin: keyboard.margin
349  anchors.left: parent.left
350  anchors.margins: keyboard.margin
351  width: parent.width
352  height: parent.height - keyboard.margin * 2
353  spacing: keyboard.rowSpacing
354  orientation: Qt.Vertical
355  verticalLayoutDirection: ListView.TopToBottom
356  interactive: false
357 
358  model: rowListModel
359 
360  delegate:
361  Item {
362  /* Wrap keyboardRow for attaching a MouseArea. Not possible
363  * in Row-s directly */
364  id: rowListDelegate
365  width: rowList.width
366  height: keyboardRow.height
367  x: keyboardRow.x
368  y: keyboardRow.y
369  z: keyboardRow.z
370 
371  MouseArea {
372  anchors.fill: parent
373  hoverEnabled: true
374  propagateComposedEvents: true
375 
376  // update index to allow for updating z value of the rows
377  onEntered: rowList.currentIndex = index;
378 
379  onPressed: {
380  // same onPress for mobile
381  rowList.currentIndex = index;
382  // need to propagate through to the key for mobile!
383  mouse.accepted = false;
384  }
385  }
386 
387  Row {
388  id: keyboardRow
389  spacing: keyboard.keySpacing
390  width: parent.width
391 
392  z: rowListDelegate.ListView.isCurrentItem ? 1 : -1
393 
394  Item {
395  id: keyboardRowSpacing
396  width: offset / 2;
397  height: keyboard.keyHeight
398  }
399 
400  Repeater {
401  id: keyboardRowRepeater
402 
403  z: rowListDelegate.ListView.isCurrentItem ? 1 : -1
404 
405  model: keys
406  delegate: VirtualKey {
407  width: (keyboard.width - keyboardRowRepeater.count *
408  keyboardRow.spacing - offset - keyboard.margin*2) /
409  keyboardRowRepeater.count
410  height: keyboard.keyHeight
411  modifiers: keyboard.modifiers
412  specialKey: specialKeyValue
413  }
414 
415  onItemAdded: item.pressed.connect(keyboard.handleVirtualKeyPress);
416 
417  onItemRemoved: item.pressed.disconnect(keyboard.handleVirtualKeyPress);
418  } // Repeater
419  } // Row
420  } // Item
421  } // ListView
422  } // background
423 
425 }
ApplicationSettings::isVirtualKeyboard
bool isVirtualKeyboard
Whether on-screen keyboard should be enabled per default in activities that use it.
Definition: ApplicationSettings.h:94
QtQuick
GCompris
ApplicationSettings
Singleton that contains GCompris' persistent settings.
Definition: ApplicationSettings.h:63
ApplicationInfo
A general purpose singleton that exposes miscellaneous native functions to the QML layer...
Definition: ApplicationInfo.h:43
ApplicationInfo::ratio
qreal ratio
Ratio factor used for scaling of sizes on high-dpi devices.
Definition: ApplicationInfo.h:91
This file is part of the KDE documentation.
Documentation copyright © 1996-2015 The KDE developers.
Generated on Tue Jun 2 2015 21:47:47 by doxygen 1.8.9.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

GCompris-qt

Skip menu "GCompris-qt"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • File List
  • Modules

Class Picker

Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal