summaryrefslogtreecommitdiffstats
path: root/src/imports/virtualkeyboard/Keyboard.qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/virtualkeyboard/Keyboard.qml')
-rw-r--r--src/imports/virtualkeyboard/Keyboard.qml242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/imports/virtualkeyboard/Keyboard.qml b/src/imports/virtualkeyboard/Keyboard.qml
new file mode 100644
index 0000000..c626dbc
--- /dev/null
+++ b/src/imports/virtualkeyboard/Keyboard.qml
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import "components"
+import Boot2Qt.InputContext 1.0
+import Qt.labs.folderlistmodel 2.0
+
+Image {
+ id: keyboard
+
+ property var activeKey: 0
+ property int localeIndex: 1
+ property string locale: layoutsModel.count > 0 ? layoutsModel.get(localeIndex, "fileBaseName") : "en_GB"
+ property bool active: Qt.inputMethod.visible
+ property bool uppercased: uppercaseOnly ? true : (lowercaseOnly ? false : InputContext.shift || InputContext.capsLock)
+ property bool uppercaseOnly: InputContext.inputMethodHints & Qt.ImhUppercaseOnly
+ property bool lowercaseOnly: InputContext.inputMethodHints & Qt.ImhLowercaseOnly
+ property bool numberMode: InputContext.inputMethodHints & (Qt.ImhDialableCharactersOnly | Qt.ImhFormattedNumbersOnly | Qt.ImhDigitsOnly)
+ property bool symbolMode
+
+ z: 1
+ source: "images/keypad.png"
+ fillMode: Image.Stretch
+ width: parent.width
+ height: keyboardLayout.height+10
+ y: Qt.inputMethod.visible ? parent.height - height : parent.height
+ visible: Qt.inputMethod.visible || Qt.inputMethod.animating;
+
+ onLocaleChanged: InputContext.setLocale(locale)
+ onUppercasedChanged: if (Qt.inputMethod.visible) InputContext.handleUppercasing(uppercased)
+
+ function changeInputLanguage() {
+ localeIndex = (localeIndex+1) % layoutsModel.count
+ }
+
+ Behavior on y {
+ SequentialAnimation {
+ ScriptAction {
+ script: {
+ if (Qt.inputMethod.visible) {
+ keyboard.symbolMode = false
+ InputContext.handleUppercasing(uppercased)
+ }
+ InputContext.setAnimating(true)
+ }
+ }
+ NumberAnimation { duration: 300; easing.type: Easing.InOutQuad }
+ ScriptAction { script: InputContext.setAnimating(false) }
+ }
+ }
+ AutoScroller {}
+ FolderListModel {
+ id: layoutsModel
+ folder: "layouts"
+ nameFilters: ["*_*.qml"]
+ }
+ PressedKey {}
+ InputEngine { id: inputEngine }
+ AlternativeKeys { id: alternativeKeys }
+ Timer { id: releaseInaccuracyTimer; interval: 500 }
+ CharacterPreviewBubble { enabled: keyboardMouse.pressed && !alternativeKeys.active }
+ Binding {
+ target: InputContext
+ property: "keyboardRectangle"
+ value: Qt.rect(keyboard.x, keyboard.y, keyboard.width, keyboard.height)
+ }
+ Column {
+ id: keyboardLayout
+ anchors.centerIn: parent
+ Loader {
+ active: false
+ visible: keyboard.symbolMode && !keyboard.numberMode
+ source: "layouts/symbols.qml"
+ onVisibleChanged: if (visible) active = true
+ Component.onCompleted: if (visible) active = true
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ Loader {
+ active: false
+ visible: keyboard.numberMode
+ source: "layouts/numbers.qml"
+ onVisibleChanged: if (visible) active = true
+ Component.onCompleted: if (visible) active = true
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ Loader {
+ visible: !keyboard.symbolMode && !keyboard.numberMode
+ source: "layouts/" + keyboard.locale +".qml"
+ }
+ }
+ MouseArea {
+ id: keyboardMouse
+
+ property var initialKey
+ property var previousKey
+ property bool dragSymbolMode
+ property real pressAndHoldMargin: 6
+ property real releaseMargin: 18
+
+ anchors.fill: keyboardLayout
+
+ function press(key) {
+ if (key && key.enabled) {
+ if (key.key != Qt.Key_unknown || key.text.length > 0)
+ inputEngine.sendKeyPress(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0, key.repeat)
+ }
+ }
+ function release(key) {
+ if (key && key.enabled) {
+ if (key.key != Qt.Key_unknown || key.text.length > 0)
+ inputEngine.sendKeyRelease(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0)
+ key.clicked()
+ } else if (initialKey !== undefined) // rollback
+ InputContext.preeditText = InputContext.preeditText.substr(0, InputContext.preeditText.length-1)
+ }
+ function click(key) {
+ if (key && key.enabled) {
+ if (key.key != Qt.Key_unknown || key.text.length > 0)
+ inputEngine.sendKeyClick(key.key, keyboard.uppercased ? key.text.toUpperCase() : key.text, keyboard.uppercased ? Qt.ShiftModifier : 0, key.repeat)
+ key.clicked()
+ }
+ }
+ function setActiveKey(activeKey) {
+ if (keyboard.activeKey)
+ keyboard.activeKey.active = false
+ keyboard.activeKey = activeKey
+ if (keyboard.activeKey)
+ keyboard.activeKey.active = true
+ }
+ function keyOnMouse(mx, my) {
+ var parentItem = keyboardLayout
+ var child = parentItem.childAt(mx, my)
+ while (child != null) {
+ var position = parentItem.mapToItem(child, mx, my)
+ mx = position.x; my = position.y
+ parentItem = child
+ child = parentItem.childAt(mx, my)
+ if (child && child.key != undefined)
+ return child
+ }
+ return undefined
+ }
+ function hitInitialKey(mouseX, mouseY, margin) {
+ if (!initialKey)
+ return false
+ var position = initialKey.mapFromItem(keyboardMouse, mouseX, mouseY)
+ return (position.x > -margin
+ && position.y > -margin
+ && position.x < initialKey.width + margin
+ && position.y < initialKey.height + margin)
+ }
+ function reset() {
+ alternativeKeys.close()
+ previousKey = keyboard.activeKey
+ setActiveKey(0)
+ if (dragSymbolMode)
+ keyboard.symbolMode = false
+ dragSymbolMode = false
+ }
+
+ onPressed: {
+ releaseInaccuracyTimer.start()
+ initialKey = keyOnMouse(mouseX, mouseY)
+ setActiveKey(initialKey ? initialKey : 0)
+ press(initialKey)
+ }
+ onPositionChanged: {
+ if (alternativeKeys.active) {
+ alternativeKeys.move(mouseX)
+ } else {
+ var key = keyOnMouse(mouseX, mouseY)
+ if (key !== keyboard.activeKey) {
+ setActiveKey(key ? key : 0)
+ }
+ }
+ }
+ onPressAndHold: {
+ var key = hitInitialKey(mouseX, mouseY, pressAndHoldMargin) ? initialKey : keyboard.activeKey
+ if (key != undefined && key == initialKey) {
+ alternativeKeys.open(key)
+ if (!alternativeKeys.active && key.key == Qt.Key_Context1) {
+ dragSymbolMode = true
+ keyboard.symbolMode = true
+ }
+ }
+ }
+ onClicked: {}
+ onReleased: {
+ var key = keyOnMouse(mouseX, mouseY)
+ if (alternativeKeys.active) {
+ alternativeKeys.move(mouseX)
+ alternativeKeys.clicked()
+ } else if (dragSymbolMode) {
+ var key = keyOnMouse(mouseX, mouseY)
+ release(initialKey)
+ click(key)
+ } else {
+ release(releaseInaccuracyTimer.running && hitInitialKey(mouseX, mouseY, releaseMargin) ? initialKey : keyOnMouse(mouseX, mouseY))
+ }
+ reset()
+ }
+ onCanceled: reset()
+ }
+}