From fb1aeaf67ce6bcb98b7f5cfc5b36be338cfc8afd Mon Sep 17 00:00:00 2001 From: Dorian Zedler Date: Sun, 11 Oct 2020 15:50:13 +0200 Subject: [PATCH] added connect page --- OmobiDisplayApp/OmobiDisplayApp.pro | 10 +- OmobiDisplayApp/QBluetoothLeUart | 2 +- OmobiDisplayApp/main.cpp | 3 + OmobiDisplayApp/main.qml | 54 ----- OmobiDisplayApp/omobidisplaybackend.cpp | 63 ++++-- OmobiDisplayApp/omobidisplaybackend.h | 18 +- .../ressources/qml/ConnectPage.qml | 194 ++++++++++++++++++ .../ressources/qml/ConnectedPage.qml | 28 +++ OmobiDisplayApp/ressources/qml/main.qml | 111 ++++++++++ OmobiDisplayApp/{ => ressources/qml}/qml.qrc | 2 + OmobiDisplayApp/ressources/shared/itsblue.png | Bin 0 -> 14032 bytes OmobiDisplayApp/ressources/shared/omobi.png | Bin 0 -> 7304 bytes OmobiDisplayApp/ressources/shared/shared.qrc | 6 + OmobiDisplayApp/test.qmodel | 55 +++++ OmobiDisplayApp/testChart.scxml | 3 + 15 files changed, 474 insertions(+), 75 deletions(-) delete mode 100644 OmobiDisplayApp/main.qml create mode 100644 OmobiDisplayApp/ressources/qml/ConnectPage.qml create mode 100644 OmobiDisplayApp/ressources/qml/ConnectedPage.qml create mode 100644 OmobiDisplayApp/ressources/qml/main.qml rename OmobiDisplayApp/{ => ressources/qml}/qml.qrc (53%) create mode 100644 OmobiDisplayApp/ressources/shared/itsblue.png create mode 100644 OmobiDisplayApp/ressources/shared/omobi.png create mode 100644 OmobiDisplayApp/ressources/shared/shared.qrc create mode 100644 OmobiDisplayApp/test.qmodel create mode 100644 OmobiDisplayApp/testChart.scxml diff --git a/OmobiDisplayApp/OmobiDisplayApp.pro b/OmobiDisplayApp/OmobiDisplayApp.pro index c21201f..7570e3d 100644 --- a/OmobiDisplayApp/OmobiDisplayApp.pro +++ b/OmobiDisplayApp/OmobiDisplayApp.pro @@ -16,7 +16,9 @@ SOURCES += \ HEADERS += \ omobidisplaybackend.h -RESOURCES += qml.qrc +RESOURCES += \ + ressources/qml/qml.qrc \ + ressources/shared/shared.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = @@ -31,3 +33,9 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin CONFIG += QBluetoothLeUart_QML include($$PWD/QBluetoothLeUart/QBluetoothLeUart.pri) + +DISTFILES += \ + test.qmodel + +STATECHARTS += \ + testChart.scxml diff --git a/OmobiDisplayApp/QBluetoothLeUart b/OmobiDisplayApp/QBluetoothLeUart index 049951e..60d10f0 160000 --- a/OmobiDisplayApp/QBluetoothLeUart +++ b/OmobiDisplayApp/QBluetoothLeUart @@ -1 +1 @@ -Subproject commit 049951ebed550535f7666fa849405ee835fc7e81 +Subproject commit 60d10f056b53b1816bd97559ad2d7527bbc158a8 diff --git a/OmobiDisplayApp/main.cpp b/OmobiDisplayApp/main.cpp index 857793b..c25f814 100644 --- a/OmobiDisplayApp/main.cpp +++ b/OmobiDisplayApp/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "omobidisplaybackend.h" @@ -13,6 +14,8 @@ int main(int argc, char *argv[]) qmlRegisterType("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayBackend"); QBluetoothLeUart::init(); + QQuickStyle::setStyle("Material"); + QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, diff --git a/OmobiDisplayApp/main.qml b/OmobiDisplayApp/main.qml deleted file mode 100644 index 377b76f..0000000 --- a/OmobiDisplayApp/main.qml +++ /dev/null @@ -1,54 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.0 -import QtQuick.Window 2.12 -import de.itsblue.omobidisplayapp 1.0 -import de.itsblue.bluetoothleuart 1.0 - -ApplicationWindow { - width: 640 - height: 480 - visible: true - title: qsTr("Hello World") - - Page { - id: app - - anchors.fill: parent - - OmobiDisplayBackend { - id: backend - } - - Button { - id: connectButton - text: "Scan for devices" - - visible: backend.bleController.state === QBluetoothLeUART.Idle - - onClicked: { - backend.bleController.startScanningForDevices() - } - } - - ListView { - id: list - anchors.top: connectButton.bottom - anchors.margins: 10 - - height: parent.height - - model: backend.bleController.avaliableDevices.length - - delegate: Button { - property var thisDevice: backend.bleController.avaliableDevices[index] - - text: thisDevice["name"] - - onClicked: { - backend.bleController.connectToDevice(thisDevice["id"]) - } - - } - } - } -} diff --git a/OmobiDisplayApp/omobidisplaybackend.cpp b/OmobiDisplayApp/omobidisplaybackend.cpp index 3b3ec13..26ca122 100644 --- a/OmobiDisplayApp/omobidisplaybackend.cpp +++ b/OmobiDisplayApp/omobidisplaybackend.cpp @@ -2,13 +2,15 @@ OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent) { - this->ble = new QBluetoothLeUart(); connect(this->ble, &QBluetoothLeUart::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange); connect(this->ble, &QBluetoothLeUart::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice); connect(this->ble, &QBluetoothLeUart::dataReceived, this, &OmobiDisplayBackend::DataHandler); connect(this->ble, &QBluetoothLeUart::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected); + + this->setState(Idle); + this->ble->startScanningForDevices(); } @@ -17,24 +19,36 @@ void OmobiDisplayBackend::startScanning() { } void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state){ - - qDebug() << state; - switch(state){ - case QBluetoothLeUart::AcquireData: - { - qDebug() << "Now acquiring data!"; - - /* Initialise Slot DataHandler(QString) - gets new data */ - - this->ble->sendData("Hat geklappt"); - break; - } - default: - //nothing for now + case QBluetoothLeUart::Idle: { + this->setState(Idle); break; - - + } + case QBluetoothLeUart::Scanning: { + this->setState(Scanning); + break; + } + case QBluetoothLeUart::ScanFinished: { + this->setState(ReadyToConnect); + break; + } + case QBluetoothLeUart::Connecting: { + this->setState(Connecting); + break; + } + case QBluetoothLeUart::ScanningForService: { + this->setState(Connecting); + break; + } + case QBluetoothLeUart::ServiceFound: { + this->setState(Connecting); + break; + } + case QBluetoothLeUart::Connected: + { + this->setState(Connected); + break; + } } } @@ -55,3 +69,18 @@ void OmobiDisplayBackend::DataHandler(const QString &s){ QBluetoothLeUart* OmobiDisplayBackend::getBleController() { return this->ble; } + +OmobiDisplayBackend::OmobiDisplayAppState OmobiDisplayBackend::getState() { + return this->state; +} + +void OmobiDisplayBackend::setState(OmobiDisplayAppState state) { + if(state == this->state) + return; + + this->state = state; + emit this->stateChanged(); + + if(this->state == Idle) + this->ble->startScanningForDevices(); +} diff --git a/OmobiDisplayApp/omobidisplaybackend.h b/OmobiDisplayApp/omobidisplaybackend.h index 9aa02f7..4a2d0a2 100644 --- a/OmobiDisplayApp/omobidisplaybackend.h +++ b/OmobiDisplayApp/omobidisplaybackend.h @@ -8,16 +8,27 @@ class OmobiDisplayBackend : public QObject { Q_OBJECT Q_PROPERTY(QBluetoothLeUart* bleController READ getBleController NOTIFY bleControllerChanged) + Q_PROPERTY(OmobiDisplayAppState state READ getState WRITE setState NOTIFY stateChanged) public: explicit OmobiDisplayBackend(QObject *parent = nullptr); - Q_INVOKABLE void startScanning(); + enum OmobiDisplayAppState { + Idle, + Scanning, + ReadyToConnect, + Connecting, + Connected + }; + Q_ENUM(OmobiDisplayAppState) private: + OmobiDisplayAppState state; QBluetoothLeUart *ble; public slots: - QBluetoothLeUart* getBleController(); + Q_INVOKABLE void startScanning(); + Q_INVOKABLE QBluetoothLeUart* getBleController(); + Q_INVOKABLE OmobiDisplayAppState getState(); private slots: void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state); @@ -25,7 +36,10 @@ private slots: void DataHandler(const QString &s); void handleBluetoothDeviceConected(); + void setState(OmobiDisplayAppState state); + signals: + void stateChanged(); void bleControllerChanged(); }; diff --git a/OmobiDisplayApp/ressources/qml/ConnectPage.qml b/OmobiDisplayApp/ressources/qml/ConnectPage.qml new file mode 100644 index 0000000..2b2f111 --- /dev/null +++ b/OmobiDisplayApp/ressources/qml/ConnectPage.qml @@ -0,0 +1,194 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.9 +import QtQuick.Layouts 1.0 +import de.itsblue.omobidisplayapp 1.0 +import de.itsblue.bluetoothleuart 1.0 +import QtQuick.Controls.Material 2.0 + +Page { + id: root + + property string statusText + property bool working + + ColumnLayout { + anchors { + fill: parent + margins: parent.height * 0.05 + topMargin: 0 + } + + Text { + Layout.preferredWidth: parent.width * 0.6 + Layout.preferredHeight: parent.height * 0.1 + Layout.alignment: Layout.Center + + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + fontSizeMode: Text.Fit + font.pixelSize: 500 + minimumPixelSize: 1 + + text: qsTr("Available devices") + } + + ListView { + id: availableDevicesListView + + Layout.preferredWidth: parent.width + Layout.fillHeight: true + Layout.alignment: Layout.Center + + clip: true + + model: backend.bleController.availableDevicesModel + + add: Transition { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 } + NumberAnimation { property: "scale"; from: 0.9; to: 1; duration: 200 } + } + + remove: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200 } + NumberAnimation { property: "scale"; from: 1; to: 0.9; duration: 200 } + } + + spacing: 5 + + header: ItemDelegate { + id: headerDelegate + + width: parent.width + height: implicitHeight * 0.8 + + topInset: 10 + bottomInset: 10 + + text: root.statusText + + onClicked: backend.bleController.startScanningForDevices() + + Rectangle { + anchors.fill: parent + anchors.topMargin: 10 + anchors.bottomMargin: 10 + color: "transparent" + border.color: "lightgrey" + border.width: 3 + } + + Item { + anchors { + right: parent.right + rightMargin: parent.height * 0.15 + verticalCenter: parent.verticalCenter + } + + height: (parent.height - 20) * 0.7 + width: height + + BusyIndicator { + id: busyIndicator + + anchors.centerIn: parent + + width: parent.width + height: parent.height + + opacity: root.working ? 1:0 + } + } + } + + delegate: ItemDelegate { + width: parent.width + + text: name + + onClicked: backend.bleController.connectToDevice(device) + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "lightgrey" + border.width: 3 + } + } + } + } + + + Popup { + id: connectingPopup + + property bool shouldBeOpened: false + + parent: Overlay.overlay + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + closePolicy: Popup.NoAutoClose + + dim: true + + contentItem: Column { + BusyIndicator { + running: true + } + } + + onShouldBeOpenedChanged: { + if(shouldBeOpened) + connectingPopup.open() + else + connectingPopup.close() + } + } + + states: [ + State { + name: OmobiDisplayBackend.Idle + + PropertyChanges { + target: root + statusText: "Tap here to scan" + working: false + } + }, + State { + name: OmobiDisplayBackend.Scanning + + PropertyChanges { + target: root + statusText: "Scanning..." + working: true + } + }, + State { + name: OmobiDisplayBackend.ReadyToConnect + + PropertyChanges { + target: root + statusText: availableDevicesListView.model.rowCount() > 0 ? "Please select a device or tap to scan again":"No devices found. Tap to scan again" + working: false + } + }, + State { + name: OmobiDisplayBackend.Connecting + + PropertyChanges { + target: availableDevicesListView + enabled: false + } + + PropertyChanges { + target: root + statusText: "trying to connect..." + working: true + } + } + ] +} diff --git a/OmobiDisplayApp/ressources/qml/ConnectedPage.qml b/OmobiDisplayApp/ressources/qml/ConnectedPage.qml new file mode 100644 index 0000000..49396eb --- /dev/null +++ b/OmobiDisplayApp/ressources/qml/ConnectedPage.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.9 +import QtQuick.Layouts 1.0 +import de.itsblue.omobidisplayapp 1.0 +import de.itsblue.bluetoothleuart 1.0 + +Page { + id: root + + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + + TextField { + id: newTextInput + Layout.fillWidth: true + Layout.preferredHeight: 50 + } + + Button { + Layout.fillWidth: true + + onClicked: { + backend.bleController.sendData(newTextInput.text) + } + } + } +} diff --git a/OmobiDisplayApp/ressources/qml/main.qml b/OmobiDisplayApp/ressources/qml/main.qml new file mode 100644 index 0000000..205af20 --- /dev/null +++ b/OmobiDisplayApp/ressources/qml/main.qml @@ -0,0 +1,111 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.0 +import QtQuick.Window 2.12 +import de.itsblue.omobidisplayapp 1.0 +import de.itsblue.bluetoothleuart 1.0 +import QtQuick.Controls.Material 2.0 + +ApplicationWindow { + width: 540 + height: 960 + visible: true + title: qsTr("Hello World") + + Page { + id: app + + state: backend.state + + onStateChanged: { + console.log("new state: " + state) + } + + anchors.fill: parent + + header: ToolBar { + Material.background: "white" + + Image { + anchors.fill: parent + anchors.margins: parent.height * 0.1 + + fillMode: Image.PreserveAspectFit + source: "qrc:/omobi.png" + } + + } + + OmobiDisplayBackend { + id: backend + } + + StackView { + id: mainStack + + anchors.fill: parent + + property Component currentComponent + + onCurrentComponentChanged: { + if(currentComponent != currentItem) + mainStack.replace(currentComponent) + } + + Component { + id: connectPageComp + ConnectPage { + state: app.state + } + } + + Component { + id: connectedPageComp + ConnectedPage { + state: app.state + } + } + } + + states: [ + State { + name: OmobiDisplayBackend.Idle + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + + State { + name: OmobiDisplayBackend.Scanning + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + + State { + name: OmobiDisplayBackend.ReadyToConnect + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + + State { + name: OmobiDisplayBackend.Connecting + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + + State { + name: OmobiDisplayBackend.Connected + PropertyChanges { + target: mainStack + currentComponent: connectedPageComp + } + } + ] + } +} diff --git a/OmobiDisplayApp/qml.qrc b/OmobiDisplayApp/ressources/qml/qml.qrc similarity index 53% rename from OmobiDisplayApp/qml.qrc rename to OmobiDisplayApp/ressources/qml/qml.qrc index 5f6483a..4fd83c3 100644 --- a/OmobiDisplayApp/qml.qrc +++ b/OmobiDisplayApp/ressources/qml/qml.qrc @@ -1,5 +1,7 @@ main.qml + ConnectPage.qml + ConnectedPage.qml diff --git a/OmobiDisplayApp/ressources/shared/itsblue.png b/OmobiDisplayApp/ressources/shared/itsblue.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ff658c80a83eb9ffcfd20cf54de03f5a4c059a GIT binary patch literal 14032 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 iLk%_5P(uyV1^y4HkVWQ|;z42n0000 + + omobi.png + itsblue.png + + diff --git a/OmobiDisplayApp/test.qmodel b/OmobiDisplayApp/test.qmodel new file mode 100644 index 0000000..2e8f120 --- /dev/null +++ b/OmobiDisplayApp/test.qmodel @@ -0,0 +1,55 @@ + + + + {53c9b534-ff35-4fc2-bbb2-1ecf37f46c4a} + + + + + + + + {3502968e-5cd9-4ab0-b3b9-52d8cd1ec0d3} + + + test + + + + + + + {ede58291-b8a9-4a30-9631-1771046708c7} + + + + + + + + + + {ede58291-b8a9-4a30-9631-1771046708c7} + + + test + + + + + + + + + + + + + + + + + + + + diff --git a/OmobiDisplayApp/testChart.scxml b/OmobiDisplayApp/testChart.scxml new file mode 100644 index 0000000..5ea579d --- /dev/null +++ b/OmobiDisplayApp/testChart.scxml @@ -0,0 +1,3 @@ + + +