diff --git a/src/components/timer/TimerController.cpp b/src/components/timer/TimerController.cpp index ea945213ba..62bd7bde17 100644 --- a/src/components/timer/TimerController.cpp +++ b/src/components/timer/TimerController.cpp @@ -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); +} diff --git a/src/components/timer/TimerController.h b/src/components/timer/TimerController.h index 93d8afc608..ca2f207530 100644 --- a/src/components/timer/TimerController.h +++ b/src/components/timer/TimerController.h @@ -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; }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 108e380d69..768d6e588c 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -185,7 +185,7 @@ void DisplayApp::Refresh() { case Messages::TimerDone: if (currentApp == Apps::Timer) { auto* timer = static_cast(currentScreen.get()); - timer->Reset(); + timer->SetTimerAlerting(); } else { LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down); } diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index 136d6b52af..6ecfc5403b 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -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, ":"); @@ -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); @@ -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; @@ -103,19 +110,25 @@ 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; } } @@ -123,25 +136,45 @@ 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; } } diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index a6b60a1771..acb1678458 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -19,6 +19,7 @@ namespace Pinetime::Applications::Screens { void ToggleRunning(); void ButtonPressed(); void MaskReset(); + void SetTimerAlerting(); private: void SetTimerRunning(); @@ -26,7 +27,6 @@ namespace Pinetime::Applications::Screens { void UpdateMask(); Controllers::TimerController& timerController; - lv_obj_t* msecTime; lv_obj_t* btnPlayPause; lv_obj_t* txtPlayPause; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index ef631af74e..846fdc1964 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -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: