diff options
Diffstat (limited to 'src/components/TraceInputArea.qml')
-rw-r--r-- | src/components/TraceInputArea.qml | 198 |
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 + } + } + } +} |