InfiniTime.git

commit 822f857d9e3bdc38985286652bec0d9cce89297d

Author: Riku Isokoski <riksu9000@gmail.com>

stopwatch: Update UI

The time used to be yellow while paused. Changing it to white made the
paused state less distinct. Blinking the time while paused makes the
state distinct again.

 src/displayapp/InfiniTimeTheme.h | 1 
 src/displayapp/screens/StopWatch.cpp | 131 ++++++++++++++++++-----------
 src/displayapp/screens/StopWatch.h | 11 +


diff --git a/src/displayapp/InfiniTimeTheme.h b/src/displayapp/InfiniTimeTheme.h
index 52c339ddcd43a82bec94268ab0538c797973e2b9..99313cf019b8702d8fe5af5f568b0ab3dae13805 100644
--- a/src/displayapp/InfiniTimeTheme.h
+++ b/src/displayapp/InfiniTimeTheme.h
@@ -5,6 +5,7 @@
 namespace Colors {
   static constexpr lv_color_t orange = LV_COLOR_MAKE(0xff, 0xb0, 0x0);
   static constexpr lv_color_t green = LV_COLOR_MAKE(0x0, 0xb0, 0x0);
+  static constexpr lv_color_t blue = LV_COLOR_MAKE(0x0, 0x50, 0xff);
   static constexpr lv_color_t lightGray = LV_COLOR_MAKE(0xb0, 0xb0, 0xb0);
 
   static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);




diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp
index c68cd854125220202359d6927f6f1aca73ac7ed9..a094c6e05d216c276bab06a1e3d5a170e1fc0d7d 100644
--- a/src/displayapp/screens/StopWatch.cpp
+++ b/src/displayapp/screens/StopWatch.cpp
@@ -18,51 +18,60 @@   }
 
   void play_pause_event_handler(lv_obj_t* obj, lv_event_t event) {
     auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
-    stopWatch->playPauseBtnEventHandler(event);
+    if (event == LV_EVENT_CLICKED) {
+      stopWatch->playPauseBtnEventHandler();
+    }
   }
 
   void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
     auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
-    stopWatch->stopLapBtnEventHandler(event);
+    if (event == LV_EVENT_CLICKED) {
+      stopWatch->stopLapBtnEventHandler();
+    }
   }
+
+  constexpr TickType_t blinkInterval = pdMS_TO_TICKS(1000);
 }
 
 StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) : Screen(app), systemTask {systemTask} {
-
-  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);
-  lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
-  lv_label_set_text_static(time, "00:00");
-  lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -45);
-
-  msecTime = lv_label_create(lv_scr_act(), nullptr);
-  // lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
-  lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
-  lv_label_set_text_static(msecTime, "00");
-  lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_CENTER, 0, 3);
-
+  static constexpr uint8_t btnWidth = 115;
+  static constexpr uint8_t btnHeight = 80;
   btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
   btnPlayPause->user_data = this;
   lv_obj_set_event_cb(btnPlayPause, play_pause_event_handler);
-  lv_obj_set_size(btnPlayPause, 115, 50);
+  lv_obj_set_size(btnPlayPause, btnWidth, btnHeight);
   lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
   txtPlayPause = lv_label_create(btnPlayPause, nullptr);
-  lv_label_set_text_static(txtPlayPause, Symbols::play);
 
   btnStopLap = lv_btn_create(lv_scr_act(), nullptr);
   btnStopLap->user_data = this;
   lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler);
-  lv_obj_set_size(btnStopLap, 115, 50);
+  lv_obj_set_size(btnStopLap, btnWidth, btnHeight);
   lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
   txtStopLap = lv_label_create(btnStopLap, nullptr);
-  lv_label_set_text_static(txtStopLap, Symbols::stop);
   lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
   lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
 
   lapText = lv_label_create(lv_scr_act(), nullptr);
-  lv_obj_set_style_local_text_color(lapText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
-  lv_obj_align(lapText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30);
-  lv_label_set_text_static(lapText, "");
+  lv_obj_set_style_local_text_color(lapText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
+  lv_label_set_text_static(lapText, "\n");
+  lv_label_set_long_mode(lapText, LV_LABEL_LONG_BREAK);
+  lv_label_set_align(lapText, LV_LABEL_ALIGN_CENTER);
+  lv_obj_set_width(lapText, LV_HOR_RES_MAX);
+  lv_obj_align(lapText, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, -btnHeight);
+
+  msecTime = lv_label_create(lv_scr_act(), nullptr);
+  lv_label_set_text_static(msecTime, "00");
+  lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, Colors::lightGray);
+  lv_obj_align(msecTime, lapText, LV_ALIGN_OUT_TOP_MID, 0, 0);
+
+  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);
+  lv_label_set_text_static(time, "00:00");
+  lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, Colors::lightGray);
+  lv_obj_align(time, msecTime, LV_ALIGN_OUT_TOP_MID, 0, 0);
+
+  SetInterfaceStopped();
 
   taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
 }
@@ -73,42 +82,62 @@   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, Colors::lightGray);
-  lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
+void StopWatch::SetInterfacePaused() {
+  lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
+  lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
+  lv_label_set_text_static(txtPlayPause, Symbols::play);
+  lv_label_set_text_static(txtStopLap, Symbols::stop);
+}
+
+void StopWatch::SetInterfaceRunning() {
+  lv_obj_set_state(time, LV_STATE_DEFAULT);
+  lv_obj_set_state(msecTime, LV_STATE_DEFAULT);
+  lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
+  lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
+
+  lv_label_set_text_static(txtPlayPause, Symbols::pause);
+  lv_label_set_text_static(txtStopLap, Symbols::lapsFlag);
+
+  lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
+  lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
+}
+
+void StopWatch::SetInterfaceStopped() {
+  lv_obj_set_state(time, LV_STATE_DISABLED);
+  lv_obj_set_state(msecTime, LV_STATE_DISABLED);
+  lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
 
   lv_label_set_text_static(time, "00:00");
   lv_label_set_text_static(msecTime, "00");
 
   lv_label_set_text_static(lapText, "");
-  lapsDone = 0;
+  lv_label_set_text_static(txtPlayPause, Symbols::play);
+  lv_label_set_text_static(txtStopLap, Symbols::lapsFlag);
   lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
   lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
 }
 
+void StopWatch::Reset() {
+  SetInterfaceStopped();
+  currentState = States::Init;
+  oldTimeElapsed = 0;
+  lapsDone = 0;
+}
+
 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, Colors::highlight);
-  lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
-  lv_label_set_text_static(txtPlayPause, Symbols::pause);
-  lv_label_set_text_static(txtStopLap, Symbols::lapsFlag);
+  SetInterfaceRunning();
   startTime = xTaskGetTickCount();
   currentState = States::Running;
   systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
 }
 
 void StopWatch::Pause() {
+  SetInterfacePaused();
   startTime = 0;
   // Store the current time elapsed in cache
   oldTimeElapsed = laps[lapsDone];
+  blinkTime = xTaskGetTickCount() + blinkInterval;
   currentState = States::Halted;
-  lv_label_set_text_static(txtPlayPause, Symbols::play);
-  lv_label_set_text_static(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);
 }
 
@@ -119,26 +148,30 @@
     TimeSeparated_t currentTimeSeparated = convertTicksToTimeSegments(laps[lapsDone]);
     lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
     lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
+  } else if (currentState == States::Halted) {
+    const TickType_t currentTime = xTaskGetTickCount();
+    if (currentTime > blinkTime) {
+      blinkTime = currentTime + blinkInterval;
+      if (lv_obj_get_state(time, LV_LABEL_PART_MAIN) == LV_STATE_DEFAULT) {
+        lv_obj_set_state(time, LV_STATE_DISABLED);
+        lv_obj_set_state(msecTime, LV_STATE_DISABLED);
+      } else {
+        lv_obj_set_state(time, LV_STATE_DEFAULT);
+        lv_obj_set_state(msecTime, LV_STATE_DEFAULT);
+      }
+    }
   }
 }
 
-void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
-  if (event != LV_EVENT_CLICKED) {
-    return;
-  }
-  if (currentState == States::Init) {
+void StopWatch::playPauseBtnEventHandler() {
+  if (currentState == States::Init || currentState == States::Halted) {
     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) {
-    return;
-  }
+void StopWatch::stopLapBtnEventHandler() {
   // If running, then this button is used to save laps
   if (currentState == States::Running) {
     lv_label_set_text(lapText, "");




diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h
index f2f57110b07d566550402212897fe482351d593e..ce9d0feaa37d461fe911e4af50163925bc6f4073 100644
--- a/src/displayapp/screens/StopWatch.h
+++ b/src/displayapp/screens/StopWatch.h
@@ -24,19 +24,24 @@     StopWatch(DisplayApp* app, System::SystemTask& systemTask);
     ~StopWatch() override;
     void Refresh() override;
 
-    void playPauseBtnEventHandler(lv_event_t event);
-    void stopLapBtnEventHandler(lv_event_t event);
+    void playPauseBtnEventHandler();
+    void stopLapBtnEventHandler();
     bool OnButtonPushed() override;
 
+  private:
+    void SetInterfacePaused();
+    void SetInterfaceRunning();
+    void SetInterfaceStopped();
+
     void Reset();
     void Start();
     void Pause();
 
-  private:
     Pinetime::System::SystemTask& systemTask;
     States currentState = States::Init;
     TickType_t startTime;
     TickType_t oldTimeElapsed = 0;
+    TickType_t blinkTime = 0;
     static constexpr int maxLapCount = 20;
     TickType_t laps[maxLapCount + 1];
     static constexpr int displayedLaps = 2;