Skip to content

Commit d30c493

Browse files
committed
Add an hour option to the timer application
1 parent 7b39d81 commit d30c493

File tree

5 files changed

+68
-30
lines changed

5 files changed

+68
-30
lines changed

src/components/timer/Timer.cpp

+22-7
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,41 @@
33
using namespace Pinetime::Controllers;
44

55
Timer::Timer(void* const timerData, TimerCallbackFunction_t timerCallbackFunction) {
6-
timer = xTimerCreate("Timer", 1, pdFALSE, timerData, timerCallbackFunction);
6+
timerHandle = xTimerCreate("Timer", 1, pdFALSE, timerData, timerCallbackFunction);
77
}
88

99
void Timer::StartTimer(std::chrono::milliseconds duration) {
10-
xTimerChangePeriod(timer, pdMS_TO_TICKS(duration.count()), 0);
11-
xTimerStart(timer, 0);
10+
timerOverflowIntervals = 0;
11+
12+
if (duration.count() > maxTimerMS) {
13+
timerOverflowIntervals = duration.count() / maxTimerMS;
14+
uint32_t remainingMS = duration.count() % maxTimerMS;
15+
uint8_t leftoverMinutes = remainingMS / 60 / 1000;
16+
uint8_t leftoverSeconds = (remainingMS % (60 * 1000)) / 1000;
17+
if (leftoverMinutes == 0 && leftoverSeconds == 0) {
18+
leftoverMinutes = 59;
19+
leftoverSeconds = 60;
20+
timerOverflowIntervals--;
21+
}
22+
xTimerChangePeriod(timerHandle, pdMS_TO_TICKS((leftoverMinutes * 60 * 1000) + (leftoverSeconds * 1000)), 0);
23+
} else {
24+
xTimerChangePeriod(timerHandle, pdMS_TO_TICKS(duration.count()), 0);
25+
}
26+
xTimerStart(timerHandle, 0);
1227
}
1328

1429
std::chrono::milliseconds Timer::GetTimeRemaining() {
1530
if (IsRunning()) {
16-
TickType_t remainingTime = xTimerGetExpiryTime(timer) - xTaskGetTickCount();
17-
return std::chrono::milliseconds(remainingTime * 1000 / configTICK_RATE_HZ);
31+
TickType_t remainingTime = xTimerGetExpiryTime(timerHandle) - xTaskGetTickCount();
32+
return std::chrono::milliseconds((remainingTime * 1000 / configTICK_RATE_HZ) + (timerOverflowIntervals * maxTimerMS));
1833
}
1934
return std::chrono::milliseconds(0);
2035
}
2136

2237
void Timer::StopTimer() {
23-
xTimerStop(timer, 0);
38+
xTimerStop(timerHandle, 0);
2439
}
2540

2641
bool Timer::IsRunning() {
27-
return (xTimerIsTimerActive(timer) == pdTRUE);
42+
return (xTimerIsTimerActive(timerHandle) == pdTRUE);
2843
}

src/components/timer/Timer.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ namespace Pinetime {
1919

2020
bool IsRunning();
2121

22+
uint8_t timerOverflowIntervals = 0;
23+
24+
TimerHandle_t timerHandle;
25+
26+
const uint32_t maxTimerMS = 3'600'000; // 1 hour
2227
private:
23-
TimerHandle_t timer;
2428
};
2529
}
2630
}

src/displayapp/DisplayApp.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -362,17 +362,22 @@ void DisplayApp::Refresh() {
362362
LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
363363
break;
364364
case Messages::TimerDone:
365-
if (state != States::Running) {
366-
PushMessageToSystemTask(System::Messages::GoToRunning);
367-
}
368-
if (currentApp == Apps::Timer) {
369-
lv_disp_trig_activity(nullptr);
370-
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
371-
timer->Reset();
365+
if (timer.timerOverflowIntervals > 0) {
366+
timer.StopTimer();
367+
timer.StartTimer(std::chrono::milliseconds(timer.timerOverflowIntervals * timer.maxTimerMS));
372368
} else {
373-
LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up);
369+
if (state != States::Running) {
370+
PushMessageToSystemTask(System::Messages::GoToRunning);
371+
}
372+
if (currentApp == Apps::Timer) {
373+
lv_disp_trig_activity(nullptr);
374+
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
375+
timer->Reset();
376+
} else {
377+
LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up);
378+
}
379+
motorController.RunForDuration(35);
374380
}
375-
motorController.RunForDuration(35);
376381
break;
377382
case Messages::AlarmTriggered:
378383
if (currentApp == Apps::Alarm) {

src/displayapp/screens/Timer.cpp

+24-11
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,24 @@ static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
1919

2020
Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
2121

22-
lv_obj_t* colonLabel = lv_label_create(lv_scr_act(), nullptr);
23-
lv_obj_set_style_local_text_font(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
24-
lv_obj_set_style_local_text_color(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
25-
lv_label_set_text_static(colonLabel, ":");
26-
lv_obj_align(colonLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, -29);
27-
22+
lv_obj_t* colonMinutesSeconds = lv_label_create(lv_scr_act(), nullptr);
23+
lv_obj_set_style_local_text_font(colonMinutesSeconds, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
24+
lv_obj_set_style_local_text_color(colonMinutesSeconds, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
25+
lv_label_set_text_static(colonMinutesSeconds, ":");
26+
lv_obj_align(colonMinutesSeconds, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 40, 78);
27+
28+
lv_obj_t* colonHoursMinutes = lv_label_create(lv_scr_act(), nullptr);
29+
lv_obj_set_style_local_text_font(colonHoursMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
30+
lv_obj_set_style_local_text_color(colonHoursMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
31+
lv_label_set_text_static(colonHoursMinutes, ":");
32+
lv_obj_align(colonHoursMinutes, lv_scr_act(), LV_ALIGN_IN_TOP_MID, -41, 78);
33+
34+
hourCounter.Create();
2835
minuteCounter.Create();
2936
secondCounter.Create();
30-
lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
31-
lv_obj_align(secondCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
37+
lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 26);
38+
lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_MID, 0, 26);
39+
lv_obj_align(secondCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, -10, 26);
3240

3341
highlightObjectMask = lv_objmask_create(lv_scr_act(), nullptr);
3442
lv_obj_set_size(highlightObjectMask, 240, 50);
@@ -120,18 +128,21 @@ void Timer::Refresh() {
120128
void Timer::DisplayTime() {
121129
displaySeconds = std::chrono::duration_cast<std::chrono::seconds>(timer.GetTimeRemaining());
122130
if (displaySeconds.IsUpdated()) {
123-
minuteCounter.SetValue(displaySeconds.Get().count() / 60);
131+
hourCounter.SetValue(displaySeconds.Get().count() / 3600);
132+
minuteCounter.SetValue((displaySeconds.Get().count() % 3600) / 60);
124133
secondCounter.SetValue(displaySeconds.Get().count() % 60);
125134
}
126135
}
127136

128137
void Timer::SetTimerRunning() {
138+
hourCounter.HideControls();
129139
minuteCounter.HideControls();
130140
secondCounter.HideControls();
131141
lv_label_set_text_static(txtPlayPause, "Pause");
132142
}
133143

134144
void Timer::SetTimerStopped() {
145+
hourCounter.ShowControls();
135146
minuteCounter.ShowControls();
136147
secondCounter.ShowControls();
137148
lv_label_set_text_static(txtPlayPause, "Start");
@@ -142,9 +153,11 @@ void Timer::ToggleRunning() {
142153
DisplayTime();
143154
timer.StopTimer();
144155
SetTimerStopped();
145-
} else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
146-
auto timerDuration = std::chrono::minutes(minuteCounter.GetValue()) + std::chrono::seconds(secondCounter.GetValue());
156+
} else if (secondCounter.GetValue() + minuteCounter.GetValue() + hourCounter.GetValue() > 0) {
157+
std::chrono::milliseconds timerDuration = std::chrono::hours(hourCounter.GetValue()) + std::chrono::minutes(minuteCounter.GetValue()) +
158+
std::chrono::seconds(secondCounter.GetValue());
147159
timer.StartTimer(timerDuration);
160+
displaySeconds = std::chrono::duration_cast<std::chrono::seconds>(timer.GetTimeRemaining());
148161
Refresh();
149162
SetTimerRunning();
150163
}

src/displayapp/screens/Timer.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ namespace Pinetime::Applications {
3838
lv_objmask_mask_t* highlightMask;
3939

4040
lv_task_t* taskRefresh;
41-
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
42-
Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
41+
Widgets::Counter hourCounter = Widgets::Counter(0, 99, jetbrains_mono_42);
42+
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_42);
43+
Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_42);
4344

4445
bool buttonPressing = false;
4546
lv_coord_t maskPosition = 0;

0 commit comments

Comments
 (0)