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.
This commit is contained in:
parent
81bc16fd92
commit
822f857d9e
3 changed files with 91 additions and 52 deletions
|
@ -5,6 +5,7 @@
|
||||||
namespace Colors {
|
namespace Colors {
|
||||||
static constexpr lv_color_t orange = LV_COLOR_MAKE(0xff, 0xb0, 0x0);
|
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 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 lightGray = LV_COLOR_MAKE(0xb0, 0xb0, 0xb0);
|
||||||
|
|
||||||
static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);
|
static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);
|
||||||
|
|
|
@ -18,51 +18,60 @@ namespace {
|
||||||
|
|
||||||
void play_pause_event_handler(lv_obj_t* obj, lv_event_t event) {
|
void play_pause_event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||||
auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
|
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) {
|
void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||||
auto* stopWatch = static_cast<StopWatch*>(obj->user_data);
|
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} {
|
StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) : Screen(app), systemTask {systemTask} {
|
||||||
|
static constexpr uint8_t btnWidth = 115;
|
||||||
time = lv_label_create(lv_scr_act(), nullptr);
|
static constexpr uint8_t btnHeight = 80;
|
||||||
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);
|
|
||||||
|
|
||||||
btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
|
btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
|
||||||
btnPlayPause->user_data = this;
|
btnPlayPause->user_data = this;
|
||||||
lv_obj_set_event_cb(btnPlayPause, play_pause_event_handler);
|
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);
|
lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||||
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
|
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
|
||||||
lv_label_set_text_static(txtPlayPause, Symbols::play);
|
|
||||||
|
|
||||||
btnStopLap = lv_btn_create(lv_scr_act(), nullptr);
|
btnStopLap = lv_btn_create(lv_scr_act(), nullptr);
|
||||||
btnStopLap->user_data = this;
|
btnStopLap->user_data = this;
|
||||||
lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler);
|
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);
|
lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||||
txtStopLap = lv_label_create(btnStopLap, nullptr);
|
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(btnStopLap, LV_STATE_DISABLED);
|
||||||
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
||||||
|
|
||||||
lapText = lv_label_create(lv_scr_act(), nullptr);
|
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_set_style_local_text_color(lapText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||||
lv_obj_align(lapText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30);
|
lv_label_set_text_static(lapText, "\n");
|
||||||
lv_label_set_text_static(lapText, "");
|
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);
|
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
||||||
}
|
}
|
||||||
|
@ -73,42 +82,62 @@ StopWatch::~StopWatch() {
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_clean(lv_scr_act());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::Reset() {
|
void StopWatch::SetInterfacePaused() {
|
||||||
currentState = States::Init;
|
lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||||
oldTimeElapsed = 0;
|
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
|
||||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
lv_label_set_text_static(txtPlayPause, Symbols::play);
|
||||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
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(time, "00:00");
|
||||||
lv_label_set_text_static(msecTime, "00");
|
lv_label_set_text_static(msecTime, "00");
|
||||||
|
|
||||||
lv_label_set_text_static(lapText, "");
|
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(btnStopLap, LV_STATE_DISABLED);
|
||||||
lv_obj_set_state(txtStopLap, 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() {
|
void StopWatch::Start() {
|
||||||
lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
|
SetInterfaceRunning();
|
||||||
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);
|
|
||||||
startTime = xTaskGetTickCount();
|
startTime = xTaskGetTickCount();
|
||||||
currentState = States::Running;
|
currentState = States::Running;
|
||||||
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
|
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::Pause() {
|
void StopWatch::Pause() {
|
||||||
|
SetInterfacePaused();
|
||||||
startTime = 0;
|
startTime = 0;
|
||||||
// Store the current time elapsed in cache
|
// Store the current time elapsed in cache
|
||||||
oldTimeElapsed = laps[lapsDone];
|
oldTimeElapsed = laps[lapsDone];
|
||||||
|
blinkTime = xTaskGetTickCount() + blinkInterval;
|
||||||
currentState = States::Halted;
|
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);
|
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,26 +148,30 @@ void StopWatch::Refresh() {
|
||||||
TimeSeparated_t currentTimeSeparated = convertTicksToTimeSegments(laps[lapsDone]);
|
TimeSeparated_t currentTimeSeparated = convertTicksToTimeSegments(laps[lapsDone]);
|
||||||
lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
|
lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
|
||||||
lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
|
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) {
|
void StopWatch::playPauseBtnEventHandler() {
|
||||||
if (event != LV_EVENT_CLICKED) {
|
if (currentState == States::Init || currentState == States::Halted) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (currentState == States::Init) {
|
|
||||||
Start();
|
Start();
|
||||||
} else if (currentState == States::Running) {
|
} else if (currentState == States::Running) {
|
||||||
Pause();
|
Pause();
|
||||||
} else if (currentState == States::Halted) {
|
|
||||||
Start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
|
void StopWatch::stopLapBtnEventHandler() {
|
||||||
if (event != LV_EVENT_CLICKED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If running, then this button is used to save laps
|
// If running, then this button is used to save laps
|
||||||
if (currentState == States::Running) {
|
if (currentState == States::Running) {
|
||||||
lv_label_set_text(lapText, "");
|
lv_label_set_text(lapText, "");
|
||||||
|
|
|
@ -24,19 +24,24 @@ namespace Pinetime::Applications::Screens {
|
||||||
~StopWatch() override;
|
~StopWatch() override;
|
||||||
void Refresh() override;
|
void Refresh() override;
|
||||||
|
|
||||||
void playPauseBtnEventHandler(lv_event_t event);
|
void playPauseBtnEventHandler();
|
||||||
void stopLapBtnEventHandler(lv_event_t event);
|
void stopLapBtnEventHandler();
|
||||||
bool OnButtonPushed() override;
|
bool OnButtonPushed() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetInterfacePaused();
|
||||||
|
void SetInterfaceRunning();
|
||||||
|
void SetInterfaceStopped();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
void Start();
|
void Start();
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
private:
|
|
||||||
Pinetime::System::SystemTask& systemTask;
|
Pinetime::System::SystemTask& systemTask;
|
||||||
States currentState = States::Init;
|
States currentState = States::Init;
|
||||||
TickType_t startTime;
|
TickType_t startTime;
|
||||||
TickType_t oldTimeElapsed = 0;
|
TickType_t oldTimeElapsed = 0;
|
||||||
|
TickType_t blinkTime = 0;
|
||||||
static constexpr int maxLapCount = 20;
|
static constexpr int maxLapCount = 20;
|
||||||
TickType_t laps[maxLapCount + 1];
|
TickType_t laps[maxLapCount + 1];
|
||||||
static constexpr int displayedLaps = 2;
|
static constexpr int displayedLaps = 2;
|
||||||
|
|
Loading…
Reference in a new issue