Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Count up, set background red, and ring when timer completes. #1498

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/components/timer/TimerController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,35 @@ void TimerController::Init(Pinetime::System::SystemTask* systemTask) {
void TimerController::StartTimer(uint32_t duration) {
xTimerChangePeriod(timer, pdMS_TO_TICKS(duration), 0);
xTimerStart(timer, 0);
state = TimerState::Running;
}

uint32_t TimerController::GetTimeRemaining() {
if (IsRunning()) {
TickType_t remainingTime = xTimerGetExpiryTime(timer) - xTaskGetTickCount();
return (remainingTime * 1000 / configTICK_RATE_HZ);
TickType_t remainingTime = 0;
switch (state) {
case TimerState::Not_Running:
break;
case TimerState::Running:
remainingTime = xTimerGetExpiryTime(timer) - xTaskGetTickCount();
break;
case TimerState::Alerting:
remainingTime = xTaskGetTickCount() - xTimerGetExpiryTime(timer);
break;
}
return 0;
return (remainingTime * 1000 / configTICK_RATE_HZ);
}

void TimerController::StopTimer() {
xTimerStop(timer, 0);
}

bool TimerController::IsRunning() {
return (xTimerIsTimerActive(timer) == pdTRUE);
state = TimerState::Not_Running;
}

void TimerController::OnTimerEnd() {
state = TimerState::Alerting;
systemTask->PushMessage(System::Messages::OnTimerDone);
}

void TimerController::StopAlerting() {
state = TimerState::Not_Running;
systemTask->PushMessage(System::Messages::StopRinging);
}
11 changes: 9 additions & 2 deletions src/components/timer/TimerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,20 @@ namespace Pinetime {

uint32_t GetTimeRemaining();

bool IsRunning();

void OnTimerEnd();

void StopAlerting();

enum class TimerState { Not_Running, Running, Alerting };

TimerState State() const {
return state;
}

private:
System::SystemTask* systemTask = nullptr;
TimerHandle_t timer;
TimerState state = TimerState::Not_Running;
};
}
}
2 changes: 1 addition & 1 deletion src/displayapp/DisplayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void DisplayApp::Refresh() {
case Messages::TimerDone:
if (currentApp == Apps::Timer) {
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
timer->Reset();
timer->SetTimerAlerting();
} else {
LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down);
}
Expand Down
89 changes: 61 additions & 28 deletions src/displayapp/screens/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : Screen(app), timerController {timerController} {

lv_obj_t* colonLabel = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
lv_obj_set_style_local_text_font(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
lv_obj_set_style_local_text_color(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_label_set_text_static(colonLabel, ":");
Expand Down Expand Up @@ -62,10 +63,16 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : S
txtPlayPause = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(txtPlayPause, btnPlayPause, LV_ALIGN_CENTER, 0, 0);

if (timerController.IsRunning()) {
SetTimerRunning();
} else {
SetTimerStopped();
switch (timerController.State()) {
case Controllers::TimerController::TimerState::Running:
SetTimerRunning();
break;
case Controllers::TimerController::TimerState::Not_Running:
SetTimerStopped();
break;
case Controllers::TimerController::TimerState::Alerting:
SetTimerAlerting();
break;
}

taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
Expand All @@ -85,7 +92,7 @@ void Timer::MaskReset() {
buttonPressing = false;
// A click event is processed before a release event,
// so the release event would override the "Pause" text without this check
if (!timerController.IsRunning()) {
if (timerController.State() == Controllers::TimerController::TimerState::Not_Running) {
lv_label_set_text_static(txtPlayPause, "Start");
}
maskPosition = 0;
Expand All @@ -103,45 +110,71 @@ void Timer::UpdateMask() {
}

void Timer::Refresh() {
if (timerController.IsRunning()) {
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
minuteCounter.SetValue(seconds / 60);
secondCounter.SetValue(seconds % 60);
} else if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) {
lv_label_set_text_static(txtPlayPause, "Reset");
maskPosition += 15;
if (maskPosition > 240) {
MaskReset();
Reset();
} else {
UpdateMask();
}
switch (timerController.State()) {
case Controllers::TimerController::TimerState::Running:
case Controllers::TimerController::TimerState::Alerting: {
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
minuteCounter.SetValue(seconds / 60);
secondCounter.SetValue(seconds % 60);
} break;
case Controllers::TimerController::TimerState::Not_Running:
if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) {
lv_label_set_text_static(txtPlayPause, "Reset");
maskPosition += 15;
if (maskPosition > 240) {
MaskReset();
Reset();
} else {
UpdateMask();
}
}
break;
}
}

void Timer::SetTimerRunning() {
minuteCounter.HideControls();
secondCounter.HideControls();
lv_label_set_text_static(txtPlayPause, "Pause");
MaskReset();
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
}

void Timer::SetTimerAlerting() {
minuteCounter.HideControls();
secondCounter.HideControls();
lv_label_set_text_static(txtPlayPause, "Reset");
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
}

void Timer::SetTimerStopped() {
minuteCounter.ShowControls();
secondCounter.ShowControls();
lv_label_set_text_static(txtPlayPause, "Start");
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
}

void Timer::ToggleRunning() {
if (timerController.IsRunning()) {
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
minuteCounter.SetValue(seconds / 60);
secondCounter.SetValue(seconds % 60);
timerController.StopTimer();
SetTimerStopped();
} else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000);
Refresh();
SetTimerRunning();
switch (timerController.State()) {
case Controllers::TimerController::TimerState::Running: {
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
minuteCounter.SetValue(seconds / 60);
secondCounter.SetValue(seconds % 60);
}
timerController.StopTimer();
SetTimerStopped();
break;
case Controllers::TimerController::TimerState::Alerting:
timerController.StopAlerting();
Reset();
break;
case Controllers::TimerController::TimerState::Not_Running:
if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000);
Refresh();
SetTimerRunning();
}
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/displayapp/screens/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ namespace Pinetime::Applications::Screens {
void ToggleRunning();
void ButtonPressed();
void MaskReset();
void SetTimerAlerting();

private:
void SetTimerRunning();
void SetTimerStopped();
void UpdateMask();
Controllers::TimerController& timerController;

lv_obj_t* msecTime;
lv_obj_t* btnPlayPause;
lv_obj_t* txtPlayPause;

Expand Down
2 changes: 1 addition & 1 deletion src/systemtask/SystemTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void SystemTask::Work() {
if (state == SystemTaskState::Sleeping) {
GoToRunning();
}
motorController.RunForDuration(35);
motorController.StartRinging();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone);
break;
case Messages::SetOffAlarm:
Expand Down