ref #549 "fix parsing of the virtual keyboard module"

This commit is contained in:
Andrei Yankovich 2021-03-03 14:10:53 +03:00
parent 2881c1f311
commit 3f58c342c3
22 changed files with 1074 additions and 31 deletions

View File

@ -21,7 +21,8 @@ lessThan(QT_MAJOR_VERSION, 6):lessThan(QT_MINOR_VERSION, 14) {
UnitTests \
tests/TestOnlyC \
tests/TestQtWidgets \
tests/TestQMLWidgets
tests/TestQMLWidgets \
tests/virtualkeyboard
unix:SUBDIRS += tests/quicknanobrowser
unix:SUBDIRS += tests/webui

View File

@ -79,7 +79,8 @@ QtModuleEntry DeployCore::qtModuleEntries[] = {
{ QtWebChannelModule, "webchannel", "QtXWebChannel", nullptr },
{ QtTextToSpeechModule, "texttospeech", "QtXTextToSpeech", nullptr },
{ QtSerialBusModule, "serialbus", "QtXSerialBus", nullptr },
{ QtWebViewModule, "webview", "QtXWebView", nullptr }
{ QtWebViewModule, "webview", "QtXWebView", nullptr },
{ QtVirtualKeyboard, "virtualkeyboard", "QtXVirtualKeyboard", nullptr }
};
DeployCore::QtModule DeployCore::getQtModule(const QString& path) {
@ -691,6 +692,17 @@ bool DeployCore::checkSystemBakupSnapInterface() {
return QDir(DeployCore::snapRootFS()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).size();
}
QString DeployCore::getLibCoreName(const QFileInfo &info) {
auto baseName = info.baseName();
QString result; if (baseName.left(3) == "lib") {
result = baseName.mid(3);
} else {
result = baseName;
}
return result;
}
uint qHash(WinAPI i) {
return static_cast<uint>(i);
}

View File

@ -174,9 +174,10 @@ public:
Qt3DAnimationModule = 0x0002000000000000,
QtWebViewModule = 0x0004000000000000,
Qt3DExtrasModule = 0x0008000000000000,
QtVirtualKeyboard = 0x0010000000000000,
// Qt6
QtOpenGLWidgetsModule = 0x0010000000000000,
QtSvgWidgetsModule = 0x0020000000000000
QtOpenGLWidgetsModule = 0x0020000000000000,
QtSvgWidgetsModule = 0x0040000000000000
};
DeployCore() = delete;
@ -248,6 +249,14 @@ public:
static QString snapRootFS();
static QString transportPathToSnapRoot(const QString &path);
static bool checkSystemBakupSnapInterface();
/**
* @brief getLibCoreName This method remove platfomr specificly prefixes and sufixes of the librarry.
* Example : getLibCoreName(libTest.so) return Test
* @param baseName This is information about checked library.
* @return return core name of the library.
*/
static QString getLibCoreName(const QFileInfo& info);
};
#endif // DEPLOYUTILS_H

View File

@ -14,6 +14,13 @@
PluginsParser::PluginsParser(){
}
// This maping using for the plugins group. But not all plugins from group should be copyed.
// For example the platforminputcontexts group plugins contains the qtvirtualkeyboardplugin. This plugin depends of the QtVirtualKeyboadr library.
// But this plugin should be copied only when the deistribution has a QtVirtualKeyboard module.
// If the qtvirtualkeyboardplugin plugin will be copied befor the adding QtVirtualKeyboard then in the distribution will have a not used Qt module.
// For fix this issue we need to add plugins into ditalsSluginModuleMappings list.
// all plugins from array ditalsSluginModuleMappings will have their modules updated.
static const PluginModuleMapping pluginModuleMappings[] =
{
{"qml1tooling", DeployCore::QtModule::QtDeclarativeModule},
@ -24,7 +31,7 @@ static const PluginModuleMapping pluginModuleMappings[] =
{"platforms", DeployCore::QtModule::QtGuiModule},
{"platformthemes", DeployCore::QtModule::QtGuiModule},
{"platforminputcontexts", DeployCore::QtModule::QtGuiModule},
{"virtualkeyboard", DeployCore::QtModule::QtGuiModule},
{"virtualkeyboard", DeployCore::QtModule::QtVirtualKeyboard},
{"geoservices", DeployCore::QtModule::QtLocationModule},
{"audio", DeployCore::QtModule::QtMultimediaModule},
{"mediaservice", DeployCore::QtModule::QtMultimediaModule},
@ -55,6 +62,12 @@ static const PluginModuleMapping pluginModuleMappings[] =
};
static const PluginModuleMapping ditalsSluginModuleMappings[] = {
{"qtvirtualkeyboardplugin", DeployCore::QtModule::QtVirtualKeyboard}
};
static const PlatformMapping platformMappings[] =
{
{"qminimal", Unix | Win },
@ -85,7 +98,7 @@ static const PlatformMapping platformMappings[] =
};
quint64 PluginsParser::qtModuleForPlugin(const QString &subDirName) const {
quint64 PluginsParser::qtModuleForPluginGroup(const QString &subDirName) const {
const auto end = std::end(pluginModuleMappings);
const auto result =
@ -98,6 +111,19 @@ quint64 PluginsParser::qtModuleForPlugin(const QString &subDirName) const {
return result != end ? result->module : 0; // "designer"
}
quint64 PluginsParser::qtModuleForPlugin(const QString &plugin) const {
const auto end = std::end(ditalsSluginModuleMappings);
const auto result =
std::find_if(std::begin(ditalsSluginModuleMappings), end,
[&plugin] (const PluginModuleMapping &m) {
return plugin == QLatin1String(m.directoryName);
});
return result != end ? result->module : 0; // "designer"
}
Platform PluginsParser::platformForPlugin(const QString &name) const {
const auto end = std::end(platformMappings);
const auto result =
@ -132,7 +158,8 @@ bool PluginsParser::scan(const QString& pluginPath,
return true;
}
void PluginsParser::addPlugins(const QStringList& list, const QString& package, QHash<QString, QSet<QString>>& container) {
void PluginsParser::addPlugins(const QStringList& list, const QString& package,
QHash<QString, QSet<QString>>& container) {
const DeployConfig* cnf = DeployCore::_config;
for (const auto plugin: list) {
@ -140,12 +167,10 @@ void PluginsParser::addPlugins(const QStringList& list, const QString& package,
auto listPlugins = QDir(cnf->qtDir.getPlugins() + "/" + plugin).entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
for (const auto &plugin: listPlugins) {
QuasarAppUtils::Params::log("Disable plugin: " + plugin.baseName(), QuasarAppUtils::Debug);
container[package].insert(getPluginNameFromFile( plugin.baseName()));
}
} else {
QuasarAppUtils::Params::log("Disable plugin: " + plugin, QuasarAppUtils::Debug);
container[package].insert(getPluginNameFromFile(plugin));
}
}
@ -202,11 +227,16 @@ void PluginsParser::scanPluginGroup(const QFileInfo& plugin,
DeployCore::QtModule qtModules) const {
auto plugins = QDir(plugin.absoluteFilePath()).entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
auto module = qtModuleForPlugin(plugin.fileName());
auto groupModule = qtModuleForPluginGroup(plugin.fileName());
for (const auto& info: plugins) {
if (isEnabledPlugin(getPluginNameFromFile(info.baseName()), package) ||
(!isDisabledPlugin(getPluginNameFromFile(info.baseName()), package) && (qtModules & module))) {
bool fEnabled = isEnabledPlugin(getPluginNameFromFile(info.baseName()), package);
bool fDisabled = isDisabledPlugin(getPluginNameFromFile(info.baseName()), package);
auto pluginModule = qtModuleForPlugin(DeployCore::getLibCoreName(info));
auto module = (pluginModule)? pluginModule : groupModule;
if (fEnabled || (!fDisabled && (qtModules & module))) {
result += info.absoluteFilePath();
}
}
@ -222,8 +252,6 @@ bool PluginsParser::isEnabledPlugin(const QString &plugin, const QString &packag
QStringList PluginsParser::defaultForbidenPlugins() {
return {
"qtvirtualkeyboardplugin",
"virtualkeyboard",
};
}

View File

@ -51,7 +51,9 @@ private:
QHash<QString, QSet<QString>> _disabledPlugins;
QHash<QString, QSet<QString>> _enabledPlugins;
quint64 qtModuleForPlugin(const QString &subDirName) const;
quint64 qtModuleForPluginGroup(const QString &subDirName) const;
quint64 qtModuleForPlugin(const QString &plugin) const;
Platform platformForPlugin(const QString &name) const;
bool copyPlugin(const QString &plugin, const QString &package);

View File

@ -1263,6 +1263,58 @@ QSet<QString> ModulesQt513::qmlLibs(const QString &distDir) const {
return Tree;
}
QSet<QString> ModulesQt513::qmlVirtualKeyBoadrLibs(const QString &distDir) const {
TestUtils utils;
auto Tree = qmlLibs(distDir);
#ifdef Q_OS_LINUX
Tree += utils.createTree({
"./" + distDir + "/basic.sh",
"./" + distDir + "/bin/basic",
"./" + distDir + "/lib/libQt5RemoteObjects.so",
"./" + distDir + "/lib/libQt5VirtualKeyboard.so",
"./" + distDir + "/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so",
"./" + distDir + "/plugins/virtualkeyboard/libqtvirtualkeyboard_hangul.so",
"./" + distDir + "/plugins/virtualkeyboard/libqtvirtualkeyboard_openwnn.so",
"./" + distDir + "/plugins/virtualkeyboard/libqtvirtualkeyboard_pinyin.so",
"./" + distDir + "/plugins/virtualkeyboard/libqtvirtualkeyboard_tcime.so",
"./" + distDir + "/plugins/virtualkeyboard/libqtvirtualkeyboard_thai.so",
"./" + distDir + "/qml/QtQml/Models.2/libmodelsplugin.so",
"./" + distDir + "/qml/QtQml/Models.2/plugins.qmltypes",
"./" + distDir + "/qml/QtQml/Models.2/qmldir",
"./" + distDir + "/qml/QtQml/RemoteObjects/libqtqmlremoteobjects.so",
"./" + distDir + "/qml/QtQml/RemoteObjects/plugins.qmltypes",
"./" + distDir + "/qml/QtQml/RemoteObjects/qmldir",
"./" + distDir + "/qml/QtQml/StateMachine/libqtqmlstatemachine.so",
"./" + distDir + "/qml/QtQml/StateMachine/plugins.qmltypes",
"./" + distDir + "/qml/QtQml/StateMachine/qmldir",
"./" + distDir + "/qml/QtQml/WorkerScript.2/libworkerscriptplugin.so",
"./" + distDir + "/qml/QtQml/WorkerScript.2/plugins.qmltypes",
"./" + distDir + "/qml/QtQml/WorkerScript.2/qmldir",
"./" + distDir + "/qml/QtQml/libqmlplugin.so",
"./" + distDir + "/qml/QtQml/plugins.qmltypes",
"./" + distDir + "/qml/QtQml/qmldir",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Settings/libqtquickvirtualkeyboardsettingsplugin.so",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Settings/plugins.qmltypes",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Settings/qmldir",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Styles/libqtquickvirtualkeyboardstylesplugin.so",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Styles/plugins.qmltypes",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/Styles/qmldir",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/libqtquickvirtualkeyboardplugin.so",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/plugins.qmltypes",
"./" + distDir + "/qml/QtQuick/VirtualKeyboard/qmldir"
});
#else
Tree += utils.createTree({
});
#endif
return Tree;
}
QSet<QString> ModulesQt513::testDistroLibs(const QString &distDir) const {
TestUtils utils;
#ifdef Q_OS_WIN

View File

@ -24,6 +24,8 @@ public:
virtual QSet<QString> onlyC(const QString &distDir = DISTRO_DIR) const;
virtual QSet<QString> qtLibs(const QString &distDir = DISTRO_DIR) const;
virtual QSet<QString> qmlLibs(const QString &distDir = DISTRO_DIR) const;
virtual QSet<QString> qmlVirtualKeyBoadrLibs(const QString &distDir = DISTRO_DIR) const;
virtual QSet<QString> testDistroLibs(const QString &distDir = DISTRO_DIR) const;
virtual QSet<QString> testOutLibs(const QString &distDir = DISTRO_DIR) const;

View File

@ -1,14 +1,11 @@
{
"binDir": "$BIN_DIR",
"bin": "$BIN_DIR",
"clear": true,
"libDir": "./",
"recursiveDepth": "5",
"targetPackage": [
["Dstro1", "TestOnlyC"],
["Dstro2", "QtWidgetsProject"],
["Dstro2", "TestQMLWidgets"],
["Dstro2", "quicknanobrowser"],
["Dstro2", "webui"]
["Dstro2", "QtWidgetsProject"]
]
}

View File

@ -145,6 +145,8 @@ private slots:
void testDependencyMap();
void testQmlScaner();
void testVirtualKeyBoard();
};
bool deploytest::runProcess(const QString &DistroPath,
@ -716,6 +718,23 @@ void deploytest::testQmlScaner() {
}
void deploytest::testVirtualKeyBoard() {
TestUtils utils;
#ifdef Q_OS_UNIX
QString bin = TestBinDir + "basic";
QString qmake = TestQtDir + "bin/qmake";
#else
QString bin = TestBinDir + "basic.exe";
QString qmake = TestQtDir + "bin/qmake.exe";
#endif
auto comapareTree = TestModule.qmlVirtualKeyBoadrLibs();
runTestParams({"-bin", bin, "clear" ,
"-qmake", qmake,
"-qmlDir", TestBinDir + "/../virtualkeyboard"}, &comapareTree);
}
void deploytest::testQmlExtrct() {
QmlCreator creator("./");
auto imports = creator.getQmlImports();
@ -1190,14 +1209,17 @@ void deploytest::testBinDir() {
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/bin/QtWidgetsProject",
"./" + DISTRO_DIR + "/bin/TestQMLWidgets",
"./" + DISTRO_DIR + "/bin/basic",
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/QtWidgetsProject.sh",
"./" + DISTRO_DIR + "/TestQMLWidgets.sh"});
"./" + DISTRO_DIR + "/TestQMLWidgets.sh",
"./" + DISTRO_DIR + "/basic.sh"});
#else
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "/TestOnlyC.exe",
"./" + DISTRO_DIR + "/QtWidgetsProject.exe",
"./" + DISTRO_DIR + "/TestQMLWidgets.exe",
"./" + DISTRO_DIR + "/basic.exe",
"./" + DISTRO_DIR + "/qt.conf"});
#endif
@ -1227,15 +1249,18 @@ void deploytest::testConfFile() {
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/bin/QtWidgetsProject",
"./" + DISTRO_DIR + "/bin/TestQMLWidgets",
"./" + DISTRO_DIR + "/bin/basic",
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/QtWidgetsProject.sh",
"./" + DISTRO_DIR + "/TestQMLWidgets.sh"});
"./" + DISTRO_DIR + "/TestQMLWidgets.sh",
"./" + DISTRO_DIR + "/basic.sh"});
#else
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "/TestOnlyC.exe",
"./" + DISTRO_DIR + "/qt.conf",
"./" + DISTRO_DIR + "/QtWidgetsProject.exe",
"./" + DISTRO_DIR + "/TestQMLWidgets.exe"});
"./" + DISTRO_DIR + "/TestQMLWidgets.exe",
"./" + DISTRO_DIR + "/basic.exe",
"./" + DISTRO_DIR + "/qt.conf"});
#endif
#ifdef Q_OS_UNIX
@ -1437,14 +1462,16 @@ void deploytest::testConfFile() {
QFile::remove(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json");
auto file = "testCase.json";
#ifdef Q_OS_UNIX
bin = TestBinDir + "QtWidgetsProject," + TestBinDir + "TestOnlyC";
#else
bin = TestBinDir + "QtWidgetsProject.exe," + TestBinDir + "TestOnlyC.exe";
#endif
QVERIFY(utils.deployFile(":/testResurces/testRes/testMultiPackageConfig.json", file,
{{"$BIN_DIR", TestBinDir.toLatin1()}}));
{{"$BIN_DIR", bin.toLatin1()}}));
comapareTree = TestModule.onlyC(DISTRO_DIR + "/Dstro1") +
TestModule.qtLibs(DISTRO_DIR + "/Dstro2") +
TestModule.qmlLibs(DISTRO_DIR + "/Dstro2") +
TestModule.qtWebEngine(DISTRO_DIR + "/Dstro2") +
TestModule.qtWebEngineWidgets(DISTRO_DIR + "/Dstro2");
TestModule.qtLibs(DISTRO_DIR + "/Dstro2");
#ifdef Q_OS_LINUX
auto qmlDir = TestBinDir + "/../";
@ -1453,8 +1480,7 @@ void deploytest::testConfFile() {
#endif
runTestParams({"-confFile", file,
"-qmlDir", "Dstro2;" + qmlDir},
runTestParams({"-confFile", file},
&comapareTree);
}

View File

@ -0,0 +1,146 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.VirtualKeyboard 2.1
import "content"
Rectangle {
width: 1280
height: 720
color: "#F6F6F6"
// Only set with CONFIG+=disable-desktop.
property bool handwritingInputPanelActive: false
Flickable {
id: flickable
anchors.fill: parent
contentWidth: content.width
contentHeight: content.height
interactive: contentHeight > height
flickableDirection: Flickable.VerticalFlick
property real scrollMarginVertical: 20
ScrollBar.vertical: ScrollBar {}
MouseArea {
id: content
width: flickable.width
height: textEditors.height + 24
onClicked: focus = true
Column {
id: textEditors
spacing: 15
x: 12
y: 12
width: parent.width - 26
Label {
color: "#565758"
text: "Tap fields to enter text"
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 22
}
TextField {
width: parent.width
placeholderText: "One line field"
enterKeyAction: EnterKeyAction.Next
onAccepted: passwordField.focus = true
}
TextField {
id: passwordField
width: parent.width
echoMode: TextInput.Password
placeholderText: "Password field"
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
enterKeyAction: EnterKeyAction.Next
onAccepted: upperCaseField.focus = true
}
TextField {
id: upperCaseField
width: parent.width
placeholderText: "Upper case field"
inputMethodHints: Qt.ImhUppercaseOnly
enterKeyAction: EnterKeyAction.Next
onAccepted: lowerCaseField.focus = true
}
TextField {
id: lowerCaseField
width: parent.width
placeholderText: "Lower case field"
inputMethodHints: Qt.ImhLowercaseOnly
enterKeyAction: EnterKeyAction.Next
onAccepted: phoneNumberField.focus = true
}
TextField {
id: phoneNumberField
validator: RegExpValidator { regExp: /^[0-9\+\-\#\*\ ]{6,}$/ }
width: parent.width
placeholderText: "Phone number field"
inputMethodHints: Qt.ImhDialableCharactersOnly
enterKeyAction: EnterKeyAction.Next
onAccepted: formattedNumberField.focus = true
}
TextField {
id: formattedNumberField
width: parent.width
placeholderText: "Formatted number field"
inputMethodHints: Qt.ImhFormattedNumbersOnly
enterKeyAction: EnterKeyAction.Next
onAccepted: digitsField.focus = true
}
TextField {
id: digitsField
width: parent.width
placeholderText: "Digits only field"
inputMethodHints: Qt.ImhDigitsOnly
enterKeyAction: EnterKeyAction.Next
onAccepted: textArea.focus = true
}
TextArea {
id: textArea
width: parent.width
placeholderText: "Multiple line field"
height: Math.max(206, implicitHeight)
}
}
}
}
// Hide the text fields' cursors when fullscreen handwriting is active.
MouseArea {
anchors.fill: parent
visible: handwritingInputPanelActive
}
}

View File

@ -0,0 +1,174 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6.
import QtQml 2.14
import QtQuick.Window 2.2
import QtQuick.VirtualKeyboard 2.2
import QtQuick.VirtualKeyboard.Settings 2.2
import "content"
Item {
width: 1280
height: 720
Item {
id: appContainer
width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height
height: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width
anchors.centerIn: parent
Basic {
id: virtualKeyboard
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
handwritingInputPanelActive: handwritingInputPanel.available && handwritingInputPanel.active
}
/* Handwriting input panel for full screen handwriting input.
This component is an optional add-on for the InputPanel component, that
is, its use does not affect the operation of the InputPanel component,
but it also can not be used as a standalone component.
The handwriting input panel is positioned to cover the entire area of
application. The panel itself is transparent, but once it is active the
user can draw handwriting on it.
*/
HandwritingInputPanel {
z: 79
id: handwritingInputPanel
anchors.fill: parent
inputPanel: inputPanel
Rectangle {
z: -1
anchors.fill: parent
color: "black"
opacity: 0.10
}
}
/* Container area for the handwriting mode button.
Handwriting mode button can be moved freely within the container area.
In this example, a single click changes the handwriting mode and a
double-click changes the availability of the full screen handwriting input.
*/
Item {
z: 99
visible: handwritingInputPanel.enabled && Qt.inputMethod.visible
anchors { left: parent.left; top: parent.top; right: parent.right; bottom: inputPanel.top; }
HandwritingModeButton {
id: handwritingModeButton
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 10
floating: true
flipable: true
width: 76
height: width
state: handwritingInputPanel.state
onClicked: handwritingInputPanel.active = !handwritingInputPanel.active
onDoubleClicked: handwritingInputPanel.available = !handwritingInputPanel.available
}
}
/* Keyboard input panel.
The keyboard is anchored to the bottom of the application.
*/
InputPanel {
id: inputPanel
z: 89
y: yPositionWhenHidden
x: Screen.orientation === Qt.LandscapeOrientation ? 0 : (parent.width-parent.height) / 2
width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height
keyboard.shadowInputControl.height: (Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width) - keyboard.height
property real yPositionWhenHidden: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width + (parent.height-parent.width) / 2
states: State {
name: "visible"
/* The visibility of the InputPanel can be bound to the Qt.inputMethod.visible property,
but then the handwriting input panel and the keyboard input panel can be visible
at the same time. Here the visibility is bound to InputPanel.active property instead,
which allows the handwriting panel to control the visibility when necessary.
*/
when: inputPanel.active
PropertyChanges {
target: inputPanel
y: inputPanel.yPositionWhenHidden - inputPanel.height
}
}
transitions: Transition {
id: inputPanelTransition
from: ""
to: "visible"
reversible: true
enabled: !VirtualKeyboardSettings.fullScreenMode
ParallelAnimation {
NumberAnimation {
properties: "y"
duration: 250
easing.type: Easing.InOutQuad
}
}
}
Binding {
target: InputContext
property: "animating"
value: inputPanelTransition.running
restoreMode: Binding.RestoreBinding
}
AutoScroller {}
}
Binding {
target: VirtualKeyboardSettings
property: "fullScreenMode"
value: appContainer.height > 0 && (appContainer.width / appContainer.height) > (16.0 / 9.0)
restoreMode: Binding.RestoreBinding
}
}
property bool inLandscapeOrientation: Screen.orientation === Qt.LandscapeOrientation
Screen.orientationUpdateMask: Qt.LandscapeOrientation | Qt.PortraitOrientation
Binding {
target: appContainer.Window.window !== null ? appContainer.Window.window.contentItem : null
property: "rotation"
value: inLandscapeOrientation ? 0 : 90
}
}

View File

@ -0,0 +1,35 @@
TEMPLATE = app
TARGET = basic
QT += qml quick
SOURCES += main.cpp
CONFIG += link_pkgconfig
static {
QT += svg
QTPLUGIN += qtvirtualkeyboardplugin
}
target.path = $$[QT_INSTALL_EXAMPLES]/virtualkeyboard/basic
INSTALLS += target
RESOURCES += \
demo.qrc
OTHER_FILES += \
Basic.qml \
basic-b2qt.qml \
content/AutoScroller.qml \
content/HandwritingModeButton.qml \
content/TextArea.qml \
content/TextField.qml \
disable-xcb {
message("The disable-xcb option has been deprecated. Please use disable-desktop instead.")
CONFIG += disable-desktop
}
disable-desktop|android-embedded|!isEmpty(CROSS_COMPILE)|qnx {
DEFINES += MAIN_QML=\\\"basic-b2qt.qml\\\"
} else {
DEFINES += MAIN_QML=\\\"Basic.qml\\\"
}
DESTDIR="$$PWD/../../build"

View File

@ -0,0 +1,104 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
import QtQuick.VirtualKeyboard 2.1
Item {
property var innerFlickable
property var outerFlickable
property var inputItem: InputContext.priv.inputItem
onInputItemChanged: {
innerFlickable = null
outerFlickable = null
if (inputItem !== null) {
var parent_ = inputItem.parent
while (parent_) {
if (parent_.maximumFlickVelocity) {
if (innerFlickable) {
outerFlickable = parent_
break
} else {
innerFlickable = parent_
}
}
parent_ = parent_.parent
}
delayedLoading.restart()
}
}
function ensureVisible(flickable) {
if (Qt.inputMethod.visible && inputItem && flickable && flickable.visible && flickable.interactive) {
var verticallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.VerticalFlick
|| (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentHeight > flickable.height))
var horizontallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.HorizontalFlick
|| (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentWidth > flickable.width))
if ((!verticallyFlickable && !horizontallyFlickable) || !inputItem.hasOwnProperty("cursorRectangle"))
return
var cursorRectangle = flickable.contentItem.mapFromItem(inputItem, inputItem.cursorRectangle.x, inputItem.cursorRectangle.y)
var oldContentY = flickable.contentY
if (verticallyFlickable) {
var scrollMarginVertical = (flickable && flickable.scrollMarginVertical) ? flickable.scrollMarginVertical : 10
if (flickable.contentY >= cursorRectangle.y - scrollMarginVertical)
flickable.contentY = Math.max(0, cursorRectangle.y - scrollMarginVertical)
else if (flickable.contentY + flickable.height <= cursorRectangle.y + inputItem.cursorRectangle.height + scrollMarginVertical)
flickable.contentY = Math.min(flickable.contentHeight - flickable.height, cursorRectangle.y + inputItem.cursorRectangle.height - flickable.height + scrollMarginVertical)
}
if (horizontallyFlickable) {
var scrollMarginHorizontal = (flickable && flickable.scrollMarginHorizontal) ? flickable.scrollMarginHorizontal : 10
if (flickable.contentX >= cursorRectangle.x - scrollMarginHorizontal)
flickable.contentX = Math.max(0, cursorRectangle.x - scrollMarginHorizontal)
else if (flickable.contentX + flickable.width <= cursorRectangle.x + inputItem.cursorRectangle.width + scrollMarginHorizontal)
flickable.contentX = Math.min(flickable.contentWidth - flickable.width, cursorRectangle.x + inputItem.cursorRectangle.width - flickable.width + scrollMarginHorizontal)
}
}
}
Timer {
id: delayedLoading
interval: 10
onTriggered: {
ensureVisible(innerFlickable)
ensureVisible(outerFlickable)
}
}
Connections {
ignoreUnknownSignals: true
target: Qt.inputMethod
function onAnimatingChanged() { if (inputItem && !Qt.inputMethod.animating) delayedLoading.restart() }
function onKeyboardRectangleChanged() { if (inputItem) delayedLoading.restart() }
function onCursorRectangleChanged() { if (inputItem && inputItem.activeFocus) delayedLoading.restart() }
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="390px" height="390px" viewBox="0 0 390 390" style="enable-background:new 0 0 390 390;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.3;enable-background:new ;}
.st1{opacity:0.5;}
.st2{fill:#FFFFFF;}
.st3{fill:#5CAA15;}
.st4{fill:none;}
</style>
<g id="Active">
<g>
<circle class="st0" cx="195" cy="195" r="191"/>
<g class="st1">
<path class="st2" d="M195,4c105.5,0,191,85.5,191,191s-85.5,191-191,191S4,300.5,4,195S89.5,4,195,4 M195,0
c-26.3,0-51.9,5.2-75.9,15.3c-23.2,9.8-44.1,23.9-62,41.8s-32,38.8-41.8,62C5.2,143.1,0,168.7,0,195s5.2,51.9,15.3,75.9
c9.8,23.2,23.9,44.1,41.8,62s38.8,32,62,41.8c24,10.2,49.6,15.3,75.9,15.3s51.9-5.2,75.9-15.3c23.2-9.8,44.1-23.9,62-41.8
s32-38.8,41.8-62c10.2-24,15.3-49.6,15.3-75.9s-5.2-51.9-15.3-75.9c-9.8-23.2-23.9-44.1-41.8-62s-38.8-32-62-41.8
C246.9,5.2,221.3,0,195,0L195,0z"/>
</g>
</g>
<circle class="st3" cx="195" cy="195" r="141"/>
</g>
<g id="icon">
<g>
<g>
<path class="st2" d="M155.6,247.3c-10.1,0-18.9-5-23.1-13.6c-10.1-21,5.4-37.4,21.7-54.7c1.2-1.2,2.4-2.5,3.6-3.8
c5.3-5.7,5.2-11.5,3.5-14.8c-1.8-3.4-5.5-4.9-10.2-4.2c-16.5,2.6-21.2,26.4-21.2,26.6l-11.9-2.2c0.3-1.3,6.4-32.3,31.2-36.3
c9.8-1.6,18.5,2.4,22.7,10.4c4.7,8.9,2.6,20.1-5.3,28.6c-1.2,1.3-2.4,2.6-3.6,3.8c-16.7,17.8-25.9,28.5-19.6,41.4
c3.3,6.8,11.1,7.6,16.9,6.3c9.2-2.1,19.8-11.1,19.7-29.5c-0.2-28.1,16.2-41.8,30.2-44.9c14.5-3.2,28.4,3.6,34.7,17
c1.3,2.8,2.3,5.4,3.1,8.1c13.3,0.7,25.5,4.3,26,4.4l-3.4,11.5c-0.1,0-9.7-2.8-20.6-3.8c0.5,16.5-8.6,28.9-20.1,34.7
c-11.9,6-24,3.8-28.9-5.2c-3.1-5.6-1.9-14.7,2.9-22.5c7.9-13,21.3-17.4,31.5-18.8c-0.4-1.2-0.9-2.4-1.4-3.4
c-3.9-8.3-12.2-12.4-21.1-10.4c-9.7,2.2-21,12.1-20.8,33.1c0.2,25.5-15.6,38.1-29,41.3C160.5,247,158,247.3,155.6,247.3z
M237.8,197.7c-14,1.5-20.6,8.5-23.4,12.9c-3.3,5.2-3.4,9.8-2.9,10.9c1.6,2.9,7.3,3,13,0.2C235.3,216.2,238.3,206.6,237.8,197.7z
"/>
</g>
<rect x="118" y="144" class="st4" width="156" height="104"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="390px" height="390px" viewBox="0 0 390 390" style="enable-background:new 0 0 390 390;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.3;enable-background:new ;}
.st1{opacity:0.5;}
.st2{fill:#FFFFFF;}
.st3{fill:#26282A;}
.st4{fill:none;}
</style>
<g id="Available">
<g>
<circle class="st0" cx="195" cy="195" r="191"/>
<g class="st1">
<path class="st2" d="M195,4c105.5,0,191,85.5,191,191s-85.5,191-191,191S4,300.5,4,195S89.5,4,195,4 M195,0
c-26.3,0-51.9,5.2-75.9,15.3c-23.2,9.8-44.1,23.9-62,41.8s-32,38.8-41.8,62C5.2,143.1,0,168.7,0,195s5.2,51.9,15.3,75.9
c9.8,23.2,23.9,44.1,41.8,62s38.8,32,62,41.8c24,10.2,49.6,15.3,75.9,15.3s51.9-5.2,75.9-15.3c23.2-9.8,44.1-23.9,62-41.8
s32-38.8,41.8-62c10.2-24,15.3-49.6,15.3-75.9s-5.2-51.9-15.3-75.9c-9.8-23.2-23.9-44.1-41.8-62s-38.8-32-62-41.8
C246.9,5.2,221.3,0,195,0L195,0z"/>
</g>
</g>
<circle class="st3" cx="195" cy="195" r="141"/>
</g>
<g id="icon">
<g>
<g>
<path class="st2" d="M155.6,247.3c-10.1,0-18.9-5-23.1-13.6c-10.1-21,5.4-37.4,21.7-54.7c1.2-1.2,2.4-2.5,3.6-3.8
c5.3-5.7,5.2-11.5,3.5-14.8c-1.8-3.4-5.5-4.9-10.2-4.2c-16.5,2.6-21.2,26.4-21.2,26.6l-11.9-2.2c0.3-1.3,6.4-32.3,31.2-36.3
c9.8-1.6,18.5,2.4,22.7,10.4c4.7,8.9,2.6,20.1-5.3,28.6c-1.2,1.3-2.4,2.6-3.6,3.8c-16.7,17.8-25.9,28.5-19.6,41.4
c3.3,6.8,11.1,7.6,16.9,6.3c9.2-2.1,19.8-11.1,19.7-29.5c-0.2-28.1,16.2-41.8,30.2-44.9c14.5-3.2,28.4,3.6,34.7,17
c1.3,2.8,2.3,5.4,3.1,8.1c13.3,0.7,25.5,4.3,26,4.4l-3.4,11.5c-0.1,0-9.7-2.8-20.6-3.8c0.5,16.5-8.6,28.9-20.1,34.7
c-11.9,6-24,3.8-28.9-5.2c-3.1-5.6-1.9-14.7,2.9-22.5c7.9-13,21.3-17.4,31.5-18.8c-0.4-1.2-0.9-2.4-1.4-3.4
c-3.9-8.3-12.2-12.4-21.1-10.4c-9.7,2.2-21,12.1-20.8,33.1c0.2,25.5-15.6,38.1-29,41.3C160.5,247,158,247.3,155.6,247.3z
M237.8,197.7c-14,1.5-20.6,8.5-23.4,12.9c-3.3,5.2-3.4,9.8-2.9,10.9c1.6,2.9,7.3,3,13,0.2C235.3,216.2,238.3,206.6,237.8,197.7z
"/>
</g>
<rect x="118" y="144" class="st4" width="156" height="104"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="390px" height="390px" viewBox="0 0 390 390" style="enable-background:new 0 0 390 390;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.3;enable-background:new ;}
.st1{opacity:0.5;}
.st2{fill:#FFFFFF;}
.st3{fill:none;}
</style>
<g id="Unavailable">
<g>
<circle class="st0" cx="195" cy="195" r="191"/>
<g class="st1">
<path class="st2" d="M195,4c105.5,0,191,85.5,191,191s-85.5,191-191,191S4,300.5,4,195S89.5,4,195,4 M195,0
c-26.3,0-51.9,5.2-75.9,15.3c-23.2,9.8-44.1,23.9-62,41.8s-32,38.8-41.8,62C5.2,143.1,0,168.7,0,195s5.2,51.9,15.3,75.9
c9.8,23.2,23.9,44.1,41.8,62s38.8,32,62,41.8c24,10.2,49.6,15.3,75.9,15.3s51.9-5.2,75.9-15.3c23.2-9.8,44.1-23.9,62-41.8
s32-38.8,41.8-62c10.2-24,15.3-49.6,15.3-75.9s-5.2-51.9-15.3-75.9c-9.8-23.2-23.9-44.1-41.8-62s-38.8-32-62-41.8
C246.9,5.2,221.3,0,195,0L195,0z"/>
</g>
</g>
</g>
<g id="icon">
<g>
<g>
<path class="st2" d="M155.6,247.3c-10.1,0-18.9-5-23.1-13.6c-10.1-21,5.4-37.4,21.7-54.7c1.2-1.2,2.4-2.5,3.6-3.8
c5.3-5.7,5.2-11.5,3.5-14.8c-1.8-3.4-5.5-4.9-10.2-4.2c-16.5,2.6-21.2,26.4-21.2,26.6l-11.9-2.2c0.3-1.3,6.4-32.3,31.2-36.3
c9.8-1.6,18.5,2.4,22.7,10.4c4.7,8.9,2.6,20.1-5.3,28.6c-1.2,1.3-2.4,2.6-3.6,3.8c-16.7,17.8-25.9,28.5-19.6,41.4
c3.3,6.8,11.1,7.6,16.9,6.3c9.2-2.1,19.8-11.1,19.7-29.5c-0.2-28.1,16.2-41.8,30.2-44.9c14.5-3.2,28.4,3.6,34.7,17
c1.3,2.8,2.3,5.4,3.1,8.1c13.3,0.7,25.5,4.3,26,4.4l-3.4,11.5c-0.1,0-9.7-2.8-20.6-3.8c0.5,16.5-8.6,28.9-20.1,34.7
c-11.9,6-24,3.8-28.9-5.2c-3.1-5.6-1.9-14.7,2.9-22.5c7.9-13,21.3-17.4,31.5-18.8c-0.4-1.2-0.9-2.4-1.4-3.4
c-3.9-8.3-12.2-12.4-21.1-10.4c-9.7,2.2-21,12.1-20.8,33.1c0.2,25.5-15.6,38.1-29,41.3C160.5,247,158,247.3,155.6,247.3z
M237.8,197.7c-14,1.5-20.6,8.5-23.4,12.9c-3.3,5.2-3.4,9.8-2.9,10.9c1.6,2.9,7.3,3,13,0.2C235.3,216.2,238.3,206.6,237.8,197.7z
"/>
</g>
<rect x="118" y="144" class="st3" width="156" height="104"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,165 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
Item {
id: handwritingModeButton
state: "unavailable"
property bool floating
property bool flipable
readonly property real __minWidthHeight: Math.min(width, height)
signal clicked()
signal doubleClicked()
Flipable {
id: flipableImage
anchors.fill: parent
property bool flipped
front: Image {
sourceSize.width: handwritingModeButton.__minWidthHeight
sourceSize.height: handwritingModeButton.__minWidthHeight
smooth: false
source: "qrc:/content/FloatingButton_Unavailable.svg"
}
back: Image {
id: buttonImage
sourceSize.width: handwritingModeButton.__minWidthHeight
sourceSize.height: handwritingModeButton.__minWidthHeight
smooth: false
source: "qrc:/content/FloatingButton_Available.svg"
}
states: State {
PropertyChanges { target: rotation; angle: 180 }
when: flipableImage.flipped
}
transform: Rotation {
id: rotation
origin.x: flipableImage.width / 2
origin.y: flipableImage.height / 2
axis { x: 0; y: 1; z: 0 }
angle: 0
}
transitions: Transition {
enabled: handwritingModeButton.flipable
NumberAnimation { target: rotation; property: "angle"; duration: 400 }
}
}
states: [
State {
name: "available"
PropertyChanges { target: flipableImage; flipped: true }
},
State {
name: "active"
PropertyChanges { target: flipableImage; flipped: true }
PropertyChanges { target: buttonImage; source: "qrc:/content/FloatingButton_Active.svg" }
}
]
function snapHorizontal() {
if (!floating)
return
if (mouseArea.drag.maximumX > mouseArea.drag.minimumX) {
if (x + 20 >= mouseArea.drag.maximumX) {
anchors.left = undefined
anchors.right = parent.right
} else if (x - 20 <= mouseArea.drag.minimumX) {
anchors.right = undefined
anchors.left = parent.left
}
}
}
function snapVertical() {
if (!floating)
return
if (mouseArea.drag.maximumY > mouseArea.drag.minimumY) {
if (y + 20 >= mouseArea.drag.maximumY) {
anchors.top = undefined
anchors.bottom = parent.bottom
} else if (y - 20 <= mouseArea.drag.minimumY) {
anchors.bottom = undefined
anchors.top = parent.top
}
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
drag {
target: handwritingModeButton.floating ? handwritingModeButton : undefined
axis: Drag.XAxis | Drag.YAxis
minimumX: 0
maximumX: handwritingModeButton.parent.width - handwritingModeButton.width
onMaximumXChanged: !mouseArea.drag.active && handwritingModeButton.snapHorizontal()
minimumY: 0
maximumY: handwritingModeButton.parent.height - handwritingModeButton.height
onMaximumYChanged: !mouseArea.drag.active && handwritingModeButton.snapVertical()
}
onPressed: {
if (!handwritingModeButton.floating)
return
handwritingModeButton.anchors.left = undefined
handwritingModeButton.anchors.top = undefined
handwritingModeButton.anchors.right = undefined
handwritingModeButton.anchors.bottom = undefined
}
onReleased: {
handwritingModeButton.snapHorizontal()
handwritingModeButton.snapVertical()
}
onClicked: {
handwritingModeButton.snapHorizontal()
handwritingModeButton.snapVertical()
clickTimer.restart()
}
onDoubleClicked: {
clickTimer.stop()
handwritingModeButton.snapHorizontal()
handwritingModeButton.snapVertical()
handwritingModeButton.doubleClicked()
}
Timer {
id: clickTimer
interval: Qt.styleHints ? Qt.styleHints.mouseDoubleClickInterval / 3 : 0
repeat: false
onTriggered: handwritingModeButton.clicked()
}
}
}

View File

@ -0,0 +1,53 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.10
import QtQuick.Controls 2.3 as Controls
import QtQuick.VirtualKeyboard 2.3
Controls.TextArea {
id: control
color: "#2B2C2E"
selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15)
selectedTextColor: color
selectByMouse: true
font.pixelSize: Qt.application.font.pixelSize * 2
property int enterKeyAction: EnterKeyAction.None
readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || text.length > 0 || inputMethodComposing
EnterKeyAction.actionId: control.enterKeyAction
EnterKeyAction.enabled: control.enterKeyEnabled
background: Rectangle {
color: "#FFFFFF"
border.width: 1
border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF"
}
}

View File

@ -0,0 +1,53 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.10
import QtQuick.Controls 2.3 as Controls
import QtQuick.VirtualKeyboard 2.3
Controls.TextField {
id: control
color: "#2B2C2E"
selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15)
selectedTextColor: color
selectByMouse: true
font.pixelSize: Qt.application.font.pixelSize * 2
property int enterKeyAction: EnterKeyAction.None
readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || acceptableInput || inputMethodComposing
EnterKeyAction.actionId: control.enterKeyAction
EnterKeyAction.enabled: control.enterKeyEnabled
background: Rectangle {
color: "#FFFFFF"
border.width: 1
border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF"
}
}

View File

@ -0,0 +1,13 @@
<RCC>
<qresource prefix="/">
<file>content/AutoScroller.qml</file>
<file>content/TextArea.qml</file>
<file>content/TextField.qml</file>
<file>content/HandwritingModeButton.qml</file>
<file>content/FloatingButton_Active.svg</file>
<file>content/FloatingButton_Available.svg</file>
<file>content/FloatingButton_Unavailable.svg</file>
<file>Basic.qml</file>
<file>basic-b2qt.qml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,47 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QQuickView>
#include <QGuiApplication>
#include <QQmlEngine>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QGuiApplication app(argc, argv);
QQuickView view(QString("qrc:/%2").arg(MAIN_QML));
if (view.status() == QQuickView::Error)
return -1;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}

View File

@ -0,0 +1,3 @@
TEMPLATE = subdirs
qtHaveModule(quickcontrols2): SUBDIRS += basic