diff options
author | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2017-01-11 00:11:00 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2017-01-30 10:51:15 +0000 |
commit | ad44e00c0d01dea15358b98865623e8f11f295a8 (patch) | |
tree | b3f61fa370e95cd58a0e3cbd9be2de03287c6d9b /src/virtualkeyboard/content | |
parent | 3076d61bc6a8462559162ac4a529ab6a9ec183c4 (diff) |
Add full screen input mode for super wide screens
In full screen mode the virtual keyboard replicates the contents of
the focused input field to full screen input field located on top
of keyboard.
This mode can be activated by VirtualKeyboardSettings.fullScreenMode.
[ChangeLog] Added full screen input mode for super wide screens.
Change-Id: Ib2650c04767fb0945cc2bedc5b1801d254a15a41
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/virtualkeyboard/content')
-rw-r--r-- | src/virtualkeyboard/content/InputPanel.qml | 3 | ||||
-rw-r--r-- | src/virtualkeyboard/content/components/Keyboard.qml | 62 | ||||
-rw-r--r-- | src/virtualkeyboard/content/components/SelectionControl.qml | 27 | ||||
-rw-r--r-- | src/virtualkeyboard/content/components/ShadowInputControl.qml | 138 | ||||
-rw-r--r-- | src/virtualkeyboard/content/content.qrc | 1 | ||||
-rw-r--r-- | src/virtualkeyboard/content/styles/default/style.qml | 20 | ||||
-rw-r--r-- | src/virtualkeyboard/content/styles/retro/style.qml | 24 |
7 files changed, 257 insertions, 18 deletions
diff --git a/src/virtualkeyboard/content/InputPanel.qml b/src/virtualkeyboard/content/InputPanel.qml index 3e354471..2b6772de 100644 --- a/src/virtualkeyboard/content/InputPanel.qml +++ b/src/virtualkeyboard/content/InputPanel.qml @@ -60,8 +60,10 @@ Item { property alias keyboard: keyboard SelectionControl { + objectName: "selectionControl" x: -parent.x y: -parent.y + enabled: active && !keyboard.fullScreenMode } implicitHeight: keyboard.height @@ -74,5 +76,6 @@ Item { MouseArea { z: -1 anchors.fill: keyboard + enabled: active } } diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml index 2bb68d3e..2bd2ff2e 100644 --- a/src/virtualkeyboard/content/components/Keyboard.qml +++ b/src/virtualkeyboard/content/components/Keyboard.qml @@ -29,7 +29,8 @@ import QtQuick 2.0 import QtQuick.Layouts 1.0 -import QtQuick.VirtualKeyboard 2.1 +import QtQuick.Window 2.2 +import QtQuick.VirtualKeyboard 2.2 import QtQuick.VirtualKeyboard.Styles 2.1 import QtQuick.VirtualKeyboard.Settings 2.2 import Qt.labs.folderlistmodel 2.0 @@ -62,6 +63,7 @@ Item { property bool handwritingMode property bool fullScreenHandwritingMode property bool symbolMode + property bool fullScreenMode: VirtualKeyboardSettings.fullScreenMode property var defaultInputMethod: initDefaultInputMethod() property var plainInputMethod: PlainInputMethod {} property var customInputMethod: null @@ -104,6 +106,10 @@ Item { if (!isValidLocale(localeIndex) || VirtualKeyboardSettings.locale) localeIndex = defaultLocaleIndex } + onFullScreenModeChanged: { + wordCandidateView.disableAnimation = VirtualKeyboardSettings.fullScreenMode + keyboard.fullScreenMode = VirtualKeyboardSettings.fullScreenMode + } } onAvailableLocaleIndicesChanged: hideLanguagePopup() onAvailableCustomLocaleIndicesChanged: hideLanguagePopup() @@ -465,7 +471,10 @@ Item { Binding { target: InputContext property: "keyboardRectangle" - value: Qt.rect(keyboard.x, keyboard.y + wordCandidateView.currentYOffset, keyboard.width, keyboard.height - wordCandidateView.currentYOffset) + value: Qt.rect(keyboard.x, + keyboard.y + wordCandidateView.currentYOffset - (shadowInputControl.visible ? shadowInputControl.height : 0), + keyboard.width, + keyboard.height - wordCandidateView.currentYOffset + (shadowInputControl.visible ? shadowInputControl.height : 0)) when: keyboard.active && !InputContext.animating } Binding { @@ -540,15 +549,58 @@ Item { } } + ShadowInputControl { + id: shadowInputControl + objectName: "shadowInputControl" + z: -3 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: wordCandidateView.top + height: (keyboard.parent.parent ? keyboard.parent.parent.height : Screen.height) - + keyboard.height - (wordCandidateView.visibleCondition ? wordCandidateView.height : 0) + visible: fullScreenMode && (shadowInputControlVisibleTimer.running || InputContext.animating) + + Connections { + target: keyboard + onActiveChanged: { + if (keyboard.active) + shadowInputControlVisibleTimer.start() + else + shadowInputControlVisibleTimer.stop() + } + } + + Timer { + id: shadowInputControlVisibleTimer + interval: 2147483647 + repeat: true + } + + MouseArea { + onPressed: keyboard.hideLanguagePopup() + anchors.fill: parent + enabled: languagePopupList.enabled + } + } + + SelectionControl { + objectName: "fullScreenModeSelectionControl" + inputContext: InputContext.shadow + anchors.top: shadowInputControl.top + anchors.left: shadowInputControl.left + enabled: keyboard.enabled && fullScreenMode + } + ListView { id: wordCandidateView objectName: "wordCandidateView" clip: true z: -2 + property bool disableAnimation: VirtualKeyboardSettings.fullScreenMode property bool empty: true - readonly property bool visibleCondition: (((!wordCandidateView.empty || wordCandidateViewAutoHideTimer.running) && + readonly property bool visibleCondition: (((!wordCandidateView.empty || wordCandidateViewAutoHideTimer.running || shadowInputControl.visible) && InputContext.inputEngine.wordCandidateListVisibleHint) || VirtualKeyboardSettings.wordCandidateList.alwaysVisible) && - keyboard.active + (keyboard.active || shadowInputControl.visible) readonly property real visibleYOffset: VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? 0 : -height readonly property real currentYOffset: visibleCondition || wordCandidateViewTransition.running ? visibleYOffset : 0 height: Math.round(style.selectionListHeight) @@ -609,7 +661,7 @@ Item { transitions: Transition { id: wordCandidateViewTransition to: "visible" - enabled: !InputContext.animating && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible + enabled: !InputContext.animating && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible && !wordCandidateView.disableAnimation reversible: true ParallelAnimation { NumberAnimation { diff --git a/src/virtualkeyboard/content/components/SelectionControl.qml b/src/virtualkeyboard/content/components/SelectionControl.qml index a24c1116..125a8eb7 100644 --- a/src/virtualkeyboard/content/components/SelectionControl.qml +++ b/src/virtualkeyboard/content/components/SelectionControl.qml @@ -33,18 +33,19 @@ import QtQuick.VirtualKeyboard 2.1 Item { id: root property bool handleIsMoving: false - visible: InputContext.selectionControlVisible || handleIsMoving + property var inputContext: InputContext + visible: enabled && (inputContext.selectionControlVisible || handleIsMoving) && !InputContext.animating Loader { id: anchorHandle sourceComponent: keyboard.style.selectionHandle - x: visible ? Qt.inputMethod.anchorRectangle.x - width/2 : 0 - y: visible ? Qt.inputMethod.anchorRectangle.y + Qt.inputMethod.anchorRectangle.height : 0 + x: visible ? inputContext.anchorRectangle.x - width/2 : 0 + y: visible ? inputContext.anchorRectangle.y + inputContext.anchorRectangle.height : 0 Behavior on opacity { NumberAnimation { duration: 200 } } - opacity: InputContext.anchorRectIntersectsClipRect ? 1.0 : 0.0 + opacity: inputContext.anchorRectIntersectsClipRect ? 1.0 : 0.0 MouseArea { width: parent.width * 2 @@ -55,10 +56,10 @@ Item { // The middle of a handle is mapped to the middle of the line above it root.handleIsMoving = true var xx = x + anchorHandle.x + mouse.x - var yy = y + anchorHandle.y + mouse.y - (anchorHandle.height + Qt.inputMethod.anchorRectangle.height)/2 + var yy = y + anchorHandle.y + mouse.y - (anchorHandle.height + inputContext.anchorRectangle.height)/2 var x2 = cursorHandle.x + cursorHandle.width/2 - var y2 = cursorHandle.y - Qt.inputMethod.cursorRectangle.height/2 - InputContext.setSelectionOnFocusObject(Qt.point(xx,yy), Qt.point(x2,y2)) + var y2 = cursorHandle.y - inputContext.cursorRectangle.height/2 + inputContext.setSelectionOnFocusObject(Qt.point(xx,yy), Qt.point(x2,y2)) } onReleased: { root.handleIsMoving = false @@ -70,13 +71,13 @@ Item { Loader { id: cursorHandle sourceComponent: keyboard.style.selectionHandle - x: visible ? Qt.inputMethod.cursorRectangle.x - width/2 : 0 - y: visible ? Qt.inputMethod.cursorRectangle.y + Qt.inputMethod.cursorRectangle.height : 0 + x: visible ? inputContext.cursorRectangle.x - width/2 : 0 + y: visible ? inputContext.cursorRectangle.y + inputContext.cursorRectangle.height : 0 Behavior on opacity { NumberAnimation { duration: 200 } } - opacity: InputContext.cursorRectIntersectsClipRect ? 1.0 : 0.0 + opacity: inputContext.cursorRectIntersectsClipRect ? 1.0 : 0.0 MouseArea { width: parent.width * 2 @@ -86,10 +87,10 @@ Item { // we don't move the handles, the handles will move as the selection changes. root.handleIsMoving = true var xx = anchorHandle.x + anchorHandle.width/2 - var yy = anchorHandle.y - Qt.inputMethod.anchorRectangle.height/2 + var yy = anchorHandle.y - inputContext.anchorRectangle.height/2 var x2 = x + cursorHandle.x + mouse.x - var y2 = y + cursorHandle.y + mouse.y - (cursorHandle.height + Qt.inputMethod.cursorRectangle.height)/2 - InputContext.setSelectionOnFocusObject(Qt.point(xx, yy), Qt.point(x2, y2)) + var y2 = y + cursorHandle.y + mouse.y - (cursorHandle.height + inputContext.cursorRectangle.height)/2 + inputContext.setSelectionOnFocusObject(Qt.point(xx, yy), Qt.point(x2, y2)) } onReleased: { root.handleIsMoving = false diff --git a/src/virtualkeyboard/content/components/ShadowInputControl.qml b/src/virtualkeyboard/content/components/ShadowInputControl.qml new file mode 100644 index 00000000..b935d5c6 --- /dev/null +++ b/src/virtualkeyboard/content/components/ShadowInputControl.qml @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.VirtualKeyboard 2.2 +import QtQuick.VirtualKeyboard.Settings 2.2 + +Item { + id: control + + enabled: keyboard.active && VirtualKeyboardSettings.fullScreenMode + + MouseArea { + anchors.fill: parent + } + + onXChanged: InputContext.shadow.updateSelectionProperties() + onYChanged: InputContext.shadow.updateSelectionProperties() + + Loader { + sourceComponent: keyboard.style.fullScreenInputContainerBackground + anchors.fill: parent + Loader { + id: fullScreenInputBackground + sourceComponent: keyboard.style.fullScreenInputBackground + anchors.fill: parent + anchors.margins: keyboard.style.fullScreenInputMargins + z: 1 + Flickable { + id: flickable + clip: true + z: 2 + width: parent.width + height: parent.height + flickableDirection: Flickable.HorizontalFlick + interactive: contentWidth > width + contentWidth: shadowInput.width + onContentXChanged: InputContext.shadow.updateSelectionProperties() + + function ensureVisible(rectangle) { + if (contentX >= rectangle.x) + contentX = rectangle.x + else if (contentX + width <= rectangle.x + rectangle.width) + contentX = rectangle.x + rectangle.width - width; + } + + TextInput { + id: shadowInput + objectName: "shadowInput" + property bool blinkStatus: true + width: Math.max(flickable.width, implicitWidth) + height: implicitHeight + anchors.verticalCenter: parent.verticalCenter + leftPadding: keyboard.style.fullScreenInputPadding + rightPadding: keyboard.style.fullScreenInputPadding + activeFocusOnPress: false + font: keyboard.style.fullScreenInputFont + inputMethodHints: InputContext.inputMethodHints + cursorDelegate: keyboard.style.fullScreenInputCursor + passwordCharacter: keyboard.style.fullScreenInputPasswordCharacter + color: keyboard.style.fullScreenInputColor + selectionColor: keyboard.style.fullScreenInputSelectionColor + selectedTextColor: keyboard.style.fullScreenInputSelectedTextColor + echoMode: (InputContext.inputMethodHints & Qt.ImhHiddenText) ? TextInput.Password : TextInput.Normal + selectByMouse: true + onCursorPositionChanged: { + cursorSyncTimer.restart() + blinkStatus = true + cursorTimer.restart() + } + onSelectionStartChanged: cursorSyncTimer.restart() + onSelectionEndChanged: cursorSyncTimer.restart() + onCursorRectangleChanged: flickable.ensureVisible(cursorRectangle) + + function getAnchorPosition() { + if (selectionStart == selectionEnd) + return cursorPosition + else if (selectionStart == cursorPosition) + return selectionEnd + else + return selectionStart + } + + Timer { + id: cursorSyncTimer + interval: 0 + onTriggered: { + var anchorPosition = shadowInput.getAnchorPosition() + if (anchorPosition !== InputContext.anchorPosition || shadowInput.cursorPosition !== InputContext.cursorPosition) + InputContext.forceCursorPosition(anchorPosition, shadowInput.cursorPosition) + } + } + + Timer { + id: cursorTimer + interval: Qt.styleHints.cursorFlashTime / 2 + repeat: true + running: true + onTriggered: shadowInput.blinkStatus = !shadowInput.blinkStatus + } + } + } + } + } + + Binding { + target: InputContext.shadow + property: "inputItem" + value: shadowInput + when: VirtualKeyboardSettings.fullScreenMode + } +} diff --git a/src/virtualkeyboard/content/content.qrc b/src/virtualkeyboard/content/content.qrc index 20627466..431e4205 100644 --- a/src/virtualkeyboard/content/content.qrc +++ b/src/virtualkeyboard/content/content.qrc @@ -29,5 +29,6 @@ <file>components/WordCandidatePopupList.qml</file> <file>components/LanguagePopupList.qml</file> <file>components/SelectionControl.qml</file> + <file>components/ShadowInputControl.qml</file> </qresource> </RCC> diff --git a/src/virtualkeyboard/content/styles/default/style.qml b/src/virtualkeyboard/content/styles/default/style.qml index e02b749e..03f0344f 100644 --- a/src/virtualkeyboard/content/styles/default/style.qml +++ b/src/virtualkeyboard/content/styles/default/style.qml @@ -954,4 +954,24 @@ KeyboardStyle { sourceSize.width: 20 source: resourcePrefix + "images/selectionhandle-bottom.svg" } + + fullScreenInputContainerBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputMargins: Math.round(15 * scaleHint) + + fullScreenInputPadding: Math.round(30 * scaleHint) + + fullScreenInputCursor: Rectangle { + width: 1 + color: "#000" + visible: parent.blinkStatus + } + + fullScreenInputFont.pixelSize: 58 * scaleHint } diff --git a/src/virtualkeyboard/content/styles/retro/style.qml b/src/virtualkeyboard/content/styles/retro/style.qml index 04e7ea81..a1cb3ffc 100644 --- a/src/virtualkeyboard/content/styles/retro/style.qml +++ b/src/virtualkeyboard/content/styles/retro/style.qml @@ -994,4 +994,28 @@ KeyboardStyle { sourceSize.width: 20 source: resourcePrefix + "images/selectionhandle-bottom.svg" } + + fullScreenInputContainerBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputBackground: Rectangle { + color: "#FFF" + } + + fullScreenInputMargins: Math.round(15 * scaleHint) + + fullScreenInputPadding: Math.round(30 * scaleHint) + + fullScreenInputCursor: Rectangle { + width: 1 + color: "#000" + visible: parent.blinkStatus + } + + fullScreenInputFont.pixelSize: 58 * scaleHint + + fullScreenInputPasswordCharacter: "*" + + fullScreenInputSelectionColor: "#B57C47" } |