summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/displayapp/DisplayApp.cpp2
-rw-r--r--src/displayapp/screens/StopWatch.cpp197
-rw-r--r--src/displayapp/screens/StopWatch.h16
3 files changed, 95 insertions, 120 deletions
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index de93428c..04ebd2d3 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -337,7 +337,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None);
break;
case Apps::StopWatch:
- currentScreen = std::make_unique<Screens::StopWatch>(this);
+ currentScreen = std::make_unique<Screens::StopWatch>(this, *systemTask);
break;
case Apps::Twos:
currentScreen = std::make_unique<Screens::Twos>(this);
diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp
index 7c128d1b..f4db5d6e 100644
--- a/src/displayapp/screens/StopWatch.cpp
+++ b/src/displayapp/screens/StopWatch.cpp
@@ -45,17 +45,16 @@ static void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
stopWatch->stopLapBtnEventHandler(event);
}
-StopWatch::StopWatch(DisplayApp* app)
+StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask)
: Screen(app),
+ systemTask {systemTask},
running {true},
currentState {States::Init},
- currentEvent {Events::Stop},
startTime {},
oldTimeElapsed {},
currentTimeSeparated {},
lapBuffer {},
- lapNr {},
- lapPressed {false} {
+ lapNr {} {
time = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
@@ -105,128 +104,100 @@ StopWatch::StopWatch(DisplayApp* app)
}
StopWatch::~StopWatch() {
+ systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
lv_obj_clean(lv_scr_act());
}
+void StopWatch::reset() {
+ currentState = States::Init;
+ oldTimeElapsed = 0;
+ lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
+ lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
+
+ lv_label_set_text(time, "00:00");
+ lv_label_set_text(msecTime, "00");
+
+ lv_label_set_text(lapOneText, "");
+ lv_label_set_text(lapTwoText, "");
+ lapBuffer.clearBuffer();
+ lapNr = 0;
+ lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
+ lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
+}
+
+void StopWatch::start() {
+ lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
+ lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
+ lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
+ lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
+ lv_label_set_text(txtPlayPause, Symbols::pause);
+ lv_label_set_text(txtStopLap, Symbols::lapsFlag);
+ startTime = xTaskGetTickCount();
+ currentState = States::Running;
+ systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
+}
+
+void StopWatch::pause() {
+ startTime = 0;
+ // Store the current time elapsed in cache
+ oldTimeElapsed += timeElapsed;
+ currentState = States::Halted;
+ lv_label_set_text(txtPlayPause, Symbols::play);
+ lv_label_set_text(txtStopLap, Symbols::stop);
+ lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
+ lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
+ systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
+}
+
bool StopWatch::Refresh() {
- // @startuml CHIP8_state
- // State "Init" as init
- // State "Running" as run
- // State "Halted" as halt
-
- // [*] --> init
- // init -> run : press play
- // run -> run : press lap
- // run --> halt : press pause
- // halt --> run : press play
- // halt --> init : press stop
- // @enduml
- // Copy paste the above plantuml text to visualize the state diagram
- switch (currentState) {
- // Init state when an user first opens the app
- // and when a stop/reset button is pressed
- case States::Init: {
- // The initial default value
- lv_label_set_text(time, "00:00");
- lv_label_set_text(msecTime, "00");
-
- lv_label_set_text(lapOneText, "");
- lv_label_set_text(lapTwoText, "");
- lapBuffer.clearBuffer();
- lapNr = 0;
-
- if (currentEvent == Events::Play) {
- lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
- lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
-
- startTime = xTaskGetTickCount();
- currentState = States::Running;
- } else {
- lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
- lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
- }
- break;
- }
- case States::Running: {
- lv_label_set_text(txtPlayPause, Symbols::pause);
- lv_label_set_text(txtStopLap, Symbols::lapsFlag);
-
- const auto timeElapsed = calculateDelta(startTime, xTaskGetTickCount());
- currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
-
- lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
- lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
-
- if (lapPressed == true) {
- if (lapBuffer[1]) {
- lv_label_set_text_fmt(
- lapOneText, "#%2d %2d:%02d.%02d", (lapNr - 1), lapBuffer[1]->mins, lapBuffer[1]->secs, lapBuffer[1]->hundredths);
- }
- if (lapBuffer[0]) {
- lv_label_set_text_fmt(
- lapTwoText, "#%2d %2d:%02d.%02d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->hundredths);
- }
- // Reset the bool to avoid setting the text in each cycle until there is a change
- lapPressed = false;
- }
-
- if (currentEvent == Events::Pause) {
- // Reset the start time
- startTime = 0;
- // Store the current time elapsed in cache
- oldTimeElapsed += timeElapsed;
- currentState = States::Halted;
- lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
- lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
- } else {
- lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
- lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
- }
- break;
- }
- case States::Halted: {
- lv_label_set_text(txtPlayPause, Symbols::play);
- lv_label_set_text(txtStopLap, Symbols::stop);
-
- if (currentEvent == Events::Play) {
- startTime = xTaskGetTickCount();
- currentState = States::Running;
- }
- if (currentEvent == Events::Stop) {
- currentState = States::Init;
- oldTimeElapsed = 0;
- lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
- lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
- }
- break;
- }
+ if (currentState == States::Running) {
+ timeElapsed = calculateDelta(startTime, xTaskGetTickCount());
+ currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
+
+ lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
+ lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
}
return running;
}
void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
- if (event == LV_EVENT_CLICKED) {
- if (currentState == States::Init) {
- currentEvent = Events::Play;
- } else {
- // Simple Toggle for play/pause
- currentEvent = (currentEvent == Events::Play ? Events::Pause : Events::Play);
- }
+ if (event != LV_EVENT_PRESSED) {
+ return;
+ }
+ if (currentState == States::Init) {
+ start();
+ } else if (currentState == States::Running) {
+ pause();
+ } else if (currentState == States::Halted) {
+ start();
}
}
void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
- if (event == LV_EVENT_CLICKED) {
- // If running, then this button is used to save laps
- if (currentState == States::Running) {
- lapBuffer.addLaps(currentTimeSeparated);
- lapNr++;
- lapPressed = true;
-
- } else if (currentState == States::Halted) {
- currentEvent = Events::Stop;
- } else {
- // Not possible to reach here. Do nothing.
+ if (event != LV_EVENT_PRESSED) {
+ return;
+ }
+ // If running, then this button is used to save laps
+ if (currentState == States::Running) {
+ lapBuffer.addLaps(currentTimeSeparated);
+ lapNr++;
+ if (lapBuffer[1]) {
+ lv_label_set_text_fmt(
+ lapOneText, "#%2d %2d:%02d.%02d", (lapNr - 1), lapBuffer[1]->mins, lapBuffer[1]->secs, lapBuffer[1]->hundredths);
+ }
+ if (lapBuffer[0]) {
+ lv_label_set_text_fmt(lapTwoText, "#%2d %2d:%02d.%02d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->hundredths);
}
+ } else if (currentState == States::Halted) {
+ reset();
+ }
+}
+
+bool StopWatch::OnButtonPushed() {
+ if (currentState == States::Running) {
+ pause();
+ } else {
+ running = false;
}
+ return true;
}
diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h
index ff604361..e132f158 100644
--- a/src/displayapp/screens/StopWatch.h
+++ b/src/displayapp/screens/StopWatch.h
@@ -8,13 +8,12 @@
#include "portmacro_cmsis.h"
#include <array>
+#include "systemtask/SystemTask.h"
namespace Pinetime::Applications::Screens {
enum class States { Init, Running, Halted };
- enum class Events { Play, Pause, Stop };
-
struct TimeSeparated_t {
int mins;
int secs;
@@ -63,23 +62,28 @@ namespace Pinetime::Applications::Screens {
class StopWatch : public Screen {
public:
- StopWatch(DisplayApp* app);
+ StopWatch(DisplayApp* app, System::SystemTask& systemTask);
~StopWatch() override;
bool Refresh() override;
void playPauseBtnEventHandler(lv_event_t event);
void stopLapBtnEventHandler(lv_event_t event);
+ bool OnButtonPushed() override;
+
+ void reset();
+ void start();
+ void pause();
private:
+ Pinetime::System::SystemTask& systemTask;
+ TickType_t timeElapsed;
bool running;
States currentState;
- Events currentEvent;
TickType_t startTime;
TickType_t oldTimeElapsed;
TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs
LapTextBuffer_t<2> lapBuffer;
- int lapNr;
- bool lapPressed;
+ int lapNr = 0;
lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
lv_obj_t *lapOneText, *lapTwoText;
};