From eeb939ed2693d66e5a862894571a0ccd20efd818 Mon Sep 17 00:00:00 2001 From: dorian Date: Fri, 29 Mar 2019 23:42:56 +0100 Subject: [PATCH] - added 'disconnect' functionality for base station - made IP->adress of base station editable - some cleanup --- headers/baseconn.h | 2 + headers/climbingrace.h | 3 + qml/SettingsDialog.qml | 126 +++++++++++++++++--------- qml/components/ConnectionDelegate.qml | 21 +++-- qml/components/ConnectionIcon.qml | 3 + qml/components/InputDelegate.qml | 15 +-- qml/components/NextPageDelegate.qml | 2 + qml/components/SmoothItemDelegate.qml | 11 ++- qml/main.qml | 18 +++- sources/appsettings.cpp | 2 + sources/baseconn.cpp | 36 +++++++- sources/climbingrace.cpp | 37 ++++---- 12 files changed, 198 insertions(+), 78 deletions(-) diff --git a/headers/baseconn.h b/headers/baseconn.h index afcc757..58ad337 100644 --- a/headers/baseconn.h +++ b/headers/baseconn.h @@ -110,6 +110,8 @@ public slots: private slots: void readyRead(); + + void socketStateChanged(QAbstractSocket::SocketState socketState); }; extern BaseConn * pGlobalBaseConn; diff --git a/headers/climbingrace.h b/headers/climbingrace.h index 68a93e0..8b88acb 100644 --- a/headers/climbingrace.h +++ b/headers/climbingrace.h @@ -89,8 +89,11 @@ public slots: Q_INVOKABLE QString readSetting(QString key); Q_INVOKABLE bool connectBaseStation(); + Q_INVOKABLE void disconnectBaseStation(); Q_INVOKABLE QString getBaseStationState(); Q_INVOKABLE QVariant getBaseStationConnections(); + + Q_INVOKABLE bool reloadBaseStationIpAdress(); }; #endif // CLIMBINGRACE_H diff --git a/qml/SettingsDialog.qml b/qml/SettingsDialog.qml index e267c90..00bd862 100644 --- a/qml/SettingsDialog.qml +++ b/qml/SettingsDialog.qml @@ -279,44 +279,6 @@ Popup { } } - /*-----Page to connect to extenstions like a startpad or buzzer-----*/ - Component { - id: connect - Column { - id: connect_col - property string title: qsTr("Base Station") - property int delegateHeight: height * 0.18 - - spacing: options_stack.rowSpacing - - ConnectionDelegate { - id: connect_base_del - text: "connect" - - status: { "status": speedBackend.baseStationState } - connect: speedBackend.connectBaseStation - type: "baseStation" - - width: parent.width - height: options_stack.delegateHeight - - font.pixelSize: height * 0.6 - } - - NextPageDelegate { - id: baseStationConnections_del - text: qsTr("connected extentions") - - width: parent.width - height: options_stack.delegateHeight - - onClicked: { - options_stack.push(baseStationConnections) - } - } - } - } - /*-----Page to setup automatc start sequence-----*/ Component { id: autostart @@ -363,6 +325,8 @@ Popup { enabled: ready_del.checked text: qsTr("delay (ms)") + inputHint: qsTr("time") + inputMethodHints: Qt.ImhFormattedNumbersOnly inputText: autostart_col.loadSetting("ready_delay", ready_del) @@ -386,7 +350,6 @@ Popup { } } - InputDelegate { id: at_marks_delay_del @@ -394,6 +357,8 @@ Popup { height: options_stack.delegateHeight text: qsTr("delay (ms)") + inputHint: qsTr("time") + inputMethodHints: Qt.ImhFormattedNumbersOnly enabled: at_marks_del.checked @@ -406,6 +371,84 @@ Popup { } } + /*-----Page to connect to extenstions like a startpad or buzzer-----*/ + Component { + id: connect + Column { + id: connectCol + property string title: qsTr("Base Station") + + spacing: options_stack.rowSpacing + + function baseConnected(){ + return speedBackend.baseStationState === "connected" + } + + ConnectionDelegate { + id: connectToBaseDel + text: status.status === "connected" ? qsTr("disconnect"): status.status === "disconnected" ? qsTr("connect"):qsTr("connecting...") + + status: { "status": speedBackend.baseStationState } + connect: speedBackend.connectBaseStation + disconnect: speedBackend.disconnectBaseStation + type: "baseStation" + + width: parent.width + height: options_stack.delegateHeight + + font.pixelSize: height * 0.6 + } + + InputDelegate { + id: baseStationIpDel + + text: qsTr("IP-Adress") + + inputHint: "IP" + inputText: speedBackend.readSetting("baseStationIpAdress") + inputTextFieldWidth: width * 0.7 + + onInputTextChanged: { + speedBackend.writeSetting("baseStationIpAdress", inputText) + speedBackend.reloadBaseStationIpAdress() + } + + width: parent.width + height: !connectCol.baseConnected() ? options_stack.delegateHeight:0 + + visible: height > 5 + + Behavior on height { + NumberAnimation { + duration: 400 + easing.type: Easing.Linear + } + } + } + + NextPageDelegate { + id: baseStationConnectionsDel + text: qsTr("connected extensions") + + width: parent.width + height: connectCol.baseConnected() ? options_stack.delegateHeight:0 + + visible: height > 5 + + onClicked: { + options_stack.push(baseStationConnections) + } + + Behavior on height { + NumberAnimation { + duration: 400 + easing.type: Easing.Linear + } + } + } + } + } + /*-----Page to view devices that core connected to the pase startion-----*/ Component{ id: baseStationConnections @@ -419,11 +462,12 @@ Popup { model: speedBackend.baseStationConnections.length delegate: ConnectionDelegate { + + opacity: 1 + width: parent.width height: options_stack.delegateHeight - enabled: false - text: speedBackend.baseStationConnections[index]["name"] status: {'status': speedBackend.baseStationConnections[index]["state"], 'progress': speedBackend.baseStationConnections[index]["progress"]} } diff --git a/qml/components/ConnectionDelegate.qml b/qml/components/ConnectionDelegate.qml index 8e792bb..d0f749a 100644 --- a/qml/components/ConnectionDelegate.qml +++ b/qml/components/ConnectionDelegate.qml @@ -3,18 +3,27 @@ import QtQuick.Controls 2.2 SmoothItemDelegate { id: control + property var status property var connect + property var disconnect + property string type text: qsTr(type) - enabled: status.status === "disconnected" + enabled: (status.status === "disconnected" && control.connect !== undefined) || ( status.status === "connected" && control.disconnect !== undefined ) onClicked: { - connect() - if(status.status !== "connected"){ - statusIndicator.color_override = "red" - shortDelay.start() + + if(status.status === "disconnected"){ + connect() + if(status.status !== "connected"){ + statusIndicator.color_override = "red" + shortDelay.start() + } + } + else { + disconnect() } } @@ -35,7 +44,7 @@ SmoothItemDelegate { rightMargin: ( height / control.height / 2 ) * height verticalCenter: parent.verticalCenter } - height: parent.font.pixelSize * 0.8 + height: control.height * 0.4 width: height Rectangle { diff --git a/qml/components/ConnectionIcon.qml b/qml/components/ConnectionIcon.qml index 0a19e49..1e37004 100644 --- a/qml/components/ConnectionIcon.qml +++ b/qml/components/ConnectionIcon.qml @@ -12,6 +12,7 @@ Image { width: height onOpacityChanged: visible = true + SequentialAnimation { //rotating animation running: status === "connecting" @@ -29,12 +30,14 @@ Image { easing.type: Easing.InOutQuad } } + Behavior on rotation { NumberAnimation { duration: 200 easing.type: Easing.OutQuad } } + Behavior on opacity { NumberAnimation { duration: 200 diff --git a/qml/components/InputDelegate.qml b/qml/components/InputDelegate.qml index 1edcaa3..915efca 100644 --- a/qml/components/InputDelegate.qml +++ b/qml/components/InputDelegate.qml @@ -5,6 +5,11 @@ SmoothItemDelegate { id: control property string inputText: "" + property string inputHint: "" + + property int inputMethodHints: Qt.ImhNone + + property int inputTextFieldWidth: control.width * 0.3 onInputTextChanged: { textField.text = inputText @@ -13,7 +18,7 @@ SmoothItemDelegate { text: qsTr("delay (ms)") width: parent.width - rightPadding: textField.width * 1.2 + rightPadding: textField.width + width * 0.02 height: parent.delegateHeight TextField { @@ -22,17 +27,15 @@ SmoothItemDelegate { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - width: parent.width * 0.3 + width: control.inputTextFieldWidth height: parent.height focus: true - placeholderText: qsTr("time") + placeholderText: control.inputHint font.pixelSize: height * 0.4 - opacity: control.enabled ? 1:0.2 - - inputMethodHints: Qt.ImhFormattedNumbersOnly + inputMethodHints: control.inputMethodHints palette.text: appTheme.style.textColor diff --git a/qml/components/NextPageDelegate.qml b/qml/components/NextPageDelegate.qml index cb72245..6c16109 100644 --- a/qml/components/NextPageDelegate.qml +++ b/qml/components/NextPageDelegate.qml @@ -5,6 +5,8 @@ SmoothItemDelegate { id: control text: "" + rightPadding: forwardImage.width * 1.1 + Image { id: forwardImage source: appTheme.style.backIcon diff --git a/qml/components/SmoothItemDelegate.qml b/qml/components/SmoothItemDelegate.qml index bde655f..a1547de 100644 --- a/qml/components/SmoothItemDelegate.qml +++ b/qml/components/SmoothItemDelegate.qml @@ -7,6 +7,8 @@ ItemDelegate { font.pixelSize: options_stack.text_pixelSize property color textColor: appTheme.style.textColor + opacity: enabled ? 1 : 0.2 + contentItem: Text { visible: false } @@ -27,12 +29,13 @@ ItemDelegate { fontSizeMode: Text.Fit font.pixelSize: control.height * 0.4 + + minimumPixelSize: 0 } width: parent.width background: Rectangle { - opacity: enabled ? 1 : 0.3 color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor radius: height * 0.3 @@ -43,4 +46,10 @@ ItemDelegate { } } } + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + } } diff --git a/qml/main.qml b/qml/main.qml index eca0e9b..10917af 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -209,7 +209,19 @@ Window { } } + scale: 0 + height: !root.landscape()? parent.height*0.17:parent.width*0.17 + + Component.onCompleted: { + scale = 1 + } + + Behavior on scale { + NumberAnimation { + duration: 200 + } + } } } } @@ -226,9 +238,9 @@ Window { visible: false } - /*---------------------- - Start / Stop / Reset button - ----------------------*/ + // ---------------------------------- + // -- Start / Stop / Reset button --- + // ---------------------------------- FancyButton { id : startButt diff --git a/sources/appsettings.cpp b/sources/appsettings.cpp index 9713b14..ec0c601 100644 --- a/sources/appsettings.cpp +++ b/sources/appsettings.cpp @@ -33,6 +33,8 @@ AppSettings::AppSettings(QObject* parent) this->setDefaultSetting("theme", "Light"); + this->setDefaultSetting("baseStationIpAdress", "192.168.4.1"); + pGlobalAppSettings = this; } diff --git a/sources/baseconn.cpp b/sources/baseconn.cpp index 8107412..c14225d 100644 --- a/sources/baseconn.cpp +++ b/sources/baseconn.cpp @@ -11,6 +11,8 @@ BaseConn::BaseConn(QObject *parent) : QObject(parent) connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(gotError(QAbstractSocket::SocketError))); + connect(this->socket, &QAbstractSocket::stateChanged, this, &BaseConn::socketStateChanged); + this->nextConnectionId = 1; this->connections = QVariantList({}); } @@ -54,6 +56,9 @@ bool BaseConn::connectToHost() { void BaseConn::closeConnection() { + this->connections = QVariantList({}); + emit this->connectionsChanged(); + qDebug() << "closing connection"; switch (socket->state()) { @@ -213,6 +218,26 @@ void BaseConn::setState(QString newState){ emit stateChanged(); } +void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) { + switch (socketState) { + case QAbstractSocket::UnconnectedState: + { + this->setState("disconnected"); + break; + } + case QAbstractSocket::ConnectedState: + { + this->setState("connected"); + break; + } + default: + { + qDebug() << "+ --- UNKNOWN SOCKET STATE: " << socketState; + break; + } + } +} + int BaseConn::getProgress() const { return(connection_progress); @@ -223,13 +248,20 @@ bool BaseConn::refreshConnections() { if(reply["status"] != 200){ //handle Error!! + if(reply["status"] == 910){ + this->connections = QVariantList({}); + return true; + } qDebug() << "+ --- error refreshing connections: " << reply["status"]; return false; } QVariantList tmpConnections = reply["data"].toList(); - this->connections = reply["data"].toList(); + if(this->connections != reply["data"].toList()){ + this->connections = reply["data"].toList(); + emit this->connectionsChanged(); + } return true; @@ -239,7 +271,7 @@ QVariant BaseConn::getConnections() { return(connections); /* "id": "id of the extention (int)", - "type": "type of the extention (can be: 'STARTPAD', 'TOPPAP')", + "type": "type of the extention (can be: 'STARTPAD', 'TOPPAD')", "name": "name of the extention", "ip": "ip-adress of he extention (string)", "state": "state of the extention (can be: 'disconnected', 'connecting', 'connected')" diff --git a/sources/climbingrace.cpp b/sources/climbingrace.cpp index 64be312..7a4c109 100644 --- a/sources/climbingrace.cpp +++ b/sources/climbingrace.cpp @@ -18,8 +18,9 @@ ClimbingRace::ClimbingRace(QObject *parent) : QObject(parent) this->appSettings = new AppSettings; this->baseConn = new BaseConn; - this->baseConn->setIP("192.168.4.1"); + this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); connect(this->baseConn, &BaseConn::stateChanged, this, &ClimbingRace::baseStationStateChanged); + connect(this->baseConn, &BaseConn::connectionsChanged, this, &ClimbingRace::baseStationConnectionsChanged); this->speedTimers.append( new SpeedTimer ); @@ -195,14 +196,14 @@ int ClimbingRace::resetRace() { // ------------------------- void ClimbingRace::syncWithBaseStation() { + + this->baseConn->refreshConnections(); + if(this->baseConn->state != "connected"){ this->baseStationSyncTimer->start(); return; } - this->baseConn->refreshConnections(); - emit this->baseStationConnectionsChanged(); - QVariantMap tmpReply = this->baseConn->sendCommand(2000); if(tmpReply["status"] != 200){ @@ -229,20 +230,6 @@ void ClimbingRace::syncWithBaseStation() { speedTimers[0]->setState(SpeedTimer::STARTING); } -// tmpReply = this->baseConn->sendCommand(2004); -// if(tmpReply["status"] != 200){ -// //handle Error!! -// qDebug() << "+ --- getting next start action from basestation failed: " << tmpReply["status"]; -// this->baseStationSyncTimer->start(); -// return; -// } -// else { -// if(this->nextStartAction != tmpReply["data"].toInt()){ -// this->nextStartAction = tmpReply["data"].toInt(); -// this->nextStartActionChanged(this->nextStartAction); -// } -// } - tmpReply = this->baseConn->sendCommand(2005); if(tmpReply["status"] != 200){ //handle error!! @@ -360,7 +347,6 @@ void ClimbingRace::playSoundsAndStartRace() { bool ClimbingRace::playSound(QString path) { - //connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); player->setMedia(QUrl(path)); player->setVolume(50); player->play(); @@ -509,9 +495,14 @@ QString ClimbingRace::readSetting(QString key) { } bool ClimbingRace::connectBaseStation() { + this->reloadBaseStationIpAdress(); return this->baseConn->connectToHost(); } +void ClimbingRace::disconnectBaseStation() { + this->baseConn->closeConnection(); +} + QString ClimbingRace::getBaseStationState() { return this->baseConn->getState(); } @@ -519,3 +510,11 @@ QString ClimbingRace::getBaseStationState() { QVariant ClimbingRace::getBaseStationConnections() { return baseConn->getConnections(); } + +bool ClimbingRace::reloadBaseStationIpAdress() { + if(this->baseConn->state == "disconnected"){ + this->baseConn->setIP(pGlobalAppSettings->loadSetting("baseStationIpAdress")); + return true; + } + return false; +}