aboutsummaryrefslogtreecommitdiffstats
path: root/src/virtualkeyboard/content
diff options
context:
space:
mode:
authorJarkko Koivikko <jarkko.koivikko@code-q.fi>2015-02-12 10:07:00 +0200
committerJarkko Koivikko <jarkko.koivikko@code-q.fi>2015-06-17 12:33:42 +0300
commit28cf4492839f598a3058d40feab37a3274a02771 (patch)
treeb219ffa5c0679f8f99e454d65be5103c900ea14a /src/virtualkeyboard/content
parentd0ded0ea4a0f322fe1fd54348ad0e0b4ae74a1af (diff)
Add support for pattern recognition based input methods
This change adds generic support for pattern recognition based input methods. Added new API for the input engine and input method to process trace data. The trace data can originate from various input devices, e.g. from touch screen or from a dedicated hardware touch panel. Added new data model type for trace supporting both the C++ and QML interfaces. The new data model is DeclarativeTrace and Trace respectively, and it stores the trace data captured from the input device. The trace object is owned by the input method and is accessible to the UI layer, capture device and the input method. First, when the trace event begins, the capture device invokes the InputEngine.traceBegin(). The input engine forwards this call to the input method, which creates the trace object in response to successful call. Then the capture device receives the trace object and starts collecting the data. Also, in case of touch screen input, there are also the UI layer which renders the data. For this purpose there are new kinds of Style elements available in the Styles plugin. TraceCanvas is a specialized Canvas for rendering the trace object on screen. The TraceCanvas is a normal styling component, and can be customized like any other style element. Finally, the InputMethod.traceEnd() is called when the trace interaction ends. The trace is removed from screen automatically when the trace object is deleted. I.e., the input method has full control on how many traces it wants to collect for single recognition phase. Change-Id: I80ed90032f715726280197d9e94e7f0bd8280ff3 Reviewed-by: Gatis Paeglis <gatis.paeglis@theqtcompany.com>
Diffstat (limited to 'src/virtualkeyboard/content')
-rw-r--r--src/virtualkeyboard/content/components/HandwritingModeKey.qml40
-rw-r--r--src/virtualkeyboard/content/components/Keyboard.qml4
-rw-r--r--src/virtualkeyboard/content/components/TraceInputArea.qml165
-rw-r--r--src/virtualkeyboard/content/components/TraceInputKey.qml97
-rw-r--r--src/virtualkeyboard/content/content.qrc3
-rw-r--r--src/virtualkeyboard/content/styles/default/default_style.qrc2
-rw-r--r--src/virtualkeyboard/content/styles/default/images/handwriting-868482.svg18
-rw-r--r--src/virtualkeyboard/content/styles/default/images/textmode-868482.svg33
-rw-r--r--src/virtualkeyboard/content/styles/default/style.qml125
-rw-r--r--src/virtualkeyboard/content/styles/retro/images/handwriting-110b05.svg18
-rw-r--r--src/virtualkeyboard/content/styles/retro/images/key154px_colorA.svg19
-rw-r--r--src/virtualkeyboard/content/styles/retro/images/textmode-110b05.svg33
-rw-r--r--src/virtualkeyboard/content/styles/retro/retro_style.qrc3
-rw-r--r--src/virtualkeyboard/content/styles/retro/style.qml141
14 files changed, 695 insertions, 6 deletions
diff --git a/src/virtualkeyboard/content/components/HandwritingModeKey.qml b/src/virtualkeyboard/content/components/HandwritingModeKey.qml
new file mode 100644
index 00000000..7eb44a93
--- /dev/null
+++ b/src/virtualkeyboard/content/components/HandwritingModeKey.qml
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://www.qt.io
+**
+** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://www.qt.io
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+/*!
+ \qmltype HandwritingModeKey
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard
+ \ingroup qtvirtualkeyboard-qml
+ \inherits Key
+ \since QtQuick.Enterprise.VirtualKeyboard 1.4
+
+ \brief Hand writing mode key for keyboard layouts.
+
+ This key toggles between the handwriting mode layout and the main layout.
+*/
+
+Key {
+ key: Qt.Key_Context2
+ displayText: "HWR"
+ functionKey: true
+ visible: VirtualKeyboardInputMethods.indexOf("HandwritingInputMethod") !== -1
+ onClicked: keyboard.handwritingMode = !keyboard.handwritingMode
+ keyPanelDelegate: keyboard.style ? keyboard.style.handwritingKeyPanel : undefined
+}
diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml
index e9271b7e..c5d79556 100644
--- a/src/virtualkeyboard/content/components/Keyboard.qml
+++ b/src/virtualkeyboard/content/components/Keyboard.qml
@@ -44,10 +44,12 @@ Item {
if (InputContext.inputMethodHints & Qt.ImhFormattedNumbersOnly) return "numbers"
if (InputContext.inputMethodHints & Qt.ImhDigitsOnly) return "digits"
if (keyboard.symbolMode) return "symbols"
+ if (keyboard.handwritingMode) return "handwriting"
return "main"
}
property bool active: Qt.inputMethod.visible
property bool uppercased: InputContext.shift
+ property bool handwritingMode
property bool symbolMode
property var defaultInputMethod: initDefaultInputMethod()
property var plainInputMethod: PlainInputMethod {}
@@ -94,7 +96,7 @@ Item {
updateInputMethod()
}
onPreferNumbersChanged: {
- keyboard.symbolMode = preferNumbers
+ keyboard.symbolMode = !keyboard.handwritingMode && preferNumbers
if (!preferNumbers)
inputModeNeedsReset = true
updateInputMethod()
diff --git a/src/virtualkeyboard/content/components/TraceInputArea.qml b/src/virtualkeyboard/content/components/TraceInputArea.qml
new file mode 100644
index 00000000..7f54173f
--- /dev/null
+++ b/src/virtualkeyboard/content/components/TraceInputArea.qml
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://www.qt.io
+**
+** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://www.qt.io
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.2
+import QtQuick.Enterprise.VirtualKeyboard 1.4
+
+/*!
+ \qmltype TraceInputArea
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard
+ \ingroup qtvirtualkeyboard-qml
+ \inherits MultiPointTouchArea
+ \since QtQuick.Enterprise.VirtualKeyboard 1.4
+
+ \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 current style
+ \l {KeyboardStyle::traceCanvasDelegate} {KeyboardStyle.traceCanvasDelegate}.
+*/
+
+MultiPointTouchArea {
+ id: traceInputArea
+
+ /*! Pattern recognition mode of this input area.
+
+ The default value is \l {DeclarativeInputEngine::PatternRecognitionDisabled} {InputEngine.PatternRecognitionDisabled}.
+ */
+ property int patternRecognitionMode: InputEngine.PatternRecognitionDisabled
+
+ /*! 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 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)
+
+ property var __traceCanvasList: ([])
+
+ /*! \internal */
+ function findTraceCanvasById(traceId) {
+ for (var i = 0; i < __traceCanvasList.length;) {
+ var traceCanvas = __traceCanvasList[i]
+ if (!traceCanvas || !traceCanvas.trace)
+ __traceCanvasList.splice(i, 1)
+ else if (traceCanvas.trace.traceId === traceId)
+ return traceCanvas
+ else
+ i++
+ }
+ return null
+ }
+
+ 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
+ })
+
+ enabled: patternRecognitionMode !== InputEngine.PatternRecognitionDisabled && InputContext.inputEngine.patternRecognitionModes.indexOf(patternRecognitionMode) !== -1
+
+ onPressed: {
+ if (!keyboard.style.traceCanvasDelegate)
+ return
+ for (var i = 0; i < touchPoints.length; i++) {
+ var trace = InputContext.inputEngine.traceBegin(touchPoints[i].pointId, patternRecognitionMode, __traceCaptureDeviceInfo, __traceScreenInfo)
+ if (trace) {
+ var traceCanvas = keyboard.style.traceCanvasDelegate.createObject(traceInputArea, { "trace": trace, "autoDestroy": true })
+ traceCanvas.anchors.fill = traceCanvas.parent
+ 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())
+ }
+ __traceCanvasList.push(traceCanvas)
+ }
+ }
+ }
+
+ onUpdated: {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceCanvas = findTraceCanvasById(touchPoints[i].pointId)
+ 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: {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceCanvas = findTraceCanvasById(touchPoints[i].pointId)
+ if (traceCanvas) {
+ traceCanvas.trace.isFinal = true
+ __traceCanvasList.splice(__traceCanvasList.indexOf(traceCanvas), 1)
+ InputContext.inputEngine.traceEnd(traceCanvas.trace)
+ }
+ }
+ }
+
+ onCanceled: {
+ for (var i = 0; i < touchPoints.length; i++) {
+ var traceCanvas = findTraceCanvasById(touchPoints[i].pointId)
+ if (traceCanvas) {
+ traceCanvas.trace.isFinal = true
+ traceCanvas.trace.isCanceled = true
+ __traceCanvasList.splice(__traceCanvasList.indexOf(traceCanvas), 1)
+ InputContext.inputEngine.traceEnd(traceCanvas.trace)
+ }
+ }
+ }
+}
diff --git a/src/virtualkeyboard/content/components/TraceInputKey.qml b/src/virtualkeyboard/content/components/TraceInputKey.qml
new file mode 100644
index 00000000..9b22cd62
--- /dev/null
+++ b/src/virtualkeyboard/content/components/TraceInputKey.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://www.qt.io
+**
+** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://www.qt.io
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.0
+
+/*!
+ \qmltype TraceInputKey
+ \inqmlmodule QtQuick.Enterprise.VirtualKeyboard
+ \ingroup qtvirtualkeyboard-qml
+ \inherits Item
+ \since QtQuick.Enterprise.VirtualKeyboard 1.4
+
+ \brief A specialized key for collecting touch input data.
+
+ This type can be placed in the keyboard layout. It collects
+ and renders touch input data (trace) from the key area.
+*/
+
+Item {
+ id: traceInputKey
+
+ /*! Sets the key weight value which determines the relative size of the key.
+
+ Use this property to change the key size in the layout.
+
+ The default value is inherited from the parent element
+ of the key in the layout hierarchy.
+ */
+ property real weight: parent.keyWeight
+
+ /*! Pattern recognition mode of this input area.
+
+ The default value is \l {DeclarativeInputEngine::PatternRecognitionDisabled} {InputEngine.PatternRecognitionDisabled}.
+ */
+ property alias patternRecognitionMode: traceInputArea.patternRecognitionMode
+
+ /*! List of horizontal rulers in the input area.
+
+ The rulers are defined as a number of pixels from the top edge of the bounding box.
+
+ Here is an example how to define rulers:
+
+ \code
+ horizontalRulers: [boundingBox.height / 3, boundingBox.height / 3 * 2]
+ verticalRulers: [boundingBox.width / 3, boundingBox.width / 3 * 2]
+ \endcode
+ */
+ property alias horizontalRulers: traceInputArea.horizontalRulers
+
+ /*! List of vertical rulers in the input area.
+
+ The rulers are defined as a number of pixels from the left edge of the bounding box.
+ */
+ property alias verticalRulers: traceInputArea.verticalRulers
+
+ /*! Bounding box for the trace input.
+
+ This property is readonly and is automatically updated based on the item size
+ and margins.
+ */
+ readonly property alias boundingBox: traceInputArea.boundingBox
+
+ Layout.minimumWidth: traceInputKeyPanel.implicitWidth
+ Layout.minimumHeight: traceInputKeyPanel.implicitHeight
+ Layout.preferredWidth: weight
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Loader {
+ id: traceInputKeyPanel
+ sourceComponent: keyboard.style.traceInputKeyPanelDelegate
+ anchors.fill: parent
+ onStatusChanged: if (status == Loader.Ready) traceInputKeyPanel.item.control = traceInputKey
+ }
+
+ TraceInputArea {
+ id: traceInputArea
+ anchors.fill: traceInputKeyPanel
+ anchors.margins: traceInputKeyPanel.item ? traceInputKeyPanel.item.traceMargins : 0
+ }
+}
diff --git a/src/virtualkeyboard/content/content.qrc b/src/virtualkeyboard/content/content.qrc
index 51ec1896..6c23d86a 100644
--- a/src/virtualkeyboard/content/content.qrc
+++ b/src/virtualkeyboard/content/content.qrc
@@ -22,5 +22,8 @@
<file>components/ShiftKey.qml</file>
<file>components/SpaceKey.qml</file>
<file>components/SymbolModeKey.qml</file>
+ <file>components/TraceInputKey.qml</file>
+ <file>components/TraceInputArea.qml</file>
+ <file>components/HandwritingModeKey.qml</file>
</qresource>
</RCC>
diff --git a/src/virtualkeyboard/content/styles/default/default_style.qrc b/src/virtualkeyboard/content/styles/default/default_style.qrc
index 8c691ce6..c6762b54 100644
--- a/src/virtualkeyboard/content/styles/default/default_style.qrc
+++ b/src/virtualkeyboard/content/styles/default/default_style.qrc
@@ -5,10 +5,12 @@
<file>images/check-868482.svg</file>
<file>images/enter-868482.svg</file>
<file>images/globe-868482.svg</file>
+ <file>images/handwriting-868482.svg</file>
<file>images/hidekeyboard-868482.svg</file>
<file>images/search-868482.svg</file>
<file>images/shift-80c342.svg</file>
<file>images/shift-868482.svg</file>
<file>images/shift-c5d6b6.svg</file>
+ <file>images/textmode-868482.svg</file>
</qresource>
</RCC>
diff --git a/src/virtualkeyboard/content/styles/default/images/handwriting-868482.svg b/src/virtualkeyboard/content/styles/default/images/handwriting-868482.svg
new file mode 100644
index 00000000..d7af73ca
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/handwriting-868482.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 156 104" enable-background="new 0 0 156 104" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#868482" d="M37.6,103.3c-10.1,0-18.9-5-23.1-13.6C4.4,68.7,19.9,52.3,36.2,35c1.2-1.2,2.4-2.5,3.6-3.8
+ c5.3-5.7,5.2-11.5,3.5-14.8c-1.8-3.4-5.5-4.9-10.2-4.2c-16.5,2.6-21.2,26.4-21.2,26.6L0,36.6C0.3,35.3,6.4,4.3,31.2,0.3
+ c9.8-1.6,18.5,2.4,22.7,10.4c4.7,8.9,2.6,20.1-5.3,28.6c-1.2,1.3-2.4,2.6-3.6,3.8C28.3,60.9,19.1,71.6,25.4,84.5
+ c3.3,6.8,11.1,7.6,16.9,6.3c9.2-2.1,19.8-11.1,19.7-29.5c-0.2-28.1,16.2-41.8,30.2-44.9c14.5-3.2,28.4,3.6,34.7,17
+ c1.3,2.8,2.3,5.4,3.1,8.1c13.3,0.7,25.5,4.3,26,4.4l-3.4,11.5c-0.1,0-9.7-2.8-20.6-3.8c0.5,16.5-8.6,28.9-20.1,34.7
+ c-11.9,6-24,3.8-28.9-5.2c-3.1-5.6-1.9-14.7,2.9-22.5c7.9-13,21.3-17.4,31.5-18.8c-0.4-1.2-0.9-2.4-1.4-3.4
+ c-3.9-8.3-12.2-12.4-21.1-10.4c-9.7,2.2-21,12.1-20.8,33.1c0.2,25.5-15.6,38.1-29,41.3C42.5,103,40,103.3,37.6,103.3z M119.8,53.7
+ c-14,1.5-20.6,8.5-23.4,12.9c-3.3,5.2-3.4,9.8-2.9,10.9c1.6,2.9,7.3,3,13,0.2C117.3,72.2,120.3,62.6,119.8,53.7z"/>
+ </g>
+ <rect fill="none" width="156" height="104"/>
+</g>
+</svg>
diff --git a/src/virtualkeyboard/content/styles/default/images/textmode-868482.svg b/src/virtualkeyboard/content/styles/default/images/textmode-868482.svg
new file mode 100644
index 00000000..2f9428c2
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/default/images/textmode-868482.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="124px" height="96px" viewBox="0 0 124 96" enable-background="new 0 0 124 96" xml:space="preserve">
+<g>
+ <g>
+ <g>
+ <path fill="#868482" d="M55.4,70.8L46.9,49H19.4L11,70.8H2.9L30,2h6.7l27,68.8H55.4z M44.4,41.8l-8-21.2c-1-2.7-2.1-6-3.2-9.9
+ c-0.7,3-1.7,6.3-3,9.9l-8.1,21.2H44.4z"/>
+ <path fill="#868482" d="M66.6,72.8H54.1L45.5,51H20.8l-8.4,21.8H0L28.7,0h9.4L66.6,72.8z M56.8,68.8h4L35.4,4h-1.9l1.7,6.2
+ c1.1,3.8,2.1,7.1,3.1,9.7l9,24h-28l9.1-23.9c1.2-3.5,2.2-6.7,2.9-9.6L32.8,4h-1.4L5.9,68.8h3.8L18.1,47h30.2L56.8,68.8z
+ M25.1,39.8h16.4l-7-18.5c-0.4-1.1-0.8-2.2-1.2-3.4c-0.4,1.1-0.7,2.2-1.2,3.4L25.1,39.8z"/>
+ </g>
+ <g>
+ <path fill="#868482" d="M116.2,70.8l-1.5-7.3h-0.4c-2.6,3.2-5.1,5.4-7.7,6.5s-5.7,1.7-9.5,1.7c-5.1,0-9.1-1.3-12-3.9
+ s-4.3-6.4-4.3-11.2c0-10.4,8.3-15.8,24.9-16.3l8.7-0.3v-3.2c0-4-0.9-7-2.6-8.9s-4.5-2.9-8.3-2.9c-4.3,0-9.1,1.3-14.5,3.9l-2.4-6
+ c2.5-1.4,5.3-2.5,8.3-3.2s6-1.2,9.1-1.2c6.1,0,10.7,1.4,13.6,4.1s4.4,7.1,4.4,13.1v35.1H116.2z M98.7,65.3c4.8,0,8.6-1.3,11.4-4
+ s4.1-6.4,4.1-11.2v-4.6l-7.8,0.3c-6.2,0.2-10.6,1.2-13.4,2.9S89,53.1,89,56.7c0,2.8,0.9,5,2.6,6.4S95.6,65.3,98.7,65.3z"/>
+ <path fill="#868482" d="M97.1,73.8c-5.6,0-10.1-1.5-13.3-4.5c-3.3-3-5-7.3-5-12.7c0-11.6,9-17.8,26.8-18.3l6.8-0.2v-1.3
+ c0-3.5-0.7-6.1-2.1-7.6c-1.3-1.5-3.6-2.2-6.8-2.2c-4,0-8.6,1.3-13.7,3.7l-1.9,0.9L84,22.1l1.6-0.8c2.7-1.4,5.6-2.6,8.8-3.4
+ c3.2-0.8,6.4-1.2,9.6-1.2c6.6,0,11.7,1.6,15,4.6c3.4,3.1,5.1,8,5.1,14.5v37.1h-9.4l-1.1-5.3c-2,2-4,3.5-6,4.4
+ C104.7,73.1,101.2,73.8,97.1,73.8z M103.5,23c4.4,0,7.7,1.2,9.8,3.5c2.1,2.3,3.1,5.7,3.1,10.3V42l-10.7,0.3
+ c-23,0.7-23,10.9-23,14.3c0,4.3,1.2,7.5,3.7,9.7c2.5,2.3,6.1,3.4,10.6,3.4c3.5,0,6.4-0.5,8.7-1.5c2.2-1,4.6-3,6.9-6l0.6-0.8h2.6
+ l0.7,1.6l1.2,5.7h2.1V35.8c0-5.4-1.3-9.3-3.8-11.6c-2.6-2.4-6.7-3.5-12.3-3.5c-2.8,0-5.7,0.4-8.6,1.1c-2.2,0.6-4.3,1.3-6.3,2.3
+ l0.9,2.3C94.9,24.1,99.4,23,103.5,23z M98.7,67.3c-3.5,0-6.4-0.9-8.5-2.7C88,62.8,87,60.1,87,56.7c0-4.3,1.7-7.6,5-9.6
+ c3.1-1.9,7.8-3,14.4-3.2l9.9-0.4v6.7c0,5.3-1.6,9.6-4.8,12.6C108.3,65.8,104,67.3,98.7,67.3z M112.2,47.6l-5.7,0.2
+ c-5.8,0.2-10,1.1-12.4,2.6C92,51.8,91,53.8,91,56.7c0,2.2,0.6,3.8,1.9,4.9c1.3,1.1,3.3,1.7,5.8,1.7c4.3,0,7.6-1.1,10-3.4
+ c2.4-2.3,3.5-5.5,3.5-9.7V47.6z"/>
+ </g>
+ </g>
+ <rect y="88" fill="#868482" width="124" height="8"/>
+</g>
+</svg>
diff --git a/src/virtualkeyboard/content/styles/default/style.qml b/src/virtualkeyboard/content/styles/default/style.qml
index e0556404..b1f1a623 100644
--- a/src/virtualkeyboard/content/styles/default/style.qml
+++ b/src/virtualkeyboard/content/styles/default/style.qml
@@ -17,8 +17,8 @@
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Enterprise.VirtualKeyboard 1.3
-import QtQuick.Enterprise.VirtualKeyboard.Styles 1.3
+import QtQuick.Enterprise.VirtualKeyboard 1.4
+import QtQuick.Enterprise.VirtualKeyboard.Styles 1.4
KeyboardStyle {
id: currentStyle
@@ -487,6 +487,51 @@ KeyboardStyle {
]
}
+ handwritingKeyPanel: KeyPanel {
+ Rectangle {
+ id: hwrKeyBackground
+ radius: 5
+ color: "#35322f"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ Image {
+ id: hwrKeyIcon
+ anchors.centerIn: parent
+ readonly property size hwrKeyIconSize: keyboard.handwritingMode ? Qt.size(124, 96) : Qt.size(156, 104)
+ sourceSize.width: hwrKeyIconSize.width * keyIconScale
+ sourceSize.height: hwrKeyIconSize.height * keyIconScale
+ smooth: false
+ source: resourcePrefix + (keyboard.handwritingMode ? "images/textmode-868482.svg" : "images/handwriting-868482.svg")
+ }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: hwrKeyBackground
+ opacity: 0.80
+ }
+ PropertyChanges {
+ target: hwrKeyIcon
+ opacity: 0.6
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: hwrKeyBackground
+ opacity: 0.8
+ }
+ PropertyChanges {
+ target: hwrKeyIcon
+ opacity: 0.2
+ }
+ }
+ ]
+ }
+
characterPreviewMargin: 0
characterPreviewDelegate: Item {
property string text
@@ -607,4 +652,80 @@ KeyboardStyle {
border.color: "yellow"
border.width: 5
}
+
+ traceInputKeyPanelDelegate: TraceInputKeyPanel {
+ traceMargins: keyBackgroundMargin
+ Rectangle {
+ id: traceInputKeyPanelBackground
+ radius: 5
+ color: "#35322f"
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ Text {
+ id: hwrInputModeIndicator
+ visible: control.patternRecognitionMode === InputEngine.HandwritingRecoginition
+ text: InputContext.inputEngine.inputMode === InputEngine.Latin ? "Abc" : "123"
+ color: "white"
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: keyContentMargin
+ font {
+ family: fontFamily
+ weight: Font.Normal
+ pixelSize: 44 * scaleHint
+ capitalization: {
+ if (InputContext.capsLock)
+ return Font.AllUppercase
+ if (InputContext.shift)
+ return Font.MixedCase
+ return Font.AllLowercase
+ }
+ }
+ }
+ }
+ Canvas {
+ id: traceInputKeyGuideLines
+ anchors.fill: traceInputKeyPanelBackground
+ opacity: 0.1
+ onPaint: {
+ var ctx = getContext("2d")
+ ctx.lineWidth = 1
+ ctx.strokeStyle = Qt.rgba(0xFF, 0xFF, 0xFF)
+ ctx.clearRect(0, 0, width, height)
+ var i
+ if (control.horizontalRulers) {
+ for (i = 0; i < control.horizontalRulers.length; i++) {
+ ctx.beginPath()
+ ctx.moveTo(0, control.horizontalRulers[i])
+ ctx.lineTo(width, control.horizontalRulers[i])
+ ctx.stroke()
+ }
+ }
+ if (control.verticalRulers) {
+ for (i = 0; i < control.verticalRulers.length; i++) {
+ ctx.beginPath()
+ ctx.moveTo(control.verticalRulers[i], 0)
+ ctx.lineTo(control.verticalRulers[i], height)
+ ctx.stroke()
+ }
+ }
+ }
+ }
+ }
+
+ traceCanvasDelegate: TraceCanvas {
+ id: traceCanvas
+ onAvailableChanged: {
+ if (!available)
+ return
+ var ctx = getContext("2d")
+ ctx.lineWidth = 10 * scaleHint
+ ctx.lineCap = "round"
+ ctx.strokeStyle = Qt.rgba(0xFF, 0xFF, 0xFF)
+ ctx.fillStyle = ctx.strokeStyle
+ }
+ autoDestroyDelay: 800
+ onTraceChanged: if (trace === null) opacity = 0
+ Behavior on opacity { PropertyAnimation { easing.type: Easing.OutCubic; duration: 150 } }
+ }
}
diff --git a/src/virtualkeyboard/content/styles/retro/images/handwriting-110b05.svg b/src/virtualkeyboard/content/styles/retro/images/handwriting-110b05.svg
new file mode 100644
index 00000000..d19c4da7
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/handwriting-110b05.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="156px" height="104px" viewBox="0 0 156 104" enable-background="new 0 0 156 104" xml:space="preserve">
+<g>
+ <rect fill="none" width="156" height="104"/>
+ <g>
+ <path fill="#110B05" d="M37.6,103.3c-10.1,0-18.9-5-23.1-13.6C4.4,68.7,19.9,52.3,36.2,35c1.2-1.2,2.4-2.5,3.6-3.8
+ c5.3-5.7,5.2-11.5,3.5-14.8c-1.8-3.4-5.5-4.9-10.2-4.2c-16.5,2.6-21.2,26.4-21.2,26.6L0,36.6C0.3,35.3,6.4,4.3,31.2,0.3
+ c9.8-1.6,18.5,2.4,22.7,10.4c4.7,8.9,2.6,20.1-5.3,28.6c-1.2,1.3-2.4,2.6-3.6,3.8C28.3,60.9,19.1,71.6,25.4,84.5
+ c3.3,6.8,11.1,7.6,16.9,6.3c9.2-2.1,19.8-11.1,19.7-29.5c-0.2-28.1,16.2-41.8,30.2-44.9c14.5-3.2,28.4,3.6,34.7,17
+ c1.3,2.8,2.3,5.4,3.1,8.1c13.3,0.7,25.5,4.3,26,4.4l-3.4,11.5c-0.1,0-9.7-2.8-20.6-3.8c0.5,16.5-8.6,28.9-20.1,34.7
+ c-11.9,6-24,3.8-28.9-5.2c-3.1-5.6-1.9-14.7,2.9-22.5c7.9-13,21.3-17.4,31.5-18.8c-0.4-1.2-0.9-2.4-1.4-3.4
+ c-3.9-8.3-12.2-12.4-21.1-10.4c-9.7,2.2-21,12.1-20.8,33.1c0.2,25.5-15.6,38.1-29,41.3C42.5,103,40,103.3,37.6,103.3z M119.8,53.7
+ c-14,1.5-20.6,8.5-23.4,12.9c-3.3,5.2-3.4,9.8-2.9,10.9c1.6,2.9,7.3,3,13,0.2C117.3,72.2,120.3,62.6,119.8,53.7z"/>
+ </g>
+</g>
+</svg>
diff --git a/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.svg b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.svg
new file mode 100644
index 00000000..13af8a63
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/key154px_colorA.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 154 154" enable-background="new 0 0 154 154" xml:space="preserve">
+<g>
+ <radialGradient id="SVGID_1_" cx="77" cy="77" r="73" gradientUnits="userSpaceOnUse">
+ <stop offset="0" style="stop-color:#CFBE90"/>
+ <stop offset="1" style="stop-color:#B2945A"/>
+ </radialGradient>
+ <path fill="url(#SVGID_1_)" d="M77,150c-40.3,0-73-32.7-73-73C4,36.7,36.7,4,77,4c40.3,0,73,32.7,73,73C150,117.3,117.3,150,77,150
+ z"/>
+ <path fill="#C2B49B" d="M77,8c38,0,69,31,69,69s-31,69-69,69S8,115,8,77S39,8,77,8 M77,0C34.5,0,0,34.5,0,77s34.5,77,77,77
+ s77-34.5,77-77S119.5,0,77,0L77,0z"/>
+</g>
+<g opacity="8.000000e-02">
+ <path d="M77,16c33.6,0,61,27.4,61,61s-27.4,61-61,61s-61-27.4-61-61S43.4,16,77,16 M77,8C38.9,8,8,38.9,8,77s30.9,69,69,69
+ s69-30.9,69-69S115.1,8,77,8L77,8z"/>
+</g>
+</svg>
diff --git a/src/virtualkeyboard/content/styles/retro/images/textmode-110b05.svg b/src/virtualkeyboard/content/styles/retro/images/textmode-110b05.svg
new file mode 100644
index 00000000..b891d960
--- /dev/null
+++ b/src/virtualkeyboard/content/styles/retro/images/textmode-110b05.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="124px" height="96px" viewBox="0 0 124 96" enable-background="new 0 0 124 96" xml:space="preserve">
+<g>
+ <g>
+ <g>
+ <path fill="#110B05" d="M55.4,70.8L46.9,49H19.4L11,70.8H2.9L30,2h6.7l27,68.8H55.4z M44.4,41.8l-8-21.2c-1-2.7-2.1-6-3.2-9.9
+ c-0.7,3-1.7,6.3-3,9.9l-8.1,21.2H44.4z"/>
+ <path fill="#110B05" d="M66.6,72.8H54.1L45.5,51H20.8l-8.4,21.8H0L28.7,0h9.4L66.6,72.8z M56.8,68.8h4L35.4,4h-1.9l1.7,6.2
+ c1.1,3.8,2.1,7.1,3.1,9.7l9,24h-28l9.1-23.9c1.2-3.5,2.2-6.7,2.9-9.6L32.8,4h-1.4L5.9,68.8h3.8L18.1,47h30.2L56.8,68.8z
+ M25.1,39.8h16.4l-7-18.5c-0.4-1.1-0.8-2.2-1.2-3.4c-0.4,1.1-0.7,2.2-1.2,3.4L25.1,39.8z"/>
+ </g>
+ <g>
+ <path fill="#110B05" d="M116.2,70.8l-1.5-7.3h-0.4c-2.6,3.2-5.1,5.4-7.7,6.5s-5.7,1.7-9.5,1.7c-5.1,0-9.1-1.3-12-3.9
+ s-4.3-6.4-4.3-11.2c0-10.4,8.3-15.8,24.9-16.3l8.7-0.3v-3.2c0-4-0.9-7-2.6-8.9s-4.5-2.9-8.3-2.9c-4.3,0-9.1,1.3-14.5,3.9l-2.4-6
+ c2.5-1.4,5.3-2.5,8.3-3.2s6-1.2,9.1-1.2c6.1,0,10.7,1.4,13.6,4.1s4.4,7.1,4.4,13.1v35.1H116.2z M98.7,65.3c4.8,0,8.6-1.3,11.4-4
+ s4.1-6.4,4.1-11.2v-4.6l-7.8,0.3c-6.2,0.2-10.6,1.2-13.4,2.9S89,53.1,89,56.7c0,2.8,0.9,5,2.6,6.4S95.6,65.3,98.7,65.3z"/>
+ <path fill="#110B05" d="M97.1,73.8c-5.6,0-10.1-1.5-13.3-4.5c-3.3-3-5-7.3-5-12.7c0-11.6,9-17.8,26.8-18.3l6.8-0.2v-1.3
+ c0-3.5-0.7-6.1-2.1-7.6c-1.3-1.5-3.6-2.2-6.8-2.2c-4,0-8.6,1.3-13.7,3.7l-1.9,0.9L84,22.1l1.6-0.8c2.7-1.4,5.6-2.6,8.8-3.4
+ c3.2-0.8,6.4-1.2,9.6-1.2c6.6,0,11.7,1.6,15,4.6c3.4,3.1,5.1,8,5.1,14.5v37.1h-9.4l-1.1-5.3c-2,2-4,3.5-6,4.4
+ C104.7,73.1,101.2,73.8,97.1,73.8z M103.5,23c4.4,0,7.7,1.2,9.8,3.5c2.1,2.3,3.1,5.7,3.1,10.3V42l-10.7,0.3
+ c-23,0.7-23,10.9-23,14.3c0,4.3,1.2,7.5,3.7,9.7c2.5,2.3,6.1,3.4,10.6,3.4c3.5,0,6.4-0.5,8.7-1.5c2.2-1,4.6-3,6.9-6l0.6-0.8h2.6
+ l0.7,1.6l1.2,5.7h2.1V35.8c0-5.4-1.3-9.3-3.8-11.6c-2.6-2.4-6.7-3.5-12.3-3.5c-2.8,0-5.7,0.4-8.6,1.1c-2.2,0.6-4.3,1.3-6.3,2.3
+ l0.9,2.3C94.9,24.1,99.4,23,103.5,23z M98.7,67.3c-3.5,0-6.4-0.9-8.5-2.7C88,62.8,87,60.1,87,56.7c0-4.3,1.7-7.6,5-9.6
+ c3.1-1.9,7.8-3,14.4-3.2l9.9-0.4v6.7c0,5.3-1.6,9.6-4.8,12.6C108.3,65.8,104,67.3,98.7,67.3z M112.2,47.6l-5.7,0.2
+ c-5.8,0.2-10,1.1-12.4,2.6C92,51.8,91,53.8,91,56.7c0,2.2,0.6,3.8,1.9,4.9c1.3,1.1,3.3,1.7,5.8,1.7c4.3,0,7.6-1.1,10-3.4
+ c2.4-2.3,3.5-5.5,3.5-9.7V47.6z"/>
+ </g>
+ </g>
+ <rect y="88" fill="#110B05" width="124" height="8"/>
+</g>
+</svg>
diff --git a/src/virtualkeyboard/content/styles/retro/retro_style.qrc b/src/virtualkeyboard/content/styles/retro/retro_style.qrc
index 82056d00..0de3a9f9 100644
--- a/src/virtualkeyboard/content/styles/retro/retro_style.qrc
+++ b/src/virtualkeyboard/content/styles/retro/retro_style.qrc
@@ -7,6 +7,7 @@
<file>images/key154px_capslock.png</file>
<file>images/key154px_colorA_long.png</file>
<file>images/key154px_colorA.png</file>
+ <file>images/key154px_colorA.svg</file>
<file>images/key154px_colorB.png</file>
<file>images/key154px_shiftcase_long.png</file>
<file>images/key154px_shiftcase.png</file>
@@ -24,10 +25,12 @@
<file>images/check-c5a96f.svg</file>
<file>images/enter-c5a96f.svg</file>
<file>images/globe-110b05.svg</file>
+ <file>images/handwriting-110b05.svg</file>
<file>images/hidekeyboard-c5a96f.svg</file>
<file>images/search-c5a96f.svg</file>
<file>images/shift-c5a96f.svg</file>
<file>images/shift-cd8865.svg</file>
<file>images/shift-dc4f28.svg</file>
+ <file>images/textmode-110b05.svg</file>
</qresource>
</RCC>
diff --git a/src/virtualkeyboard/content/styles/retro/style.qml b/src/virtualkeyboard/content/styles/retro/style.qml
index 7af2fe81..82a6ebcd 100644
--- a/src/virtualkeyboard/content/styles/retro/style.qml
+++ b/src/virtualkeyboard/content/styles/retro/style.qml
@@ -17,8 +17,8 @@
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Enterprise.VirtualKeyboard 1.3
-import QtQuick.Enterprise.VirtualKeyboard.Styles 1.3
+import QtQuick.Enterprise.VirtualKeyboard 1.4
+import QtQuick.Enterprise.VirtualKeyboard.Styles 1.4
KeyboardStyle {
id: currentStyle
@@ -27,7 +27,8 @@ KeyboardStyle {
readonly property real keyBackgroundMargin: Math.round(9 * scaleHint)
readonly property real keyContentMargin: Math.round(50 * scaleHint)
readonly property real keyIconScale: scaleHint * 0.6
- readonly property string resourcePrefix: "qrc:/content/styles/retro/"
+ readonly property string resourcePath: "content/styles/retro/"
+ readonly property string resourcePrefix: "qrc:/" + resourcePath
readonly property string inputLocale: InputContext.locale
property color inputLocaleIndicatorColor: "#110b05"
@@ -560,6 +561,57 @@ KeyboardStyle {
]
}
+ handwritingKeyPanel: KeyPanel {
+ BorderImage {
+ id: hwrKeyBackground
+ source: resourcePrefix + "images/key154px_colorB.png"
+ width: (parent.width - 2 * hwrKeyBackground) / scale
+ height: sourceSize.height
+ anchors.centerIn: parent
+ border.left: 76
+ border.top: 76
+ border.right: 76
+ border.bottom: 76
+ horizontalTileMode: BorderImage.Stretch
+ scale: (parent.height - 2 * keyBackgroundMargin) / sourceSize.height
+ }
+ Image {
+ id: hwrKeyIcon
+ anchors.centerIn: parent
+ readonly property size hwrKeyIconSize: keyboard.handwritingMode ? Qt.size(124, 96) : Qt.size(156, 104)
+ sourceSize.width: hwrKeyIconSize.width * keyIconScale
+ sourceSize.height: hwrKeyIconSize.height * keyIconScale
+ smooth: false
+ source: resourcePrefix + (keyboard.handwritingMode ? "images/textmode-110b05.svg" : "images/handwriting-110b05.svg")
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: control.pressed
+ PropertyChanges {
+ target: hwrKeyBackground
+ opacity: 0.70
+ }
+ PropertyChanges {
+ target: hwrKeyIcon
+ opacity: 0.70
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges {
+ target: hwrKeyBackground
+ opacity: 0.20
+ }
+ PropertyChanges {
+ target: hwrKeyIcon
+ opacity: 0.20
+ }
+ }
+ ]
+ }
+
characterPreviewMargin: Math.round(20 * scaleHint)
characterPreviewDelegate: Item {
property string text
@@ -723,4 +775,87 @@ KeyboardStyle {
border.color: "yellow"
border.width: 5
}
+
+ traceInputKeyPanelDelegate: TraceInputKeyPanel {
+ traceMargins: keyBackgroundMargin
+ BorderImage {
+ id: traceInputKeyPanelBackground
+ readonly property int traceInputKeyPanelSvgImageHeight: Math.round(height / 12)
+ readonly property real traceInputKeyPanelSvgImageScale: traceInputKeyPanelSvgImageHeight / 154
+ source: "image://qtvkbsvg/%1/images/key154px_colorA.svg?height=%2".arg(resourcePath).arg(traceInputKeyPanelSvgImageHeight)
+ anchors.fill: parent
+ anchors.margins: keyBackgroundMargin
+ border.left: 76 * traceInputKeyPanelSvgImageScale
+ border.top: 76 * traceInputKeyPanelSvgImageScale
+ border.right: 78 * traceInputKeyPanelSvgImageScale
+ border.bottom: 78 * traceInputKeyPanelSvgImageScale
+ horizontalTileMode: BorderImage.Stretch
+ verticalTileMode: BorderImage.Stretch
+ }
+ Text {
+ id: hwrInputModeIndicator
+ visible: control.patternRecognitionMode === InputEngine.HandwritingRecoginition
+ text: InputContext.inputEngine.inputMode === InputEngine.Latin ? "Abc" : "123"
+ color: "black"
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: keyContentMargin * 1.5
+ font {
+ family: fontFamily
+ weight: Font.Bold
+ pixelSize: 72 * scaleHint
+ capitalization: {
+ if (InputContext.capsLock)
+ return Font.AllUppercase
+ if (InputContext.shift)
+ return Font.MixedCase
+ return Font.AllLowercase
+ }
+ }
+ }
+ Canvas {
+ id: traceInputKeyGuideLines
+ anchors.fill: traceInputKeyPanelBackground
+ opacity: 0.1
+ onPaint: {
+ var ctx = getContext("2d")
+ ctx.lineWidth = 1
+ ctx.strokeStyle = Qt.rgba(0xFF, 0xFF, 0xFF)
+ ctx.clearRect(0, 0, width, height)
+ var i
+ if (control.horizontalRulers) {
+ for (i = 0; i < control.horizontalRulers.length; i++) {
+ ctx.beginPath()
+ ctx.moveTo(0, control.horizontalRulers[i])
+ ctx.lineTo(width, control.horizontalRulers[i])
+ ctx.stroke()
+ }
+ }
+ if (control.verticalRulers) {
+ for (i = 0; i < control.verticalRulers.length; i++) {
+ ctx.beginPath()
+ ctx.moveTo(control.verticalRulers[i], 0)
+ ctx.lineTo(control.verticalRulers[i], height)
+ ctx.stroke()
+ }
+ }
+ }
+ }
+ }
+
+ traceCanvasDelegate: TraceCanvas {
+ id: traceCanvas
+ onAvailableChanged: {
+ if (!available)
+ return
+ var ctx = getContext("2d")
+ ctx.lineWidth = 10 * scaleHint
+ ctx.lineCap = "round"
+ ctx.strokeStyle = Qt.rgba(0, 0, 0)
+ ctx.fillStyle = ctx.strokeStyle
+ }
+ autoDestroyDelay: 800
+ onTraceChanged: if (trace === null) opacity = 0
+ Behavior on opacity { PropertyAnimation { easing.type: Easing.OutCubic; duration: 150 } }
+ }
}