Skip to content

Commit 3bd68b5

Browse files
committed
Add speed and inclination +/- buttons to floating template
Add new control tiles for speed and inclination in the floating template (both vertical and horizontal variants). These tiles display the current value with +/- buttons for adjustment, useful for treadmill users who want to control speed and incline from the floating overlay. Changes: - Add speedcontrol and inclinecontrol tiles to floating.htm and hfloating.htm - Add SpeedPlus/SpeedMinus and InclinationPlus/InclinationMinus JavaScript functions - Add WebSocket message handlers (speed_plus, speed_minus, inclination_plus, inclination_minus) - Add corresponding signals and slots in templateinfosenderbuilder and homeform - Wire up to existing Plus/Minus functions which handle speed and inclination changes https://claude.ai/code/session_01QgLyRenM7sSWqqGU1Esy3s
1 parent bf75b2b commit 3bd68b5

6 files changed

Lines changed: 236 additions & 2 deletions

File tree

src/homeform.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,10 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) {
558558
&homeform::pelotonOffset_Minus);
559559
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::gears_Plus, this, &homeform::gearUp);
560560
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::gears_Minus, this, &homeform::gearDown);
561+
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::speed_Plus, this, &homeform::speedPlus);
562+
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::speed_Minus, this, &homeform::speedMinus);
563+
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::inclination_Plus, this, &homeform::inclinationPlus);
564+
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::inclination_Minus, this, &homeform::inclinationMinus);
561565
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::pelotonOffset, this, &homeform::pelotonOffset);
562566
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::pelotonAskStart, this, &homeform::pelotonAskStart);
563567
connect(this->innerTemplateManager, &TemplateInfoSenderBuilder::peloton_start_workout, this,
@@ -1610,6 +1614,22 @@ void homeform::gearDown() {
16101614
}
16111615
}
16121616

1617+
void homeform::speedPlus() {
1618+
Plus(QStringLiteral("speed"));
1619+
}
1620+
1621+
void homeform::speedMinus() {
1622+
Minus(QStringLiteral("speed"));
1623+
}
1624+
1625+
void homeform::inclinationPlus() {
1626+
Plus(QStringLiteral("inclination"));
1627+
}
1628+
1629+
void homeform::inclinationMinus() {
1630+
Minus(QStringLiteral("inclination"));
1631+
}
1632+
16131633
void homeform::ftmsAccessoryConnected(smartspin2k *d) {
16141634
connect(this, &homeform::autoResistanceChanged, d, &smartspin2k::autoResistanceChanged);
16151635
connect(d, &smartspin2k::gearUp, this, &homeform::gearUp);

src/homeform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,10 @@ class homeform : public QObject {
10561056
void sortTilesTimeout();
10571057
void gearUp();
10581058
void gearDown();
1059+
void speedPlus();
1060+
void speedMinus();
1061+
void inclinationPlus();
1062+
void inclinationMinus();
10591063
void changeTimestamp(QTime source, QTime actual);
10601064
void pelotonOffset_Plus();
10611065
void pelotonOffset_Minus();

src/inner_templates/floating/floating.htm

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,25 @@ <h2 style="color: #FFFFFF; font-family: sans-serif">Peloton Workout in progress!
199199
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
200200
onclick="GearsPlus()">+</button></td>
201201
</tr>
202-
<tr class="nextrow" sort-order="17">
202+
<tr class="speedcontrol" sort-order="18">
203+
<td class="icon">🏃</td>
204+
<td style="text-align: left">SPEED</td>
205+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
206+
onclick="SpeedMinus()">-</button></td>
207+
<td class="speedcontrol-value values"><b>0.0</b></td>
208+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
209+
onclick="SpeedPlus()">+</button></td>
210+
</tr>
211+
<tr class="inclinecontrol" sort-order="19">
212+
<td class="icon">📐</td>
213+
<td style="text-align: left">INCLINE</td>
214+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
215+
onclick="InclinationMinus()">-</button></td>
216+
<td class="inclinecontrol-value values"><b>0.0</b></td>
217+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
218+
onclick="InclinationPlus()">+</button></td>
219+
</tr>
220+
<tr class="nextrow" sort-order="20">
203221
<td class="icon">🕶</td>
204222
<td style="text-align: left">NEXT</td>
205223
<td class="nextrow-value values" colspan="5"><b></b></td>
@@ -306,6 +324,62 @@ <h2 style="color: #FFFFFF; font-family: sans-serif">Peloton Workout in progress!
306324
});
307325
}
308326

327+
function SpeedPlus() {
328+
let el = new MainWSQueueElement({
329+
msg: 'speed_plus',
330+
}, function (msg) {
331+
if (msg.msg === 'R_speed_plus') {
332+
return msg.content;
333+
}
334+
return null;
335+
}, 15000, 1);
336+
el.enqueue().catch(function (err) {
337+
console.error('Error is ' + err);
338+
});
339+
}
340+
341+
function SpeedMinus() {
342+
let el = new MainWSQueueElement({
343+
msg: 'speed_minus',
344+
}, function (msg) {
345+
if (msg.msg === 'R_speed_minus') {
346+
return msg.content;
347+
}
348+
return null;
349+
}, 15000, 1);
350+
el.enqueue().catch(function (err) {
351+
console.error('Error is ' + err);
352+
});
353+
}
354+
355+
function InclinationPlus() {
356+
let el = new MainWSQueueElement({
357+
msg: 'inclination_plus',
358+
}, function (msg) {
359+
if (msg.msg === 'R_inclination_plus') {
360+
return msg.content;
361+
}
362+
return null;
363+
}, 15000, 1);
364+
el.enqueue().catch(function (err) {
365+
console.error('Error is ' + err);
366+
});
367+
}
368+
369+
function InclinationMinus() {
370+
let el = new MainWSQueueElement({
371+
msg: 'inclination_minus',
372+
}, function (msg) {
373+
if (msg.msg === 'R_inclination_minus') {
374+
return msg.content;
375+
}
376+
return null;
377+
}, 15000, 1);
378+
el.enqueue().catch(function (err) {
379+
console.error('Error is ' + err);
380+
});
381+
}
382+
309383
function Lap() {
310384
let el = new MainWSQueueElement({
311385
msg: 'lap',
@@ -845,6 +919,8 @@ <h2 style="color: #FFFFFF; font-family: sans-serif">Peloton Workout in progress!
845919
$('.inclination-value').html("<b>" + inclination.toFixed(1) + "</b>");
846920
$('.inclination-avg').html(inclination_lapavg.toFixed(1));
847921
$('.inclination-max').html(inclination_lapmax.toFixed(1));
922+
$('.speedcontrol-value').html("<b>" + speed.toFixed(1) + "</b>");
923+
$('.inclinecontrol-value').html("<b>" + inclination.toFixed(1) + "</b>");
848924
$('.elevation-value').html("<b>" + elevation.toFixed(1) + "</b>");
849925
if (tile_target_cadence_enabled && target_cadence > 0)
850926
$('.cadence-value').html("<b>" + cadence.toFixed(0) + "/" + target_cadence.toFixed(0) + "</b>");

src/inner_templates/floating/hfloating.htm

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,25 @@ <h2 style="color: #FFFFFF; font-family: sans-serif">Peloton Workout in progress!
373373
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
374374
onclick="GearsPlus()">+</button></td>
375375
</tr>
376-
<tr class="nextrow" sort-order="17">
376+
<tr class="speedcontrol" sort-order="18">
377+
<td class="icon">🏃</td>
378+
<td style="text-align: left">SPEED</td>
379+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
380+
onclick="SpeedMinus()">-</button></td>
381+
<td class="speedcontrol-value values"><b>0.0</b></td>
382+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
383+
onclick="SpeedPlus()">+</button></td>
384+
</tr>
385+
<tr class="inclinecontrol" sort-order="19">
386+
<td class="icon">📐</td>
387+
<td style="text-align: left">INCLINE</td>
388+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
389+
onclick="InclinationMinus()">-</button></td>
390+
<td class="inclinecontrol-value values"><b>0.0</b></td>
391+
<td colspan="2"><button style="width: 40px; font-size: 24px; color: white; background-color:#4C70BF"
392+
onclick="InclinationPlus()">+</button></td>
393+
</tr>
394+
<tr class="nextrow" sort-order="20">
377395
<td class="icon">🕶</td>
378396
<td style="text-align: left">NEXT</td>
379397
<td class="nextrow-value values" colspan="5"><b></b></td>
@@ -826,6 +844,62 @@ <h3>Select metrics to display</h3>
826844
});
827845
}
828846

847+
function SpeedPlus() {
848+
let el = new MainWSQueueElement({
849+
msg: 'speed_plus',
850+
}, function (msg) {
851+
if (msg.msg === 'R_speed_plus') {
852+
return msg.content;
853+
}
854+
return null;
855+
}, 15000, 1);
856+
el.enqueue().catch(function (err) {
857+
console.error('Error is ' + err);
858+
});
859+
}
860+
861+
function SpeedMinus() {
862+
let el = new MainWSQueueElement({
863+
msg: 'speed_minus',
864+
}, function (msg) {
865+
if (msg.msg === 'R_speed_minus') {
866+
return msg.content;
867+
}
868+
return null;
869+
}, 15000, 1);
870+
el.enqueue().catch(function (err) {
871+
console.error('Error is ' + err);
872+
});
873+
}
874+
875+
function InclinationPlus() {
876+
let el = new MainWSQueueElement({
877+
msg: 'inclination_plus',
878+
}, function (msg) {
879+
if (msg.msg === 'R_inclination_plus') {
880+
return msg.content;
881+
}
882+
return null;
883+
}, 15000, 1);
884+
el.enqueue().catch(function (err) {
885+
console.error('Error is ' + err);
886+
});
887+
}
888+
889+
function InclinationMinus() {
890+
let el = new MainWSQueueElement({
891+
msg: 'inclination_minus',
892+
}, function (msg) {
893+
if (msg.msg === 'R_inclination_minus') {
894+
return msg.content;
895+
}
896+
return null;
897+
}, 15000, 1);
898+
el.enqueue().catch(function (err) {
899+
console.error('Error is ' + err);
900+
});
901+
}
902+
829903
// Function to clear/lap
830904
function Lap() {
831905
let el = new MainWSQueueElement({
@@ -1368,6 +1442,10 @@ <h3>Select metrics to display</h3>
13681442
$('.inclination-avg').html(data.inclination_lapavg.toFixed(1));
13691443
$('.inclination-max').html(data.inclination_lapmax.toFixed(1));
13701444

1445+
// Speed and Incline control tiles
1446+
$('.speedcontrol-value').html("<b>" + data.speed.toFixed(1) + "</b>");
1447+
$('.inclinecontrol-value').html("<b>" + data.inclination.toFixed(1) + "</b>");
1448+
13711449
// Elevation
13721450
$('.elevation-value').html("<b>" + data.elevation.toFixed(1) + "</b>");
13731451

src/templateinfosenderbuilder.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,42 @@ void TemplateInfoSenderBuilder::onGearsMinus(const QJsonValue &msgContent, Templ
10841084
tempSender->send(out.toJson());
10851085
}
10861086

1087+
void TemplateInfoSenderBuilder::onSpeedPlus(const QJsonValue &msgContent, TemplateInfoSender *tempSender) {
1088+
Q_UNUSED(msgContent);
1089+
QJsonObject main, outObj;
1090+
emit speed_Plus();
1091+
main[QStringLiteral("msg")] = QStringLiteral("R_speed_plus");
1092+
QJsonDocument out(main);
1093+
tempSender->send(out.toJson());
1094+
}
1095+
1096+
void TemplateInfoSenderBuilder::onSpeedMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender) {
1097+
Q_UNUSED(msgContent);
1098+
QJsonObject main, outObj;
1099+
emit speed_Minus();
1100+
main[QStringLiteral("msg")] = QStringLiteral("R_speed_minus");
1101+
QJsonDocument out(main);
1102+
tempSender->send(out.toJson());
1103+
}
1104+
1105+
void TemplateInfoSenderBuilder::onInclinationPlus(const QJsonValue &msgContent, TemplateInfoSender *tempSender) {
1106+
Q_UNUSED(msgContent);
1107+
QJsonObject main, outObj;
1108+
emit inclination_Plus();
1109+
main[QStringLiteral("msg")] = QStringLiteral("R_inclination_plus");
1110+
QJsonDocument out(main);
1111+
tempSender->send(out.toJson());
1112+
}
1113+
1114+
void TemplateInfoSenderBuilder::onInclinationMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender) {
1115+
Q_UNUSED(msgContent);
1116+
QJsonObject main, outObj;
1117+
emit inclination_Minus();
1118+
main[QStringLiteral("msg")] = QStringLiteral("R_inclination_minus");
1119+
QJsonDocument out(main);
1120+
tempSender->send(out.toJson());
1121+
}
1122+
10871123
void TemplateInfoSenderBuilder::onPelotonStartWorkout(const QJsonValue &msgContent, TemplateInfoSender *tempSender) {
10881124
Q_UNUSED(msgContent);
10891125
QJsonObject main, outObj;
@@ -1255,6 +1291,18 @@ void TemplateInfoSenderBuilder::onDataReceived(const QByteArray &data) {
12551291
} else if (msg == QStringLiteral("gears_minus")) {
12561292
onGearsMinus(jsonObject[QStringLiteral("content")], sender);
12571293
return;
1294+
} else if (msg == QStringLiteral("speed_plus")) {
1295+
onSpeedPlus(jsonObject[QStringLiteral("content")], sender);
1296+
return;
1297+
} else if (msg == QStringLiteral("speed_minus")) {
1298+
onSpeedMinus(jsonObject[QStringLiteral("content")], sender);
1299+
return;
1300+
} else if (msg == QStringLiteral("inclination_plus")) {
1301+
onInclinationPlus(jsonObject[QStringLiteral("content")], sender);
1302+
return;
1303+
} else if (msg == QStringLiteral("inclination_minus")) {
1304+
onInclinationMinus(jsonObject[QStringLiteral("content")], sender);
1305+
return;
12581306
} else if (msg == QStringLiteral("peloton_start_workout")) {
12591307
onPelotonStartWorkout(jsonObject[QStringLiteral("content")], sender);
12601308
return;

src/templateinfosenderbuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class TemplateInfoSenderBuilder : public QObject {
3434
void pelotonOffset_Minus();
3535
void gears_Plus();
3636
void gears_Minus();
37+
void speed_Plus();
38+
void speed_Minus();
39+
void inclination_Plus();
40+
void inclination_Minus();
3741
int pelotonOffset();
3842
bool pelotonAskStart();
3943
void peloton_start_workout();
@@ -79,6 +83,10 @@ class TemplateInfoSenderBuilder : public QObject {
7983
void onPelotonOffsetMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
8084
void onGearsPlus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
8185
void onGearsMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
86+
void onSpeedPlus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
87+
void onSpeedMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
88+
void onInclinationPlus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
89+
void onInclinationMinus(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
8290
void onPelotonStartWorkout(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
8391
void onPelotonAbortWorkout(const QJsonValue &msgContent, TemplateInfoSender *tempSender);
8492
void onFloatingClose(const QJsonValue &msgContent, TemplateInfoSender *tempSender);

0 commit comments

Comments
 (0)