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 0000000..a9ff658 Binary files /dev/null and b/OmobiDisplayApp/ressources/shared/itsblue.png differ diff --git a/OmobiDisplayApp/ressources/shared/omobi.png b/OmobiDisplayApp/ressources/shared/omobi.png new file mode 100644 index 0000000..5c2b8ed Binary files /dev/null and b/OmobiDisplayApp/ressources/shared/omobi.png differ diff --git a/OmobiDisplayApp/ressources/shared/shared.qrc b/OmobiDisplayApp/ressources/shared/shared.qrc new file mode 100644 index 0000000..8be7d48 --- /dev/null +++ b/OmobiDisplayApp/ressources/shared/shared.qrc @@ -0,0 +1,6 @@ + + + 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 @@ + + +