Warning, /education/gcompris/src/core/VirtualKeyboard.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - VirtualKeyboard.qml 0002 * 0003 * SPDX-FileCopyrightText: 2014 Holger Kaelberer <holger.k@elberer.de> 0004 * 0005 * Authors: 0006 * Holger Kaelberer <holger.k@elberer.de> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import GCompris 1.0 0012 0013 /** 0014 * A QML component providing an on screen keyboard. 0015 * @ingroup components 0016 * 0017 * VirtualKeyboard displays a virtual on screen keyboard that can be used 0018 * in applications that need keyboard support, especially on mobile devices. 0019 * 0020 * The component itself does not provide builtin localized keyboard layouts, 0021 * the user has to define the keyboard-layout dynamically. 0022 * 0023 * @inherit QtQuick.Item 0024 */ 0025 Item { 0026 id: keyboard 0027 0028 /* Public interface: */ 0029 0030 /** 0031 * type:list 0032 * 0033 * Default basic qwerty-layout used unless the user provides another. 0034 * @sa layout. 0035 */ 0036 readonly property var qwertyLayout: 0037 [ [ { label: "1", shiftLabel: "!" }, 0038 { label: "2", shiftLabel: "@" }, 0039 { label: "3", shiftLabel: "#" }, 0040 { label: "4", shiftLabel: "$" }, 0041 { label: "5", shiftLabel: "%" }, 0042 { label: "6", shiftLabel: "^" }, 0043 { label: "7", shiftLabel: "&" }, 0044 { label: "8", shiftLabel: "*" }, 0045 { label: "9", shiftLabel: "(" }, 0046 { label: "0", shiftLabel: ")" }, 0047 { label: "-", shiftLabel: "_" }, 0048 { label: "=", shiftLabel: "+" } ], 0049 0050 [ { label: "q", shiftLabel: "Q" }, 0051 { label: "w", shiftLabel: "W" }, 0052 { label: "e", shiftLabel: "E" }, 0053 { label: "r", shiftLabel: "R" }, 0054 { label: "t", shiftLabel: "T" }, 0055 { label: "y", shiftLabel: "Y" }, 0056 { label: "u", shiftLabel: "U" }, 0057 { label: "i", shiftLabel: "I" }, 0058 { label: "o", shiftLabel: "O" }, 0059 { label: "p", shiftLabel: "P" } ], 0060 0061 [ { label: "a", shiftLabel: "A" }, 0062 { label: "s", shiftLabel: "S" }, 0063 { label: "d", shiftLabel: "D" }, 0064 { label: "f", shiftLabel: "F" }, 0065 { label: "g", shiftLabel: "G" }, 0066 { label: "h", shiftLabel: "H" }, 0067 { label: "j", shiftLabel: "J" }, 0068 { label: "k", shiftLabel: "K" }, 0069 { label: "l", shiftLabel: "L" } ], 0070 0071 [ { label: "z", shiftLabel: "Z" }, 0072 { label: "x", shiftLabel: "X" }, 0073 { label: "c", shiftLabel: "C" }, 0074 { label: "v", shiftLabel: "V" }, 0075 { label: "b", shiftLabel: "B" }, 0076 { label: "n", shiftLabel: "N" }, 0077 { label: "m", shiftLabel: "M" } ]] 0078 0079 0080 /** 0081 * type:string 0082 * Symbol that can be used for the space key. 0083 */ 0084 readonly property string space: "\u2423" 0085 0086 /** 0087 * type:string 0088 * Symbol that can be used for the backspace key. 0089 */ 0090 readonly property string backspace: "\u2190" 0091 0092 /** 0093 * type:string 0094 * Symbol for the shift-up key. 0095 */ 0096 readonly property string shiftUpSymbol: "\u21E7" 0097 0098 /** 0099 * type:string 0100 * Symbol for the shift-down key. 0101 */ 0102 readonly property string shiftDownSymbol: "\u21E9" 0103 0104 /** 0105 * type:list 0106 * Keyboard layout. 0107 * 0108 * The layout should be provided by the user. It can contain 0109 * unicode characters, and can be set dynamically also on a per-level 0110 * basis. 0111 * 0112 * The expected format of the @ref layout property is a list of row lists. 0113 * Example: 0114 * 0115 * @code 0116 * [ 0117 * [ <-- start of the first row 0118 * { label: "1", shiftLabel: "!" }, <-- first key of the first row 0119 * { label: "2", shiftLabel: "@" }, 0120 * ... 0121 * ], 0122 * [ 0123 * { label: "q", shiftLabel: "Q" }, 0124 * { label: "w", shiftLabel: "W" }, 0125 * ... 0126 * ], 0127 * ... 0128 * ] 0129 * @endcode 0130 * 0131 * The order passed in layout will not be altered. 0132 * 0133 * Use the @ref shiftKey property to activate a shift button which allows 0134 * to assign 2 letters on one key. You can define an additional shiftLabel 0135 * per key, or leave it undefined, in which case VirtualKeyboard 0136 * automatically defines the shift-label (using 0137 * String.toLocaleUpperCase()). 0138 * 0139 * Default is to use the qwertyLayout. 0140 * 0141 * @sa qwertyLayout shiftKey 0142 */ 0143 property var layout: null 0144 0145 /** 0146 * type:bool 0147 * Whether a shift key should be used. 0148 */ 0149 property bool shiftKey: false 0150 0151 // property bool ctrlKey: false; 0152 // ... 0153 0154 /** 0155 * type:int 0156 * Vertical spacing between rows in pixel. 0157 * Default: 5 * ApplicationInfo.ratio 0158 */ 0159 property int rowSpacing: 5 * ApplicationInfo.ratio 0160 0161 /** 0162 * type:int 0163 * Horizontal spacing between keys in pixel. 0164 * Default: 3 * ApplicationInfo.ratio 0165 */ 0166 property int keySpacing: 3 * ApplicationInfo.ratio 0167 0168 /** 0169 * type:int 0170 * Height of the keys in pixel. 0171 * Default: 45 * ApplicationInfo.ratio 0172 */ 0173 property int keyHeight: 45 * ApplicationInfo.ratio 0174 0175 /** 0176 * type:int 0177 * Margin around the keyboard in pixel. 0178 * Default: 5 * ApplicationInfo.ratio 0179 */ 0180 property int margin: 5 * ApplicationInfo.ratio 0181 0182 /** 0183 * type:bool 0184 * Whether the keyboard should be hidden. 0185 * 0186 * Besides this property the visibility of the virtual keyboard also 0187 * depends on the setting ApplicationSettings.isVirtualKeyboard and 0188 * its successful initialization. 0189 */ 0190 property bool hide 0191 0192 /** 0193 * Emitted for every keypress. 0194 * 0195 * @param text The label of the pressed key. 0196 */ 0197 signal keypress(string text) 0198 0199 /** 0200 * Emitted upon error. 0201 * 0202 * @param msg Error message. 0203 */ 0204 signal error(string msg) 0205 0206 /// @cond INTERNAL_DOCS 0207 0208 opacity: 0.9 0209 0210 visible: !hide && ApplicationSettings.isVirtualKeyboard && priv.initialized 0211 enabled: visible 0212 0213 z: 9999 0214 width: parent.width 0215 height: visible ? priv.cHeight : 0 0216 anchors.horizontalCenter: parent.horizontalCenter 0217 0218 property int modifiers: Qt.NoModifier; // currently active key modifiers, internal only 0219 0220 // private properties: 0221 QtObject { 0222 id: priv 0223 0224 readonly property int cHeight: numRows * keyboard.keyHeight + 0225 (numRows + 1) * keyboard.rowSpacing 0226 property int numRows: 0 0227 property bool initialized: false 0228 } 0229 0230 WorkerScript { 0231 id: keyboardWorker 0232 0233 source: "virtualkeyboard_worker.js" 0234 onMessage: { 0235 // worker finished 0236 activity.loading.stop(); 0237 if (messageObject.error !== "") { 0238 error(messageObject.error); 0239 } else { 0240 // update all changed values (except the model): 0241 priv.numRows = messageObject.numRows; 0242 priv.initialized = messageObject.initialized; 0243 } 0244 } 0245 } 0246 0247 function populateKeyboard(a) { 0248 activity.loading.start(); 0249 // populate asynchronously in a worker thread: 0250 keyboardWorker.sendMessage({ 0251 shiftKey: keyboard.shiftKey, 0252 shiftUpSymbol: keyboard.shiftUpSymbol, 0253 shiftDownSymbol: keyboard.shiftDownSymbol, 0254 a: a, 0255 rowListModel: rowListModel 0256 }); 0257 } 0258 0259 function handleVirtualKeyPress(virtualKey) { 0260 if (virtualKey.specialKey === Qt.Key_Shift) 0261 keyboard.modifiers ^= Qt.ShiftModifier; 0262 // else if (virtualKey.specialKey == Qt.Key_Alt) 0263 // keyboard.modifiers ^= Qt.AltModifier; 0264 else 0265 keyboard.keypress(virtualKey.text); 0266 } 0267 0268 onLayoutChanged: { 0269 priv.initialized = false; 0270 if (layout != null) 0271 populateKeyboard(layout); 0272 } 0273 0274 ListModel { 0275 id: rowListModel 0276 /* Currently expects the following 0277 * ListElement { 0278 * rowNum: 1 0279 * keys: [ { label: "a", shiftLabel: "A" }, 0280 * { label: "b", shiftLabel: "B" }, 0281 * { label: "Shift", shiftLabel: "Shift", special }, 0282 * ...} 0283 * ] 0284 * } 0285 */ 0286 } 0287 0288 Behavior on height { 0289 NumberAnimation { 0290 duration: 500 0291 easing.type: Easing.OutCubic 0292 } 0293 } 0294 0295 Rectangle { 0296 id: keyboardBackground 0297 0298 width: parent.width 0299 height: keyboard.height 0300 color: "#8C8F8C" 0301 opacity: keyboard.opacity 0302 0303 ListView { 0304 id: rowList 0305 0306 anchors.top: parent.top 0307 anchors.topMargin: keyboard.margin 0308 anchors.left: parent.left 0309 anchors.margins: keyboard.margin 0310 width: parent.width 0311 height: parent.height - keyboard.margin * 2 0312 spacing: keyboard.rowSpacing 0313 orientation: Qt.Vertical 0314 verticalLayoutDirection: ListView.TopToBottom 0315 interactive: false 0316 0317 model: rowListModel 0318 0319 delegate: 0320 Item { 0321 /* Wrap keyboardRow for attaching a MouseArea. Not possible 0322 * in Row-s directly */ 0323 id: rowListDelegate 0324 width: rowList.width 0325 height: keyboardRow.height 0326 x: keyboardRow.x 0327 y: keyboardRow.y 0328 z: keyboardRow.z 0329 0330 MouseArea { 0331 anchors.fill: parent 0332 propagateComposedEvents: true 0333 0334 // update index to allow for updating z value of the rows 0335 onEntered: rowList.currentIndex = index; 0336 0337 onPressed: { 0338 // same onPress for mobile 0339 rowList.currentIndex = index; 0340 // need to propagate through to the key for mobile! 0341 mouse.accepted = false; 0342 } 0343 } 0344 0345 Row { 0346 id: keyboardRow 0347 spacing: keyboard.keySpacing 0348 width: parent.width 0349 0350 z: rowListDelegate.ListView.isCurrentItem ? 1 : -1 0351 0352 Item { 0353 id: keyboardRowSpacing 0354 width: offset / 2; 0355 height: keyboard.keyHeight 0356 } 0357 0358 Repeater { 0359 id: keyboardRowRepeater 0360 0361 z: rowListDelegate.ListView.isCurrentItem ? 1 : -1 0362 0363 model: keys 0364 delegate: VirtualKey { 0365 width: (keyboard.width - keyboardRowRepeater.count * 0366 keyboardRow.spacing - offset - keyboard.margin*2) / 0367 keyboardRowRepeater.count 0368 height: keyboard.keyHeight 0369 modifiers: keyboard.modifiers 0370 specialKey: specialKeyValue 0371 } 0372 0373 onItemAdded: item.pressed.connect(keyboard.handleVirtualKeyPress); 0374 0375 onItemRemoved: item.pressed.disconnect(keyboard.handleVirtualKeyPress); 0376 } // Repeater 0377 } // Row 0378 } // Item 0379 } // ListView 0380 } // keyboardBackground 0381 0382 /// @endcond 0383 }