summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Nurmenniemi <sami.nurmenniemi@qt.io>2017-10-25 13:17:22 +0300
committerSami Nurmenniemi <sami.nurmenniemi@qt.io>2017-11-22 10:43:24 +0000
commit8d03def677ff09f43322f4d38b6d56e6ebf0e1f9 (patch)
tree968ae957f7a43c882d69d476e08702fb3505f8fd
parentc48368aa9db97c5ae28fa91d31f15cc1d52f8f10 (diff)
Add loader animation to the application startup
Task-number: QTBUG-60089 Change-Id: Iadfd5898098a2aa5d6b717263275f929a08d24f0 Reviewed-by: Kari Oikarinen <kari.oikarinen@qt.io>
-rw-r--r--qml.qrc2
-rw-r--r--qml/BootScreen.qml3
-rw-r--r--qml/DemoInfoPopup.qml24
-rw-r--r--qml/DetailView.qml21
-rw-r--r--qml/FlickSlider.qml56
-rw-r--r--qml/LaunchScreen.qml24
-rw-r--r--qml/Main.qml313
-rw-r--r--qml/MainWindow.qml330
8 files changed, 432 insertions, 341 deletions
diff --git a/qml.qrc b/qml.qrc
index a2b22b8..a18b658 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -21,5 +21,7 @@
<file>qml/settings.xml</file>
<file>qml/ImageTextDelegate.qml</file>
<file>qml/BusyIndicator.qml</file>
+ <file>qml/MainWindow.qml</file>
+ <file>qml/FlickSlider.qml</file>
</qresource>
</RCC>
diff --git a/qml/BootScreen.qml b/qml/BootScreen.qml
index cab6838..1318495 100644
--- a/qml/BootScreen.qml
+++ b/qml/BootScreen.qml
@@ -32,6 +32,7 @@ Rectangle {
id: bootScreen
color: viewSettings.backgroundColor
opacity: 0.95
+ property string applicationName: ""
Column {
anchors.centerIn: parent
@@ -54,7 +55,7 @@ Rectangle {
font.pixelSize: bootScreen.height * 0.05
font.styleName: "Bold"
color: "white"
- text: engine.applicationName
+ text: applicationName
}
}
}
diff --git a/qml/DemoInfoPopup.qml b/qml/DemoInfoPopup.qml
index 5cc64aa..11bc826 100644
--- a/qml/DemoInfoPopup.qml
+++ b/qml/DemoInfoPopup.qml
@@ -121,26 +121,12 @@ Rectangle {
width: frame.width * 0.9
wrapMode: Text.WordWrap
}
+ }
- ScrollBar.vertical: ScrollBar {
- parent: flickable.parent
- anchors.top: flickable.top
- anchors.bottom: flickable.bottom
- anchors.right: parent.right
- anchors.rightMargin: viewSettings.pageMargin * 0.2
- anchors.topMargin: viewSettings.pageMargin * 0.5
- width: viewSettings.pageMargin * 0.6
- size: 0.3
- position: 0.2
- active: true
- orientation: Qt.Vertical
-
- contentItem: Rectangle {
- implicitWidth: root.margin * 0.3
- implicitHeight: root.height * 0.1
- color: viewSettings.scrollBarColor
- }
- }
+ FlickSlider {
+ flickItem: flickable
+ anchors.right: frame.right
+ width: viewSettings.pageMargin * 0.5
}
}
}
diff --git a/qml/DetailView.qml b/qml/DetailView.qml
index e390267..231be57 100644
--- a/qml/DetailView.qml
+++ b/qml/DetailView.qml
@@ -59,7 +59,6 @@ Item {
anchors.rightMargin: viewSettings.pageMargin
contentHeight: descriptionHolder.height
contentWidth: width
- clip: true
Column {
id: descriptionHolder
@@ -147,20 +146,12 @@ Item {
thumbList.currentIndex = index
}
}
- ScrollBar.horizontal: ScrollBar{
- parent: thumbList.parent
- anchors.bottom: parent.bottom
- anchors.bottomMargin: viewSettings.pageMargin * 0.3
- anchors.left: parent.left
- anchors.leftMargin: viewSettings.pageMargin
- anchors.right: parent.right
- anchors.rightMargin: viewSettings.pageMargin
- size: 0.3
- contentItem: Rectangle{
- color: viewSettings.scrollBarColor
- implicitHeight: thumbList.height * 0.03
- }
- }
+ }
+
+ FlickSlider {
+ flickItem: thumbList
+ anchors.bottom: listHolder.bottom
+ isVertical: false
}
}
}
diff --git a/qml/FlickSlider.qml b/qml/FlickSlider.qml
new file mode 100644
index 0000000..5db0096
--- /dev/null
+++ b/qml/FlickSlider.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Device Creation.
+**
+** $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.0
+
+// QTBUG-50992, using customized ScrollBar inside Loader does not work, implement with rectangle
+Rectangle {
+ property var flickItem
+ property bool isVertical: true
+
+ color: viewSettings.scrollBarColor
+ anchors.margins: viewSettings.pageMargin * 0.375
+ height: isVertical ? flickItem.height * 0.3 : viewSettings.pageMargin * 0.25
+ width: isVertical ? viewSettings.pageMargin * 0.25 : flickItem.width * 0.2
+
+ // How much (0...1) the view area covers from the content height/width
+ property real visibilityRatio: isVertical ? flickItem.visibleArea.heightRatio : flickItem.visibleArea.widthRatio
+
+ // How many pixels the slider can move in the view area
+ property real moveSize: isVertical ? flickItem.height - height : flickItem.width - width
+
+ // Coefficient between x/y position (0...1) and slider move pixels
+ property real slideCoefficient: (visibilityRatio < 1) ? (moveSize)/(1 - visibilityRatio) : 1
+
+ // Slider is only visible if view area is smaller than the content
+ visible: (visibilityRatio < 1)
+
+ // Actual calculation of the slider position
+ x: isVertical ? 0 : slideCoefficient * flickItem.visibleArea.xPosition + flickItem.x
+ y: isVertical ? slideCoefficient * flickItem.visibleArea.yPosition + flickItem.y : 0
+}
diff --git a/qml/LaunchScreen.qml b/qml/LaunchScreen.qml
index a83d524..7d369b7 100644
--- a/qml/LaunchScreen.qml
+++ b/qml/LaunchScreen.qml
@@ -27,7 +27,7 @@
**
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.3
Item {
id: gridroot
@@ -51,24 +51,10 @@ Item {
width: grid.cellWidth
onClicked: root.launchApplication(sLocation, sMainFile, sName, sDescription)
}
- ScrollBar.vertical: ScrollBar {
- parent: gridroot
- anchors.top: grid.top
- anchors.bottom: grid.bottom
- anchors.right: parent.right
- anchors.rightMargin: viewSettings.pageMargin * 0.25
- anchors.topMargin: viewSettings.pageMargin * 0.5
- width: viewSettings.pageMargin * 0.5
- size: 0.3
- position: 0.2
- active: true
- orientation: Qt.Vertical
+ }
- contentItem: Rectangle {
- implicitWidth: viewSettings.pageMargin * 0.25
- implicitHeight: root.height * 0.1
- color: viewSettings.scrollBarColor
- }
- }
+ FlickSlider {
+ flickItem: grid
+ anchors.right: parent.right
}
}
diff --git a/qml/Main.qml b/qml/Main.qml
index 23d365c..99c6e4d 100644
--- a/qml/Main.qml
+++ b/qml/Main.qml
@@ -26,20 +26,16 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-import QtQuick 2.4
+import QtQml 2.2
+import QtQuick 2.6
import QtQuick.Window 2.2
-import QtQuick.VirtualKeyboard 2.1
-import QtDeviceUtilities.SettingsUI 1.0
-import com.qtcompany.B2QtLauncher 1.0
Window {
id: window
visible: true
- //width: qpa_platform === "wayland" ? 800 : Screen.desktopAvailableWidth
- //height: qpa_platform === "wayland" ? 600 : Screen.desktopAvailableHeight
- width: 800
- height: 600
+ width: Screen.desktopAvailableWidth
+ height: Screen.desktopAvailableHeight
color: viewSettings.backgroundColor
property alias appFont: viewSettings.appFont
@@ -48,295 +44,38 @@ Window {
id: viewSettings
}
- Component {
- id: emptyComponent
- Item {
- objectName: "empty"
+ Loader {
+ id: mainWindowLoader
+ anchors.fill: parent
+ active: false
+ source: "qrc:///qml/MainWindow.qml"
+ asynchronous: true
+ onLoaded: {
+ item.visible = true;
+ splashScreenLoader.item.visible = false;
+ splashScreenLoader.source = "";
}
}
- Component {
- id: gridComponent
- LaunchScreen {
- id: launchScreen
- }
- }
-
- Component {
- id: detailComponent
- DetailView {
- id: detailView
- }
- }
-
- Component {
- id: settingsUIComponent
- SettingsUI {
- id: settingsUI
- objectName: "settingsView"
- anchors.fill: parent
- model: "settings.xml"
- margin: viewSettings.pageMargin
- onClosed: root.closeApplication()
- }
- }
-
- LauncherApplicationsModel {
- id: applicationsModel
- onReady: engine.markApplicationsModelReady();
- Component.onCompleted: {
- //Set the directory to parse for apps
- initialize(applicationSettings.appsRoot);
- }
- }
-
- LauncherEngine {
- id: engine
- fpsEnabled: applicationSettings.isShowFPSEnabled
- }
-
- Item {
- id: root
- anchors.centerIn: window.contentItem
- property bool portraitMode: Screen.desktopAvailableHeight > Screen.desktopAvailableWidth ? true : false
- rotation: portraitMode ? 90 : 0
- width: portraitMode ? window.height : window.width
- height: portraitMode ? window.width : window.height
-
- function closeApplication()
- {
- engine.closeApplication()
- applicationLoader.setSource("")
- applicationLoader.sourceComponent = emptyComponent
- }
-
- function launchApplication(loc, mainFile, name, desc)
- {
- engine.launchApplication(loc, mainFile, name, desc)
- applicationLoader.source = engine.applicationMain
- }
-
- function launchSettings()
- {
- engine.state = "app-launching"
- applicationLoader.sourceComponent = settingsUIComponent
- }
-
- Background {}
-
- Header {
- id: header
- enabled: engine.state == "running"
- onMenuClicked: root.launchSettings()
- }
-
- Loader {
- id: contentLoader
+ Loader {
+ id: splashScreenLoader
+ anchors.fill: parent
+ sourceComponent: Item {
anchors.fill: parent
- anchors.topMargin: header.height + viewSettings.pageMargin
- sourceComponent: globalSettings.gridSelected ? gridComponent : detailComponent
- enabled: engine.state != "settings"
- }
-
- states: [
- State {
- name: "running"
- PropertyChanges { target: applicationLoader; opacity: 0; }
- PropertyChanges { target: contentLoader; opacity: 1 }
- PropertyChanges { target: header; opacity: 1 }
- PropertyChanges { target: bootScreenLoader; opacity: 0 }
- },
- State {
- name: "app-launching"
- PropertyChanges { target: header; opacity: 0 }
- PropertyChanges { target: bootScreenLoader; opacity: 1 }
- },
- State {
- name: "app-running"
- PropertyChanges { target: applicationLoader; opacity: 1 }
- PropertyChanges { target: contentLoader; opacity: 0 }
- PropertyChanges { target: header; opacity: 0 }
- PropertyChanges { target: bootScreenLoader; opacity: 0 }
- },
- State {
- name: "settings"
- PropertyChanges { target: applicationLoader; opacity: 1 }
- PropertyChanges { target: contentLoader; opacity: 1 }
- PropertyChanges { target: header; opacity: 0 }
- PropertyChanges { target: bootScreenLoader; opacity: 0 }
- },
- State {
- name: "app-closing"
- PropertyChanges { target: applicationLoader; opacity: 0; source: "" }
- PropertyChanges { target: contentLoader; opacity: 0 }
- PropertyChanges { target: header; opacity: 0 }
- PropertyChanges { target: bootScreenLoader; opacity: 0 }
- }
- ]
-
- state: engine.state
-
- Timer {
- id: failedAppLaunchTrigger;
- interval: viewSettings.stateDelay;
- running: false
- repeat: false
- onTriggered: root.closeApplication()
- }
-
- Loader {
- id: applicationLoader
- opacity: 0;
- visible: opacity > 0.1
- anchors.fill: parent
- asynchronous: true;
- onStatusChanged: {
- if (status == Loader.Error)
- failedAppLaunchTrigger.start();
- }
- onLoaded: {
- if (applicationLoader.item.objectName == "settingsView")
- engine.state = "settings"
- else if (applicationLoader.item.objectName !== "empty")
- engine.state = "app-running";
- }
-
- DemoHeader {
- id: demoHeader
- onInfoClicked: demoInfoPopup.open()
- onCloseClicked: demoClosePopup.open()
- }
- }
-
- Loader {
- id: bootScreenLoader
- visible: opacity > 0
- anchors.fill: parent
- sourceComponent: BootScreen {}
- }
-
- DemoClosePopup {
- id: demoClosePopup
- visible: false
- }
-
- DemoInfoPopup {
- id: demoInfoPopup
- visible: false
- }
-
- /* Handwriting input panel for full screen handwriting input.
-
- This component is an optional add-on for the InputPanel component, that
- is, its use does not affect the operation of the InputPanel component,
- but it also can not be used as a standalone component.
-
- The handwriting input panel is positioned to cover the entire area of
- application. The panel itself is transparent, but once it is active the
- user can draw handwriting on it.
- */
- HandwritingInputPanel {
- z: 79
- id: handwritingInputPanel
- anchors.fill: parent
- inputPanel: inputPanel
- Rectangle {
- z: -1
+ Image {
anchors.fill: parent
- color: "black"
- opacity: 0.10
- }
- }
-
- /* Container area for the handwriting mode button.
-
- Handwriting mode button can be moved freely within the container area.
- In this example, a single click changes the handwriting mode and a
- double-click changes the availability of the full screen handwriting input.
- */
- Item {
- z: 89
- visible: handwritingInputPanel.enabled && Qt.inputMethod.visible
- anchors { left: parent.left; top: parent.top; right: parent.right; bottom: inputPanel.top; }
- HandwritingModeButton {
- id: handwritingModeButton
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.margins: 10
- floating: true
- flipable: true
- width: 76
- height: width
- state: handwritingInputPanel.state
- onClicked: handwritingInputPanel.active = !handwritingInputPanel.active
- onDoubleClicked: handwritingInputPanel.available = !handwritingInputPanel.available
+ source: "images/backImg.jpg"
+ fillMode: Image.PreserveAspectCrop
}
- onVisibleChanged: console.log("hw visible: "+visible)
- Component.onCompleted: console.log("input visible " +visible)
- }
- /* Keyboard input panel.
- The keyboard is anchored to the bottom of the application.
- */
- InputPanel {
- id: inputPanel
- z: 99
- y: root.height
- anchors.left: root.left
- anchors.right: root.right
- visible: y < root.height
-
- states: State {
- name: "visible"
- /* The visibility of the InputPanel can be bound to the Qt.inputMethod.visible property,
- but then the handwriting input panel and the keyboard input panel can be visible
- at the same time. Here the visibility is bound to InputPanel.active property instead,
- which allows the handwriting panel to control the visibility when necessary.
- */
- when: inputPanel.active
- PropertyChanges {
- target: inputPanel
- y: root.height - inputPanel.height
- }
- }
- transitions: Transition {
- from: ""
- to: "visible"
- reversible: true
- ParallelAnimation {
- NumberAnimation {
- properties: "y"
- duration: 250
- easing.type: Easing.InOutQuad
- }
- }
+ BootScreen {
+ anchors.fill: parent
+ applicationName: qsTr("Qt Launcher")
}
- AutoScroller {}
}
-
- Item {
- id: fps
- opacity: engine.fpsEnabled ? 1 : 0
- Behavior on opacity { NumberAnimation { duration: 500 } }
-
- anchors.bottom: parent.bottom;
- anchors.left: parent.left;
- width: fpsLabel.width
- height: fpsLabel.height
-
- Rectangle {
- color: "black"
- opacity: 0.5
- anchors.fill: fpsLabel
- }
-
- Text {
- id: fpsLabel;
- color: "white"
- text: "FPS: " + engine.fps
- font.pixelSize: engine.sensibleButtonSize() * 0.2
- }
+ onLoaded: {
+ mainWindowLoader.active = true;
}
}
}
diff --git a/qml/MainWindow.qml b/qml/MainWindow.qml
new file mode 100644
index 0000000..aa1e19c
--- /dev/null
+++ b/qml/MainWindow.qml
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Device Creation.
+**
+** $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.4
+import QtQuick.Window 2.2
+import QtQuick.VirtualKeyboard 2.1
+import QtDeviceUtilities.SettingsUI 1.0
+import com.qtcompany.B2QtLauncher 1.0
+
+Item {
+ anchors.fill: parent
+ Component {
+ id: emptyComponent
+ Item {
+ objectName: "empty"
+ }
+ }
+
+ Component {
+ id: gridComponent
+ LaunchScreen {
+ id: launchScreen
+ }
+ }
+
+ Component {
+ id: detailComponent
+ DetailView {
+ id: detailView
+ }
+ }
+
+ Component {
+ id: settingsUIComponent
+ SettingsUI {
+ id: settingsUI
+ objectName: "settingsView"
+ anchors.fill: parent
+ model: "settings.xml"
+ margin: viewSettings.pageMargin
+ onClosed: root.closeApplication()
+ }
+ }
+
+ LauncherApplicationsModel {
+ id: applicationsModel
+ onReady: engine.markApplicationsModelReady();
+ Component.onCompleted: {
+ //Set the directory to parse for apps
+ initialize(applicationSettings.appsRoot);
+ }
+ }
+
+ LauncherEngine {
+ id: engine
+ fpsEnabled: applicationSettings.isShowFPSEnabled
+ }
+
+ Item {
+ id: root
+ anchors.centerIn: parent
+ property bool portraitMode: Screen.desktopAvailableHeight > Screen.desktopAvailableWidth ? true : false
+ rotation: portraitMode ? 90 : 0
+ width: portraitMode ? window.height : window.width
+ height: portraitMode ? window.width : window.height
+
+ function closeApplication()
+ {
+ engine.closeApplication()
+ applicationLoader.setSource("")
+ applicationLoader.sourceComponent = emptyComponent
+ }
+
+ function launchApplication(loc, mainFile, name, desc)
+ {
+ engine.launchApplication(loc, mainFile, name, desc)
+ applicationLoader.source = engine.applicationMain
+ }
+
+ function launchSettings()
+ {
+ engine.state = "app-launching"
+ applicationLoader.sourceComponent = settingsUIComponent
+ }
+
+ Background {}
+
+ Header {
+ id: header
+ enabled: engine.state == "running"
+ onMenuClicked: root.launchSettings()
+ }
+
+ Loader {
+ id: contentLoader
+ anchors.fill: parent
+ anchors.topMargin: header.height + viewSettings.pageMargin
+ sourceComponent: globalSettings.gridSelected ? gridComponent : detailComponent
+ enabled: engine.state != "settings"
+ }
+
+ states: [
+ State {
+ name: "running"
+ PropertyChanges { target: applicationLoader; opacity: 0; }
+ PropertyChanges { target: contentLoader; opacity: 1 }
+ PropertyChanges { target: header; opacity: 1 }
+ PropertyChanges { target: bootScreenLoader; opacity: 0 }
+ },
+ State {
+ name: "app-launching"
+ PropertyChanges { target: header; opacity: 0 }
+ PropertyChanges { target: bootScreenLoader; opacity: 1 }
+ },
+ State {
+ name: "app-running"
+ PropertyChanges { target: applicationLoader; opacity: 1 }
+ PropertyChanges { target: contentLoader; opacity: 0 }
+ PropertyChanges { target: header; opacity: 0 }
+ PropertyChanges { target: bootScreenLoader; opacity: 0 }
+ },
+ State {
+ name: "settings"
+ PropertyChanges { target: applicationLoader; opacity: 1 }
+ PropertyChanges { target: contentLoader; opacity: 1 }
+ PropertyChanges { target: header; opacity: 0 }
+ PropertyChanges { target: bootScreenLoader; opacity: 0 }
+ },
+ State {
+ name: "app-closing"
+ PropertyChanges { target: applicationLoader; opacity: 0; source: "" }
+ PropertyChanges { target: contentLoader; opacity: 0 }
+ PropertyChanges { target: header; opacity: 0 }
+ PropertyChanges { target: bootScreenLoader; opacity: 0 }
+ }
+ ]
+
+ state: engine.state
+
+ Timer {
+ id: failedAppLaunchTrigger;
+ interval: viewSettings.stateDelay;
+ running: false
+ repeat: false
+ onTriggered: root.closeApplication()
+ }
+
+ Loader {
+ id: applicationLoader
+ opacity: 0;
+ visible: opacity > 0.1
+
+ anchors.fill: parent
+ asynchronous: true;
+ onStatusChanged: {
+ if (status == Loader.Error)
+ failedAppLaunchTrigger.start();
+ }
+ onLoaded: {
+ if (applicationLoader.item.objectName == "settingsView")
+ engine.state = "settings"
+ else if (applicationLoader.item.objectName !== "empty")
+ engine.state = "app-running";
+ }
+
+ DemoHeader {
+ id: demoHeader
+ onInfoClicked: demoInfoPopup.open()
+ onCloseClicked: demoClosePopup.open()
+ }
+ }
+
+ Loader {
+ id: bootScreenLoader
+ visible: opacity > 0
+ anchors.fill: parent
+ sourceComponent: BootScreen {
+ applicationName: engine.applicationName
+ }
+ }
+
+ DemoClosePopup {
+ id: demoClosePopup
+ visible: false
+ }
+
+ DemoInfoPopup {
+ id: demoInfoPopup
+ visible: false
+ }
+
+ /* Handwriting input panel for full screen handwriting input.
+
+ This component is an optional add-on for the InputPanel component, that
+ is, its use does not affect the operation of the InputPanel component,
+ but it also can not be used as a standalone component.
+
+ The handwriting input panel is positioned to cover the entire area of
+ application. The panel itself is transparent, but once it is active the
+ user can draw handwriting on it.
+ */
+ HandwritingInputPanel {
+ z: 79
+ id: handwritingInputPanel
+ anchors.fill: parent
+ inputPanel: inputPanel
+ Rectangle {
+ z: -1
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.10
+ }
+ }
+
+ /* Container area for the handwriting mode button.
+
+ Handwriting mode button can be moved freely within the container area.
+ In this example, a single click changes the handwriting mode and a
+ double-click changes the availability of the full screen handwriting input.
+ */
+ Item {
+ z: 89
+ visible: handwritingInputPanel.enabled && Qt.inputMethod.visible
+ anchors { left: parent.left; top: parent.top; right: parent.right; bottom: inputPanel.top; }
+ HandwritingModeButton {
+ id: handwritingModeButton
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.margins: 10
+ floating: true
+ flipable: true
+ width: 76
+ height: width
+ state: handwritingInputPanel.state
+ onClicked: handwritingInputPanel.active = !handwritingInputPanel.active
+ onDoubleClicked: handwritingInputPanel.available = !handwritingInputPanel.available
+ }
+ onVisibleChanged: console.log("hw visible: "+visible)
+ Component.onCompleted: console.log("input visible " +visible)
+ }
+
+ /* Keyboard input panel.
+ The keyboard is anchored to the bottom of the application.
+ */
+ InputPanel {
+ id: inputPanel
+ z: 99
+ y: root.height
+ anchors.left: root.left
+ anchors.right: root.right
+ visible: y < root.height
+
+ states: State {
+ name: "visible"
+ /* The visibility of the InputPanel can be bound to the Qt.inputMethod.visible property,
+ but then the handwriting input panel and the keyboard input panel can be visible
+ at the same time. Here the visibility is bound to InputPanel.active property instead,
+ which allows the handwriting panel to control the visibility when necessary.
+ */
+ when: inputPanel.active
+ PropertyChanges {
+ target: inputPanel
+ y: root.height - inputPanel.height
+ }
+ }
+ transitions: Transition {
+ from: ""
+ to: "visible"
+ reversible: true
+ ParallelAnimation {
+ NumberAnimation {
+ properties: "y"
+ duration: 250
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ AutoScroller {}
+ }
+
+ Item {
+ id: fps
+ opacity: engine.fpsEnabled ? 1 : 0
+ Behavior on opacity { NumberAnimation { duration: 500 } }
+
+ anchors.bottom: parent.bottom;
+ anchors.left: parent.left;
+ width: fpsLabel.width
+ height: fpsLabel.height
+
+ Rectangle {
+ color: "black"
+ opacity: 0.5
+ anchors.fill: fpsLabel
+ }
+
+ Text {
+ id: fpsLabel;
+ color: "white"
+ text: "FPS: " + engine.fps
+ font.pixelSize: engine.sensibleButtonSize() * 0.2
+ }
+ }
+ }
+}