From 8c53d0b70baa03c2b07360444a7cd0ad99bb8381 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Wed, 24 Feb 2021 19:40:24 +0000 Subject: Multi face support, analog clock, 12/24 config --- src/displayapp/screens/WatchFaceDigital.cpp | 254 ++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/displayapp/screens/WatchFaceDigital.cpp (limited to 'src/displayapp/screens/WatchFaceDigital.cpp') diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp new file mode 100644 index 00000000..99df318a --- /dev/null +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -0,0 +1,254 @@ +#include "WatchFaceDigital.h" + +#include +#include +#include +#include "BatteryIcon.h" +#include "BleIcon.h" +#include "NotificationIcon.h" +#include "Symbols.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/ble/NotificationManager.h" +#include "components/heartrate/HeartRateController.h" +#include "components/settings/Settings.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; + + +WatchFaceDigital::WatchFaceDigital(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController, + Controllers::NotificationManager& notificatioManager, + Controllers::Settings &settingsController, + Controllers::HeartRateController& heartRateController): Screen(app), currentDateTime{{}}, + dateTimeController{dateTimeController}, batteryController{batteryController}, + bleController{bleController}, notificatioManager{notificatioManager}, + settingsController{settingsController}, + heartRateController{heartRateController} { + settingsController.SetClockFace(0); + + // init + /*currentDateTime = dateTimeController.CurrentDateTime(); + batteryPercentRemaining = batteryController.PercentRemaining(); + bleState = bleController.IsConnected(); + notificationState = notificatioManager.AreNewNotificationsAvailable(); + heartbeat = heartRateController.HeartRate();*/ + + displayedChar[0] = 0; + displayedChar[1] = 0; + displayedChar[2] = 0; + displayedChar[3] = 0; + displayedChar[4] = 0; + + batteryIcon = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); + + batteryPlug = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); + lv_label_set_text(batteryPlug, Symbols::plug); + lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + bleIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0000FF)); + lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + notificationIcon = lv_label_create(lv_scr_act(), NULL); + lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); + lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); + + label_date = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); + lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999)); + + label_time = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); + + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 0); + + label_time_ampm = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(label_time_ampm, ""); + lv_obj_align(label_time_ampm, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -30, -55); + + backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_click(backgroundLabel, true); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); + + + heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(heartbeatIcon, Symbols::heartBeat); + lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + + heartbeatValue = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); + lv_label_set_text(heartbeatValue, "---"); + lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + + heartbeatBpm = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(heartbeatBpm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); + lv_label_set_text(heartbeatBpm, "BPM"); + lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + + stepValue = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); + lv_label_set_text(stepValue, "0"); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + + stepIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); + lv_label_set_text(stepIcon, Symbols::shoe); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); +} + +WatchFaceDigital::~WatchFaceDigital() { + lv_obj_clean(lv_scr_act()); +} + +bool WatchFaceDigital::Refresh() { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { + auto batteryPercent = batteryPercentRemaining.Get(); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent(); + lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); + } + + bleState = bleController.IsConnected(); + if (bleState.IsUpdated()) { + if(bleState.Get() == true) { + lv_label_set_text(bleIcon, BleIcon::GetIcon(true)); + } else { + lv_label_set_text(bleIcon, BleIcon::GetIcon(false)); + } + } + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); + lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + notificationState = notificatioManager.AreNewNotificationsAvailable(); + if(notificationState.IsUpdated()) { + if(notificationState.Get() == true) + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true)); + else + lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); + } + + currentDateTime = dateTimeController.CurrentDateTime(); + + if(currentDateTime.IsUpdated()) { + auto newDateTime = currentDateTime.Get(); + + auto dp = date::floor(newDateTime); + auto time = date::make_time(newDateTime-dp); + auto yearMonthDay = date::year_month_day(dp); + + auto year = (int)yearMonthDay.year(); + auto month = static_cast((unsigned)yearMonthDay.month()); + auto day = (unsigned)yearMonthDay.day(); + auto dayOfWeek = static_cast(date::weekday(yearMonthDay).iso_encoding()); + + int hour = time.hours().count(); + auto minute = time.minutes().count(); + + char minutesChar[3]; + sprintf(minutesChar, "%02d", static_cast(minute)); + + char hoursChar[3]; + char ampmChar[3]; + if ( settingsController.GetClockType() == Controllers::Settings::ClockType::H24 ) { + sprintf(hoursChar, "%02d", hour); + } else { + if (hour > 12) { + hour -= 12; + sprintf(ampmChar, "PM"); + } else { + sprintf(ampmChar, "AM"); + } + sprintf(hoursChar, "%02d", hour); + } + + if(hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || minutesChar[1] != displayedChar[3]) { + displayedChar[0] = hoursChar[0]; + displayedChar[1] = hoursChar[1]; + displayedChar[2] = minutesChar[0]; + displayedChar[3] = minutesChar[1]; + + char timeStr[6]; + + if ( settingsController.GetClockType() == Controllers::Settings::ClockType::H12 ) { + lv_label_set_text(label_time_ampm, ampmChar); + if ( hoursChar[0] == '0' ) { hoursChar[0] = ' '; } + } + + sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); + lv_label_set_text(label_time, timeStr); + + if ( settingsController.GetClockType() == Controllers::Settings::ClockType::H12 ) { + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 0); + } else { + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + } + + } + + if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { + char dateStr[22]; + if ( settingsController.GetClockType() == Controllers::Settings::ClockType::H24 ) { + sprintf(dateStr, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); + } else { + sprintf(dateStr, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); + } + lv_label_set_text(label_date, dateStr); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); + + + currentYear = year; + currentMonth = month; + currentDayOfWeek = dayOfWeek; + currentDay = day; + } + } + + heartbeat = heartRateController.HeartRate(); + heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped; + if(heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) { + char heartbeatBuffer[4]; + if(heartbeatRunning.Get()) + sprintf(heartbeatBuffer, "%d", heartbeat.Get()); + else + sprintf(heartbeatBuffer, "---"); + + lv_label_set_text(heartbeatValue, heartbeatBuffer); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + } + + // TODO stepCount = stepController.GetValue(); + if(stepCount.IsUpdated()) { + char stepBuffer[5]; + sprintf(stepBuffer, "%lu", stepCount.Get()); + lv_label_set_text(stepValue, stepBuffer); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + } + + return running; +} + + +bool WatchFaceDigital::OnButtonPushed() { + running = false; + return false; +} + + -- cgit v1.2.3 From 97deb43fb78b581535887938a0c3c0813896fcbe Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sat, 6 Mar 2021 19:55:53 +0000 Subject: Update from JF comments to PR --- src/components/settings/Settings.cpp | 2 -- src/displayapp/screens/Clock.h | 6 ++++-- src/displayapp/screens/ScreenList.h | 18 ++---------------- src/displayapp/screens/WatchFaceAnalog.cpp | 6 ------ src/displayapp/screens/WatchFaceDigital.cpp | 7 ------- 5 files changed, 6 insertions(+), 33 deletions(-) (limited to 'src/displayapp/screens/WatchFaceDigital.cpp') diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 87cfe885..0c6cf610 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -6,9 +6,7 @@ using namespace Pinetime::Controllers; // TODO (team): // Read and write the settings to Flash // - void Settings::Init() { - // default Clock face clockFace = 0; diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 2b1be4ac..964ccbf6 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -49,8 +49,10 @@ namespace Pinetime { ScreenList<2> screens; std::unique_ptr WatchFaceDigitalScreen(); std::unique_ptr WatchFaceAnalogScreen(); - std::unique_ptr WatchFaceMinimalScreen(); - std::unique_ptr WatchFaceCustomScreen(); + + // Examples for more watch faces + //std::unique_ptr WatchFaceMinimalScreen(); + //std::unique_ptr WatchFaceCustomScreen(); bool running = true; diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index 56d9abe0..43b33f40 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -15,26 +15,12 @@ namespace Pinetime { class ScreenList : public Screen { public: - ScreenList( - DisplayApp* app, - uint8_t initScreen, - std::array()>, N>&& screens, - ScreenListModes mode - ) - : Screen(app), - initScreen{initScreen}, - screens{std::move(screens)}, - mode{mode}, - current{this->screens[initScreen]()} - { + ScreenList(DisplayApp* app, uint8_t initScreen, std::array()>, N>&& screens, ScreenListModes mode) + : Screen(app), initScreen{initScreen}, screens{std::move(screens)}, mode{mode}, current{this->screens[initScreen]()} { screenIndex = initScreen; } ~ScreenList() override { - current.reset(nullptr); - /*for(uint8_t i = 0; i < screens.size(); i++) { - screens[i]().reset(nullptr); - }*/ lv_obj_clean(lv_scr_act()); } diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index efca10c2..b51d48c7 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -103,12 +103,6 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp *app, UpdateClock(); - /*lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); - lv_obj_set_size(backgroundLabel, 240, 240); - lv_obj_set_pos(backgroundLabel, 0, 0); - lv_label_set_text_static(backgroundLabel, "");*/ - } WatchFaceAnalog::~WatchFaceAnalog() { diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 99df318a..4560ccdb 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -30,13 +30,6 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, heartRateController{heartRateController} { settingsController.SetClockFace(0); - // init - /*currentDateTime = dateTimeController.CurrentDateTime(); - batteryPercentRemaining = batteryController.PercentRemaining(); - bleState = bleController.IsConnected(); - notificationState = notificatioManager.AreNewNotificationsAvailable(); - heartbeat = heartRateController.HeartRate();*/ - displayedChar[0] = 0; displayedChar[1] = 0; displayedChar[2] = 0; -- cgit v1.2.3 From 282e34dca14ddc799b9511643e50a4f9023003ed Mon Sep 17 00:00:00 2001 From: Joaquim José Almeida Pereira Date: Mon, 8 Mar 2021 12:23:32 +0000 Subject: fix AM/PM --- src/displayapp/screens/WatchFaceDigital.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/displayapp/screens/WatchFaceDigital.cpp') diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 4560ccdb..c39fe496 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -160,11 +160,21 @@ bool WatchFaceDigital::Refresh() { if ( settingsController.GetClockType() == Controllers::Settings::ClockType::H24 ) { sprintf(hoursChar, "%02d", hour); } else { - if (hour > 12) { - hour -= 12; - sprintf(ampmChar, "PM"); - } else { - sprintf(ampmChar, "AM"); + if (hour == 0 && hour != 12) { + hour = 12; + sprintf(ampmChar, "AM"); + } + else if (hour == 12 && hour != 0) { + hour = 12; + sprintf(ampmChar, "PM"); + } + else if (hour < 12 && hour != 0) { + sprintf(ampmChar, "AM"); + } + else if (hour > 12 && hour != 0) + { + hour = hour - 12; + sprintf(ampmChar, "PM"); } sprintf(hoursChar, "%02d", hour); } -- cgit v1.2.3