Skip to content

Commit 39b7175

Browse files
committed
Timer: let timer go overtime
1 parent 71ce13d commit 39b7175

4 files changed

Lines changed: 71 additions & 44 deletions

File tree

src/components/timer/TimerController.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@
99

1010
using namespace Pinetime::Controllers;
1111

12-
1312
APP_TIMER_DEF(timerAppTimer);
1413

1514
namespace {
1615
void TimerEnd(void* p_context) {
17-
auto* controller = static_cast<Pinetime::Controllers::TimerController*> (p_context);
18-
if(controller != nullptr)
16+
auto* controller = static_cast<Pinetime::Controllers::TimerController*>(p_context);
17+
if (controller != nullptr)
1918
controller->OnTimerEnd();
2019
}
2120
}
2221

23-
2422
void TimerController::Init() {
2523
app_timer_create(&timerAppTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerEnd);
2624
}
@@ -31,37 +29,31 @@ void TimerController::StartTimer(uint32_t duration) {
3129
app_timer_start(timerAppTimer, APP_TIMER_TICKS(duration), this);
3230
endTicks = currentTicks + APP_TIMER_TICKS(duration);
3331
timerRunning = true;
32+
overtime = false;
3433
}
3534

36-
uint32_t TimerController::GetTimeRemaining() {
35+
int32_t TimerController::GetSecondsRemaining() {
3736
if (!timerRunning) {
3837
return 0;
3938
}
4039
auto currentTicks = xTaskGetTickCount();
41-
42-
TickType_t deltaTicks = 0;
43-
if (currentTicks > endTicks) {
44-
deltaTicks = 0xffffffff - currentTicks;
45-
deltaTicks += (endTicks + 1);
46-
} else {
47-
deltaTicks = endTicks - currentTicks;
48-
}
49-
50-
return (static_cast<TickType_t>(deltaTicks) / static_cast<TickType_t>(configTICK_RATE_HZ)) * 1000;
40+
41+
int32_t deltaTicks = static_cast<int32_t>(endTicks) - static_cast<int32_t>(currentTicks);
42+
43+
return (deltaTicks / static_cast<int32_t>(configTICK_RATE_HZ));
5144
}
5245

5346
void TimerController::StopTimer() {
5447
app_timer_stop(timerAppTimer);
5548
timerRunning = false;
49+
overtime = false;
5650
}
5751

58-
bool TimerController::IsRunning() {
59-
return timerRunning;
60-
}
6152
void TimerController::OnTimerEnd() {
62-
timerRunning = false;
63-
if(systemTask != nullptr)
53+
overtime = true;
54+
if (systemTask != nullptr) {
6455
systemTask->PushMessage(System::Messages::OnTimerDone);
56+
}
6557
}
6658

6759
void TimerController::Register(Pinetime::System::SystemTask* systemTask) {

src/components/timer/TimerController.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@ namespace Pinetime {
99
class SystemTask;
1010
}
1111
namespace Controllers {
12-
12+
1313
class TimerController {
1414
public:
1515
TimerController() = default;
16-
16+
1717
void Init();
18-
18+
1919
void StartTimer(uint32_t duration);
20-
20+
2121
void StopTimer();
22-
23-
uint32_t GetTimeRemaining();
24-
25-
bool IsRunning();
22+
23+
int32_t GetSecondsRemaining();
24+
25+
bool IsOvertime() {
26+
return overtime;
27+
}
28+
29+
bool IsRunning() {
30+
return timerRunning;
31+
}
2632

2733
void OnTimerEnd();
2834

@@ -32,6 +38,7 @@ namespace Pinetime {
3238
System::SystemTask* systemTask = nullptr;
3339
TickType_t endTicks;
3440
bool timerRunning = false;
41+
bool overtime = false;
3542
};
3643
}
3744
}

src/displayapp/screens/Timer.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,17 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController)
5454

5555
time = lv_label_create(lv_scr_act(), nullptr);
5656
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
57-
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
5857

59-
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
58+
int32_t seconds = timerController.GetSecondsRemaining();
59+
bool overtime = timerController.IsOvertime();
60+
61+
if (overtime) {
62+
seconds = -seconds + 1; // "+ 1" is to not show -00:00 again after +00:00
63+
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
64+
} else {
65+
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
66+
}
67+
6068
lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60);
6169

6270
lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
@@ -68,23 +76,39 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController)
6876
lv_obj_set_height(btnPlayPause, 40);
6977
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
7078
if (timerController.IsRunning()) {
71-
lv_label_set_text(txtPlayPause, Symbols::pause);
79+
lv_label_set_text(txtPlayPause, overtime ? Symbols::stop : Symbols::pause);
7280
} else {
7381
lv_label_set_text(txtPlayPause, Symbols::play);
7482
createButtons();
7583
}
76-
7784
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
7885
}
7986

8087
Timer::~Timer() {
8188
lv_task_del(taskRefresh);
8289
lv_obj_clean(lv_scr_act());
90+
if (timerController.IsRunning() and timerController.IsOvertime()) {
91+
timerController.StopTimer();
92+
}
8393
}
8494

8595
void Timer::Refresh() {
8696
if (timerController.IsRunning()) {
87-
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
97+
int32_t seconds = timerController.GetSecondsRemaining();
98+
if (timerController.IsOvertime()) {
99+
seconds = -seconds + 1; // "+ 1" is to not show -00:00 again after +00:00
100+
101+
// safety measures, lets not overflow counter as it will display badly
102+
if (seconds >= 100 * 60) {
103+
minutesToSet = 0;
104+
secondsToSet = 0;
105+
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
106+
lv_label_set_text_static(time, "00:00");
107+
lv_label_set_text(txtPlayPause, Symbols::play);
108+
timerController.StopTimer();
109+
createButtons();
110+
}
111+
}
88112
lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60);
89113
}
90114
}
@@ -94,16 +118,24 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
94118
if (obj == btnPlayPause) {
95119
if (timerController.IsRunning()) {
96120
lv_label_set_text(txtPlayPause, Symbols::play);
97-
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
98-
minutesToSet = seconds / 60;
99-
secondsToSet = seconds % 60;
121+
int32_t secondsRemaining = timerController.GetSecondsRemaining();
122+
if (timerController.IsOvertime()) {
123+
minutesToSet = 0;
124+
secondsToSet = 0;
125+
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
126+
lv_label_set_text_static(time, "00:00");
127+
} else {
128+
minutesToSet = secondsRemaining / 60;
129+
secondsToSet = secondsRemaining % 60;
130+
}
100131
timerController.StopTimer();
101132
createButtons();
102133

103134
} else if (secondsToSet + minutesToSet > 0) {
104135
lv_label_set_text(txtPlayPause, Symbols::pause);
105136
timerController.StartTimer((secondsToSet + minutesToSet * 60) * 1000);
106137

138+
// inlined destroyButtons()
107139
lv_obj_del(btnSecondsDown);
108140
btnSecondsDown = nullptr;
109141
lv_obj_del(btnSecondsUp);
@@ -153,9 +185,6 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
153185
}
154186

155187
void Timer::setDone() {
156-
lv_label_set_text(time, "00:00");
157-
lv_label_set_text(txtPlayPause, Symbols::play);
158-
secondsToSet = 0;
159-
minutesToSet = 0;
160-
createButtons();
188+
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
189+
lv_label_set_text(txtPlayPause, Symbols::stop);
161190
}

src/displayapp/screens/Timer.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ namespace Pinetime::Applications::Screens {
3131

3232
void createButtons();
3333

34-
lv_obj_t *time, *msecTime, *btnPlayPause, *txtPlayPause, *btnMinutesUp, *btnMinutesDown, *btnSecondsUp, *btnSecondsDown, *txtMUp,
35-
*txtMDown, *txtSUp, *txtSDown;
36-
3734
lv_task_t* taskRefresh;
35+
lv_obj_t *time, *btnPlayPause, *txtPlayPause, *btnMinutesUp, *btnMinutesDown, *btnSecondsUp, *btnSecondsDown, *txtMUp,
36+
*txtMDown, *txtSUp, *txtSDown;
3837
};
3938
}

0 commit comments

Comments
 (0)