From 8d213efa75d65d3117bc4e6c842d89b2aa38bb1f Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Tue, 8 May 2018 11:42:22 +0300 Subject: [PATCH] introduce test 'controls gallery' application for controls testing --- .../resources/qml/controls-uit/SpinBox.qml | 4 + libraries/ui/src/FileDialogHelper.cpp | 2 +- scripts/developer/tests/ControlsGallery.qml | 103 +++++++++++ scripts/developer/tests/Introspector.qml | 166 ++++++++++++++++++ scripts/developer/tests/controlsGallery.js | 23 +++ tests-manual/ui/qml/ControlsGalleryWindow.qml | 14 ++ tests-manual/ui/qmlscratch.pro | 5 +- tests-manual/ui/src/main.cpp | 18 +- 8 files changed, 331 insertions(+), 4 deletions(-) create mode 100644 scripts/developer/tests/ControlsGallery.qml create mode 100644 scripts/developer/tests/Introspector.qml create mode 100644 scripts/developer/tests/controlsGallery.js create mode 100644 tests-manual/ui/qml/ControlsGalleryWindow.qml diff --git a/interface/resources/qml/controls-uit/SpinBox.qml b/interface/resources/qml/controls-uit/SpinBox.qml index 9d63122dbc..7a1d064191 100644 --- a/interface/resources/qml/controls-uit/SpinBox.qml +++ b/interface/resources/qml/controls-uit/SpinBox.qml @@ -17,6 +17,10 @@ import "../controls-uit" as HifiControls SpinBox { id: spinBox + HifiConstants { + id: hifi + } + property int colorScheme: hifi.colorSchemes.light readonly property bool isLightColorScheme: colorScheme === hifi.colorSchemes.light property string label: "" diff --git a/libraries/ui/src/FileDialogHelper.cpp b/libraries/ui/src/FileDialogHelper.cpp index 6d14adf1db..54eb1fc36b 100644 --- a/libraries/ui/src/FileDialogHelper.cpp +++ b/libraries/ui/src/FileDialogHelper.cpp @@ -52,7 +52,7 @@ QUrl FileDialogHelper::pathToUrl(const QString& path) { QUrl FileDialogHelper::saveHelper(const QString& saveText, const QUrl& currentFolder, const QStringList& selectionFilters) { - qDebug(uiLogging) << "Calling save helper with " << saveText << " " << currentFolder << " " << selectionFilters; + // qDebug(uiLogging) << "Calling save helper with " << saveText << " " << currentFolder << " " << selectionFilters; QFileInfo fileInfo(saveText); diff --git a/scripts/developer/tests/ControlsGallery.qml b/scripts/developer/tests/ControlsGallery.qml new file mode 100644 index 0000000000..ceb8a26dc9 --- /dev/null +++ b/scripts/developer/tests/ControlsGallery.qml @@ -0,0 +1,103 @@ +import QtQuick 2.10 +import QtQuick.Window 2.10 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import "qrc:////qml//styles-uit" as HifiStylesUit +import "qrc:////qml//controls-uit" as HifiControlsUit + +//uncomment to use from qmlscratch tool +//import '../../../interface/resources/qml/controls-uit' as HifiControlsUit +//import '../../../interface/resources/qml/styles-uit' + +//uncomment to use with HIFI_USE_SOURCE_TREE_RESOURCES=1 +//import '../../../resources/qml/controls-uit' as HifiControlsUit +//import '../../../resources/qml/styles-uit' + +Item { + visible: true + width: 640 + height: 480 + + Introspector { + id: introspector + properties: ['realFrom', 'realTo', 'realValue', 'realStepSize', 'decimals'] + visible: true + y: 50 + x: 130 + } + + HifiStylesUit.HifiConstants { + id: hifi + } + + TabBar { + id: bar + width: parent.width + TabButton { + text: "Spinbox" + } + TabButton { + text: "... Other Controls" + } + } + + StackLayout { + id: controlsLayout + currentIndex: bar.currentIndex + anchors.top: bar.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 20 + + Item { + id: spinboxTab + anchors.fill: parent + + Column { + spacing: 20 + + HifiControlsUit.SpinBox { + realValue: 5.0 + realFrom: 16.0 + realTo: 20.0 + decimals: 2 + realStepSize: 0.01 + + width: 100 + height: 30 + + colorScheme: hifi.colorSchemes.dark + + onFocusChanged: { + if(focus) { + introspector.object = this + } + } + } + + HifiControlsUit.SpinBox { + realValue: 5.0 + realFrom: 1.0 + realTo: 20.0 + decimals: 2 + realStepSize: 0.01 + + width: 100 + height: 30 + + colorScheme: hifi.colorSchemes.light + + onFocusChanged: { + if(focus) { + introspector.object = this + } + } + } + } + } + Item { + id: otherTab + } + } +} diff --git a/scripts/developer/tests/Introspector.qml b/scripts/developer/tests/Introspector.qml new file mode 100644 index 0000000000..d21f5da976 --- /dev/null +++ b/scripts/developer/tests/Introspector.qml @@ -0,0 +1,166 @@ +import QtQuick 2.1; +import QtQuick.Window 2.1; + +MouseArea { + id: base; + opacity: 0.65; + // anchors.fill: parent; + width: 400; + height: 300; + + drag.target: list; + onWheel: { } + + onClicked: { object = null } + property var object: null + onObjectChanged: { + visible = (object != null) + } + + property var properties: [] + onPropertiesChanged: { + console.debug('properties: ', JSON.stringify(properties, 4, 0)) + } + + function getPropertiesList(obj) { + var props = []; + var propertiesObject = obj; + if(properties.length !== 0) { + propertiesObject = {}; + for(var i = 0; i < properties.length; ++i) { + propertiesObject[properties[i]] = properties[i]; + } + } + + for(var prop in propertiesObject) { + + var info = {'name' : prop}; + var value = obj[prop]; + var typeOfValue = typeof(value); + + if(typeof(value) === 'string') { + info['type'] = 'string' + } else if(typeof(value) === 'number') { + if(Number.isInteger(value)) + info['type'] = 'int' + else + info['type'] = 'float' + } else if(typeof(value) === 'boolean') { + info['type'] = 'boolean' + } else if(typeof(value) === 'function') { + continue; + } + + /* + if(prop !== 'parent' && prop !== 'data' && prop !== 'children') + console.debug('typeof(value): ', typeof(value), JSON.stringify(value, null, 4)); + */ + + info['subName'] = '' + props.push(info); + } + + return props; + } + + Rectangle { + color: "lightgray"; + anchors.fill: list; + anchors.margins: -50; + } + ListView { + id: list; + x: 50; + y: 50; + width: 400; + height: 300; + spacing: 5; + model: object !== null ? getPropertiesList(object) : []; + header: Text { + text: object !== null ? object.toString () : ''; + font.bold: true; + font.pixelSize: 20; + } + delegate: Row { + spacing: 20; + + Column { + width: 180; + + Text { + text: (modelData ["subName"] !== "" ? (modelData ["name"] + "." + modelData ["subName"]) : modelData ["name"]); + font.pixelSize: 16; + } + } + Column { + width: 200; + + Text { + text: { + return modelData ["type"] + } + font.pixelSize: 10; + } + TextInput { + id: input; + text: display; + width: parent.width; + font.pixelSize: 16; + font.underline: (text !== display); + Keys.onReturnPressed: { save (); } + Keys.onEnterPressed: { save (); } + Keys.onEscapePressed: { cancel (); } + + property string display : ""; + + function save () { + var tmp; + switch (modelData ["type"]) { + case 'boolean': + tmp = (text === "true" || text === "1"); + break; + case 'float': + tmp = parseFloat (text); + break; + case 'int': + tmp = parseInt (text); + break; + case 'string': + tmp = text; + break; + + default: + break; + } + if (modelData ["subName"] !== "") { + object [modelData ["name"]][modelData ["subName"]] = tmp; + } + else { + object [modelData ["name"]] = tmp; + } + text = display; + } + + function cancel () { + text = display; + } + + Binding on text { value: input.display; } + Binding on display { + value: { + var ret = (modelData ["subName"] !== "" + ? object [modelData ["name"]][modelData ["subName"]] + : object [modelData ["name"]]); + return ret.toString (); + } + } + Rectangle { + z: -1; + color: "white"; + anchors.fill: parent; + } + } + } + } + } +} diff --git a/scripts/developer/tests/controlsGallery.js b/scripts/developer/tests/controlsGallery.js new file mode 100644 index 0000000000..dc3fa7ba3c --- /dev/null +++ b/scripts/developer/tests/controlsGallery.js @@ -0,0 +1,23 @@ +(function() { // BEGIN LOCAL_SCOPE + + console.debug('controlsGallery: creating window') + + var qml = Script.resolvePath('ControlsGallery.qml'); + var qmlWindow = new OverlayWindow({ + title: 'Hifi Controls Gallery', + source: qml, + height: 480, + width: 640, + visible: true + }); + + console.debug('controlsGallery: creating window... done') + + qmlWindow.closed.connect(function() { Script.stop(); }); + + Script.scriptEnding.connect(function() { + console.debug('controlsGallery: end of scripting') + delete qmlWindow; + }); + +}()); // END LOCAL_SCOPE diff --git a/tests-manual/ui/qml/ControlsGalleryWindow.qml b/tests-manual/ui/qml/ControlsGalleryWindow.qml new file mode 100644 index 0000000000..32fd62da36 --- /dev/null +++ b/tests-manual/ui/qml/ControlsGalleryWindow.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import QtQuick.Window 2.3 +import QtQuick.Controls 1.4 +import '../../../scripts/developer/tests' as Tests + +ApplicationWindow { + width: 640 + height: 480 + visible: true + + Tests.ControlsGallery { + anchors.fill: parent + } +} diff --git a/tests-manual/ui/qmlscratch.pro b/tests-manual/ui/qmlscratch.pro index 5c9b91ee52..6b6ec311be 100644 --- a/tests-manual/ui/qmlscratch.pro +++ b/tests-manual/ui/qmlscratch.pro @@ -34,4 +34,7 @@ DISTFILES += \ ../../interface/resources/qml/hifi/toolbars/*.qml \ ../../interface/resources/qml/hifi/dialogs/*.qml \ ../../interface/resources/qml/hifi/dialogs/preferences/*.qml \ - ../../interface/resources/qml/hifi/overlays/*.qml + ../../interface/resources/qml/hifi/overlays/*.qml \ + ../../scripts/developer/tests/Introspector.qml \ + ../../scripts/developer/tests/ControlsGallery.qml \ + qml/ControlsGalleryWindow.qml diff --git a/tests-manual/ui/src/main.cpp b/tests-manual/ui/src/main.cpp index 312b5f3823..19002ed499 100644 --- a/tests-manual/ui/src/main.cpp +++ b/tests-manual/ui/src/main.cpp @@ -95,6 +95,7 @@ int main(int argc, char *argv[]) { app.setApplicationName("Amazing Application"); QDir::setCurrent(getRelativeDir("..")); + /* QtWebEngine::initialize(); qmlRegisterType("Hifi", 1, 0, "Preference"); @@ -117,9 +118,21 @@ int main(int argc, char *argv[]) { setChild(engine, "urlHandler"); engine.rootContext()->setContextProperty("DebugQML", true); engine.rootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); + */ - //engine.load(QUrl(QStringLiteral("qrc:/qml/gallery/main.qml"))); - engine.load(QUrl(QStringLiteral("qml/main.qml"))); + QQmlApplicationEngine engine; + addImportPath(engine, "qml"); + addImportPath(engine, "../../interface/resources/qml"); + addImportPath(engine, "../../interface/resources"); + addImportPath(engine, "../../scripts/developer/tests"); + + QFontDatabase::addApplicationFont("../../interface/resources/fonts/FiraSans-Regular.ttf"); + QFontDatabase::addApplicationFont("../../interface/resources/fonts/FiraSans-SemiBold.ttf"); + QFontDatabase::addApplicationFont("../../interface/resources/fonts/hifi-glyphs.ttf"); + + engine.load(QUrl(QStringLiteral("qml/ControlsGalleryWindow.qml"))); + + /* for (QObject* rootObject : engine.rootObjects()) { if (rootObject->objectName() == "MainWindow") { Reticle* reticle = new Reticle(rootObject); @@ -129,6 +142,7 @@ int main(int argc, char *argv[]) { break; } } + */ return app.exec(); }