diff --git a/headers/climbingrace.h b/headers/climbingrace.h index bac10c7..19edd77 100644 --- a/headers/climbingrace.h +++ b/headers/climbingrace.h @@ -95,7 +95,12 @@ public slots: Q_INVOKABLE void disconnectBaseStation(); Q_INVOKABLE QString getBaseStationState(); Q_INVOKABLE QVariant getBaseStationConnections(); + + // athlete management Q_INVOKABLE QVariant getAthletes(); + Q_INVOKABLE bool createAthlete( QString userName, QString fullName ); + Q_INVOKABLE bool deleteAthlete( QString userName ); + Q_INVOKABLE bool selectAthlete( QString userName ); Q_INVOKABLE bool reloadBaseStationIpAdress(); }; diff --git a/qml/ProfilesDialog.qml b/qml/ProfilesDialog.qml index dd17bd4..3904058 100644 --- a/qml/ProfilesDialog.qml +++ b/qml/ProfilesDialog.qml @@ -77,7 +77,7 @@ Popup { leftMargin: ( parent.width - headlineUnderline.width ) / 2 //topMargin: headlineUnderline.anchors.topMargin * 1.2 bottom: parent.bottom - bottomMargin: headlineUnderline.anchors.topMargin + bottomMargin: topContainerItm.height } Behavior on opacity { @@ -96,12 +96,18 @@ Popup { property string secondButt: "add" property var listData: speedBackend.getAthletes() + function loadData() { + profileList.enabled = false + listData = speedBackend.getAthletes() + profileList.enabled = true + } + model: listData.length Connections { target: root onOpened: { - listData = speedBackend.getAthletes() + profileList.loadData() } } @@ -120,8 +126,13 @@ Popup { delegate: SwipeDelegate { id: swipeDelegate + + property bool active: profileList.listData[index]["active"] + text: profileList.listData[index]["fullName"] - width: profileList.width + width: profileList.width - (swipeDelegate.x) + + font.pixelSize: profiles_stack.text_pixelSize @@ -129,8 +140,14 @@ Popup { removeAnim.start() } + onClicked: { + if(speedBackend.selectAthlete(profileList.listData[index]["userName"])){ + profileList.loadData() + } + } + background: Rectangle { - color: pressed ? Qt.darker("white", 1.1):"white" + color: Qt.darker( pressed ? Qt.darker("white", 1.1):"white", swipeDelegate.active ? 1.1:0 ) } @@ -154,32 +171,6 @@ Popup { onStopped: profileModel.model.remove(index) } - Component { - id: component - - Rectangle { - color: mouseAr.pressed ? "#333" : "#444" - width: parent.width - height: parent.height - clip: true - - - Label { - text: qsTr("Press me!") - color: "#21be2b" - anchors.centerIn: parent - } - - MouseArea { - id: mouseAr - anchors.fill: parent - onClicked: { - swipeDelegate.remove() - } - } - } - } - swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } @@ -188,20 +179,6 @@ Popup { anchors.left: parent.left height: parent.height - Label { - id: moveLabel - text: qsTr("Move") - color: "white" - verticalAlignment: Label.AlignVCenter - padding: 12 - height: parent.height - - SwipeDelegate.onClicked: console.log("Moving...") - - background: Rectangle { - color: moveLabel.SwipeDelegate.pressed ? Qt.darker("#ffbf47", 1.1) : "#ffbf47" - } - } Label { id: deleteLabel text: qsTr("Delete") @@ -210,7 +187,11 @@ Popup { padding: 12 height: parent.height - SwipeDelegate.onClicked: console.log("Deleting...") + SwipeDelegate.onClicked: { + if(speedBackend.deleteAthlete(profileList.listData[index]["userName"])){ + profileList.loadData() + } + } background: Rectangle { color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato" @@ -218,6 +199,7 @@ Popup { } } } + ScrollIndicator.vertical: ScrollIndicator { } } @@ -230,16 +212,37 @@ Popup { property string title: "add profile" property string secondButt: "ok" property string newProfileName: "" + + Connections { + target: head_add + + enabled: true + + onClicked: { + if(speedBackend.createAthlete(userNameTf.text, fullNameTf.text)){ + profiles_stack.pop() + } + } + } + TextField { + id: fullNameTf width: parent.width - placeholderText: "name" + placeholderText: "full name" + onTextChanged: { + parent.newProfileName = text + } + Keys.onReturnPressed: { + } + } + TextField { + id: userNameTf + width: parent.width + placeholderText: "username" onTextChanged: { parent.newProfileName = text } Keys.onReturnPressed: { - if(profileModel.model.append(text)){ - profiles_stack.pop() - } } } } @@ -430,9 +433,7 @@ Popup { profiles_stack.push(addProfileComp) break case "ok": - if(profileModel.model.append(profiles_stack.currentItem.newProfileName)){ - profiles_stack.pop() - } + //speedBackend.createAthlete(fullNameTf.text, userNameTf.text) } } diff --git a/qml/main.qml b/qml/main.qml index b47296d..86cf030 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -58,6 +58,7 @@ Window { onStateChanged: { var stateString + console.log("race state changed to: " + state) switch (state){ case 0: stateString = "IDLE" @@ -147,7 +148,7 @@ Window { Behavior on text { FadeAnimation{ target: topLa - fadeDuration: 200 + fadeDuration: 100 } } } @@ -729,6 +730,11 @@ Window { from: "STARTING" to: "RUNNING" //disable transitions for the RUNNING state + }, + Transition { + from: "RUNNING" + to: "WAITING" + //disable transitions for the RUNNING state } ] diff --git a/sources/climbingrace.cpp b/sources/climbingrace.cpp index 7afce26..bd195be 100644 --- a/sources/climbingrace.cpp +++ b/sources/climbingrace.cpp @@ -445,6 +445,74 @@ bool ClimbingRace::refreshRemoteTimers() { } } + +// - athlete management - + +QVariant ClimbingRace::getAthletes() { + QVariantMap reply = this->baseConn->sendCommand(4003); + + if(reply["status"] != 200){ + //handle Error!! + qDebug() << "+ --- error getting athletes: " << reply["status"]; + return false; + } + + QVariantList tmpAthletes = reply["data"].toList(); + + qDebug() << tmpAthletes; + + return tmpAthletes; +} + +bool ClimbingRace::createAthlete(QString userName, QString fullName) { + + QVariant requestData = QVariantMap({{"fullName", fullName}, {"userName", userName}}); + + QVariantMap reply = this->baseConn->sendCommand(4001, requestData.toJsonValue()); + + if(reply["status"] != 200){ + //handle Error!! + qDebug() << "+ --- error creating athlete: " << reply["status"]; + return false; + } + + return true; +} + +bool ClimbingRace::deleteAthlete( QString userName ){ + + QVariant requestData = QVariantMap({{"userName", userName}}); + + QVariantMap reply = this->baseConn->sendCommand(4002, requestData.toJsonValue()); + + if(reply["status"] != 200){ + //handle Error!! + qDebug() << "+ --- error deleting athlete: " << reply["status"]; + return false; + } + + return true; + +} + +bool ClimbingRace::selectAthlete( QString userName){ + + QVariant requestData = QVariantMap({{"userName", userName}}); + + QVariantMap reply = this->baseConn->sendCommand(4000, requestData.toJsonValue()); + + if(reply["status"] != 200){ + //handle Error!! + qDebug() << "+ --- error deleting athlete: " << reply["status"]; + return false; + } + + return true; + +} + + + // ------------------------- // --- functions for qml --- // ------------------------- @@ -515,21 +583,6 @@ QVariant ClimbingRace::getBaseStationConnections() { return baseConn->getConnections(); } -QVariant ClimbingRace::getAthletes() { - QVariantMap reply = this->baseConn->sendCommand(4003); - - if(reply["status"] != 200){ - //handle Error!! - qDebug() << "+ --- error getting athletes: " << reply["status"]; - return false; - } - - QVariantList tmpAthletes = reply["data"].toList(); - - qDebug() << tmpAthletes; - - return tmpAthletes; -} bool ClimbingRace::reloadBaseStationIpAdress() { if(this->baseConn->state == "disconnected"){ diff --git a/sources/speedtimer.cpp b/sources/speedtimer.cpp index 8265870..549d647 100644 --- a/sources/speedtimer.cpp +++ b/sources/speedtimer.cpp @@ -99,6 +99,8 @@ QString SpeedTimer::getState(){ return("IDLE"); case STARTING: return("STARTING"); + case WAITING: + return ("WAITING"); case RUNNING: return("RUNNING"); case STOPPED: