├── examples
└── qmlapp
│ ├── qmldir
│ ├── DejaVuSans.ttf
│ ├── syringe1.png
│ ├── FontAwesome.otf
│ ├── MainDesigner.qml
│ ├── Style.qml
│ ├── ProgressBarFlatStyle.qml
│ ├── TextFieldFlatStyle.qml
│ ├── qmlappdemo.qrc
│ ├── qmlappdemo.pro
│ ├── ButtonFlatStyle.qml
│ ├── Syringe.qml
│ ├── content
│ ├── ScrollBar.qml
│ ├── TextArea.qml
│ ├── TextField.qml
│ └── TextBase.qml
│ ├── main.cpp
│ ├── SliderFlatStyle.qml
│ ├── MainContainer.qml
│ ├── Main.qml
│ ├── MainQuickControls.qml
│ └── syringe2.svg
├── src
├── freevirtualkeyboard.json
├── virtualkeyboard.qrc
├── qmldir
├── FontAwesome.otf
├── libFreeVirtualKeyboard.so
├── virtualkeyboard_global.h
├── virtualkeyboard.pro
├── VirtualKeyboardInputContextPlugin.h
├── VirtualKeyboardInputContextPlugin.cpp
├── KeyModel.qml
├── VirtualKeyboardInputContext.h
├── KeyButton.qml
├── DeclarativeInputEngine.h
├── KeyPopup.qml
├── DeclarativeInputEngine.cpp
├── InputPanel.qml
└── VirtualKeyboardInputContext.cpp
├── doc
└── VirtualKeyboardScreenshot.png
├── .gitignore
├── S95application
├── LICENSE
├── uEnv.txt
├── LICENSE.MIT
├── README.md
└── install.sh
/examples/qmlapp/qmldir:
--------------------------------------------------------------------------------
1 | singleton Style Style.qml
--------------------------------------------------------------------------------
/src/freevirtualkeyboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "Keys": ["freevirtualkeyboard"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/virtualkeyboard.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/qmldir:
--------------------------------------------------------------------------------
1 | module QtQuick.FreeVirtualKeyboard
2 | InputPanel 1.0 InputPanel.qml
3 |
--------------------------------------------------------------------------------
/src/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/src/FontAwesome.otf
--------------------------------------------------------------------------------
/examples/qmlapp/DejaVuSans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/examples/qmlapp/DejaVuSans.ttf
--------------------------------------------------------------------------------
/examples/qmlapp/syringe1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/examples/qmlapp/syringe1.png
--------------------------------------------------------------------------------
/src/libFreeVirtualKeyboard.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/src/libFreeVirtualKeyboard.so
--------------------------------------------------------------------------------
/examples/qmlapp/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/examples/qmlapp/FontAwesome.otf
--------------------------------------------------------------------------------
/doc/VirtualKeyboardScreenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reHackable/QtFreeVirtualKeyboard/HEAD/doc/VirtualKeyboardScreenshot.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | /src/virtualkeyboard.pro.user
3 | /examples/qmlapp/qmlappdemo.pro.user.3.3-pre1
4 | /examples/qmlapp/*.exe
5 | /examples/qmlapp/qmlappdemo.pro.user
6 |
--------------------------------------------------------------------------------
/S95application:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # mount 3rd partition of SD card into userdata directory and start application
4 | # mount with sync option to disable write cache because user may simply switch
5 | # off the device
6 | #mount -o sync,noatime /dev/mmcblk0p3 /ledarray/userdata
7 | cd /vktest
8 | ./virtualkeyboardqmldemo &
9 |
--------------------------------------------------------------------------------
/examples/qmlapp/MainDesigner.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Layouts 1.0
4 |
5 | Rectangle {
6 | width: 800
7 | height: 480
8 |
9 | Flickable {
10 | id: flickable1
11 | anchors.fill: parent
12 | flickableDirection: Flickable.VerticalFlick
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/virtualkeyboard_global.h:
--------------------------------------------------------------------------------
1 | #ifndef MOCKUPVIRTUALKEYBOARD_GLOBAL_H
2 | #define MOCKUPVIRTUALKEYBOARD_GLOBAL_H
3 |
4 | #include
5 |
6 | #if defined(MOCKUPVIRTUALKEYBOARD_LIBRARY)
7 | # define MOCKUPVIRTUALKEYBOARDSHARED_EXPORT Q_DECL_EXPORT
8 | #else
9 | # define MOCKUPVIRTUALKEYBOARDSHARED_EXPORT Q_DECL_IMPORT
10 | #endif
11 |
12 | #endif // MOCKUPVIRTUALKEYBOARD_GLOBAL_H
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * ----------------------------------------------------------------------------
3 | * "THE BEER-WARE LICENSE" (Revision 42):
4 | * wrote this file. As long as you retain this notice you
5 | * can do whatever you want with this stuff. If we meet some day, and you think
6 | * this stuff is worth it, you can buy me a beer in return Tomasz Olszak
7 | * ----------------------------------------------------------------------------
8 | */
--------------------------------------------------------------------------------
/examples/qmlapp/Style.qml:
--------------------------------------------------------------------------------
1 | pragma Singleton
2 | import QtQuick 2.3
3 | import QtQuick.Window 2.0
4 |
5 | QtObject {
6 | function dp(value) {
7 | var px = Math.round(value * (screenPixelDensity / 160.0));
8 | if(Qt.platform.os == "windows" || Qt.platform.os == "mac") {
9 | console.log("dp = " + px + " Screen.pixelDensity " + screenPixelDensity);
10 | return px * 2;
11 | }
12 | else {
13 | return px;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/qmlapp/ProgressBarFlatStyle.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 |
7 |
8 | Component {
9 | id: progressBarFlatStyle
10 | ProgressBarStyle {
11 | background: Rectangle {
12 | radius: Style.dp(8)
13 | color: "#00FFFFFF"
14 | border.color: "#c9c9c9"
15 | border.width: Style.dp(w)
16 | implicitWidth: Style.dp(200)
17 | implicitHeight: Style.dp(24)
18 | }
19 | progress: Rectangle {
20 | color: "#5caa15"
21 | radius: Style.dp(8)
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/examples/qmlapp/TextFieldFlatStyle.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 | Component {
7 | id: textfieldFlatStyle
8 |
9 | TextFieldStyle {
10 | id: textfieldstyle
11 | textColor: "#333333"
12 | placeholderTextColor: "#c9c9c9"
13 | font.pixelSize: Style.dp(30)
14 | background: Rectangle {
15 | color: "#00FFFFFF"
16 | radius: Style.dp(8)
17 | border.color: "#c9c9c9"
18 | border.width: Style.dp(2)
19 | implicitHeight: textfieldstyle.font.pixelSize * 2.6
20 | }
21 | padding.left: Style.dp(30)
22 | padding.right: Style.dp(30)
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/examples/qmlapp/qmlappdemo.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | content/ScrollBar.qml
4 | content/TextArea.qml
5 | content/TextBase.qml
6 | content/TextField.qml
7 | DejaVuSans.ttf
8 | Main.qml
9 | MainContainer.qml
10 | MainQuickControls.qml
11 | MainDesigner.qml
12 | TextFieldFlatStyle.qml
13 | SliderFlatStyle.qml
14 | ProgressBarFlatStyle.qml
15 | Syringe.qml
16 | ButtonFlatStyle.qml
17 | FontAwesome.otf
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/qmlapp/qmlappdemo.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 | TARGET = virtualkeyboardqmldemo
3 | QT += qml quick
4 | SOURCES += main.cpp
5 | CONFIG += link_pkgconfig
6 |
7 |
8 | linux-buildroot-g++ {
9 | deployment.files = *.qml *.otf *.ttf *.svg
10 | target.path = /vktest
11 | deployment.path = /vktest
12 | INSTALLS += target deployment
13 | } else {
14 | target.path = $$[QT_INSTALL_EXAMPLES]/freevirtualkeyboard
15 | INSTALLS += target
16 | }
17 |
18 |
19 | RESOURCES += \
20 | qmlappdemo.qrc
21 |
22 | OTHER_FILES += \
23 | content/ScrollBar.qml \
24 | content/TextArea.qml \
25 | content/TextBase.qml \
26 | content/TextField.qml \
27 | Main.qml \
28 | MainContainer.qml
29 |
30 | DESTDIR = $$PWD
31 |
32 | DISTFILES += \
33 | StyleHelper.aml \
34 | Style.qml
35 |
--------------------------------------------------------------------------------
/examples/qmlapp/ButtonFlatStyle.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 | ButtonStyle {
7 | id: textfieldstyle
8 | property font font
9 |
10 | background: Rectangle {
11 | id: bg
12 | color: !control.pressed ? "#00FFFFFF" : "#5caa15"
13 | radius: Style.dp(8)
14 | border.color: "#5caa15"
15 | border.width: Style.dp(2)
16 | }
17 |
18 | label: Text {
19 | id: textLabel
20 | renderType: Text.NativeRendering
21 | verticalAlignment: Text.AlignVCenter
22 | horizontalAlignment: Text.AlignHCenter
23 | color: control.pressed ? "white" : "#5caa15"
24 | text: control.text
25 | font: textfieldstyle.font
26 | }
27 |
28 | padding.left: Style.dp(20)
29 | padding.right: Style.dp(20)
30 | padding.top: Style.dp(10)
31 | padding.bottom: Style.dp(10)
32 | }
33 |
--------------------------------------------------------------------------------
/uEnv.txt:
--------------------------------------------------------------------------------
1 | ##Use this file if you want to boot from SD card on a Debian system
2 | # uncomment the following lines if you need static ip
3 | ethaddr=90:59:AF:82:3A:D1
4 | ipaddr=192.168.81.10
5 | serverip=192.168.81.1
6 | gatewayip=192.168.81.1
7 | netmask=255.255.255.0
8 | hostname=bbb
9 |
10 | optargs=quiet lpj=1818624 drm.debug=7
11 | mmcboot=echo Booting from mmc ... (uk); run mmcargs; bootz ${loadaddr} - ${fdtaddr}
12 | loadzimage=echo Loading zImage ... (uk); load mmc 0:2 ${loadaddr} /boot/zImage
13 | loadfdt=load mmc 0:2 ${fdtaddr} /boot/${fdtfile}
14 | #setbootargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0
15 | mmcargs=setenv bootargs console=${console} ${optargs} ${cape_disable} ${cape_enable} root=${mmcroot} rootfstype=${mmcrootfstype} ${cmdline} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0
16 | uenvcmd=if run loadzimage; then run loadfdt;run mmcboot;fi;
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE.MIT:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Uwe Kindler
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/virtualkeyboard.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2013-04-04T23:11:38
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += qml quick quick-private gui-private
8 |
9 | CONFIG += plugin
10 |
11 | TARGET = freevirtualkeyboardplugin
12 | TEMPLATE = lib
13 |
14 |
15 | SOURCES += VirtualKeyboardInputContextPlugin.cpp \
16 | VirtualKeyboardInputContext.cpp \
17 | DeclarativeInputEngine.cpp
18 |
19 | HEADERS += VirtualKeyboardInputContextPlugin.h\
20 | VirtualKeyboardInputContext.h \
21 | DeclarativeInputEngine.h
22 |
23 |
24 | deployment.files = *.qml FontAwesome.otf qmldir
25 |
26 | linux-buildroot-g++ {
27 | deployment.path = /usr/qml/QtQuick/FreeVirtualKeyboard
28 | target.path = /usr/lib/qt/plugins/platforminputcontexts
29 | } else {
30 | deployment.path = $$[QT_INSTALL_QML]/QtQuick/FreeVirtualKeyboard
31 | target.path = $$[QT_INSTALL_PLUGINS]/platforminputcontexts
32 | }
33 |
34 |
35 | INSTALLS += target \
36 | deployment
37 |
38 | OTHER_FILES += \
39 | InputPanel.qml \
40 | KeyModel.qml \
41 | KeyButton.qml \
42 | KeyPopup.qml
43 |
44 | RESOURCES += \
45 | virtualkeyboard.qrc
46 |
--------------------------------------------------------------------------------
/src/VirtualKeyboardInputContextPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef VIRTUALKEYBOARDINPUTCONTEXTPLUGIN_H
2 | #define VIRTUALKEYBOARDINPUTCONTEXTPLUGIN_H
3 | //============================================================================
4 | /// \file VirtualKeyboardInputContextPlugin.h
5 | /// \author Uwe Kindler
6 | /// \date 08.01.2015
7 | /// \brief Declaration of VirtualKeyboardInputContextPlugin
8 | ///
9 | /// Copyright 2015 Uwe Kindler
10 | /// Licensed under MIT see LICENSE.MIT in project root
11 | //============================================================================
12 |
13 | //============================================================================
14 | // INCLUDES
15 | //============================================================================
16 | #include "virtualkeyboard_global.h"
17 | #include
18 |
19 | /**
20 | * Implementation of QPlatformInputContextPlugin
21 | */
22 | class VirtualKeyboardInputContextPlugin : public QPlatformInputContextPlugin
23 | {
24 | Q_OBJECT
25 | Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "freevirtualkeyboard.json")
26 |
27 | public:
28 | QPlatformInputContext *create(const QString&, const QStringList&);
29 | }; // class VirtualKeyboardInputContextPlugin
30 |
31 | //------------------------------------------------------------------------------
32 | #endif // VIRTUALKEYBOARDINPUTCONTEXTPLUGIN_H
33 |
--------------------------------------------------------------------------------
/src/VirtualKeyboardInputContextPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include "VirtualKeyboardInputContextPlugin.h"
2 | #include "VirtualKeyboardInputContext.h"
3 | //============================================================================
4 | /// \file VirtualKeyboardInputContextPlugin.cpp
5 | /// \author Uwe Kindler
6 | /// \date 08.01.2015
7 | /// \brief Implementation of VirtualKeyboardInputContextPlugin
8 | ///
9 | /// Copyright 2015 Uwe Kindler
10 | /// Licensed under MIT see LICENSE.MIT in project root
11 | //============================================================================
12 |
13 | //============================================================================
14 | // INCLUDES
15 | //============================================================================
16 | #include
17 |
18 |
19 | //============================================================================
20 | QPlatformInputContext* VirtualKeyboardInputContextPlugin::create(const QString& system, const QStringList& paramList)
21 | {
22 | Q_UNUSED(paramList);
23 |
24 | qDebug() << "VirtualKeyboardInputContextPlugin::create: " << system;
25 | if (system.compare(system, QStringLiteral("freevirtualkeyboard"), Qt::CaseInsensitive) == 0)
26 | {
27 | return VirtualKeyboardInputContext::instance();
28 | }
29 | return 0;
30 | }
31 |
32 |
33 | //------------------------------------------------------------------------------
34 | // EOF VirtualInputContextPlugin.cpp
35 |
--------------------------------------------------------------------------------
/examples/qmlapp/Syringe.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 | Item {
7 | id: root
8 | implicitHeight: syringeImage.height
9 | property alias maximumLevel: progressBar.maximumValue
10 | property alias minimumLevel: progressBar.minimumValue
11 | property alias level: progressBar.value
12 |
13 | Image {
14 | id: syringeImage
15 | source: "syringe2.svg"
16 | fillMode: Image.PreserveAspectFit
17 | anchors.fill: parent
18 | z: 100
19 | }
20 |
21 | ProgressBar {
22 | id: progressBar
23 | anchors.left: parent.left
24 | anchors.leftMargin: Math.round(
25 | (syringeImage.width - syringeImage.paintedWidth) / 2 + syringeImage.paintedWidth * 0.125)
26 | anchors.right: parent.right
27 | anchors.rightMargin: Math.round(
28 | (syringeImage.width - syringeImage.paintedWidth) / 2 + syringeImage.paintedWidth * 0.13)
29 | anchors.verticalCenter: parent.verticalCenter
30 | height: syringeImage.height * 0.65
31 | style: syringeProgressBarStyle
32 | z: 0
33 | }
34 |
35 | Component {
36 | id: syringeProgressBarStyle
37 | ProgressBarStyle {
38 | background: Rectangle {
39 | color: "#00FFFFFF"
40 | border.color: "transparent"
41 | border.width: 0
42 | implicitWidth: 200
43 | implicitHeight: 24
44 | }
45 | progress: Rectangle {
46 | color: "#5caa15"
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/examples/qmlapp/content/ScrollBar.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 |
19 | import QtQuick 2.0
20 |
21 | Item {
22 | property var scrollArea: parent
23 |
24 | width: 6
25 | opacity: scrollArea && scrollArea.movingVertically ? 1.0 : 0.0
26 | visible: scrollArea && scrollArea.contentHeight >= scrollArea.height
27 | anchors { right: parent.right; top: parent.top; bottom: parent.bottom; margins: 2 }
28 |
29 | Behavior on opacity { NumberAnimation { properties: "opacity"; duration: 600 } }
30 |
31 | function size() {
32 | var nh = scrollArea.visibleArea.heightRatio * height
33 | var ny = scrollArea.visibleArea.yPosition * height
34 | return ny > 3 ? Math.min(nh, Math.ceil(height - 3 - ny)) : nh + ny
35 | }
36 | Rectangle {
37 | x: 1
38 | y: scrollArea ? Math.max(2, scrollArea.visibleArea.yPosition * parent.height) : 0
39 | height: scrollArea ? size() : 0
40 | width: parent.width - 2
41 | color: Qt.rgba(1.0, 1.0, 1.0, 0.5)
42 | radius: 1
43 | }
44 | }
--------------------------------------------------------------------------------
/examples/qmlapp/main.cpp:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | /// \file main.cpp
3 | /// \author Uwe Kindler
4 | /// \date 08.01.2015
5 | /// \brief main of virtual keyboard example application
6 | //============================================================================
7 |
8 | //============================================================================
9 | // INCLUDES
10 | //============================================================================
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 |
21 | /**
22 | * main entry point for application
23 | */
24 | int main(int argc, char *argv[])
25 | {
26 | // Load virtualkeyboard input context plugin
27 | qputenv("QT_IM_MODULE", QByteArray("freevirtualkeyboard"));
28 |
29 | QGuiApplication app(argc, argv);
30 |
31 | // Set standard font so that application looks equal on all platforms
32 | QFontDatabase FontDatabase;
33 | FontDatabase.addApplicationFont(":/DejaVuSans.ttf");
34 | app.setFont(QFont("DejaVu Sans"));
35 | app.setObjectName("QGuiApplication");
36 |
37 | QQuickView view;
38 | //view.setSource(QString("qrc:/MainContainer.qml"));
39 | view.engine()->rootContext()->setContextProperty("screenPixelDensity",
40 | QGuiApplication::primaryScreen()->physicalDotsPerInch());
41 | view.setSource(QString("MainContainer.qml"));
42 | view.setObjectName("QQuickView");
43 | view.setResizeMode(QQuickView::SizeRootObjectToView);
44 | view.engine()->setObjectName("QQuickEngine");
45 | view.engine()->addImportPath(qApp->applicationDirPath());
46 |
47 | // Set size to 800 x 480 WXGA - this is the size of the upcoming Manga
48 | // screen.
49 | view.setWidth(1280);
50 | view.setHeight(800);
51 |
52 | view.show();
53 |
54 | return app.exec();
55 | }
56 |
--------------------------------------------------------------------------------
/examples/qmlapp/SliderFlatStyle.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 |
7 | Component {
8 | id: sliderFlatStyle
9 | SliderStyle {
10 | groove: Rectangle {
11 | color: "#c9c9c9"
12 | radius: Math.round(height / 2)
13 | border.color: "#c9c9c9"
14 | border.width: Style.dp(2)
15 | height: Style.dp(8)
16 |
17 | Rectangle {
18 | color: "#5caa15"
19 | radius: Math.round(height / 2)
20 | anchors.left: parent.left
21 | anchors.top: parent.top
22 | anchors.bottom: parent.bottom
23 | width: parent.width * control.value / (control.maximumValue - control.minimumValue)
24 | }
25 | }
26 |
27 | handle: Item {
28 | implicitWidth: Style.dp(45)
29 | implicitHeight: Style.dp(45)
30 | Rectangle {
31 | id: foreground
32 | color: "white"
33 | radius: Math.round(height / 2)
34 | border.color: !control.pressed ? "#999999" : "#328930"
35 | border.width: Style.dp(2)
36 | anchors.fill: parent
37 | z: 10
38 | }
39 |
40 | Rectangle {
41 | id: shadow
42 | color: "#1F000000"
43 | radius: foreground.radius
44 | border.color: "transparent"
45 | border.width: 0
46 | width: foreground.width
47 | height: foreground.height
48 | x: foreground.x + 2
49 | y: foreground.y + 2
50 | z: 9
51 | }
52 |
53 | Rectangle {
54 | id: glow
55 | width: foreground.width * 1.7
56 | height: foreground.height * 1.7
57 | border.color: "#328930"
58 | border.width: Style.dp(2)
59 | anchors.centerIn: foreground
60 | radius: Math.round(height / 2)
61 | color: "#2F5caa15"
62 | visible: control.pressed
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/examples/qmlapp/content/TextArea.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 |
19 | import QtQuick 2.0
20 |
21 | TextBase {
22 | id: textArea
23 |
24 | property alias color: textEdit.color
25 | property alias text: textEdit.text
26 | property alias textWidth: textEdit.width
27 | property alias readOnly: textEdit.readOnly
28 | property alias inputMethodHints: textEdit.inputMethodHints
29 |
30 | editor: textEdit
31 |
32 | Repeater {
33 | model: Math.floor((parent.height - 30) / editor.cursorRectangle.height)
34 | Rectangle {
35 | x: 8
36 | y: (index+1)*editor.cursorRectangle.height+6
37 | height: 1; width: textArea.width-24
38 | color: Qt.rgba(1.0, 1.0, 1.0, 0.5)
39 | }
40 | }
41 | TextEdit {
42 | id: textEdit
43 |
44 | /*EnterKeyAction.actionId: textArea.enterKeyAction
45 | EnterKeyAction.label: textArea.enterKeyText
46 | EnterKeyAction.enabled: textArea.enterKeyEnabled*/
47 |
48 | y: 6
49 | focus: true
50 | color: "#EEEEEE"
51 | wrapMode: TextEdit.Wrap
52 | cursorVisible: activeFocus
53 | height: Math.max(implicitHeight, 60)
54 | font.pixelSize: textArea.fontPixelSize
55 | selectionColor: Qt.rgba(1.0, 1.0, 1.0, 0.5)
56 | selectedTextColor: Qt.rgba(0.0, 0.0, 0.0, 0.8)
57 | anchors { left: parent.left; right: parent.right; margins: 12 }
58 | onActiveFocusChanged: if (!activeFocus) deselect()
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/KeyModel.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 |
3 | /**
4 | * This is quick and dirty model for the keys of the InputPanel *
5 | * The code has been derived from
6 | * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
7 | * Copyright 2015 Uwe Kindler
8 | * Licensed under MIT see LICENSE.MIT in project root
9 | */
10 | Item {
11 | property QtObject firstRowModel: first
12 | property QtObject secondRowModel: second
13 | property QtObject thirdRowModel: third
14 |
15 |
16 | ListModel {
17 | id:first
18 | ListElement { letter: "q"; firstSymbol: "1"; keycode: Qt.Key_Q}
19 | ListElement { letter: "w"; firstSymbol: "2"; keycode: Qt.Key_W}
20 | ListElement { letter: "e"; firstSymbol: "3"; keycode: Qt.Key_E}
21 | ListElement { letter: "r"; firstSymbol: "4"; keycode: Qt.Key_R}
22 | ListElement { letter: "t"; firstSymbol: "5"; keycode: Qt.Key_T}
23 | ListElement { letter: "y"; firstSymbol: "6"; keycode: Qt.Key_Y}
24 | ListElement { letter: "u"; firstSymbol: "7"; keycode: Qt.Key_U}
25 | ListElement { letter: "i"; firstSymbol: "8"; keycode: Qt.Key_I}
26 | ListElement { letter: "o"; firstSymbol: "9"; keycode: Qt.Key_O}
27 | ListElement { letter: "p"; firstSymbol: "0"; keycode: Qt.Key_E}
28 | }
29 | ListModel {
30 | id:second
31 | ListElement { letter: "a"; firstSymbol: "!"}
32 | ListElement { letter: "s"; firstSymbol: "@"}
33 | ListElement { letter: "d"; firstSymbol: "#"}
34 | ListElement { letter: "f"; firstSymbol: "$"}
35 | ListElement { letter: "g"; firstSymbol: "%"}
36 | ListElement { letter: "h"; firstSymbol: "&"}
37 | ListElement { letter: "j"; firstSymbol: "*"}
38 | ListElement { letter: "k"; firstSymbol: "?"}
39 | ListElement { letter: "l"; firstSymbol: "/"}
40 | }
41 | ListModel {
42 | id:third
43 | ListElement { letter: "z"; firstSymbol: "_"}
44 | ListElement { letter: "x"; firstSymbol: "\""}
45 | ListElement { letter: "c"; firstSymbol: "'"}
46 | ListElement { letter: "v"; firstSymbol: "("}
47 | ListElement { letter: "b"; firstSymbol: ")"}
48 | ListElement { letter: "n"; firstSymbol: "-"}
49 | ListElement { letter: "m"; firstSymbol: "+"}
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/examples/qmlapp/MainContainer.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 |
19 | import QtQuick 2.0
20 | import QtQuick.FreeVirtualKeyboard 1.0
21 | import QtQuick.Window 2.0
22 |
23 |
24 | Rectangle {
25 | id: root
26 | color: "black"
27 | implicitWidth: mainQml.implicitWidth
28 | implicitHeight: mainQml.implicitHeight
29 | //onWidthChanged: console.log("3 Root item size: " + height + " " + width)
30 | //onHeightChanged: console.log("3 Root item size: " + height + " " + width)
31 | Item {
32 | clip: true
33 | id: appContainer
34 | width: parent.width - 100
35 | height: parent.height - 100
36 | anchors.centerIn: parent
37 | anchors.horizontalCenterOffset: 5
38 | MainQuickControls {
39 | id: mainQml
40 | anchors.left: parent.left
41 | anchors.top: parent.top
42 | anchors.right: parent.right
43 | anchors.bottom: inputPanel.top
44 | }
45 | InputPanel {
46 | id: inputPanel
47 | z: 99
48 | y: appContainer.height
49 | anchors.left: parent.left
50 | anchors.right: parent.right
51 | states: State {
52 | name: "visible"
53 | when: Qt.inputMethod.visible
54 | PropertyChanges {
55 | target: inputPanel
56 | y: appContainer.height - inputPanel.height
57 | }
58 | }
59 | transitions: Transition {
60 | from: ""
61 | to: "visible"
62 | reversible: true
63 | ParallelAnimation {
64 | NumberAnimation {
65 | properties: "y"
66 | duration: 150
67 | easing.type: Easing.InOutQuad
68 | }
69 | }
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/examples/qmlapp/content/TextField.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 |
19 | import QtQuick 2.0
20 | //import "../../../src"
21 |
22 | TextBase {
23 | id: textField
24 |
25 | property alias color: textInput.color
26 | property alias text: textInput.text
27 | property alias textWidth: textInput.width
28 | property alias readOnly: textInput.readOnly
29 | property alias inputMethodHints: textInput.inputMethodHints
30 | property alias validator: textInput.validator
31 | property alias echoMode: textInput.echoMode
32 | property int passwordMaskDelay: 1000
33 |
34 | editor: textInput
35 | mouseParent: flickable
36 |
37 | Flickable {
38 | id: flickable
39 |
40 | x: 12
41 | clip: true
42 | width: parent.width-24
43 | height: parent.height
44 | flickableDirection: Flickable.HorizontalFlick
45 | interactive: contentWidth - 4 > width
46 |
47 | contentWidth: textInput.width+2
48 | contentHeight: textInput.height
49 | TextInput {
50 | id: textInput
51 |
52 | /*EnterKeyAction.actionId: textField.enterKeyAction
53 | EnterKeyAction.label: textField.enterKeyText
54 | EnterKeyAction.enabled: textField.enterKeyEnabled*/
55 |
56 | y: 6
57 | focus: true
58 | color: "#EEEEEE"
59 | cursorVisible: activeFocus
60 | passwordCharacter: "\u2022"
61 | font.pixelSize: textField.fontPixelSize
62 | selectionColor: Qt.rgba(1.0, 1.0, 1.0, 0.5)
63 | selectedTextColor: Qt.rgba(0.0, 0.0, 0.0, 0.8)
64 | width: Math.max(flickable.width, implicitWidth)-2
65 | onActiveFocusChanged: if (!activeFocus) deselect()
66 | objectName: parent.objectName
67 |
68 | Binding {
69 | target: textInput
70 | property: "passwordMaskDelay"
71 | value: textField.passwordMaskDelay
72 | when: textInput.hasOwnProperty("passwordMaskDelay")
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/examples/qmlapp/content/TextBase.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 | import QtQuick 2.0
19 |
20 | FocusScope {
21 | id: textBase
22 |
23 | property var editor
24 | property bool previewTextActive: !editor.activeFocus && text.length === 0
25 | property int fontPixelSize: 32
26 | property string previewText
27 | //property int enterKeyAction: EnterKeyAction.None
28 | property int enterKeyAction
29 | property string enterKeyText
30 | //property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || editor.text.length > 0 || editor.inputMethodComposing
31 | property bool enterKeyEnabled
32 | property alias mouseParent: mouseArea.parent
33 |
34 | implicitHeight: editor.height + 12
35 |
36 | signal enterKeyClicked
37 |
38 | Keys.onReleased: {
39 | if (event.key === Qt.Key_Return)
40 | enterKeyClicked()
41 | }
42 |
43 | Rectangle {
44 | // background
45 | radius: 5.0
46 | anchors.fill: parent
47 | color: Qt.rgba(1.0, 1.0, 1.0, 0.2)
48 | border { width: editor.activeFocus ? 2 : 0; color: "#CCCCCC" }
49 | }
50 | Text {
51 | id: previewText
52 |
53 | y: 8
54 | color: "#CCCCCC"
55 | visible: previewTextActive
56 | text: textBase.previewText
57 | font.pixelSize: 28
58 | anchors { left: parent.left; right: parent.right; margins: 12 }
59 |
60 | }
61 | MouseArea {
62 | id: mouseArea
63 |
64 | z: 1
65 | parent: textBase
66 | anchors.fill: parent
67 | onClicked: {
68 | if (editor.inputMethodComposing) {
69 | if (!Qt.inputMethod.visible) {
70 | Qt.inputMethod.show()
71 | return
72 | }
73 | Qt.inputMethod.commit()
74 | }
75 | var positionInEditor = mapToItem(editor, mouseX, mouseY)
76 | var cursorPosition = editor.positionAt(positionInEditor.x, positionInEditor.y)
77 | editor.cursorPosition = cursorPosition
78 | editor.forceActiveFocus()
79 | Qt.inputMethod.show()
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QtFreeVirtualKeyboard
2 | A QML based on screen virtual keyboard for embedded QML applications.
3 |
4 | 
5 |
6 | As soon as you implement your first QML application for an embedded touchscreen device, you will notice, that the open source version of Qt lacks a virtual on screen keyboard. I'm an experienced Qt developer, but I'm a complete newbie when it comes to QML programming. I'm a great fan of the [Beaglebone Black](http://beagleboard.org/BLACK) embedded Linux device and I just ordered a [capacitive touchscreen device](https://www.kickstarter.com/projects/1924187374/manga-screen-multi-touch-43-lcd) for my bone. I started learning QML to create an example application for my Beaglebone. I quickly realized that an important essential piece was missing for entering text and values: a virtual on screen keyboard for embedded QML applications - that means for applications without a window manager like X11 or Wayland.
7 |
8 | There is a nice solution for Qt Enterprise version: [Qt Virtual Keyboard](http://doc.qt.io/QtVirtualKeyboard/index.html). The documentation also comes with a nice [technical guide](http://doc.qt.io/QtVirtualKeyboard/technical-guide.html) that shows how they implemented the virtual keyboard. They implemented `QPlatformInputContextPlugin` and `QPlatformInputContext` interfaces. I googled a little bit to find a similar open source solution and found the fantastic blog post from [Tomasz Olszak](http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html). He did a virtual keyboard mockup for Qt applications on systems with a window manager (Windows or Linux Desktop). Interesting for me was the fact, that he also implemented `QPlatformInputContextPlugin` and `QPlatformInputContext` to provide its on screen keyboard. So it seems to be the right way for implementing a virtual keyboard. The UI of Tomasz implementation was completely QML based - so it was perfectly suited for integration into QML applications.
9 |
10 | Long story short, I simply copied his code and modified it, to enable integration into embedded QML applications without window manager. I added a little bit of functionality (i.e. character preview popup, or automatic scrolling of flickable elements if keyboard overlaps focused input element). So I have to say a big thank you to Tomasz Olszak for providing a nice virtual keyboard mockup. The example application in examples/qmlapp has been copied from the [Qt Virtual Keyboard example](http://doc.qt.io/QtVirtualKeyboard/qtvirtualkeyboard-enterprise-virtualkeyboard-virtualkeyboard-example.html). I only did some minor modifications to run the example with my Virtual Keyboard implementation instead of the Qt Enterprise Virtual Keyboard.
11 |
12 | This implementation is far from feature complete. But I think it is a starting point for people that need to implement virtual keyboard support for QML applications. Keep in mind that I'm a QML newbie and that my QML is far from beeing perfect. So if you find something in my QML code that could be done better, then please tell me or send me a pull request.
13 |
--------------------------------------------------------------------------------
/src/VirtualKeyboardInputContext.h:
--------------------------------------------------------------------------------
1 | #ifndef VIRTUALKEYBOARDINPUTCONTEXT_H
2 | #define VIRTUALKEYBOARDINPUTCONTEXT_H
3 | //============================================================================
4 | /// \file VirtualKeyboardInputContext.h
5 | /// \author Uwe Kindler
6 | /// \date 08.01.2015
7 | /// \brief Declaration of VirtualKeyboardInputContext
8 | ///
9 | /// Copyright 2015 Uwe Kindler
10 | /// Licensed under MIT see LICENSE.MIT in project root
11 | //============================================================================
12 |
13 | //============================================================================
14 | // INCLUDES
15 | //============================================================================
16 | #include
17 | #include
18 |
19 |
20 | //============================================================================
21 | // FORWARD DECLARATIONS
22 | //============================================================================
23 | class QQmlEngine;
24 | class QJSEngine;
25 | class VirtualKeyboardInputContextPrivate;
26 |
27 |
28 | /**
29 | * Implementation of QPlatformInputContext
30 | */
31 | class VirtualKeyboardInputContext : public QPlatformInputContext
32 | {
33 | Q_OBJECT
34 | private:
35 | /**
36 | * The input contet creates the InputEngine object and provides it
37 | * as a singleton to the QML context
38 | */
39 | static QObject* inputEngineProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
40 |
41 | protected:
42 | /**
43 | * Protected constructor - use instance function to get the one and only
44 | * object
45 | */
46 | VirtualKeyboardInputContext();
47 |
48 | public:
49 | /**
50 | * Virtual destructor
51 | */
52 | virtual ~VirtualKeyboardInputContext();
53 |
54 | /**
55 | * Returns input context validity. Deriving implementations should
56 | * return true - so we simply return true
57 | */
58 | virtual bool isValid() const;
59 |
60 | /**
61 | * This function can be reimplemented to return virtual keyboard rectangle
62 | * in currently active window coordinates. Default implementation returns
63 | * invalid rectangle.
64 | */
65 | virtual QRectF keyboardRect() const;
66 |
67 | /**
68 | * Simply calls the emitInputPanelVisibleChanged() function
69 | */
70 | virtual void showInputPanel();
71 |
72 | /**
73 | * Simply calls the emitInputPanelVisibleChanged() function
74 | */
75 | virtual void hideInputPanel();
76 |
77 | /**
78 | * Returns input panel visibility status.
79 | * This value will be available in QGuiApplication::inputMethod()->isVisible()
80 | */
81 | virtual bool isInputPanelVisible() const;
82 |
83 | /**
84 | * This function returns true whenever input method is animating
85 | * shown or hidden.
86 | */
87 | virtual bool isAnimating() const;
88 |
89 | /**
90 | * This virtual method gets called to notify updated focus to object.
91 | * \warning Input methods must not call this function directly.
92 | * This function does the main work. It sets the input mode of the
93 | * InputEngine singleton and it ensures that the focused QML object is
94 | * visible if it is a child item of a Flickable
95 | */
96 | virtual void setFocusObject(QObject *object);
97 |
98 | /**
99 | * Use this static instance function to access the singleton input context
100 | * instance
101 | */
102 | static VirtualKeyboardInputContext* instance();
103 |
104 | private:
105 | VirtualKeyboardInputContextPrivate *d;
106 |
107 | private slots:
108 | /**
109 | * This function scrolls the QML item into visible area if the focused
110 | * QML item is child of a flickable
111 | */
112 | void ensureFocusedObjectVisible();
113 | }; // VirtualKeyboardInputContext
114 |
115 | //------------------------------------------------------------------------------
116 | #endif // VIRTUALKEYBOARDINPUTCONTEXT_H
117 |
--------------------------------------------------------------------------------
/src/KeyButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import FreeVirtualKeyboard 1.0
3 |
4 | /**
5 | * This is the type implements one single key button in the InputPanel
6 | * The code has been derived from
7 | * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
8 | * Copyright 2015 Uwe Kindler
9 | * Licensed under MIT see LICENSE.MIT in project root
10 | */
11 | Item {
12 | id:root
13 | /**
14 | * The background color of this button
15 | */
16 | property color color: "#35322f"
17 |
18 | /**
19 | * The key text to show in this button
20 | */
21 | property string text
22 |
23 | /**
24 | * The font for rendering of text
25 | */
26 | property alias font: txt.font
27 |
28 | /**
29 | * The color of the text in this button
30 | */
31 | property alias textColor: txt.color
32 |
33 | /**
34 | * This property holds the pressed status of the key.
35 | */
36 | property alias isPressed: buttonMouseArea.pressed
37 |
38 | /**
39 | * This property holds a reference to the input panel.
40 | * A key can only show the charcter preview popup if this property contains
41 | * a valid refernce to the input panel
42 | */
43 | property var inputPanel
44 |
45 | /**
46 | * This property holds the highlighted status of the key
47 | * The highlighted status is a little bit different from the pressed status
48 | * If the user releases the key, it is not pressed anymore, but it is still
49 | * highlighted for some milliseconds
50 | */
51 | property bool isHighlighted: false
52 |
53 | /**
54 | * Sets the show preview attribute for the character preview key popup
55 | */
56 | property bool showPreview: true
57 |
58 | /**
59 | * Sets the key repeat attribute.
60 | * If the repeat is enabled, the key will repeat the input events while held down.
61 | * The default is false.
62 | */
63 | property bool repeat: false
64 |
65 | /**
66 | * Sets the key code for input method processing.
67 | */
68 | property int key
69 |
70 | /**
71 | * Sets the display text - this string is rendered in the keyboard layout.
72 | * The default value is the key text.
73 | */
74 | property alias displayText: txt.text
75 |
76 | /**
77 | * Sets the function key attribute.
78 | */
79 | property bool functionKey: false
80 |
81 | signal clicked()
82 | signal pressed()
83 | signal released()
84 |
85 | Rectangle {
86 | anchors.fill: parent
87 | radius: height / 30
88 | color: isHighlighted ? Qt.tint(root.color, "#801e6fa7") : root.color
89 | Text {
90 | id: txt
91 | color: "white"
92 | anchors.margins: parent.height / 6
93 | anchors.fill: parent
94 | fontSizeMode: Text.Fit
95 | font.pixelSize: height
96 | horizontalAlignment: Text.AlignHCenter
97 | verticalAlignment: Text.AlignVCenter
98 | text: root.text
99 | }
100 | MouseArea {
101 | id: buttonMouseArea
102 | anchors.fill: parent
103 | onClicked: root.clicked()
104 | onPressed: root.pressed()
105 | onReleased: root.released()
106 | }
107 | }
108 |
109 | Timer {
110 | id: highlightTimer
111 | interval: 100
112 | running: !isPressed
113 | repeat: false
114 |
115 | onTriggered: {
116 | isHighlighted = false;
117 | }
118 | }
119 |
120 | Timer {
121 | id: repeatTimer
122 | interval: 500
123 | repeat: true
124 | running: root.repeat && root.isPressed
125 |
126 | onTriggered: {
127 | if (root.state == "")
128 | {
129 | root.state = "REPEATING"
130 | console.log("switching to repeating");
131 | }
132 | else if (root.state == "REPEATING")
133 | {
134 | console.log("repeating");
135 | }
136 |
137 | if (!functionKey)
138 | {
139 | InputEngine.sendKeyToFocusItem(text)
140 | }
141 | }
142 | }
143 |
144 | onInputPanelChanged: {
145 | console.log("onInputPanelChanged: " + inputPanel.objectName);
146 | }
147 |
148 | /**
149 | * If the InputPanel property has a valid InputPanel reference and if
150 | * showPreview is true, then this function calls showKeyPopup() to
151 | * show the character preview popup.
152 | */
153 | onPressed: {
154 | if (inputPanel != null && showPreview)
155 | {
156 | inputPanel.showKeyPopup(root);
157 | }
158 | isHighlighted = true;
159 | }
160 |
161 | onReleased: {
162 | state = ""
163 | console.log("onReleased - functionKey = " + functionKey)
164 | if (!functionKey)
165 | {
166 | InputEngine.sendKeyToFocusItem(text)
167 | }
168 | }
169 |
170 | states: [
171 | State {
172 | name: "REPEATING"
173 | PropertyChanges { target: repeatTimer; interval: 50}
174 | }
175 | ]
176 | }
177 |
--------------------------------------------------------------------------------
/examples/qmlapp/Main.qml:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2014 Digia Plc
4 | ** All rights reserved.
5 | ** For any questions to Digia, please use contact form at http://www.qt.io
6 | **
7 | ** This file is part of the Qt Virtual Keyboard add-on for Qt Enterprise.
8 | **
9 | ** Licensees holding valid Qt Enterprise licenses may use this file in
10 | ** accordance with the Qt Enterprise License Agreement provided with the
11 | ** Software or, alternatively, in accordance with the terms contained in
12 | ** a written agreement between you and Digia.
13 | **
14 | ** If you have questions regarding the use of this file, please use
15 | ** contact form at http://www.qt.io
16 | **
17 | ****************************************************************************/
18 |
19 | import QtQuick 2.0
20 | import "content"
21 |
22 | Rectangle {
23 | width: parent.width
24 | height: parent.height
25 | color: "#005F3F"
26 |
27 | Flickable {
28 | id: flickable
29 |
30 | property real scrollMarginVertical: 20
31 |
32 | anchors.fill: parent
33 | contentWidth: content.width
34 | contentHeight: content.height
35 | interactive: contentHeight > height
36 | flickableDirection: Flickable.VerticalFlick
37 | children: ScrollBar {}
38 |
39 | MouseArea {
40 | id: content
41 |
42 | width: flickable.width
43 | height: textEditors.height + 24
44 |
45 | onClicked: focus = true
46 |
47 | Column {
48 | id: textEditors
49 | spacing: 15
50 | x: 12; y: 12
51 | width: parent.width - 26
52 |
53 | Text {
54 | color: "#EEEEEE"
55 | text: "Tap fields to enter text"
56 | anchors.horizontalCenter: parent.horizontalCenter
57 | font.pixelSize: 22
58 | }
59 | TextField {
60 | width: parent.width
61 | previewText: "One line field"
62 | //enterKeyAction: EnterKeyAction.Next
63 | onEnterKeyClicked: passwordField.focus = true
64 | objectName: "One line field"
65 | }
66 | TextField {
67 | id: passwordField
68 |
69 | width: parent.width
70 | echoMode: TextInput.Password
71 | previewText: "Password field"
72 | inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
73 | //enterKeyAction: EnterKeyAction.Next
74 | onEnterKeyClicked: upperCaseField.focus = true
75 | }
76 | TextField {
77 | id: upperCaseField
78 |
79 | width: parent.width
80 | previewText: "Upper case field"
81 | inputMethodHints: Qt.ImhUppercaseOnly
82 | //enterKeyAction: EnterKeyAction.Next
83 | onEnterKeyClicked: lowerCaseField.focus = true
84 | }
85 | TextField {
86 | id: lowerCaseField
87 |
88 | width: parent.width
89 | previewText: "Lower case field"
90 | inputMethodHints: Qt.ImhLowercaseOnly
91 | //enterKeyAction: EnterKeyAction.Next
92 | onEnterKeyClicked: phoneNumberField.focus = true
93 | }
94 | TextField {
95 | id: phoneNumberField
96 |
97 | validator: RegExpValidator { regExp: /^[0-9\+\-\#\*\ ]{6,}$/ }
98 | width: parent.width
99 | previewText: "Phone number field"
100 | inputMethodHints: Qt.ImhDialableCharactersOnly
101 | //enterKeyAction: EnterKeyAction.Next
102 | onEnterKeyClicked: formattedNumberField.focus = true
103 | }
104 | TextField {
105 | id: formattedNumberField
106 |
107 | width: parent.width
108 | previewText: "Formatted number field"
109 | inputMethodHints: Qt.ImhFormattedNumbersOnly
110 | //enterKeyAction: EnterKeyAction.Next
111 | onEnterKeyClicked: digitsField.focus = true
112 | }
113 | TextField {
114 | id: digitsField
115 |
116 | width: parent.width
117 | previewText: "Digits only field"
118 | inputMethodHints: Qt.ImhDigitsOnly
119 | //enterKeyAction: EnterKeyAction.Next
120 | onEnterKeyClicked: textArea.focus = true
121 | }
122 | TextArea {
123 | id: textArea
124 |
125 | width: parent.width
126 | previewText: "Multiple lines field"
127 | height: Math.max(206, implicitHeight)
128 | }
129 | }
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/DeclarativeInputEngine.h:
--------------------------------------------------------------------------------
1 | #ifndef DECLARATIVEINPUTENGINE_H
2 | #define DECLARATIVEINPUTENGINE_H
3 | //============================================================================
4 | /// \file DeclarativeInputEngine.h
5 | /// \author Uwe Kindler
6 | /// \date 08.01.2015
7 | /// \brief Declaration of CDeclarativeInputEngine
8 | ///
9 | /// Copyright 2015 Uwe Kindler
10 | /// Licensed under MIT see LICENSE.MIT in project root
11 | //============================================================================
12 |
13 | //============================================================================
14 | // INCLUDES
15 | //============================================================================
16 | #include
17 | #include
18 |
19 | struct DeclarativeInputEnginePrivate;
20 |
21 | /**
22 | * The input engine provides input context information and is responsible
23 | * for routing input events to focused QML items.
24 | * The InputEngine can be accessed as singleton instance from QML
25 | */
26 | class DeclarativeInputEngine : public QObject
27 | {
28 | Q_OBJECT
29 | Q_PROPERTY(QRect keyboardRectangle READ keyboardRectangle WRITE setKeyboardRectangle NOTIFY keyboardRectangleChanged FINAL)
30 | Q_PROPERTY(bool animating READ isAnimating WRITE setAnimating NOTIFY animatingChanged FINAL)
31 | Q_PROPERTY(int inputMode READ inputMode WRITE setInputMode NOTIFY inputModeChanged FINAL)
32 | Q_ENUMS(InputMode)
33 | private:
34 | DeclarativeInputEnginePrivate* d;
35 | friend class DeclarativeInputEnginePrivate;
36 |
37 | private slots:
38 | void animatingFinished();
39 |
40 | public:
41 | /**
42 | * The InputMode enum provides a list of valid input modes
43 | */
44 | enum InputMode {Latin, Numeric, Dialable};
45 |
46 | /**
47 | * Creates a dclarative input engine with the given parent
48 | */
49 | explicit DeclarativeInputEngine(QObject *parent = 0);
50 |
51 | /**
52 | * Virtual destructor
53 | */
54 | virtual ~DeclarativeInputEngine();
55 |
56 | /**
57 | * Returns the kesyboard rectangle
58 | */
59 | QRect keyboardRectangle() const;
60 |
61 | /**
62 | * Returns the animating status
63 | */
64 | bool isAnimating() const;
65 |
66 | /**
67 | * Use this property to set the animating status, for example during UI
68 | * transitioning states.
69 | */
70 | void setAnimating(bool Animating);
71 |
72 | /**
73 | * Returns the current input mode
74 | * \see InputMode for a list of valid input modes
75 | */
76 | int inputMode() const;
77 |
78 | /**
79 | * Use this function to set the current input mode
80 | * \see InputMode for a list of valid input modes
81 | */
82 | void setInputMode(int Mode);
83 |
84 | public slots:
85 | /**
86 | * Reverts the active key state without emitting the key event.
87 | * This method is useful when the user discards the current key and the
88 | * key state needs to be restored.
89 | * \note Not implemented yet and not used yet
90 | */
91 | void virtualKeyCancel();
92 |
93 | /**
94 | * Emits a key click event for the given key, text and modifiers.
95 | * Returns true if the key event was accepted by the input engine.
96 | * \note Not implemented yet and not used yet
97 | */
98 | bool virtualKeyClick(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers);
99 |
100 | /**
101 | * Called by the keyboard layer to indicate that key was pressed, with the
102 | * given text and modifiers.
103 | * The key is set as an active key (down key). The actual key event is
104 | * triggered when the key is released by the virtualKeyRelease() method.
105 | * The key press event can be discarded by calling virtualKeyCancel().
106 | * The key press also initiates the key repeat timer if repeat is true.
107 | * Returns true if the key was accepted by this input engine.
108 | * \note Not implemented yet and not used yet
109 | */
110 | bool virtualKeyPress(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers, bool repeat);
111 |
112 | /**
113 | * Releases the key at key. The method emits a key event for the input
114 | * method if the event has not been generated by a repeating timer.
115 | * The text and modifiers are passed to the input method.
116 | * Returns true if the key was accepted by the input engine
117 | * \note Not implemented yet and not used yet
118 | */
119 | bool virtualKeyRelease(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers);
120 |
121 | /**
122 | * This function sends the given text to the focused QML item
123 | * \note This function will get replaced by virtualKeyClick function later
124 | */
125 | void sendKeyToFocusItem(const QString &keyText);
126 |
127 | /**
128 | * Reports the active keyboard rectangle to the engine
129 | */
130 | void setKeyboardRectangle(const QRect& Rect);
131 |
132 | signals:
133 | /**
134 | * Notify signal of keyboardRectangle property
135 | */
136 | void keyboardRectangleChanged();
137 |
138 | /**
139 | * Notify signal of animating property
140 | */
141 | void animatingChanged();
142 |
143 | /**
144 | * Notify signal of inputModep property
145 | */
146 | void inputModeChanged();
147 | }; // class CDeclarativeInputEngine
148 |
149 |
150 | //---------------------------------------------------------------------------
151 | #endif // DECLARATIVEINPUTENGINE_H
152 |
--------------------------------------------------------------------------------
/src/KeyPopup.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QtGraphicalEffects 1.0
3 |
4 | /**
5 | * This is the key popup that shows a character preview above the
6 | * pressed key button like it is known from keyboards on phones.
7 | * Copyright 2015 Uwe Kindler
8 | * Licensed under MIT see LICENSE.MIT in project root
9 | */
10 | /*Item {
11 | id: root
12 | property alias text: txt.text
13 | property alias font: txt.font
14 |
15 | width: 40
16 | height: 40
17 | visible: false
18 |
19 | Item {
20 | id: container
21 | anchors.centerIn: parent
22 | width: rect.width + (2 * rectShadow.radius)
23 | height: rect.height + (2 * rectShadow.radius)
24 |
25 | Rectangle {
26 | id: rect
27 | radius: root.height / 30
28 | width: root.width
29 | height: root.height
30 | antialiasing: true
31 | anchors.centerIn: parent
32 | gradient: Gradient {
33 | GradientStop { position: 0.0; color: Qt.lighter(Qt.lighter("#35322f"))}
34 | GradientStop { position: 1.0; color: Qt.lighter("#35322f")}
35 |
36 | }
37 |
38 | Text {
39 | id: txt
40 | color: "white"
41 | anchors.fill: parent
42 | fontSizeMode: Text.Fit
43 | font.pixelSize: height
44 | horizontalAlignment: Text.AlignHCenter
45 | verticalAlignment: Text.AlignVCenter
46 | }
47 | }
48 | }
49 | DropShadow {
50 | id: rectShadow
51 | anchors.fill: source
52 | cached: true
53 | horizontalOffset: 3
54 | verticalOffset: 3
55 | radius: root.height / 10
56 | samples: 16
57 | color: "#80000000"
58 | smooth: true
59 | source: container
60 | }
61 |
62 | function popup(keybutton, inputPanel) {
63 | console.log("popup: " + inputPanel.objectName);
64 | console.log("keybutton.text: " + keybutton.text);
65 | width = keybutton.width * 1.4;
66 | height = keybutton.height * 1.4;
67 | var KeyButtonGlobalLeft = keybutton.mapToItem(inputPanel, 0, 0).x;
68 | var KeyButtonGlobalTop = keybutton.mapToItem(inputPanel, 0, 0).y;
69 | var PopupGlobalLeft = KeyButtonGlobalLeft - (width - keybutton.width) / 2;
70 | var PopupGlobalTop = KeyButtonGlobalTop - height - pimpl.verticalSpacing * 1.5;
71 | console.log("Popup position left: " + KeyButtonGlobalLeft);
72 | var PopupLeft = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).x;
73 | y = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).y;
74 | if (PopupGlobalLeft < 0)
75 | {
76 | x = 0;
77 | }
78 | else if ((PopupGlobalLeft + width) > inputPanel.width)
79 | {
80 | x = PopupLeft - (PopupGlobalLeft + width - inputPanel.width);
81 | }
82 | else
83 | {
84 | x = PopupLeft;
85 | }
86 |
87 | text = keybutton.displayText;
88 | font.family = keybutton.font.family
89 | visible = Qt.binding(function() {return keybutton.isHighlighted});
90 | }
91 | }*/
92 |
93 | Item {
94 | id: root
95 | property alias text: txt.text
96 | property alias font: txt.font
97 |
98 | width: 40
99 | height: 40
100 | visible: false
101 |
102 | Rectangle {
103 | id: popup
104 | anchors.fill: parent
105 | radius: Math.round(height / 30)
106 | z: shadow.z + 1
107 |
108 | gradient: Gradient {
109 | GradientStop { position: 0.0; color: Qt.lighter(Qt.lighter("#35322f"))}
110 | GradientStop { position: 1.0; color: Qt.lighter("#35322f")}
111 |
112 | }
113 |
114 | Text {
115 | id: txt
116 | color: "white"
117 | anchors.fill: parent
118 | fontSizeMode: Text.Fit
119 | font.pixelSize: height
120 | horizontalAlignment: Text.AlignHCenter
121 | verticalAlignment: Text.AlignVCenter
122 | }
123 | }
124 |
125 | Rectangle {
126 | id: shadow
127 | width: popup.width
128 | height: popup.height
129 | radius: popup.radius
130 | color: "#3F000000"
131 | x: 4
132 | y: 4
133 | }
134 |
135 | function popup(keybutton, inputPanel) {
136 | console.log("popup: " + inputPanel.objectName);
137 | console.log("keybutton.text: " + keybutton.text);
138 | width = keybutton.width * 1.4;
139 | height = keybutton.height * 1.4;
140 | var KeyButtonGlobalLeft = keybutton.mapToItem(inputPanel, 0, 0).x;
141 | var KeyButtonGlobalTop = keybutton.mapToItem(inputPanel, 0, 0).y;
142 | var PopupGlobalLeft = KeyButtonGlobalLeft - (width - keybutton.width) / 2;
143 | var PopupGlobalTop = KeyButtonGlobalTop - height - pimpl.verticalSpacing * 1.5;
144 | console.log("Popup position left: " + KeyButtonGlobalLeft);
145 | var PopupLeft = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).x;
146 | y = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).y;
147 | if (PopupGlobalLeft < 0)
148 | {
149 | x = 0;
150 | }
151 | else if ((PopupGlobalLeft + width) > inputPanel.width)
152 | {
153 | x = PopupLeft - (PopupGlobalLeft + width - inputPanel.width);
154 | }
155 | else
156 | {
157 | x = PopupLeft;
158 | }
159 |
160 | text = keybutton.displayText;
161 | font.family = keybutton.font.family
162 | visible = Qt.binding(function() {return keybutton.isHighlighted});
163 | }
164 | }
165 |
166 |
167 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 |
4 | # some configuration variables - adjust them to your application
5 | export APP_DIR=ledarray
6 | export APP_BINARY=bbb_ledarray
7 | DTB=bbb-ledarray-linux3.12.dtb
8 |
9 | # some variables we need
10 | export PROJECT_DIR=..
11 |
12 | export BUILDROOT=/home/user/Coding/buildroot_git
13 | export BUILDROOT_STAGING=$BUILDROOT/output/staging
14 | BUILDROOT_IMAGES=$BUILDROOT/output/images
15 |
16 | BOOTDIR=/media/user/BOOT
17 | TFTP_DIR=/home/user/BBB/tftp
18 | BUILDROOT_CETONI=/home/user/Coding/buildroot-cetoni
19 | BBB_DIR=$BUILDROOT_CETONI/board/beaglebone
20 |
21 |
22 | # check if SD card is properly mounted
23 | check_sd_mount() {
24 | if [ "$target" = "n" ]
25 | then
26 | return;
27 | fi
28 |
29 | mountpoint="/media/user"
30 | volume="$mountpoint/BOOT"
31 | if ! mount|grep $volume; then
32 | echo "Volume $volume not mounted"
33 | exit;
34 | fi
35 |
36 | volume="$mountpoint/LINUX"
37 | if ! mount|grep $volume; then
38 | echo "Volume $volume not mounted"
39 | exit;
40 | fi
41 |
42 | volume="$mountpoint/DATA"
43 | if ! mount|grep $volume; then
44 | echo "Volume $volume not mounted"
45 | exit;
46 | fi
47 | }
48 |
49 |
50 | # some functions we need
51 | set_sd_target_vars() {
52 | export ROOTFS_DIR=/media/user/LINUX
53 | export APP_PATH=$ROOTFS_DIR/$APP_DIR
54 | }
55 |
56 | set_nfs_target_vars() {
57 | export ROOTFS_DIR=/home/user/BBB/rootfs
58 | export APP_PATH=$ROOTFS_DIR/$APP_DIR
59 | }
60 |
61 |
62 | #------------------------------------------------------------------------------
63 | # Install buildroot to SD or NFS
64 | #------------------------------------------------------------------------------
65 | install_buildroot () {
66 | if [ ! -d "$BOOTDIR" ] && [ "$target" = "s" ]
67 | then
68 | echo "SD card not mounted - canceling buildroot installation"
69 | return;
70 | fi
71 |
72 | # clear rootfs and boot dir
73 | rm -r $ROOTFS_DIR/*
74 | if [ -d "$BOOTDIR" ]
75 | then
76 | rm -r $BOOTDIR/*
77 | fi
78 |
79 | # extract root filesystem to rootfs dir
80 | tar -xf $BUILDROOT_IMAGES/rootfs.tar -C $ROOTFS_DIR
81 | mv $ROOTFS_DIR/boot/$DTB $ROOTFS_DIR/boot/am335x-boneblack.dtb
82 |
83 | if [ -d "$BOOTDIR" ]
84 | then
85 | cp $BUILDROOT_IMAGES/MLO $BOOTDIR
86 | cp $BUILDROOT_IMAGES/u-boot.img $BOOTDIR
87 | cp $BBB_DIR/uEnv_zImage_Debian.txt $BOOTDIR/uEnv.txt
88 | echo "Installing $BBB_DIR/uEnv_zImage_Debian.txt"
89 | fi
90 |
91 | # copy some additional helper scripts
92 | cp $BBB_DIR/etc/wpa_supplicant.conf $ROOTFS_DIR/etc/wpa_supplicant.conf
93 | cp -r -f $BBB_DIR/usr/bin/* $ROOTFS_DIR/usr/bin
94 | cp -vf $BUILDROOT_CETONI/scripts/bbb-SD-eMMC-copy.sh $ROOTFS_DIR/usr/sbin/
95 | }
96 |
97 |
98 | #------------------------------------------------------------------------------
99 | # Install cetoni libraries to SD or NFS
100 | #------------------------------------------------------------------------------
101 | install_cetoni_libs() {
102 | # set write permissions for rootfs /usr/lib and /usr/bin for development
103 | # system
104 | if [ "$target" = "n" ]
105 | then
106 | chmod o+w $ROOTFS_DIR/usr/lib
107 | chmod o+w $ROOTFS_DIR/usr/bin
108 | cp -f -av $BUILDROOT_STAGING/usr/bin/*_test $ROOTFS_DIR/usr/bin
109 | fi
110 |
111 | # copy libraries
112 | cp -f -av $BUILDROOT_STAGING/usr/lib/libusl* $ROOTFS_DIR/usr/lib
113 | cp -f -av $BUILDROOT_STAGING/usr/lib/libcanoo* $ROOTFS_DIR/usr/lib
114 | cp -f -av $BUILDROOT_STAGING/usr/lib/liblabbcan* $ROOTFS_DIR/usr/lib
115 | cp -f -av $BUILDROOT_STAGING/usr/lib/liblabbCAN* $ROOTFS_DIR/usr/lib
116 | cp -f -av $BUILDROOT_STAGING/usr/lib/libcsi* $ROOTFS_DIR/usr/lib
117 | cp -f -av $BUILDROOT_STAGING/usr/lib/libled_array_api* $ROOTFS_DIR/usr/lib
118 | }
119 |
120 |
121 | #------------------------------------------------------------------------------
122 | # Installs the application to SD or NFS
123 | #------------------------------------------------------------------------------
124 | install_app() {
125 | echo "APP_PATH = $APP_PATH"
126 | #mkdir -p $APP_PATH/data/embedded_linux
127 | #mkdir -p $APP_PATH/userdata
128 |
129 | # copy application
130 | #cp -f -av $PROJECT_DIR/$APP_BINARY $APP_PATH
131 | #cp -f -av $PROJECT_DIR/data/start_app.sh $APP_PATH
132 | #cp -f -av $PROJECT_DIR/data/embedded_linux/* $APP_PATH/data/embedded_linux
133 | #chmod 777 $APP_PATH/$APP_BINARY
134 |
135 | # copy install script
136 | #if [ "$target" = "s" ]
137 | #then
138 | # cp -f -av S45application $ROOTFS_DIR/etc/init.d/
139 | #fi
140 | #cp -f -av S30usb $ROOTFS_DIR/etc/init.d/
141 | #cp -f -av S41usbgadget $ROOTFS_DIR/etc/init.d/
142 | #cp -f -av interfaces $ROOTFS_DIR/etc/network/
143 | }
144 |
145 |
146 |
147 | # The script must be run as root to have access to root file system ------------
148 | if ! id | grep -q root;
149 | then
150 | echo "must be run as root"
151 | exit
152 | fi
153 |
154 | while true; do
155 | echo "What do you want to install? (c=complete | a=app | b=buildroot | l=cetoni libs)"
156 | read -p ": " installtype
157 | case $installtype in
158 | [c]* ) break;;
159 | [a]* ) break;;
160 | [b]* ) break;;
161 | [l]* ) break;;
162 | * ) echo "Please select a valid ID.";;
163 | esac
164 | done
165 |
166 | while true; do
167 | read -p "Where to you want to install? (s=SDCard | n=NFS): " target
168 | case $target in
169 | [s]* ) set_sd_target_vars; break;;
170 | [n]* ) set_nfs_target_vars; break;;
171 | * ) echo "Please select a valid ID.";;
172 | esac
173 | done
174 |
175 | check_sd_mount
176 |
177 |
178 | if [ "$installtype" = "b" ] || [ "$installtype" = "c" ]
179 | then
180 | install_buildroot
181 | fi
182 |
183 | if [ "$installtype" = "l" ] || [ "$installtype" = "c" ]
184 | then
185 | install_cetoni_libs
186 | fi
187 |
188 | if [ "$installtype" = "a" ] || [ "$installtype" = "c" ]
189 | then
190 | install_app
191 | fi
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/src/DeclarativeInputEngine.cpp:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | /// \file DeclarativeInputEngine.cpp
3 | /// \author Uwe Kindler
4 | /// \date 08.01.2015
5 | /// \brief Implementation of CDeclarativeInputEngine
6 | ///
7 | /// Copyright 2015 Uwe Kindler
8 | /// Licensed under MIT see LICENSE.MIT in project root
9 | //============================================================================
10 |
11 | //============================================================================
12 | // INCLUDES
13 | //============================================================================
14 | #include "DeclarativeInputEngine.h"
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 |
26 | /**
27 | * Private data class
28 | */
29 | struct DeclarativeInputEnginePrivate
30 | {
31 | DeclarativeInputEngine* _this;
32 | bool Animating;
33 | QTimer* AnimatingFinishedTimer;//< triggers position adjustment of focused QML item is covered by keybaord rectangle
34 | int InputMode;
35 | QRect KeyboardRectangle;
36 |
37 | /**
38 | * Private data constructor
39 | */
40 | DeclarativeInputEnginePrivate(DeclarativeInputEngine* _public);
41 | }; // struct DeclarativeInputEnginePrivate
42 |
43 |
44 |
45 | //==============================================================================
46 | DeclarativeInputEnginePrivate::DeclarativeInputEnginePrivate(DeclarativeInputEngine* _public)
47 | : _this(_public),
48 | Animating(false),
49 | InputMode(DeclarativeInputEngine::Latin)
50 | {
51 |
52 | }
53 |
54 |
55 | //==============================================================================
56 | DeclarativeInputEngine::DeclarativeInputEngine(QObject *parent) :
57 | QObject(parent),
58 | d(new DeclarativeInputEnginePrivate(this))
59 | {
60 | d->AnimatingFinishedTimer = new QTimer(this);
61 | d->AnimatingFinishedTimer->setSingleShot(true);
62 | d->AnimatingFinishedTimer->setInterval(100);
63 | connect(d->AnimatingFinishedTimer, SIGNAL(timeout()), this, SLOT(animatingFinished()));
64 | }
65 |
66 |
67 | //==============================================================================
68 | DeclarativeInputEngine::~DeclarativeInputEngine()
69 | {
70 | delete d;
71 | }
72 |
73 |
74 | //==============================================================================
75 | void DeclarativeInputEngine::virtualKeyCancel()
76 | {
77 |
78 | }
79 |
80 |
81 | //==============================================================================
82 | bool DeclarativeInputEngine::virtualKeyClick(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers)
83 | {
84 | Q_UNUSED(key)
85 | Q_UNUSED(modifiers)
86 |
87 | QInputMethodEvent ev;
88 | if (text == QString("\x7F"))
89 | {
90 | //delete one char
91 | ev.setCommitString("",-1,1);
92 |
93 | } else
94 | {
95 | //add some text
96 | ev.setCommitString(text);
97 | }
98 | QCoreApplication::sendEvent(QGuiApplication::focusObject(),&ev);
99 | return true;
100 | }
101 |
102 |
103 | //==============================================================================
104 | void DeclarativeInputEngine::sendKeyToFocusItem(const QString& text)
105 | {
106 | qDebug() << "CDeclarativeInputEngine::sendKeyToFocusItem " << text;
107 | QInputMethodEvent ev;
108 | if (text == QString("\x7F"))
109 | {
110 | //delete one char
111 | ev.setCommitString("",-1,1);
112 |
113 | } else
114 | {
115 | //add some text
116 | ev.setCommitString(text);
117 | }
118 | QCoreApplication::sendEvent(QGuiApplication::focusObject(),&ev);
119 | }
120 |
121 |
122 | //==============================================================================
123 | bool DeclarativeInputEngine::virtualKeyPress(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers, bool repeat)
124 | {
125 | Q_UNUSED(key)
126 | Q_UNUSED(text)
127 | Q_UNUSED(modifiers)
128 | Q_UNUSED(repeat)
129 |
130 | // not implemented yet
131 | return true;
132 | }
133 |
134 |
135 | //==============================================================================
136 | bool DeclarativeInputEngine::virtualKeyRelease(Qt::Key key, const QString & text, Qt::KeyboardModifiers modifiers)
137 | {
138 | Q_UNUSED(key)
139 | Q_UNUSED(text)
140 | Q_UNUSED(modifiers)
141 |
142 | // not implemented yet
143 | return true;
144 | }
145 |
146 |
147 | //==============================================================================
148 | QRect DeclarativeInputEngine::keyboardRectangle() const
149 | {
150 | return d->KeyboardRectangle;
151 | }
152 |
153 |
154 | //==============================================================================
155 | void DeclarativeInputEngine::setKeyboardRectangle(const QRect& Rect)
156 | {
157 | setAnimating(true);
158 | d->AnimatingFinishedTimer->start(100);
159 | d->KeyboardRectangle = Rect;
160 | emit keyboardRectangleChanged();
161 | }
162 |
163 |
164 | //==============================================================================
165 | bool DeclarativeInputEngine::isAnimating() const
166 | {
167 | return d->Animating;
168 | }
169 |
170 |
171 | //==============================================================================
172 | void DeclarativeInputEngine::setAnimating(bool Animating)
173 | {
174 | if (d->Animating != Animating)
175 | {
176 | d->Animating = Animating;
177 | emit animatingChanged();
178 | }
179 | }
180 |
181 |
182 | //==============================================================================
183 | void DeclarativeInputEngine::animatingFinished()
184 | {
185 | setAnimating(false);
186 | }
187 |
188 |
189 | //==============================================================================
190 | int DeclarativeInputEngine::inputMode() const
191 | {
192 | return d->InputMode;
193 | }
194 |
195 |
196 | //==============================================================================
197 | void DeclarativeInputEngine::setInputMode(int Mode)
198 | {
199 | qDebug() << "CDeclarativeInputEngine::setInputMode " << Mode;
200 | if (Mode != d->InputMode)
201 | {
202 | d->InputMode = Mode;
203 | emit inputModeChanged();
204 | }
205 | }
206 |
207 | //------------------------------------------------------------------------------
208 | // EOF DeclarativeInputEngine.cpp
209 |
--------------------------------------------------------------------------------
/examples/qmlapp/MainQuickControls.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.3
2 | import QtQuick.Controls 1.2
3 | import QtQuick.Controls.Styles 1.2
4 | import "."
5 |
6 | Rectangle {
7 | id: root
8 | width: parent.width
9 | height: parent.height
10 | color: "white"
11 |
12 | FontLoader {
13 | source: "FontAwesome.otf"
14 | }
15 |
16 | // this is a standalone animation, it's not running by default
17 | PropertyAnimation { id: syringeLevelAnimation; target: syringe; property: "level"}
18 |
19 | Flickable {
20 | id: flickable
21 | anchors.fill: parent
22 | contentWidth: content.width
23 | contentHeight: content.height
24 | interactive: contentHeight > height
25 | flickableDirection: Flickable.VerticalFlick
26 |
27 | Item {
28 | id: content
29 | x: Style.dp(20)
30 | y: Style.dp(20)
31 | width: flickable.width - Style.dp(42)
32 | //height: syringeRow.implicitHeight + grid.implicitHeight
33 |
34 | Row {
35 | id: syringeRow
36 | anchors.left: content.left
37 | anchors.right: content.right
38 | height: Style.dp(160)
39 | //spacing: 10
40 | Button {
41 | id: emptyButton
42 | text: "\uf049"
43 | width: content.width * 0.15
44 | height: parent.height
45 | style: ButtonFlatStyle {
46 | font.family: "FontAwesome"
47 | font.pixelSize: Style.dp(60)
48 | }
49 |
50 | onPressedChanged: {
51 | syringeLevelAnimation.to = syringe.minimumLevel;
52 | syringeLevelAnimation.duration = syringe.level / syringe.maximumLevel * 5000 * flowSlider.maximumValue / flowSlider.value
53 | syringeLevelAnimation.running = pressed;
54 | }
55 | }
56 |
57 | Syringe {
58 | id: syringe
59 | height: parent.height
60 | width: content.width * 0.7
61 | minimumLevel: 0
62 | maximumLevel: 10
63 | level: maximumLevel / 2
64 | }
65 |
66 |
67 | Button {
68 | id: refillButton
69 | text: "\uf050"
70 | width: content.width * 0.15
71 | height: parent.height
72 | style: ButtonFlatStyle {
73 | font.family: "FontAwesome"
74 | font.pixelSize: Style.dp(60)
75 | }
76 |
77 | onPressedChanged: {
78 | syringeLevelAnimation.to = syringe.maximumLevel
79 | syringeLevelAnimation.duration = (syringe.maximumLevel - syringe.level) / syringe.maximumLevel * 5000 * flowSlider.maximumValue / flowSlider.value
80 | syringeLevelAnimation.running = pressed;
81 | }
82 | }
83 | }
84 |
85 |
86 | Grid {
87 | id: grid
88 | columns: 2
89 | verticalItemAlignment: Grid.AlignVCenter
90 | horizontalItemAlignment: Grid.AlignLeft
91 | columnSpacing: Style.dp(10)
92 | rowSpacing: Style.dp(20)
93 | anchors.left: content.left
94 | anchors.right: content.right
95 | anchors.top: syringeRow.bottom
96 | anchors.topMargin: Style.dp(20)
97 |
98 | // 1st rot ----------------------
99 | Label {
100 | text: "Level (ml):"
101 | font.pixelSize: levelTextField.font.pixelSize
102 | }
103 | TextField {
104 | id: levelTextField
105 | style: TextFieldFlatStyle {}
106 | width: grid.width - x
107 | //placeholderText: "Level (ml)"
108 | inputMethodHints: Qt.ImhFormattedNumbersOnly
109 | text: syringe.level
110 | validator: DoubleValidator {
111 | bottom: syringe.minimumLevel;
112 | top: syringe.maximumLevel;
113 | notation: DoubleValidator.StandardNotation
114 | decimals: 6
115 | }
116 | }
117 |
118 | // 1st rot ----------------------
119 | Label {
120 | text: "Volume (ml):"
121 | font.pixelSize: volumeTextField.font.pixelSize
122 | }
123 | TextField {
124 | id: volumeTextField
125 | style: TextFieldFlatStyle {}
126 | width: grid.width - x
127 | //placeholderText: "Volume (ml)"
128 | inputMethodHints: Qt.ImhFormattedNumbersOnly
129 | text: "0"
130 | validator: DoubleValidator {
131 | bottom: 0;
132 | top: 2000;
133 | notation: DoubleValidator.StandardNotation
134 | decimals: 6
135 | }
136 | }
137 |
138 | // 2nd row ----------------------
139 | Label {
140 | text: "Flow (ml/s):"
141 | font.pixelSize: flowTextField.font.pixelSize
142 | }
143 | TextField {
144 | id: flowTextField
145 | style: TextFieldFlatStyle {}
146 | width: grid.width - x
147 | //placeholderText: "Flow (ml/s)"
148 | inputMethodHints: Qt.ImhFormattedNumbersOnly
149 | validator: DoubleValidator {
150 | bottom: 0;
151 | top: 2000;
152 | notation: DoubleValidator.StandardNotation
153 | decimals: 6
154 | }
155 | }
156 |
157 | // 3rd row ----------------------
158 | Rectangle {
159 | id: dumy
160 | width: Style.dp(10)
161 | height: Style.dp(10)
162 | }
163 |
164 | Slider {
165 | id: flowSlider
166 | width: grid.width - x
167 | minimumValue: 0
168 | maximumValue: 100
169 | value: 30
170 | style: SliderFlatStyle {}
171 | onValueChanged: {
172 | flowTextField.text = value
173 | }
174 | }
175 | }
176 | }
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/src/InputPanel.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import "."
3 | import FreeVirtualKeyboard 1.0
4 |
5 | /**
6 | * This is the QML input panel that provides the virtual keyboard UI
7 | * The code has been derived from
8 | * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
9 | * Copyright 2015 Uwe Kindler
10 | * Licensed under MIT see LICENSE.MIT in project root
11 | */
12 | Item {
13 | id:root
14 | objectName: "inputPanel"
15 | width: parent.width
16 | height: width / 4
17 | // Report actual keyboard rectangle to input engine
18 | onYChanged: InputEngine.setKeyboardRectangle(Qt.rect(x, y, width, height))
19 |
20 | KeyModel {
21 | id:keyModel
22 | }
23 | FontLoader {
24 | source: "FontAwesome.otf"
25 | }
26 | QtObject {
27 | id:pimpl
28 | property bool shiftModifier: false
29 | property bool symbolModifier: false
30 | property int verticalSpacing: keyboard.height / 40
31 | property int horizontalSpacing: verticalSpacing
32 | property int rowHeight: keyboard.height/4 - verticalSpacing
33 | property int buttonWidth: (keyboard.width-column.anchors.margins)/10 - horizontalSpacing
34 | }
35 |
36 | /**
37 | * The delegate that paints the key buttons
38 | */
39 | Component {
40 | id: keyButtonDelegate
41 | KeyButton {
42 | id: button
43 | width: pimpl.buttonWidth
44 | height: pimpl.rowHeight
45 | text: (pimpl.shiftModifier) ? letter.toUpperCase() : (pimpl.symbolModifier)?firstSymbol : letter
46 | inputPanel: root
47 | }
48 | }
49 |
50 | Connections {
51 | target: InputEngine
52 | // Switch the keyboard layout to Numeric if the input mode of the InputEngine changes
53 | onInputModeChanged: {
54 | pimpl.symbolModifier = ((InputEngine.inputMode == InputEngine.Numeric)
55 | || (InputEngine.inputMode == InputEngine.Dialable))
56 | if (pimpl.symbolModifier) {
57 | pimpl.shiftModifier = false
58 | }
59 | }
60 | }
61 |
62 | /**
63 | * This function shows the character preview popup for each key button
64 | */
65 | function showKeyPopup(keyButton)
66 | {
67 | console.log("showKeyPopup");
68 | keyPopup.popup(keyButton, root);
69 | }
70 |
71 | /**
72 | * The key popup for character preview
73 | */
74 | KeyPopup {
75 | id: keyPopup
76 | visible: false
77 | z: 100
78 | }
79 |
80 |
81 | Rectangle {
82 | id:keyboard
83 | color: "black"
84 | anchors.fill: parent;
85 | MouseArea {
86 | anchors.fill: parent
87 | }
88 |
89 | Column {
90 | id:column
91 | anchors.margins: 5
92 | anchors.fill: parent
93 | spacing: pimpl.verticalSpacing
94 |
95 | Row {
96 | height: pimpl.rowHeight
97 | spacing: pimpl.horizontalSpacing
98 | anchors.horizontalCenter:parent.horizontalCenter
99 | Repeater {
100 | model: keyModel.firstRowModel
101 | delegate: keyButtonDelegate
102 | }
103 | }
104 | Row {
105 | height: pimpl.rowHeight
106 | spacing: pimpl.horizontalSpacing
107 | anchors.horizontalCenter:parent.horizontalCenter
108 | Repeater {
109 | model: keyModel.secondRowModel
110 | delegate: keyButtonDelegate
111 | }
112 | }
113 | Item {
114 | height: pimpl.rowHeight
115 | width:parent.width
116 | KeyButton {
117 | id: shiftKey
118 | color: (pimpl.shiftModifier)? "#1e6fa7": "#1e1b18"
119 | anchors.left: parent.left
120 | width: 1.25*pimpl.buttonWidth
121 | height: pimpl.rowHeight
122 | font.family: "FontAwesome"
123 | text: "\uf062"
124 | functionKey: true
125 | onClicked: {
126 | if (pimpl.symbolModifier) {
127 | pimpl.symbolModifier = false
128 | }
129 | pimpl.shiftModifier = !pimpl.shiftModifier
130 | }
131 | inputPanel: root
132 | }
133 | Row {
134 | height: pimpl.rowHeight
135 | spacing: pimpl.horizontalSpacing
136 | anchors.horizontalCenter:parent.horizontalCenter
137 | Repeater {
138 | anchors.horizontalCenter: parent.horizontalCenter
139 | model: keyModel.thirdRowModel
140 | delegate: keyButtonDelegate
141 | }
142 | }
143 | KeyButton {
144 | id: backspaceKey
145 | font.family: "FontAwesome"
146 | color: "#1e1b18"
147 | anchors.right: parent.right
148 | width: 1.25*pimpl.buttonWidth
149 | height: pimpl.rowHeight
150 | text: "\x7F"
151 | displayText: "\uf177"
152 | inputPanel: root
153 | repeat: true
154 | }
155 | }
156 | Row {
157 | height: pimpl.rowHeight
158 | spacing: pimpl.horizontalSpacing
159 | anchors.horizontalCenter:parent.horizontalCenter
160 | KeyButton {
161 | id: hideKey
162 | color: "#1e1b18"
163 | width: 1.25*pimpl.buttonWidth
164 | height: pimpl.rowHeight
165 | font.family: "FontAwesome"
166 | text: "\uf078"
167 | functionKey: true
168 | onClicked: {
169 | Qt.inputMethod.hide()
170 | }
171 | inputPanel: root
172 | showPreview: false
173 | }
174 | KeyButton {
175 | color: "#1e1b18"
176 | width: 1.25*pimpl.buttonWidth
177 | height: pimpl.rowHeight
178 | text: ""
179 | inputPanel: root
180 | functionKey: true
181 | }
182 | KeyButton {
183 | width: pimpl.buttonWidth
184 | height: pimpl.rowHeight
185 | text: ","
186 | inputPanel: root
187 | }
188 | KeyButton {
189 | id: spaceKey
190 | width: 3*pimpl.buttonWidth
191 | height: pimpl.rowHeight
192 | text: " "
193 | inputPanel: root
194 | showPreview: false
195 | }
196 | KeyButton {
197 | width: pimpl.buttonWidth
198 | height: pimpl.rowHeight
199 | text: "."
200 | inputPanel: root
201 | }
202 | KeyButton {
203 | id: symbolKey
204 | color: "#1e1b18"
205 | width: 1.25*pimpl.buttonWidth
206 | height: pimpl.rowHeight
207 | text: (!pimpl.symbolModifier)? "12#" : "ABC"
208 | functionKey: true
209 | onClicked: {
210 | if (pimpl.shiftModifier) {
211 | pimpl.shiftModifier = false
212 | }
213 | pimpl.symbolModifier = !pimpl.symbolModifier
214 | }
215 | inputPanel: root
216 | }
217 | KeyButton {
218 | id: enterKey
219 | color: "#1e1b18"
220 | width: 1.25*pimpl.buttonWidth
221 | height: pimpl.rowHeight
222 | displayText: "Enter"
223 | text: "\n"
224 | inputPanel: root
225 | }
226 | }
227 | }
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/src/VirtualKeyboardInputContext.cpp:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | /// \file VirtualKeyboardInputContext.cpp
3 | /// \author Uwe Kindler
4 | /// \date 08.01.2015
5 | /// \brief Implementation of VirtualKeyboardInputContext
6 | ///
7 | /// Copyright 2015 Uwe Kindler
8 | /// Licensed under MIT see LICENSE.MIT in project root
9 | //============================================================================
10 |
11 | //============================================================================
12 | // INCLUDES
13 | //============================================================================
14 | #include "VirtualKeyboardInputContext.h"
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include "DeclarativeInputEngine.h"
28 |
29 |
30 | /**
31 | * Private data class for VirtualKeyboardInputContext
32 | */
33 | class VirtualKeyboardInputContextPrivate
34 | {
35 | public:
36 | VirtualKeyboardInputContextPrivate();
37 | QQuickFlickable* Flickable;
38 | QQuickItem* FocusItem;
39 | bool Visible;
40 | DeclarativeInputEngine* InputEngine;
41 | QPropertyAnimation* FlickableContentScrollAnimation;//< for smooth scrolling of flickable content item
42 | };
43 |
44 |
45 | //==============================================================================
46 | VirtualKeyboardInputContextPrivate::VirtualKeyboardInputContextPrivate()
47 | : Flickable(0),
48 | FocusItem(0),
49 | Visible(false),
50 | InputEngine(new DeclarativeInputEngine())
51 | {
52 |
53 | }
54 |
55 |
56 | //==============================================================================
57 | VirtualKeyboardInputContext::VirtualKeyboardInputContext() :
58 | QPlatformInputContext(), d(new VirtualKeyboardInputContextPrivate)
59 | {
60 | d->FlickableContentScrollAnimation = new QPropertyAnimation(this);
61 | d->FlickableContentScrollAnimation->setPropertyName("contentY");
62 | d->FlickableContentScrollAnimation->setDuration(400);
63 | d->FlickableContentScrollAnimation->setEasingCurve(QEasingCurve(QEasingCurve::OutBack));
64 | qmlRegisterSingletonType("FreeVirtualKeyboard", 1, 0,
65 | "InputEngine", inputEngineProvider);
66 | connect(d->InputEngine, SIGNAL(animatingChanged()), this, SLOT(ensureFocusedObjectVisible()));
67 | }
68 |
69 |
70 | //==============================================================================
71 | VirtualKeyboardInputContext::~VirtualKeyboardInputContext()
72 | {
73 |
74 | }
75 |
76 |
77 | //==============================================================================
78 | VirtualKeyboardInputContext* VirtualKeyboardInputContext::instance()
79 | {
80 | static VirtualKeyboardInputContext* InputContextInstance = new VirtualKeyboardInputContext;
81 | return InputContextInstance;
82 | }
83 |
84 |
85 |
86 | //==============================================================================
87 | bool VirtualKeyboardInputContext::isValid() const
88 | {
89 | return true;
90 | }
91 |
92 |
93 | //==============================================================================
94 | QRectF VirtualKeyboardInputContext::keyboardRect() const
95 | {
96 | return QRectF();
97 | }
98 |
99 |
100 | //==============================================================================
101 | void VirtualKeyboardInputContext::showInputPanel()
102 | {
103 | d->Visible = true;
104 | QPlatformInputContext::showInputPanel();
105 | emitInputPanelVisibleChanged();
106 | }
107 |
108 |
109 | //==============================================================================
110 | void VirtualKeyboardInputContext::hideInputPanel()
111 | {
112 | d->Visible = false;
113 | QPlatformInputContext::hideInputPanel();
114 | emitInputPanelVisibleChanged();
115 | }
116 |
117 |
118 | //==============================================================================
119 | bool VirtualKeyboardInputContext::isInputPanelVisible() const
120 | {
121 | return d->Visible;
122 | }
123 |
124 |
125 | //==============================================================================
126 | bool VirtualKeyboardInputContext::isAnimating() const
127 | {
128 | return false;
129 | }
130 |
131 |
132 | //==============================================================================
133 | void VirtualKeyboardInputContext::setFocusObject(QObject *object)
134 | {
135 | static const int NumericInputHints = Qt::ImhPreferNumbers | Qt::ImhDate
136 | | Qt::ImhTime | Qt::ImhDigitsOnly | Qt::ImhFormattedNumbersOnly;
137 | static const int DialableInputHints = Qt::ImhDialableCharactersOnly;
138 |
139 |
140 | qDebug() << "VirtualKeyboardInputContext::setFocusObject";
141 | if (!object)
142 | {
143 | return;
144 | }
145 |
146 | // we only support QML at the moment - so if this is not a QML item, then
147 | // we leave immediatelly
148 | d->FocusItem = dynamic_cast(object);
149 | if (!d->FocusItem)
150 | {
151 | return;
152 | }
153 |
154 | // Check if an input control has focus that accepts text input - if not,
155 | // then we can leave immediatelly
156 | bool AcceptsInput = d->FocusItem->inputMethodQuery(Qt::ImEnabled).toBool();
157 | if (!AcceptsInput)
158 | {
159 | return;
160 | }
161 |
162 | // Set input mode depending on input method hints queried from focused
163 | // object / item
164 | Qt::InputMethodHints InputMethodHints(d->FocusItem->inputMethodQuery(Qt::ImHints).toInt());
165 | qDebug() << QString("InputMethodHints: %1").arg(InputMethodHints, 0, 16);
166 | if (InputMethodHints & DialableInputHints)
167 | {
168 | d->InputEngine->setInputMode(DeclarativeInputEngine::Dialable);
169 | }
170 | else if (InputMethodHints & NumericInputHints)
171 | {
172 | d->InputEngine->setInputMode(DeclarativeInputEngine::Numeric);
173 | }
174 | else
175 | {
176 | d->InputEngine->setInputMode(DeclarativeInputEngine::Latin);
177 | }
178 |
179 | // Search for the top most flickable so that we can scroll the control
180 | // into the visible area, if the keyboard hides the control
181 | QQuickItem* i = d->FocusItem;
182 | d->Flickable = 0;
183 | while (i)
184 | {
185 | QQuickFlickable* Flickable = dynamic_cast(i);
186 | if (Flickable)
187 | {
188 | d->Flickable = Flickable;
189 | qDebug() << "is QQuickFlickable";
190 | }
191 | i = i->parentItem();
192 | }
193 |
194 | ensureFocusedObjectVisible();
195 | }
196 |
197 |
198 | //==============================================================================
199 | void VirtualKeyboardInputContext::ensureFocusedObjectVisible()
200 | {
201 | // If the keyboard is hidden, no scrollable element exists or the keyboard
202 | // is just animating, then we leave here
203 | if (!d->Visible || !d->Flickable || d->InputEngine->isAnimating())
204 | {
205 | return;
206 | }
207 |
208 | qDebug() << "VirtualKeyboardInputContext::ensureFocusedObjectVisible";
209 | QRectF FocusItemRect(0, 0, d->FocusItem->width(), d->FocusItem->height());
210 | FocusItemRect = d->Flickable->mapRectFromItem(d->FocusItem, FocusItemRect);
211 | qDebug() << "FocusItemRect: " << FocusItemRect;
212 | qDebug() << "Content origin: " << QPointF(d->Flickable->contentX(),
213 | d->Flickable->contentY());
214 | qDebug() << "Flickable size: " << QSize(d->Flickable->width(), d->Flickable->height());
215 | d->FlickableContentScrollAnimation->setTargetObject(d->Flickable);
216 | qreal ContentY = d->Flickable->contentY();
217 | if (FocusItemRect.bottom() >= d->Flickable->height())
218 | {
219 | qDebug() << "Item outside!!! FocusItemRect.bottom() >= d->Flickable->height()";
220 | ContentY = d->Flickable->contentY() + (FocusItemRect.bottom() - d->Flickable->height()) + 20;
221 | d->FlickableContentScrollAnimation->setEndValue(ContentY);
222 | d->FlickableContentScrollAnimation->start();
223 | }
224 | else if (FocusItemRect.top() < 0)
225 | {
226 | qDebug() << "Item outside!!! d->FocusItem->position().x < 0";
227 | ContentY = d->Flickable->contentY() + FocusItemRect.top() - 20;
228 | d->FlickableContentScrollAnimation->setEndValue(ContentY);
229 | d->FlickableContentScrollAnimation->start();
230 | }
231 | }
232 |
233 |
234 | //==============================================================================
235 | QObject* VirtualKeyboardInputContext::inputEngineProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
236 | {
237 | Q_UNUSED(engine)
238 | Q_UNUSED(scriptEngine)
239 | return VirtualKeyboardInputContext::instance()->d->InputEngine;
240 | }
241 |
242 | //------------------------------------------------------------------------------
243 | // EOF VirtualKeyboardInpitContext.cpp
244 |
245 |
--------------------------------------------------------------------------------
/examples/qmlapp/syringe2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
297 |
--------------------------------------------------------------------------------