aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/TraceInputArea.qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/TraceInputArea.qml')
-rw-r--r--src/components/TraceInputArea.qml198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/components/TraceInputArea.qml b/src/components/TraceInputArea.qml
new file mode 100644
index 00000000..2e403170
--- /dev/null
+++ b/src/components/TraceInputArea.qml
@@ -0,0 +1,198 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Window
+import QtQuick.VirtualKeyboard
+
+/*!
+ \qmltype TraceInputArea
+ \inqmlmodule QtQuick.VirtualKeyboard.Components
+ \ingroup qmlclass
+ \ingroup qtvirtualkeyboard-components-qml
+ \inherits MultiPointTouchArea
+ \since QtQuick.VirtualKeyboard 2.0
+
+ \brief A specialized MultiPointTouchArea for collecting touch input data.
+
+ This type handles the trace interaction between the touch screen and the input engine.
+
+ The traces are rendered using the delegate from the
+ \l {KeyboardStyle::}{traceCanvasDelegate} property of the current
+ \l KeyboardStyle.
+*/
+
+MultiPointTouchArea {
+ id: traceInputArea
+
+ /*! Pattern recognition mode of this input area.
+
+ The default value is \l {InputEngine::patternRecognitionModes} {InputEngine.PatternRecognitionMode.None}.
+ */
+ property int patternRecognitionMode: InputEngine.PatternRecognitionMode.None
+
+ /*! List of horizontal rulers in the input area.
+
+ The rulers are defined as a number of pixels from the top edge of the boundingBox.
+
+ Here is an example that demonstrates how to define rulers:
+
+ \code
+ horizontalRulers: [boundingBox.height / 3, boundingBox.height / 3 * 2]
+ verticalRulers: [boundingBox.width / 3, boundingBox.width / 3 * 2]
+ \endcode
+ */
+ property var horizontalRulers
+
+ /*! List of vertical rulers in the input area.
+
+ The rulers are defined as a number of pixels from the left edge of the boundingBox.
+ */
+ property var verticalRulers
+
+ /*! Bounding box for the trace input.
+
+ This property is readonly and is automatically updated based on the item size
+ and margins.
+ */
+ readonly property rect boundingBox: (width > 0 && height > 0) ?
+ Qt.rect(traceInputArea.x + traceInputArea.anchors.leftMargin,
+ traceInputArea.y + traceInputArea.anchors.topMargin,
+ traceInputArea.width,
+ traceInputArea.height) :
+ Qt.rect(0, 0, 0, 0)
+
+ /*! Canvas type of this trace input area.
+
+ This property can be used to distinguish between different types of canvases.
+ For example, in full screen handwriting mode this property is set to \c "fullscreen", and
+ in keyboard handwriting mode this property is set to \c "keyboard".
+ */
+ property string canvasType
+
+ property var __activeTraceCanvases: ({})
+ property var __traceCanvasList: ([])
+ property var __recycledTraceCanvasList: ([])
+
+ Component.onCompleted: {
+ for (var i = 0; i < 6; i++) {
+ __recycledTraceCanvasList.push(__createTraceCanvas())
+ }
+ }
+
+ function __getTraceCanvas() {
+ while (__recycledTraceCanvasList.length == 0 &&
+ __traceCanvasList.length >= 15 &&
+ !__traceCanvasList.shift().recycle()) {}
+
+ return __recycledTraceCanvasList.length > 0 ?
+ __recycledTraceCanvasList.pop() :
+ __createTraceCanvas()
+ }
+
+ function __createTraceCanvas() {
+ var traceCanvas = keyboard.style.traceCanvasDelegate.createObject(traceInputArea)
+ traceCanvas.onRecycle.connect(__onTraceCanvasRecycled)
+ traceCanvas.anchors.fill = traceCanvas.parent
+ return traceCanvas
+ }
+
+ function __onTraceCanvasRecycled(traceCanvas) {
+ var index = __traceCanvasList.findIndex(function(otherCanvas) {
+ return traceCanvas === otherCanvas
+ })
+ if (index !== -1) {
+ __traceCanvasList.splice(index, index + 1)
+ }
+ __recycledTraceCanvasList.push(traceCanvas)
+ }
+
+ property var __traceCaptureDeviceInfo:
+ ({
+ channels: ['t'],
+ sampleRate: 60,
+ uniform: false,
+ latency: 0.0,
+ dpi: Screen.pixelDensity * 25.4
+ })
+ property var __traceScreenInfo:
+ ({
+ boundingBox: traceInputArea.boundingBox,
+ horizontalRulers: traceInputArea.horizontalRulers,
+ verticalRulers: traceInputArea.verticalRulers,
+ canvasType: traceInputArea.canvasType
+ })
+
+ enabled: patternRecognitionMode !== InputEngine.PatternRecognitionMode.None && InputContext.inputEngine.patternRecognitionModes.indexOf(patternRecognitionMode) !== -1
+
+ onPressed: (touchPoints) => {
+ if (!keyboard.style.traceCanvasDelegate)
+ return
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceId = touchPoints[i].pointId
+ var trace = InputContext.inputEngine.traceBegin(traceId, patternRecognitionMode, __traceCaptureDeviceInfo, __traceScreenInfo)
+ if (trace) {
+ var traceCanvas = __getTraceCanvas()
+ if (traceCanvas) {
+ traceCanvas.trace = trace
+ var index = trace.addPoint(Qt.point(touchPoints[i].x, touchPoints[i].y))
+ if (trace.channels.indexOf('t') !== -1) {
+ var dt = new Date()
+ trace.setChannelData('t', index, dt.getTime())
+ }
+ __activeTraceCanvases[traceId] = traceCanvas
+ } else {
+ __activeTraceCanvases[traceId] = null
+ }
+ } else {
+ __activeTraceCanvases[traceId] = null
+ }
+ }
+ }
+
+ onUpdated: (touchPoints) => {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceId = touchPoints[i].pointId
+ var traceCanvas = __activeTraceCanvases[traceId]
+ if (traceCanvas) {
+ var trace = traceCanvas.trace
+ var index = trace.addPoint(Qt.point(touchPoints[i].x, touchPoints[i].y))
+ if (trace.channels.indexOf('t') !== -1) {
+ var dt = new Date()
+ trace.setChannelData('t', index, dt.getTime())
+ }
+ }
+ }
+ }
+
+ onReleased: (touchPoints) => {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceId = touchPoints[i].pointId
+ var traceCanvas = __activeTraceCanvases[traceId]
+ if (traceCanvas) {
+ if (traceCanvas.trace) {
+ traceCanvas.trace.final = true
+ InputContext.inputEngine.traceEnd(traceCanvas.trace)
+ }
+ __traceCanvasList.push(traceCanvas)
+ __activeTraceCanvases[traceId] = null
+ }
+ }
+ }
+
+ onCanceled: (touchPoints) => {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceId = touchPoints[i].pointId
+ var traceCanvas = __activeTraceCanvases[traceId]
+ if (traceCanvas) {
+ if (traceCanvas.trace) {
+ traceCanvas.trace.final = true
+ traceCanvas.trace.canceled = true
+ InputContext.inputEngine.traceEnd(traceCanvas.trace)
+ }
+ __traceCanvasList.push(traceCanvas)
+ __activeTraceCanvases[traceId] = null
+ }
+ }
+ }
+}