mirror of
https://github.com/InfiniTimeOrg/InfiniTime.git
synced 2026-01-21 08:22:25 +01:00
timer: Add ringing and counter
The timer app issues a short buzz once and then disappears. There is no trace left that the timer finished or how long ago. This change makes the motor start ringing and presents a timer counter. The timer stops buzzing after 10 seconds, and finally resets after 1 minute.
This commit is contained in:
parent
7128fc045d
commit
54f20ff4cb
@ -34,6 +34,10 @@ void MotorController::StopRinging() {
|
||||
nrf_gpio_pin_set(PinMap::Motor);
|
||||
}
|
||||
|
||||
bool MotorController::IsRinging() {
|
||||
return (xTimerIsTimerActive(longVib) == pdTRUE);
|
||||
}
|
||||
|
||||
void MotorController::StopMotor(TimerHandle_t /*xTimer*/) {
|
||||
nrf_gpio_pin_set(PinMap::Motor);
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ namespace Pinetime {
|
||||
void RunForDuration(uint8_t motorDuration);
|
||||
void StartRinging();
|
||||
void StopRinging();
|
||||
bool IsRinging();
|
||||
|
||||
private:
|
||||
static void Ring(TimerHandle_t xTimer);
|
||||
|
||||
@ -41,3 +41,7 @@ void Timer::StopTimer() {
|
||||
bool Timer::IsRunning() {
|
||||
return (xTimerIsTimerActive(timer) == pdTRUE);
|
||||
}
|
||||
|
||||
void Timer::ResetExpiredTime() {
|
||||
triggered = false;
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace Pinetime {
|
||||
|
||||
bool IsRunning();
|
||||
|
||||
void ResetExpiredTime();
|
||||
|
||||
private:
|
||||
TimerHandle_t timer;
|
||||
TickType_t expiry;
|
||||
|
||||
@ -368,19 +368,21 @@ void DisplayApp::Refresh() {
|
||||
case Messages::NewNotification:
|
||||
LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
|
||||
break;
|
||||
case Messages::TimerDone:
|
||||
case Messages::TimerDone: {
|
||||
if (state != States::Running) {
|
||||
PushMessageToSystemTask(System::Messages::GoToRunning);
|
||||
}
|
||||
if (currentApp == Apps::Timer) {
|
||||
lv_disp_trig_activity(nullptr);
|
||||
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
|
||||
timer->Reset();
|
||||
} else {
|
||||
// Load timer app if not loaded
|
||||
if (currentApp != Apps::Timer) {
|
||||
LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up);
|
||||
}
|
||||
motorController.RunForDuration(35);
|
||||
// Set the timer to ringing mode
|
||||
lv_disp_trig_activity(nullptr);
|
||||
auto* timerScreen = static_cast<Screens::Timer*>(currentScreen.get());
|
||||
timerScreen->SetTimerRinging();
|
||||
motorController.StartRinging();
|
||||
break;
|
||||
}
|
||||
case Messages::AlarmTriggered:
|
||||
if (currentApp == Apps::Alarm) {
|
||||
auto* alarm = static_cast<Screens::Alarm*>(currentScreen.get());
|
||||
|
||||
@ -17,7 +17,8 @@ static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
}
|
||||
}
|
||||
|
||||
Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
|
||||
Timer::Timer(Controllers::Timer& timerController, Controllers::MotorController& motorController)
|
||||
: timer {timerController}, motorController {motorController} {
|
||||
|
||||
lv_obj_t* colonLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
@ -62,7 +63,9 @@ Timer::Timer(Controllers::Timer& timerController) : timer {timerController} {
|
||||
// Create the label as a child of the button so it stays centered by default
|
||||
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
|
||||
|
||||
if (timer.IsRunning()) {
|
||||
if (motorController.IsRinging()) {
|
||||
SetTimerRinging();
|
||||
} else if (timer.IsRunning()) {
|
||||
SetTimerRunning();
|
||||
} else {
|
||||
SetTimerStopped();
|
||||
@ -103,7 +106,17 @@ void Timer::UpdateMask() {
|
||||
}
|
||||
|
||||
void Timer::Refresh() {
|
||||
if (timer.IsRunning()) {
|
||||
if (isRinging) {
|
||||
DisplayTime();
|
||||
// Stop buzzing after 10 seconds, but continue the counter
|
||||
if (motorController.IsRinging() && displaySeconds.Get().count() > 10) {
|
||||
motorController.StopRinging();
|
||||
}
|
||||
// Reset timer after 1 minute
|
||||
if (displaySeconds.Get().count() > 60) {
|
||||
Reset();
|
||||
}
|
||||
} else if (timer.IsRunning()) {
|
||||
DisplayTime();
|
||||
} else if (buttonPressing && xTaskGetTickCount() - pressTime > pdMS_TO_TICKS(150)) {
|
||||
lv_label_set_text_static(txtPlayPause, "Reset");
|
||||
@ -130,16 +143,30 @@ void Timer::SetTimerRunning() {
|
||||
minuteCounter.HideControls();
|
||||
secondCounter.HideControls();
|
||||
lv_label_set_text_static(txtPlayPause, "Pause");
|
||||
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
}
|
||||
|
||||
void Timer::SetTimerStopped() {
|
||||
isRinging = false;
|
||||
minuteCounter.ShowControls();
|
||||
secondCounter.ShowControls();
|
||||
lv_label_set_text_static(txtPlayPause, "Start");
|
||||
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
||||
}
|
||||
|
||||
void Timer::SetTimerRinging() {
|
||||
isRinging = true;
|
||||
minuteCounter.HideControls();
|
||||
secondCounter.HideControls();
|
||||
lv_label_set_text_static(txtPlayPause, "Reset");
|
||||
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
}
|
||||
|
||||
void Timer::ToggleRunning() {
|
||||
if (timer.IsRunning()) {
|
||||
if (isRinging) {
|
||||
motorController.StopRinging();
|
||||
Reset();
|
||||
} else if (timer.IsRunning()) {
|
||||
DisplayTime();
|
||||
timer.StopTimer();
|
||||
SetTimerStopped();
|
||||
@ -152,6 +179,7 @@ void Timer::ToggleRunning() {
|
||||
}
|
||||
|
||||
void Timer::Reset() {
|
||||
timer.ResetExpiredTime();
|
||||
DisplayTime();
|
||||
SetTimerStopped();
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "components/motor/MotorController.h"
|
||||
#include "systemtask/SystemTask.h"
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
@ -14,13 +15,14 @@ namespace Pinetime::Applications {
|
||||
namespace Screens {
|
||||
class Timer : public Screen {
|
||||
public:
|
||||
Timer(Controllers::Timer& timerController);
|
||||
Timer(Controllers::Timer& timerController, Controllers::MotorController& motorController);
|
||||
~Timer() override;
|
||||
void Refresh() override;
|
||||
void Reset();
|
||||
void ToggleRunning();
|
||||
void ButtonPressed();
|
||||
void MaskReset();
|
||||
void SetTimerRinging();
|
||||
|
||||
private:
|
||||
void SetTimerRunning();
|
||||
@ -28,6 +30,7 @@ namespace Pinetime::Applications {
|
||||
void UpdateMask();
|
||||
void DisplayTime();
|
||||
Pinetime::Controllers::Timer& timer;
|
||||
Pinetime::Controllers::MotorController& motorController;
|
||||
|
||||
lv_obj_t* btnPlayPause;
|
||||
lv_obj_t* txtPlayPause;
|
||||
@ -42,6 +45,7 @@ namespace Pinetime::Applications {
|
||||
Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
|
||||
|
||||
bool buttonPressing = false;
|
||||
bool isRinging = false;
|
||||
lv_coord_t maskPosition = 0;
|
||||
TickType_t pressTime = 0;
|
||||
Utility::DirtyValue<std::chrono::seconds> displaySeconds;
|
||||
@ -54,7 +58,7 @@ namespace Pinetime::Applications {
|
||||
static constexpr const char* icon = Screens::Symbols::hourGlass;
|
||||
|
||||
static Screens::Screen* Create(AppControllers& controllers) {
|
||||
return new Screens::Timer(controllers.timer);
|
||||
return new Screens::Timer(controllers.timer, controllers.motorController);
|
||||
};
|
||||
|
||||
static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user