diff --git a/ScStwMonitorSrc/FadeAnimation.qml b/ScStwMonitorSrc/FadeAnimation.qml deleted file mode 100644 index df750b1..0000000 --- a/ScStwMonitorSrc/FadeAnimation.qml +++ /dev/null @@ -1,72 +0,0 @@ -/* - Speed Climbing Stopwatch - Simple Stopwatch for Climbers - Copyright (C) 2018 Itsblue Development - Dorian Zeder - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, version 3 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -import QtQuick 2.0 - -SequentialAnimation { - id: root - property QtObject target - property int fadeDuration: 150 - property int fadeDuration_in: fadeDuration - property int fadeDuration_out: fadeDuration - - property alias outValueScale: outAnimationScale.to - property alias inValueScale: inAnimationScale.to - - property alias outValueOpacity: outAnimationOpacity.to - property alias inValueOpacity: inAnimationOpacity.to - - property string easingType: "Quad" - ParallelAnimation { - NumberAnimation { // in the default case, fade scale to 0 - id: outAnimationScale - target: root.target - property: "scale" - duration: root.fadeDuration_in - to: 0.9 - easing.type: Easing["In"+root.easingType] - } - NumberAnimation { // in the default case, fade scale to 0 - id: outAnimationOpacity - target: root.target - property: "opacity" - duration: root.fadeDuration_in - to: 0 - easing.type: Easing["In"+root.easingType] - } - } - PropertyAction { } // actually change the property targeted by the Behavior between the 2 other animations - ParallelAnimation { - NumberAnimation { // in the default case, fade scale back to 1 - id: inAnimationScale - target: root.target - property: "scale" - duration: root.fadeDuration_out - to: 1 - easing.type: Easing["Out"+root.easingType] - } - NumberAnimation { // in the default case, fade scale to 0 - id: inAnimationOpacity - target: root.target - property: "opacity" - duration: root.fadeDuration_in - to: 1 - easing.type: Easing["In"+root.easingType] - } - } - -} diff --git a/ScStwMonitorSrc/FancyBusyIndicator.qml b/ScStwMonitorSrc/FancyBusyIndicator.qml deleted file mode 100644 index 0d15d80..0000000 --- a/ScStwMonitorSrc/FancyBusyIndicator.qml +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick 2.1 -import QtQuick.Controls 2.2 - -BusyIndicator { - id: control - - property double speed: 1 - property color lineColor: "#21be2b" - - width: 100 - height: 100 - - contentItem: Canvas { - id: spinnerCanvas - anchors.fill: parent - - property double progress: 0 - - function drawSpinner(ctx, width, height, progress){ - var margins = width * 0.01 - var lineWidth = width * 0.1 - - ctx.clearRect(0,0,width,height) - - ctx.beginPath(); - ctx.arc(width * 0.5 + margins, height * 0.5 + margins, height*0.5 - margins*2 - lineWidth , 0, 2*Math.PI); - - ctx.strokeStyle = "#dedede"; - ctx.lineWidth = lineWidth - ctx.stroke(); - - ctx.beginPath(); - ctx.arc(width * 0.5 + margins, height * 0.5 + margins, height*0.5 - margins*2 - lineWidth, 2*Math.PI * progress, 2*Math.PI * progress + 0.5*Math.PI); - - ctx.strokeStyle = "#48db09"; - ctx.stroke(); - } - - - Timer { - interval: Math.floor(20 * 1/control.speed) - running: control.opacity > 0 && control.visible && control.running - repeat: true - - onTriggered: { - spinnerCanvas.progress += 0.0027*6 - if(spinnerCanvas.progress >= 1){ - spinnerCanvas.progress = 0 - } - - spinnerCanvas.requestPaint() - } - } - - onPaint: { - var ctx = getContext("2d"); - spinnerCanvas.drawSpinner(ctx, spinnerCanvas.height, spinnerCanvas.width, spinnerCanvas.progress) - } - - } -} diff --git a/ScStwMonitorSrc/ScStwMonitorSrc.pro b/ScStwMonitorSrc/ScStwMonitorSrc.pro index 88ddfa4..b29b93d 100755 --- a/ScStwMonitorSrc/ScStwMonitorSrc.pro +++ b/ScStwMonitorSrc/ScStwMonitorSrc.pro @@ -18,13 +18,12 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ - main.cpp \ - baseconn.cpp \ + sources/main.cpp \ sources/scstwmonitorbackend.cpp RESOURCES += \ - qml.qrc \ - shared.qrc + resources/qml/qml.qrc \ + resources/shared/shared.qrc # include submodules @@ -44,7 +43,6 @@ else: unix:!android: target.path = /home/pi/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target HEADERS += \ - baseconn.h \ headers/scstwmonitorbackend.h DISTFILES += \ @@ -67,8 +65,8 @@ ios { xcode_product_bundle_identifier_setting.value = "de.itsblue.ScStwMonitor" OBJECTIVE_SOURCES += \ - sleepprevent.mm + sources/sleepprevent.mm OBJECTIVE_HEADERS += \ - sleepprevent.h + headers/sleepprevent.h } diff --git a/ScStwMonitorSrc/TimerColumn.qml b/ScStwMonitorSrc/TimerColumn.qml deleted file mode 100644 index 5bfc078..0000000 --- a/ScStwMonitorSrc/TimerColumn.qml +++ /dev/null @@ -1,146 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import de.itsblue.ScStw 2.0 -import de.itsblue.ScStwMonitor 2.0 - -Column { - id: timerCol - - opacity: backend.scStwClient.state === ScStwClient.CONNECTED ? 1:0 - - spacing: 0 - - Repeater { - id: timerRep - - property var clearedTimers: removeDisabledTimers(backend.race.timers) - - function removeDisabledTimers(timers) { - var ret = [] - for(var i = 0; i < timers.length; i++) { - if(timers[i]["state"] !== ScStwTimer.DISABLED) - ret.push(timers[i]) - } - return ret - } - - model: clearedTimers.length - - delegate: Item { - id: timerDel - - width: parent.width - height: timerCol.height / timerRep.model - - Label { - id: laneNameLa - - anchors { - left: parent.left - } - - leftPadding: parent.width * 0.03 - - width: parent.width * 0.15 - height: parent.height * 0.5 - - fontSizeMode: Text.Fit - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - - text: ""//index === 0 ? "A":"B" - - color: "#2a5266" - - font.pixelSize: height - font.family: timerFont.name - - Rectangle { - anchors.fill: parent - color: "red" - opacity: 0 - } - } - - Label { - id: timerTextLa - - anchors.centerIn: parent - anchors.horizontalCenterOffset: laneNameLa.text !== "" ? parent.width * 0.06:0 - anchors.verticalCenterOffset: -(parent.height * 0.04 * reactTimeLa.opacity) - - width: parent.width * 0.8 - height: parent.height * 0.8 - - elide: "ElideRight" - color: ([ScStwTimer.WON].indexOf(timerRep.clearedTimers[index]["state"]) >= 0 ? "#6bd43b" : - [ScStwTimer.FAILED,ScStwTimer.LOST].indexOf(timerRep.clearedTimers[index]["state"]) >= 0 ? "#e03b2f": - "black") - - text: timerRep.clearedTimers[index]["text"] - - fontSizeMode: Text.Fit - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - - font.pixelSize: height - font.family: timerFont.name - minimumPixelSize: 1 - } - - Label { - id: reactTimeLa - - property int rtime: timerRep.clearedTimers[index]["reactionTime"] - - anchors { - centerIn: parent - verticalCenterOffset: timerTextLa.contentHeight * 0.4 + reactTimeLa.contentHeight * 0.4 + timerTextLa.anchors.verticalCenterOffset - horizontalCenterOffset: parent.width * 0.06 - } - - width: parent.width * 0.6 - height: parent.height * 0.15 - - scale: enabled ? 1:0.9 - opacity: enabled ? 1:0 - - enabled: timerRep.clearedTimers[index]["state"] >= ScStwTimer.STARTING && rtime !== 0 - - fontSizeMode: Text.Fit - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - - text: "reaction time (ms): " + Math.round(rtime) - - color: "black"//appTheme.style.textColor - - font.pixelSize: timerTextLa.font.pixelSize * 0.5 - font.family: timerFont.name - minimumPixelSize: 1 - - Behavior on opacity { - NumberAnimation { - duration: 200 - } - } - - Behavior on scale { - NumberAnimation { - duration: 200 - } - } - - } - } - } - - Behavior on opacity { - NumberAnimation { - duration: 200 - } - } -} diff --git a/ScStwMonitorSrc/VolumeHigh.png b/ScStwMonitorSrc/VolumeHigh.png deleted file mode 100644 index 0ed4293..0000000 Binary files a/ScStwMonitorSrc/VolumeHigh.png and /dev/null differ diff --git a/ScStwMonitorSrc/VolumeLow.png b/ScStwMonitorSrc/VolumeLow.png deleted file mode 100644 index 038f967..0000000 Binary files a/ScStwMonitorSrc/VolumeLow.png and /dev/null differ diff --git a/ScStwMonitorSrc/baseconn.cpp b/ScStwMonitorSrc/baseconn.cpp deleted file mode 100755 index 332e83d..0000000 --- a/ScStwMonitorSrc/baseconn.cpp +++ /dev/null @@ -1,504 +0,0 @@ -#include "baseconn.h" - -BaseConn::BaseConn(QObject *parent) : QObject(parent) -{ - socket = new QTcpSocket(this); - - this->timeoutTimer = new QTimer(this); - this->timeoutTimer->setSingleShot(true); - - this->state = "disconnected"; - - connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(gotError(QAbstractSocket::SocketError))); - - connect(this->socket, &QAbstractSocket::stateChanged, this, &BaseConn::socketStateChanged); - connect(this, &BaseConn::gotUpdate, this, &BaseConn::handleUpdate); - - this->nextConnectionId = 1; - - // init refresh timers - this->autoConnectRetryTimer = new QTimer(this); - this->autoConnectRetryTimer->setInterval(1000); - this->autoConnectRetryTimer->setSingleShot(true); - connect(this->autoConnectRetryTimer, &QTimer::timeout, this, &BaseConn::doConnectionAttempt); - this->autoConnectRetryTimer->start(); - - this->timerTextRefreshTimer = new QTimer(this); - this->timerTextRefreshTimer->setInterval(1); - this->timerTextRefreshTimer->setSingleShot(true); - connect(this->timerTextRefreshTimer, &QTimer::timeout, this, &BaseConn::refreshTimerTextList); - this->timerTextRefreshTimer->start(); -} - -void BaseConn::connectToHost() { - qDebug() << "+--- connecting"; - setState("connecting"); - - connect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout())); - - //connect - this->socket->connectToHost(this->ip, this->port); - - timeoutTimer->start(3000); -} - -void BaseConn::connectionTimeout() { - this->socket->abort(); - disconnect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout())); -} - -bool BaseConn::init() { - disconnect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout())); - this->timeoutTimer->stop(); - - connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead); - - this->setState("connected"); - - // init remote session - QJsonArray updateSubs = {"onTimersChanged", "onRaceStateChanged", "onNextStartActionChanged"}; - QJsonObject sessionParams = {{"updateSubs", updateSubs}, {"init", true}}; - - if(this->sendCommand(1, sessionParams)["status"] != 200) { - return false; - } - - return true; -} - -void BaseConn::deInit() { -} - -void BaseConn::closeConnection() -{ - qDebug() << "+--- closing connection"; - switch (socket->state()) - { - case 0: - socket->disconnectFromHost(); - break; - case 2: - socket->abort(); - break; - default: - socket->abort(); - } - - setState("disconnected"); -} - -void BaseConn::gotError(QAbstractSocket::SocketError err) -{ - //qDebug() << "got error"; - QString strError = "unknown"; - switch (err) - { - case 0: - strError = "Connection was refused"; - break; - case 1: - strError = "Remote host closed the connection"; - this->closeConnection(); - break; - case 2: - strError = "Host address was not found"; - break; - case 5: - strError = "Connection timed out"; - break; - default: - strError = "Unknown error"; - } - - emit gotError(strError); -} - -// ------------------------------------- -// --- socket communication handling --- -// ------------------------------------- - -void BaseConn::socketStateChanged(QAbstractSocket::SocketState socketState) { - switch (socketState) { - case QAbstractSocket::UnconnectedState: - { - this->setState("disconnected"); - break; - } - case QAbstractSocket::ConnectedState: - { - if(this->init()) { - this->setState("connected"); - } - else { - this->closeConnection(); - } - - break; - } - default: - { - //qDebug() << "+ --- UNKNOWN SOCKET STATE: " << socketState; - break; - } - } -} - -QVariantMap BaseConn::sendCommand(int header, QJsonValue data){ - if(this->state != "connected"){ - return {{"status", 910}, {"data", "not connected"}}; - } - - // generate id and witing requests entry - int thisId = nextConnectionId; - //qDebug() << "sending command: " << header << " with data: " << data << " and id: " << thisId; - nextConnectionId ++; - - QEventLoop *loop = new QEventLoop(this); - QTimer *timer = new QTimer(this); - QJsonObject reply; - - this->waitingRequests.append({thisId, loop, reply}); - - QJsonObject requestObj; - requestObj.insert("id", thisId); - requestObj.insert("header", header); - requestObj.insert("data", data); - - QString jsonRequest = QJsonDocument(requestObj).toJson(); - - timer->setSingleShot(true); - // quit the loop when the timer times out - loop->connect(timer, SIGNAL(timeout()), loop, SLOT(quit())); - // quit the loop when the connection was established - // loop.connect(this, &BaseConn::gotReply, &loop, &QEventLoop::quit); - // start the timer before starting to connect - timer->start(3000); - - //write data - socket->write(jsonRequest.toLatin1()); - - //wait for an answer to finish (programm gets stuck in here) - loop->exec(); - - bool replyFound = false; - - // find reply and delete the request from waiting list - for(int i = 0; iwaitingRequests.length(); i++){ - if(this->waitingRequests[i].id == thisId){ - // request was found - replyFound = true; - // delete event loop - if(this->waitingRequests[i].loop != nullptr) { - delete this->waitingRequests[i].loop; - } - // store reply - reply = this->waitingRequests[i].reply; - // remove reply from waiting list - this->waitingRequests.removeAt(i); - } - } - - if(!replyFound) { - // some internal error occured - return {{"status", 900}, {"data", ""}}; - } - - if(timer->remainingTime() == -1){ - //the time has been triggered -> timeout - return {{"status", 911}, {"data", ""}}; - } - - delete timer; - - return {{"status", reply.value("header").toInt()}, {"data", reply.value("data").toVariant()}}; - -} - -void BaseConn::readyRead() { - - //qDebug() << "ready to ready " << socket->bytesAvailable() << " bytes" ; - QString reply = socket->readAll(); - - //qWarning() << "socket read: " << reply; - - processSocketMessage(reply); -} - -void BaseConn::processSocketMessage(QString message){ - QString startKey = ""; - QString endKey = ""; - - //qWarning() << "... processing message now ... : " << message; - - if(message == ""){ - return; - } - - if((message.startsWith(startKey) && message.endsWith(endKey)) && (message.count(startKey) == 1 && message.count(endKey) == 1)){ - // non-split message ( e.g.: 123456789 - } - else if(!message.contains(endKey) && (!this->readBuffer.isEmpty() || message.startsWith(startKey))){ - // begin of a split message ( e.g.: 123 ) - // or middle of a split message ( e.g.: 456 ) - //qWarning() << "this is a begin or middle of split a message"; - this->readBuffer += message; - return; - } - else if(!message.contains(startKey) && message.endsWith(endKey)) { - // end of a split message ( e.g.: 789 ) - - if(!this->readBuffer.isEmpty()){ - message = readBuffer + message; - readBuffer.clear(); - } - } - else if((message.count(startKey) > 1 || message.count(endKey) > 1) || (message.contains(endKey) && !message.endsWith(endKey) && message.contains(startKey) && !message.startsWith(startKey))) { - // multiple messages in one packet ( e.g.: 123456789987654321 ) - // or multiple message fragments in one message ( e.g.: 56789987654321 or 5678998765 ) - //qDebug() << "detected multiple messages"; - - int startOfSecondMessage = message.lastIndexOf(startKey); - // process first part of message - QString firstMessage = message.left(startOfSecondMessage); - this->processSocketMessage(firstMessage); - // process second part of message - QString secondMessage = message.right(message.length() - startOfSecondMessage); - this->processSocketMessage(secondMessage); - - return; - } - else { - // invalid message - return; - } - - //qWarning() << "... done processing, message: " << message; - this->socketReplyRecieved(message); -} - -void BaseConn::socketReplyRecieved(QString reply) { - reply.replace("", ""); - reply.replace("", ""); - - int id = 0; - - QJsonDocument jsonReply = QJsonDocument::fromJson(reply.toUtf8()); - QJsonObject replyObj = jsonReply.object(); - - //qDebug() << "got: " << reply; - - if(!replyObj.isEmpty()){ - id = replyObj.value("id").toInt(); - - if(id == -1) { - // this message is an update!! - emit this->gotUpdate(replyObj.toVariantMap()); - return; - } - - for(int i = 0; i < this->waitingRequests.length(); i++){ - if(this->waitingRequests[i].id == id){ - this->waitingRequests[i].reply = replyObj; - if(this->waitingRequests[i].loop != nullptr){ - this->waitingRequests[i].loop->quit(); - } - return; - } - } - } - - latestReadReply = reply; - emit gotUnexpectedReply(reply); -} - -// ------------------------ -// --- helper functions --- -// ------------------------ - -void BaseConn::doConnectionAttempt() -{ - if(this->state == "disconnected") { - qDebug() << "+--- trying to connect"; - this->connectToHost(); - } - - this->autoConnectRetryTimer->start(); -} - -void BaseConn::setState(QString newState){ - if(this->state != newState) { - qDebug() << "+--- BaseConn state changed: " << newState; - this->state = newState; - emit stateChanged(); - if(this->state == "disconnected") { - this->deInit(); - } - } -} - -int BaseConn::writeRemoteSetting(QString key, QString value) { - QJsonArray requestData; - requestData.append(key); - requestData.append(value); - return this->sendCommand(3000, requestData)["status"].toInt(); -} - -QString BaseConn::readRemoteSetting(QString key) -{ - QVariantMap reply = this->sendCommand(3001, key); - if(reply["status"] != 200){ - return "false"; - } - return reply["data"].toString(); -} - -// ------------------ -// - for timer sync - -// ------------------ - -void BaseConn::handleUpdate(QVariantMap data) { - int header = data["header"].toInt(); - switch (header) { - case 9000: - { - // the remote race state changed - this->remoteRaceState = data["data"].toInt(); - this->raceStateChanged(); - break; - } - case 9001: - { - // the remote timers have changed - this->refreshRemoteTimers(data["data"].toList()); - break; - } - case 9003: - { - // the next start action has changed - this->nextStartActionTotalDelay = data["data"].toMap()["nextActionDelay"].toDouble(); - this->nextStartActionDelayStartedAt = this->date->currentMSecsSinceEpoch() - (this->nextStartActionTotalDelay * data["data"].toMap()["nextActionDelayProg"].toDouble()); - this->nextStartAction = NextStartAction( data["data"].toMap()["nextAction"].toInt() ); - - emit this->nextStartActionChanged(); - } - - } -} - -void BaseConn::refreshRemoteTimers(QVariantList timers) { - QVariantList remoteTimers; - - for (int i = 0; i < timers.length(); i++) { - QVariantMap thisTimer = timers[i].toMap(); - if(thisTimer["state"].toInt() != DISABLED ) { - thisTimer.insert("startTime", this->date->currentMSecsSinceEpoch() - thisTimer["currTime"].toDouble()); - remoteTimers.append(thisTimer); - } - } - - this->remoteTimers = remoteTimers; -} - -void BaseConn::refreshTimerTextList() { - QVariantList tmpTimerTextList; - - for (int i = 0; i < this->remoteTimers.toList().length(); i++) { - - QString newText; - - switch (this->remoteTimers.toList()[i].toMap()["state"].toInt()) { - case IDLE: - newText = "00.000"; - break; - case STARTING: - newText = "00.000"; - break; - case WAITING: - newText = "False Start"; - break; - case RUNNING: { - double currTime = this->date->currentMSecsSinceEpoch() - this->remoteTimers.toList()[i].toMap()["startTime"].toDouble(); - QString currTimeString = (currTime < 10000 ? "0":"") + QString::number( currTime / 1000.0, 'f', 3 );//QString::number( (currTime) / 1000.0, 'f', 1 ); - newText = currTimeString; - break; - } - case WON: { - double currTime = this->remoteTimers.toList()[i].toMap()["currTime"].toDouble(); - newText = (currTime < 10000 ? "0":"") + QString::number( currTime / 1000.0, 'f', 3 ); - break; - } - case LOST: { - double currTime = this->remoteTimers.toList()[i].toMap()["currTime"].toDouble(); - newText = (currTime < 10000 ? "0":"") + QString::number( currTime / 1000.0, 'f', 3 ); - break; - } - case FAILED: - newText = "False Start"; - break; - case CANCELLED: - newText = "Cancelled"; - break; - case DISABLED: - newText = "---"; - break; - } - - QVariantMap timerMap = {{"text", newText}, {"reactTime", this->remoteTimers.toList()[i].toMap()["reactTime"].toInt()}, {"state", this->remoteTimers.toList()[i].toMap()["state"].toInt()}}; - tmpTimerTextList.append(timerMap); - } - - if(tmpTimerTextList != this->timerTextList) { - this->timerTextList = tmpTimerTextList; - emit this->timerTextChanged(); - } - - // calculate next start action delay progress - double nextStartActionRemainingDelay = this->nextStartActionTotalDelay - ( this->date->currentMSecsSinceEpoch() - this->nextStartActionDelayStartedAt ); - if(nextStartActionRemainingDelay > 0){ - this->nextStartActionDelayProgress = nextStartActionRemainingDelay / this->nextStartActionTotalDelay; - emit this->nextStartActionDelayProgressChanged(); - } - else { - this->nextStartActionDelayProgress = 0; - emit this->nextStartActionDelayProgressChanged(); - } - - this->timerTextRefreshTimer->start(); -} - -// ----------- -// - for qml - -// ----------- - -void BaseConn::setIP(const QString &ipAdress){ - this->ip = ipAdress; -} - -QString BaseConn::getIP() const -{ - return(this->ip); -} - -QString BaseConn::getState() const -{ - return(this->state); -} - -QVariant BaseConn::getTimerTextList() -{ - return this->timerTextList; -} - -int BaseConn::getRaceState() -{ - return this->remoteRaceState; -} - -double BaseConn::getNextStartActionDelayProgress() { - return this->nextStartActionDelayProgress; -} - -int BaseConn::getNextStartAction() { - return this->nextStartAction; -} diff --git a/ScStwMonitorSrc/baseconn.h b/ScStwMonitorSrc/baseconn.h deleted file mode 100755 index d7bf76f..0000000 --- a/ScStwMonitorSrc/baseconn.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef BASECONN_H -#define BASECONN_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -class BaseConn : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString ipAddress READ getIP WRITE setIP) - Q_PROPERTY(QString state READ getState NOTIFY stateChanged) - Q_PROPERTY(QVariant timers READ getTimerTextList NOTIFY timerTextChanged) - Q_PROPERTY(int raceState READ getRaceState NOTIFY raceStateChanged) - - Q_PROPERTY(double nextStartActionDelayProgress READ getNextStartActionDelayProgress NOTIFY nextStartActionDelayProgressChanged) - Q_PROPERTY(int nextStartAction READ getNextStartAction NOTIFY nextStartActionChanged) - -public: - explicit BaseConn(QObject *parent = nullptr); - - // values for the socket connection - QString ip; - ushort port = 3563; - int errors; - int errors_until_disconnect = 4; - - // the current state - QString state; - // can be: - // - 'disconnected' - // - 'connecting' - // - 'connected' - - QString latestReadReply; - - //---general status values---// - - // stuff for storing the timers - enum timerState { IDLE, STARTING, WAITING, RUNNING, WON, LOST, FAILED, CANCELLED, DISABLED }; - - QVariant remoteTimers; - QVariant timerTextList; - int remoteRaceState; - - // for next start action - enum NextStartAction { AtYourMarks, Ready, Start, None }; - NextStartAction nextStartAction; - double nextStartActionDelayProgress; - // only used in remote mode: - double nextStartActionDelayStartedAt; - double nextStartActionTotalDelay; - -private: - QDateTime *date; - //to get the current time - - QTcpSocket *socket; - //socket for communication with the extention - - QTimer *autoConnectRetryTimer; // timer to frequently trigger a connection attempt to the base station - QTimer *timeoutTimer; // timer to trigger connection timeout - QTimer *timerTextRefreshTimer; // timer to refresh the text of the timers on the frontend - - QString readBuffer; - - int nextConnectionId; - - struct waitingRequest { - int id; - QEventLoop * loop; - QJsonObject reply; - }; - - QList waitingRequests; - -signals: - void stateChanged(); - //is emitted, when the connection state changes - - void gotUnexpectedReply(QString reply); - - void gotUpdate(QVariantMap data); - - void gotError(QString error); - - // for qml - void timerTextChanged(); - void raceStateChanged(); - - void nextStartActionChanged(); - void nextStartActionDelayProgressChanged(); - -public slots: - - Q_INVOKABLE void connectToHost(); - //function to connect to the base station - - void connectionTimeout(); - - Q_INVOKABLE bool init(); - Q_INVOKABLE void deInit(); - - Q_INVOKABLE void closeConnection(); - - void gotError(QAbstractSocket::SocketError err); - - // --- socket communication handling --- - - Q_INVOKABLE QVariantMap sendCommand(int header, QJsonValue data = ""); - - // helper functions - void doConnectionAttempt(); - void setState(QString newState); - int writeRemoteSetting(QString key, QString value); - QString readRemoteSetting(QString key); - - // for timer sync - void handleUpdate(QVariantMap data); - void refreshRemoteTimers(QVariantList timers); - void refreshTimerTextList(); - - // for qml - QString getIP() const; - void setIP(const QString &ipAdress); - - QString getState() const; - - QVariant getTimerTextList(); - int getRaceState(); - - Q_INVOKABLE double getNextStartActionDelayProgress(); - Q_INVOKABLE int getNextStartAction(); - -private slots: - void readyRead(); - - void processSocketMessage(QString message); - - void socketReplyRecieved(QString reply); - - void socketStateChanged(QAbstractSocket::SocketState socketState); -}; - -#endif // BASECONN_H diff --git a/ScStwMonitorSrc/fonts/Arvo-Bold.ttf b/ScStwMonitorSrc/fonts/Arvo-Bold.ttf deleted file mode 100644 index 38341b1..0000000 Binary files a/ScStwMonitorSrc/fonts/Arvo-Bold.ttf and /dev/null differ diff --git a/ScStwMonitorSrc/fonts/Arvo-BoldItalic.ttf b/ScStwMonitorSrc/fonts/Arvo-BoldItalic.ttf deleted file mode 100644 index b87118b..0000000 Binary files a/ScStwMonitorSrc/fonts/Arvo-BoldItalic.ttf and /dev/null differ diff --git a/ScStwMonitorSrc/fonts/Arvo-Regular.ttf b/ScStwMonitorSrc/fonts/Arvo-Regular.ttf deleted file mode 100644 index d8d0ec8..0000000 Binary files a/ScStwMonitorSrc/fonts/Arvo-Regular.ttf and /dev/null differ diff --git a/ScStwMonitorSrc/fonts/Arvo-RegularItalic.ttf b/ScStwMonitorSrc/fonts/Arvo-RegularItalic.ttf deleted file mode 100644 index 1a19337..0000000 Binary files a/ScStwMonitorSrc/fonts/Arvo-RegularItalic.ttf and /dev/null differ diff --git a/ScStwMonitorSrc/sleepprevent.h b/ScStwMonitorSrc/headers/sleepprevent.h similarity index 100% rename from ScStwMonitorSrc/sleepprevent.h rename to ScStwMonitorSrc/headers/sleepprevent.h diff --git a/ScStwMonitorSrc/icon/favicon.xcf b/ScStwMonitorSrc/icon/favicon.xcf index 53636a6..584e4a2 100644 Binary files a/ScStwMonitorSrc/icon/favicon.xcf and b/ScStwMonitorSrc/icon/favicon.xcf differ diff --git a/ScStwMonitorSrc/qml.qrc b/ScStwMonitorSrc/qml.qrc deleted file mode 100755 index e80de3b..0000000 --- a/ScStwMonitorSrc/qml.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - main.qml - FancyBusyIndicator.qml - TimerColumn.qml - FadeAnimation.qml - - diff --git a/ScStwMonitorSrc/main.qml b/ScStwMonitorSrc/resources/qml/main.qml similarity index 92% rename from ScStwMonitorSrc/main.qml rename to ScStwMonitorSrc/resources/qml/main.qml index 14b0ebf..f955b7a 100755 --- a/ScStwMonitorSrc/main.qml +++ b/ScStwMonitorSrc/resources/qml/main.qml @@ -7,6 +7,8 @@ import QtQuick.Layouts 1.0 import de.itsblue.ScStw 2.0 import de.itsblue.ScStwMonitor 2.0 +import de.itsblue.ScStw.Styling 2.0 +import ScStwQmlComponents 1.0 Window { id: window @@ -21,6 +23,10 @@ Window { id: app anchors.fill: parent + background: Rectangle { + color: appTheme.theme.colors.background + } + function landscape() { return app.width > app.height } @@ -30,6 +36,14 @@ Window { scStwClient.ipAddress: appSettings.baseStationIp } + ScStwAppThemeManager { + id: appTheme + + Component.onCompleted: { + appTheme.setTheme("Light") + } + } + Settings { id: appSettings property string baseStationIp: "192.168.4.1" @@ -52,11 +66,6 @@ Window { } } - FontLoader { - id: timerFont - source:"qrc:///fonts/PTMono-Regular.ttf" - } - Loader { id: mainComponentLoader @@ -96,6 +105,10 @@ Window { TimerColumn { anchors.fill: parent + timers: backend.race.timers + colors: appTheme.theme.colors + fontName: appTheme.theme.fonts.timers + opacity: !showControls || [ScStwRace.IDLE,ScStwRace.STARTING].indexOf(backend.race.state) < 0 ? 1:0 Behavior on opacity { @@ -136,7 +149,7 @@ Window { font.pixelSize: height * 0.3 - color: backend.race.state === ScStwRace.STARTING ? "#e0b928":"grey" + color: backend.race.state === ScStwRace.STARTING ? appTheme.theme.colors.warning:appTheme.theme.colors.text text: implicitText === "NEXT_START_ACTION" ? ["", "at your \nmarks", "ready", "starting..."][backend.race.nextStartActionDetails[ScStwRace.NextStartAction]+1]:implicitText @@ -245,15 +258,14 @@ Window { } } - Image { - Layout.preferredHeight: parent.height * 0.5 + Icon { + Layout.preferredHeight: parent.height * 0.7 Layout.preferredWidth: height * 0.7 Layout.alignment: Layout.Center - mipmap: true - - fillMode: Image.PreserveAspectFit - source: "qrc:/VolumeLow.png" + fontName: appTheme.theme.fonts.icons + icon: appTheme.theme.icons.volumeDown + color: appTheme.theme.colors.text } Slider { @@ -311,14 +323,14 @@ Window { } } - Image { - Layout.preferredHeight: parent.height * 0.5 - Layout.preferredWidth: height + Icon { + Layout.preferredHeight: parent.height * 0.7 + Layout.preferredWidth: height * 0.7 Layout.alignment: Layout.Center - mipmap: true - fillMode: Image.PreserveAspectFit - source: "qrc:/VolumeHigh.png" + fontName: appTheme.theme.fonts.icons + icon: appTheme.theme.icons.volumeUp + color: appTheme.theme.colors.text } } @@ -385,7 +397,7 @@ Window { anchors.fill: parent - FancyBusyIndicator { + BusyIndicator { id: loadingInd anchors.centerIn: parent diff --git a/ScStwMonitorSrc/resources/qml/qml.qrc b/ScStwMonitorSrc/resources/qml/qml.qrc new file mode 100755 index 0000000..5f6483a --- /dev/null +++ b/ScStwMonitorSrc/resources/qml/qml.qrc @@ -0,0 +1,5 @@ + + + main.qml + + diff --git a/ScStwMonitorSrc/Banner.png b/ScStwMonitorSrc/resources/shared/Banner.png similarity index 100% rename from ScStwMonitorSrc/Banner.png rename to ScStwMonitorSrc/resources/shared/Banner.png diff --git a/ScStwMonitorSrc/SpeedHold.png b/ScStwMonitorSrc/resources/shared/SpeedHold.png similarity index 100% rename from ScStwMonitorSrc/SpeedHold.png rename to ScStwMonitorSrc/resources/shared/SpeedHold.png diff --git a/ScStwMonitorSrc/fonts/PTMono-Regular.ttf b/ScStwMonitorSrc/resources/shared/fonts/PTMono-Regular.ttf similarity index 100% rename from ScStwMonitorSrc/fonts/PTMono-Regular.ttf rename to ScStwMonitorSrc/resources/shared/fonts/PTMono-Regular.ttf diff --git a/ScStwMonitorSrc/resources/shared/shared.qrc b/ScStwMonitorSrc/resources/shared/shared.qrc new file mode 100644 index 0000000..8f0bfb3 --- /dev/null +++ b/ScStwMonitorSrc/resources/shared/shared.qrc @@ -0,0 +1,7 @@ + + + fonts/PTMono-Regular.ttf + Banner.png + SpeedHold.png + + diff --git a/ScStwMonitorSrc/shared.qrc b/ScStwMonitorSrc/shared.qrc deleted file mode 100644 index fb10f14..0000000 --- a/ScStwMonitorSrc/shared.qrc +++ /dev/null @@ -1,13 +0,0 @@ - - - fonts/Arvo-Bold.ttf - fonts/Arvo-BoldItalic.ttf - fonts/Arvo-Regular.ttf - fonts/Arvo-RegularItalic.ttf - fonts/PTMono-Regular.ttf - Banner.png - SpeedHold.png - VolumeHigh.png - VolumeLow.png - - diff --git a/ScStwMonitorSrc/main.cpp b/ScStwMonitorSrc/sources/main.cpp similarity index 100% rename from ScStwMonitorSrc/main.cpp rename to ScStwMonitorSrc/sources/main.cpp diff --git a/ScStwMonitorSrc/sleepprevent.mm b/ScStwMonitorSrc/sources/sleepprevent.mm similarity index 100% rename from ScStwMonitorSrc/sleepprevent.mm rename to ScStwMonitorSrc/sources/sleepprevent.mm diff --git a/shared-libraries b/shared-libraries index 81e90dd..305656a 160000 --- a/shared-libraries +++ b/shared-libraries @@ -1 +1 @@ -Subproject commit 81e90dddec4cca57ebae4900575f58a6610d4789 +Subproject commit 305656ab1e06679326a0fe99485dfbdbb88f34b0