Commit 571ad679 authored by Dorian Zedler's avatar Dorian Zedler

added volume control and next action details to controlled mode

parent f8025562
/*
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 <https://www.gnu.org/licenses/>.
*/
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]
}
}
}
import QtQuick 2.0
import QtQuick.Controls 2.0
Column {
id: timerCol
opacity: baseConn.state === "connected" ? 1:0
spacing: 0
Repeater {
id: timerRep
model: baseConn.timers === undefined ? 0:baseConn.timers.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: ([4].indexOf(baseConn.timers[index]["state"]) >= 0 ? "#6bd43b" :
[2,5,6].indexOf(baseConn.timers[index]["state"]) >= 0 ? "#e03b2f":
"black")
text: baseConn.timers[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: baseConn.timers[index]["reactTime"]
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: baseConn.timers[index]["state"] >= 3 && 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
}
}
}
......@@ -57,7 +57,7 @@ bool BaseConn::init() {
this->setState("connected");
// init remote session
QJsonArray updateSubs = {"onTimersChanged", "onRaceStateChanged"};
QJsonArray updateSubs = {"onTimersChanged", "onRaceStateChanged", "onNextStartActionChanged"};
QJsonObject sessionParams = {{"updateSubs", updateSubs}, {"init", true}};
if(this->sendCommand(1, sessionParams)["status"] != 200) {
......@@ -337,6 +337,22 @@ void BaseConn::setState(QString newState){
}
}
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 -
// ------------------
......@@ -357,7 +373,15 @@ void BaseConn::handleUpdate(QVariantMap data) {
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();
}
}
}
......@@ -429,6 +453,17 @@ void BaseConn::refreshTimerTextList() {
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();
}
......@@ -459,3 +494,11 @@ int BaseConn::getRaceState()
{
return this->remoteRaceState;
}
double BaseConn::getNextStartActionDelayProgress() {
return this->nextStartActionDelayProgress;
}
int BaseConn::getNextStartAction() {
return this->nextStartAction;
}
......@@ -21,6 +21,9 @@ class BaseConn : public QObject
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);
......@@ -48,6 +51,14 @@ public:
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
......@@ -85,6 +96,9 @@ signals:
void timerTextChanged();
void raceStateChanged();
void nextStartActionChanged();
void nextStartActionDelayProgressChanged();
public slots:
Q_INVOKABLE void connectToHost();
......@@ -106,6 +120,8 @@ public slots:
// 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);
......@@ -121,6 +137,9 @@ public slots:
QVariant getTimerTextList();
int getRaceState();
Q_INVOKABLE double getNextStartActionDelayProgress();
Q_INVOKABLE int getNextStartAction();
private slots:
void readyRead();
......
......@@ -20,7 +20,7 @@ int main(int argc, char *argv[])
QQmlApplicationEngine engine;
QSize size = app.screens()[0]->size();
QSize size = app.screens().first()->size();
engine.rootContext()->setContextProperty("XscreenHeight", size.height());
engine.rootContext()->setContextProperty("XscreenWidth", size.width());
......
This diff is collapsed.
......@@ -2,5 +2,7 @@
<qresource prefix="/">
<file>main.qml</file>
<file>FancyBusyIndicator.qml</file>
<file>TimerColumn.qml</file>
<file>FadeAnimation.qml</file>
</qresource>
</RCC>
......@@ -6,5 +6,8 @@
<file>fonts/Arvo-RegularItalic.ttf</file>
<file>fonts/PTMono-Regular.ttf</file>
<file>Banner.png</file>
<file>SpeedHold.png</file>
<file>VolumeHigh.png</file>
<file>VolumeLow.png</file>
</qresource>
</RCC>
......@@ -84,7 +84,7 @@ void setup() {
}
// configure static ip
IPAddress local_IP(192, 168, 4, (thisIsToppad ? (thisIsLaneA ? 10 : 12) : (thisIsLaneA ? 11 : 13)));
IPAddress local_IP(192, 168, 4, (thisIsToppad ? (thisIsLaneA ? 10 : 12) : (thisIsLaneA ? 13 : 11)));
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment