aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/FlickKey.qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/FlickKey.qml')
-rw-r--r--src/components/FlickKey.qml96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/components/FlickKey.qml b/src/components/FlickKey.qml
new file mode 100644
index 00000000..e9afb492
--- /dev/null
+++ b/src/components/FlickKey.qml
@@ -0,0 +1,96 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.VirtualKeyboard
+
+/*!
+ \qmltype FlickKey
+ \inqmlmodule QtQuick.VirtualKeyboard.Components
+ \ingroup qmlclass
+ \ingroup qtvirtualkeyboard-components-qml
+ \ingroup qtvirtualkeyboard-key-types
+ \inherits Key
+ \since QtQuick.VirtualKeyboard 6.1
+
+ \brief Flick key for keyboard layouts.
+
+ Allows to enter an alternative character in a four-way gesture.
+ Characters are taken from the alternate keys starting with the
+ key at index \c 0 (excluding the main key text) and the positions
+ are filled in the following order: left, top, bottom, right.
+*/
+
+Key {
+
+ property int __key
+ property string __text
+ property point pt1
+ readonly property real __centerRadius: width * 0.4
+ readonly property var flickKeys: {
+ var keys = InputContext.uppercase ? alternativeKeys.toUpperCase() : alternativeKeys.toLowerCase()
+ var textIndex = keys.indexOf(InputContext.uppercase ? __text.toUpperCase() : __text.toLowerCase())
+ if (textIndex === -1)
+ return keys
+ return keys.slice(0, textIndex).concat(keys.slice(textIndex + 1))
+ }
+ property string flickLeft: flickKeys.length > 0 ? flickKeys[0] : ""
+ property string flickTop: flickKeys.length > 2 ? flickKeys[1] : ""
+ property string flickBottom: flickKeys.length > 3 ? flickKeys[3] : (flickKeys.length > 2 ? flickKeys[2] : "")
+ property string flickRight: flickKeys.length > 3 ? flickKeys[2] : (flickKeys.length === 2 ? flickKeys[1] : "")
+
+ keyType: QtVirtualKeyboard.KeyType.FlickKey
+
+ Component.onCompleted: {
+ __key = key
+ __text = text
+ }
+
+ onActiveChanged: {
+ key = __key
+ text = __text
+ }
+
+ function __angle(pt2) {
+ var dx = pt2.x - pt1.x
+ var dy = pt2.y - pt1.y
+ var theta = Math.atan2(-dy, dx) * 360 / (2 * Math.PI)
+ var theta_normalized = theta < 0 ? theta + 360 : theta
+ return theta_normalized >= 360 ? 0 : theta_normalized
+ }
+
+ function __distance(pt2) {
+ var dx = pt2.x - pt1.x
+ dx = dx * dx
+ var dy = pt2.y - pt1.y
+ dy = dy * dy
+ return Math.sqrt(dx + dy)
+ }
+
+ function press(x, y) {
+ pt1 = Qt.point(x, y)
+ }
+
+ function update(x, y) {
+ var pt = Qt.point(x, y)
+ var distance = __distance(pt)
+ if (distance < __centerRadius) {
+ return
+ }
+ var currentText
+ var angle = __angle(pt)
+ if (angle < 45 || angle > 315) {
+ currentText = flickRight
+ } else if (angle < 135) {
+ currentText = flickTop
+ } else if (angle < 225) {
+ currentText = flickLeft
+ } else {
+ currentText = flickBottom
+ }
+ if (currentText.length === 1 && text !== currentText) {
+ key = currentText.toUpperCase().charCodeAt(0)
+ text = currentText
+ }
+ }
+}