diff options
Diffstat (limited to 'src/displayapp/screens')
58 files changed, 1551 insertions, 1043 deletions
diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index c1ee6469..d6371ce6 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -18,10 +18,18 @@ #include "displayapp/screens/Alarm.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; using Pinetime::Controllers::AlarmController; +namespace { + void ValueChangedHandler(void* userData) { + auto* screen = static_cast<Alarm*>(userData); + screen->OnValueChanged(); + } +} + static void btnEventHandler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<Alarm*>(obj->user_data); screen->OnButtonEvent(obj, event); @@ -34,58 +42,33 @@ static void StopAlarmTaskCallback(lv_task_t* task) { Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController, - Pinetime::Controllers::Settings& settingsController, + Controllers::Settings::ClockType clockType, System::SystemTask& systemTask) - : Screen(app), alarmController {alarmController}, settingsController {settingsController}, 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, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - - alarmHours = alarmController.Hours(); - alarmMinutes = alarmController.Minutes(); - lv_label_set_text_fmt(time, "%02hhu:%02hhu", alarmHours, alarmMinutes); - - lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -25); - - lblampm = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); - lv_obj_set_style_local_text_color(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - lv_label_set_text_static(lblampm, " "); - lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 0, 30); - - btnHoursUp = lv_btn_create(lv_scr_act(), nullptr); - btnHoursUp->user_data = this; - lv_obj_set_event_cb(btnHoursUp, btnEventHandler); - lv_obj_set_size(btnHoursUp, 60, 40); - lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -85); - txtHrUp = lv_label_create(btnHoursUp, nullptr); - lv_label_set_text_static(txtHrUp, "+"); - - btnHoursDown = lv_btn_create(lv_scr_act(), nullptr); - btnHoursDown->user_data = this; - lv_obj_set_event_cb(btnHoursDown, btnEventHandler); - lv_obj_set_size(btnHoursDown, 60, 40); - lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, 35); - txtHrDown = lv_label_create(btnHoursDown, nullptr); - lv_label_set_text_static(txtHrDown, "-"); - - btnMinutesUp = lv_btn_create(lv_scr_act(), nullptr); - btnMinutesUp->user_data = this; - lv_obj_set_event_cb(btnMinutesUp, btnEventHandler); - lv_obj_set_size(btnMinutesUp, 60, 40); - lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, -85); - txtMinUp = lv_label_create(btnMinutesUp, nullptr); - lv_label_set_text_static(txtMinUp, "+"); - - btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); - btnMinutesDown->user_data = this; - lv_obj_set_event_cb(btnMinutesDown, btnEventHandler); - lv_obj_set_size(btnMinutesDown, 60, 40); - lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, 35); - txtMinDown = lv_label_create(btnMinutesDown, nullptr); - lv_label_set_text_static(txtMinDown, "-"); + : Screen(app), alarmController {alarmController}, systemTask {systemTask} { + + hourCounter.Create(); + lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); + if (clockType == Controllers::Settings::ClockType::H12) { + hourCounter.EnableTwelveHourMode(); + + lblampm = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_label_set_text_static(lblampm, "AM"); + lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER); + lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 0, 30); + } + hourCounter.SetValue(alarmController.Hours()); + hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + minuteCounter.Create(); + lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); + minuteCounter.SetValue(alarmController.Minutes()); + minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + 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); + lv_label_set_text_static(colonLabel, ":"); + lv_obj_align(colonLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, -29); btnStop = lv_btn_create(lv_scr_act(), nullptr); btnStop->user_data = this; @@ -97,6 +80,8 @@ Alarm::Alarm(DisplayApp* app, lv_label_set_text_static(txtStop, Symbols::stop); lv_obj_set_hidden(btnStop, true); + static constexpr lv_color_t bgColor = Colors::bgAlt; + btnRecur = lv_btn_create(lv_scr_act(), nullptr); btnRecur->user_data = this; lv_obj_set_event_cb(btnRecur, btnEventHandler); @@ -104,13 +89,18 @@ Alarm::Alarm(DisplayApp* app, lv_obj_align(btnRecur, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); txtRecur = lv_label_create(btnRecur, nullptr); SetRecurButtonState(); + lv_obj_set_style_local_bg_color(btnRecur, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor); btnInfo = lv_btn_create(lv_scr_act(), nullptr); btnInfo->user_data = this; lv_obj_set_event_cb(btnInfo, btnEventHandler); - lv_obj_set_size(btnInfo, 50, 40); - lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 0, -85); - txtInfo = lv_label_create(btnInfo, nullptr); + lv_obj_set_size(btnInfo, 50, 50); + lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, -4); + lv_obj_set_style_local_bg_color(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor); + lv_obj_set_style_local_border_width(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_border_color(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + + lv_obj_t* txtInfo = lv_label_create(btnInfo, nullptr); lv_label_set_text_static(txtInfo, "i"); enableSwitch = lv_switch_create(lv_scr_act(), nullptr); @@ -119,6 +109,7 @@ Alarm::Alarm(DisplayApp* app, lv_obj_set_size(enableSwitch, 100, 50); // Align to the center of 115px from edge lv_obj_align(enableSwitch, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 7, 0); + lv_obj_set_style_local_bg_color(enableSwitch, LV_SWITCH_PART_BG, LV_STATE_DEFAULT, bgColor); UpdateAlarmTime(); @@ -136,8 +127,14 @@ Alarm::~Alarm() { lv_obj_clean(lv_scr_act()); } +void Alarm::DisableAlarm() { + if (alarmController.State() == AlarmController::AlarmState::Set) { + alarmController.DisableAlarm(); + lv_switch_off(enableSwitch, LV_ANIM_ON); + } +} + void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { - using Pinetime::Controllers::AlarmController; if (event == LV_EVENT_CLICKED) { if (obj == btnStop) { StopAlerting(); @@ -159,49 +156,8 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } return; } - // If any other button was pressed, disable the alarm - // this is to make it clear that the alarm won't be set until it is turned back on - if (alarmController.State() == AlarmController::AlarmState::Set) { - alarmController.DisableAlarm(); - lv_switch_off(enableSwitch, LV_ANIM_ON); - } - if (obj == btnMinutesUp) { - if (alarmMinutes >= 59) { - alarmMinutes = 0; - } else { - alarmMinutes++; - } - UpdateAlarmTime(); - return; - } - if (obj == btnMinutesDown) { - if (alarmMinutes == 0) { - alarmMinutes = 59; - } else { - alarmMinutes--; - } - UpdateAlarmTime(); - return; - } - if (obj == btnHoursUp) { - if (alarmHours >= 23) { - alarmHours = 0; - } else { - alarmHours++; - } - UpdateAlarmTime(); - return; - } - if (obj == btnHoursDown) { - if (alarmHours == 0) { - alarmHours = 23; - } else { - alarmHours--; - } - UpdateAlarmTime(); - return; - } if (obj == btnRecur) { + DisableAlarm(); ToggleRecurrence(); } } @@ -224,30 +180,20 @@ bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown; } +void Alarm::OnValueChanged() { + DisableAlarm(); + UpdateAlarmTime(); +} + void Alarm::UpdateAlarmTime() { - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { - switch (alarmHours) { - case 0: - lv_label_set_text_static(lblampm, "AM"); - lv_label_set_text_fmt(time, "%02d:%02d", 12, alarmMinutes); - break; - case 1 ... 11: - lv_label_set_text_static(lblampm, "AM"); - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); - break; - case 12: - lv_label_set_text_static(lblampm, "PM"); - lv_label_set_text_fmt(time, "%02d:%02d", 12, alarmMinutes); - break; - case 13 ... 23: - lv_label_set_text_static(lblampm, "PM"); - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours - 12, alarmMinutes); - break; + if (lblampm != nullptr) { + if (hourCounter.GetValue() >= 12) { + lv_label_set_text_static(lblampm, "PM"); + } else { + lv_label_set_text_static(lblampm, "AM"); } - } else { - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); } - alarmController.SetAlarmTime(alarmHours, alarmMinutes); + alarmController.SetAlarmTime(hourCounter.GetValue(), minuteCounter.GetValue()); } void Alarm::SetAlerting() { @@ -283,6 +229,9 @@ void Alarm::SetSwitchState(lv_anim_enable_t anim) { } void Alarm::ShowInfo() { + if (btnMessage != nullptr) { + return; + } btnMessage = lv_btn_create(lv_scr_act(), nullptr); btnMessage->user_data = this; lv_obj_set_event_cb(btnMessage, btnEventHandler); diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 80e446f1..fba9d5d9 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -21,6 +21,7 @@ #include "systemtask/SystemTask.h" #include "displayapp/LittleVgl.h" #include "components/alarm/AlarmController.h" +#include "displayapp/widgets/Counter.h" namespace Pinetime { namespace Applications { @@ -29,29 +30,28 @@ namespace Pinetime { public: Alarm(DisplayApp* app, Controllers::AlarmController& alarmController, - Pinetime::Controllers::Settings& settingsController, + Controllers::Settings::ClockType clockType, System::SystemTask& systemTask); ~Alarm() override; void SetAlerting(); void OnButtonEvent(lv_obj_t* obj, lv_event_t event); bool OnButtonPushed() override; bool OnTouchEvent(TouchEvents event) override; + void OnValueChanged(); void StopAlerting(); private: - uint8_t alarmHours; - uint8_t alarmMinutes; Controllers::AlarmController& alarmController; - Controllers::Settings& settingsController; System::SystemTask& systemTask; - lv_obj_t *time, *lblampm, *btnStop, *txtStop, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown, - *txtHrUp, *txtHrDown, *btnRecur, *txtRecur, *btnInfo, *txtInfo, *enableSwitch; + lv_obj_t *btnStop, *txtStop, *btnRecur, *txtRecur, *btnInfo, *enableSwitch; + lv_obj_t* lblampm = nullptr; lv_obj_t* txtMessage = nullptr; lv_obj_t* btnMessage = nullptr; lv_task_t* taskStopAlarm = nullptr; enum class EnableButtonState { On, Off, Alerting }; + void DisableAlarm(); void SetRecurButtonState(); void SetSwitchState(lv_anim_enable_t anim); void SetAlarm(); @@ -59,6 +59,8 @@ namespace Pinetime { void HideInfo(); void ToggleRecurrence(); void UpdateAlarmTime(); + Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_76); + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76); }; }; }; diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 9fd408e1..9f3e9568 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -21,10 +21,12 @@ auto ApplicationList::CreateScreenList() const { ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::Ble& bleController, Controllers::DateTime& dateTimeController) : Screen(app), settingsController {settingsController}, batteryController {batteryController}, + bleController {bleController}, dateTimeController {dateTimeController}, screens {app, settingsController.GetAppMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} { } @@ -43,5 +45,12 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen(unsigned int screenNum) co apps[i] = applications[screenNum * appsPerScreen + i]; } - return std::make_unique<Screens::Tile>(screenNum, nScreens, app, settingsController, batteryController, dateTimeController, apps); + return std::make_unique<Screens::Tile>(screenNum, + nScreens, + app, + settingsController, + batteryController, + bleController, + dateTimeController, + apps); } diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 14d7623c..e7c094bf 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -19,6 +19,7 @@ namespace Pinetime { explicit ApplicationList(DisplayApp* app, Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::Ble& bleController, Controllers::DateTime& dateTimeController); ~ApplicationList() override; bool OnTouchEvent(TouchEvents event) override; @@ -29,6 +30,7 @@ namespace Pinetime { Controllers::Settings& settingsController; Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::Ble& bleController; Controllers::DateTime& dateTimeController; static constexpr int appsPerScreen = 6; diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index d9d479f8..9febda61 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/BatteryInfo.h" #include "displayapp/DisplayApp.h" #include "components/battery/BatteryController.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -16,9 +17,9 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_align(charging_bar, nullptr, LV_ALIGN_CENTER, 0, 10); lv_bar_set_anim_time(charging_bar, 1000); lv_obj_set_style_local_radius(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, lv_color_hex(0x222222)); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_style_local_bg_opa(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_OPA_100); - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); status = lv_label_create(lv_scr_act(), nullptr); @@ -33,7 +34,7 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60); voltage = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0)); + lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange); lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER); lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95); @@ -62,7 +63,7 @@ void BatteryInfo::Refresh() { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_label_set_text_static(status, "Battery low"); } else { - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::highlight); lv_label_set_text_static(status, "Discharging"); } diff --git a/src/displayapp/screens/CheckboxList.cpp b/src/displayapp/screens/CheckboxList.cpp index ee64167d..b89add43 100644 --- a/src/displayapp/screens/CheckboxList.cpp +++ b/src/displayapp/screens/CheckboxList.cpp @@ -1,7 +1,6 @@ #include "displayapp/screens/CheckboxList.h" #include "displayapp/DisplayApp.h" #include "displayapp/screens/Styles.h" -#include "displayapp/screens/Symbols.h" using namespace Pinetime::Applications::Screens; @@ -21,7 +20,7 @@ CheckboxList::CheckboxList(const uint8_t screenID, const char* optionsSymbol, void (Controllers::Settings::*SetOptionIndex)(uint8_t), uint8_t (Controllers::Settings::*GetOptionIndex)() const, - std::array<const char*, MAXLISTITEMS> options) + std::array<const char*, MaxItems> options) : Screen(app), screenID {screenID}, settingsController {settingsController}, @@ -43,7 +42,7 @@ CheckboxList::CheckboxList(const uint8_t screenID, pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); + lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints.data(), 2); const uint16_t indicatorSize = LV_VER_RES / numScreens; const uint16_t indicatorPos = indicatorSize * screenID; @@ -56,7 +55,7 @@ CheckboxList::CheckboxList(const uint8_t screenID, pageIndicator = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); + lv_line_set_points(pageIndicator, pageIndicatorPoints.data(), 2); } lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); @@ -90,7 +89,7 @@ CheckboxList::CheckboxList(const uint8_t screenID, lv_obj_set_event_cb(cbOption[i], event_handler); SetRadioButtonStyle(cbOption[i]); - if (static_cast<unsigned int>((settingsController.*GetOptionIndex)() - MAXLISTITEMS * screenID) == i) { + if (static_cast<unsigned int>((settingsController.*GetOptionIndex)() - MaxItems * screenID) == i) { lv_checkbox_set_checked(cbOption[i], true); } } @@ -108,7 +107,7 @@ void CheckboxList::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (strcmp(options[i], "")) { if (object == cbOption[i]) { lv_checkbox_set_checked(cbOption[i], true); - (settingsController.*SetOptionIndex)(MAXLISTITEMS * screenID + i); + (settingsController.*SetOptionIndex)(MaxItems * screenID + i); } else { lv_checkbox_set_checked(cbOption[i], false); } diff --git a/src/displayapp/screens/CheckboxList.h b/src/displayapp/screens/CheckboxList.h index 6660acde..5bdd143e 100644 --- a/src/displayapp/screens/CheckboxList.h +++ b/src/displayapp/screens/CheckboxList.h @@ -3,17 +3,18 @@ #include <lvgl/lvgl.h> #include <cstdint> #include <memory> +#include <array> #include "displayapp/screens/Screen.h" #include "displayapp/Apps.h" #include "components/settings/Settings.h" -#define MAXLISTITEMS 4 - namespace Pinetime { namespace Applications { namespace Screens { class CheckboxList : public Screen { public: + static constexpr size_t MaxItems = 4; + CheckboxList(const uint8_t screenID, const uint8_t numScreens, DisplayApp* app, @@ -22,7 +23,7 @@ namespace Pinetime { const char* optionsSymbol, void (Controllers::Settings::*SetOptionIndex)(uint8_t), uint8_t (Controllers::Settings::*GetOptionIndex)() const, - std::array<const char*, MAXLISTITEMS> options); + std::array<const char*, MaxItems> options); ~CheckboxList() override; @@ -35,12 +36,10 @@ namespace Pinetime { const char* optionsSymbol; void (Controllers::Settings::*SetOptionIndex)(uint8_t); uint8_t (Controllers::Settings::*GetOptionIndex)() const; - std::array<const char*, MAXLISTITEMS> options; - - lv_obj_t* cbOption[MAXLISTITEMS]; - - lv_point_t pageIndicatorBasePoints[2]; - lv_point_t pageIndicatorPoints[2]; + std::array<const char*, MaxItems> options; + std::array<lv_obj_t*, MaxItems> cbOption; + std::array<lv_point_t, 2> pageIndicatorBasePoints; + std::array<lv_point_t, 2> pageIndicatorPoints; lv_obj_t* pageIndicatorBase; lv_obj_t* pageIndicator; }; diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index cd4288a1..0f4ec5b3 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -10,6 +10,7 @@ #include "displayapp/DisplayApp.h" #include "displayapp/screens/WatchFaceDigital.h" #include "displayapp/screens/WatchFaceTerminal.h" +#include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFaceAnalog.h" #include "displayapp/screens/WatchFacePineTimeStyle.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h" @@ -23,7 +24,8 @@ Clock::Clock(DisplayApp* app, Controllers::NotificationManager& notificatioManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController) + Controllers::MotionController& motionController, + Controllers::FS& filesystem) : Screen(app), dateTimeController {dateTimeController}, batteryController {batteryController}, @@ -32,6 +34,7 @@ Clock::Clock(DisplayApp* app, settingsController {settingsController}, heartRateController {heartRateController}, motionController {motionController}, + filesystem {filesystem}, screen {[this, &settingsController]() { switch (settingsController.GetClockFace()) { case 0: @@ -47,6 +50,9 @@ Clock::Clock(DisplayApp* app, return WatchFaceTerminalScreen(); break; case 4: + return WatchFaceInfineatScreen(); + break; + case 5: return WatchFaceCasioStyleG7710(); break; } @@ -108,6 +114,17 @@ std::unique_ptr<Screen> Clock::WatchFaceTerminalScreen() { motionController); } +std::unique_ptr<Screen> Clock::WatchFaceInfineatScreen() { + return std::make_unique<Screens::WatchFaceInfineat>(app, + dateTimeController, + batteryController, + bleController, + notificatioManager, + settingsController, + motionController, + filesystem); +} + std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() { return std::make_unique<Screens::WatchFaceCasioStyleG7710>(app, dateTimeController, @@ -116,5 +133,6 @@ std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() { notificatioManager, settingsController, heartRateController, - motionController); + motionController, + filesystem); } diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 5446a11b..84f1a1c4 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -28,7 +28,8 @@ namespace Pinetime { Controllers::NotificationManager& notificatioManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController); + Controllers::MotionController& motionController, + Controllers::FS& filesystem); ~Clock() override; bool OnTouchEvent(TouchEvents event) override; @@ -42,12 +43,14 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + Controllers::FS& filesystem; std::unique_ptr<Screen> screen; std::unique_ptr<Screen> WatchFaceDigitalScreen(); std::unique_ptr<Screen> WatchFaceAnalogScreen(); std::unique_ptr<Screen> WatchFacePineTimeStyleScreen(); std::unique_ptr<Screen> WatchFaceTerminalScreen(); + std::unique_ptr<Screen> WatchFaceInfineatScreen(); std::unique_ptr<Screen> WatchFaceCasioStyleG7710(); }; } diff --git a/src/displayapp/screens/Error.cpp b/src/displayapp/screens/Error.cpp index 1f2c61d6..74f222a9 100644 --- a/src/displayapp/screens/Error.cpp +++ b/src/displayapp/screens/Error.cpp @@ -36,7 +36,8 @@ Error::Error(Pinetime::Applications::DisplayApp* app, System::BootErrors error) lv_obj_set_event_cb(btnOk, ButtonEventCallback); lv_obj_set_size(btnOk, LV_HOR_RES, 50); lv_obj_align(btnOk, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); - lv_obj_set_style_local_value_str(btnOk, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Proceed"); + lv_obj_t* lblOk = lv_label_create(btnOk, nullptr); + lv_label_set_text_static(lblOk, "Proceed"); lv_obj_set_style_local_bg_color(btnOk, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); } diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index a3c97616..a2314690 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -3,6 +3,7 @@ #include "Version.h" #include "components/firmwarevalidator/FirmwareValidator.h" #include "displayapp/DisplayApp.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -42,7 +43,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, lv_obj_set_size(buttonValidate, 115, 50); lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); - lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight); labelButtonValidate = lv_label_create(buttonValidate, nullptr); lv_label_set_text_static(labelButtonValidate, "Validate"); @@ -51,7 +52,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, buttonReset->user_data = this; lv_obj_set_size(buttonReset, 115, 50); lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); - lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0x0, 0x0)); + lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); labelButtonReset = lv_label_create(buttonReset, nullptr); diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index b76ff5c0..e06b59b5 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/FlashLight.h" #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -18,17 +19,17 @@ FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app, Controllers::BrightnessController& brightnessController) : Screen(app), systemTask {systemTask}, brightnessController {brightnessController} { - brightnessController.Set(brightnessLevel); + brightnessController.Set(Controllers::BrightnessController::Levels::Low); flashLight = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); - lv_label_set_text_static(flashLight, Symbols::highlight); + lv_label_set_text_static(flashLight, Symbols::flashlight); lv_obj_align(flashLight, nullptr, LV_ALIGN_CENTER, 0, 0); - for (auto& i : indicators) { - i = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_size(i, 15, 10); - lv_obj_set_style_local_border_width(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 2); + for (auto& indicator : indicators) { + indicator = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_size(indicator, 15, 10); + lv_obj_set_style_local_border_width(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 2); } lv_obj_align(indicators[1], flashLight, LV_ALIGN_OUT_BOTTOM_MID, 0, 5); @@ -57,22 +58,15 @@ FlashLight::~FlashLight() { } void FlashLight::SetColors() { - if (isOn) { - lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - for (auto& i : indicators) { - lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_WHITE); - lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - } - } else { - lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - for (auto& i : indicators) { - lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_BLACK); - lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - } + lv_color_t bgColor = isOn ? LV_COLOR_WHITE : LV_COLOR_BLACK; + lv_color_t fgColor = isOn ? Colors::lightGray : LV_COLOR_WHITE; + + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, bgColor); + lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, fgColor); + for (auto& indicator : indicators) { + lv_obj_set_style_local_bg_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, fgColor); + lv_obj_set_style_local_bg_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, bgColor); + lv_obj_set_style_local_border_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, fgColor); } } @@ -94,32 +88,40 @@ void FlashLight::SetIndicators() { void FlashLight::Toggle() { isOn = !isOn; SetColors(); + if (isOn) { + brightnessController.Set(brightnessLevel); + } else { + brightnessController.Set(Controllers::BrightnessController::Levels::Low); + } } bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { using namespace Pinetime::Controllers; + auto SetState = [this]() { + if (isOn) { + brightnessController.Set(brightnessLevel); + } + SetIndicators(); + }; + if (event == TouchEvents::SwipeLeft) { if (brightnessLevel == BrightnessController::Levels::High) { brightnessLevel = BrightnessController::Levels::Medium; - brightnessController.Set(brightnessLevel); - SetIndicators(); + SetState(); } else if (brightnessLevel == BrightnessController::Levels::Medium) { brightnessLevel = BrightnessController::Levels::Low; - brightnessController.Set(brightnessLevel); - SetIndicators(); + SetState(); } return true; } if (event == TouchEvents::SwipeRight) { if (brightnessLevel == BrightnessController::Levels::Low) { brightnessLevel = BrightnessController::Levels::Medium; - brightnessController.Set(brightnessLevel); - SetIndicators(); + SetState(); } else if (brightnessLevel == BrightnessController::Levels::Medium) { brightnessLevel = BrightnessController::Levels::High; - brightnessController.Set(brightnessLevel); - SetIndicators(); + SetState(); } return true; } diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 35e06bbc..305e0c4b 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -3,6 +3,7 @@ #include <components/heartrate/HeartRateController.h> #include "displayapp/DisplayApp.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -36,10 +37,11 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app, lv_obj_set_style_local_text_font(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); - if (isHrRunning) - lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); - else - lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + if (isHrRunning) { + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight); + } else { + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); + } lv_label_set_text_static(label_hr, "000"); lv_obj_align(label_hr, nullptr, LV_ALIGN_CENTER, 0, -40); @@ -97,12 +99,12 @@ void HeartRate::OnStartStopEvent(lv_event_t event) { heartRateController.Start(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); - lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight); } else { heartRateController.Stop(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); - lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); } } } diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index 733b4e27..0b6864e8 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/InfiniPaint.h" #include "displayapp/DisplayApp.h" #include "displayapp/LittleVgl.h" +#include "displayapp/InfiniTimeTheme.h" #include <algorithm> // std::fill @@ -26,7 +27,7 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { selectColor = LV_COLOR_MAGENTA; break; case 1: - selectColor = LV_COLOR_MAKE(0x0, 0xb0, 0x0); + selectColor = Colors::green; break; case 2: selectColor = LV_COLOR_WHITE; diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 4486d6fd..d5a09be9 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -3,34 +3,9 @@ using namespace Pinetime::Applications::Screens; Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::DisplayApp* app, lv_obj_t* labelText) - : Screen(app), labelText {labelText} { + : Screen(app), labelText {labelText}, pageIndicator(screenID, numScreens) { - if (numScreens > 1) { - pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[0].y = 0; - pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[1].y = LV_VER_RES; - - pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); - lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - - uint16_t indicatorSize = LV_VER_RES / numScreens; - uint16_t indicatorPos = indicatorSize * screenID; - - pageIndicatorPoints[0].x = LV_HOR_RES - 1; - pageIndicatorPoints[0].y = indicatorPos; - pageIndicatorPoints[1].x = LV_HOR_RES - 1; - pageIndicatorPoints[1].y = indicatorPos + indicatorSize; - - pageIndicator = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); - lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); - } + pageIndicator.Create(); } Label::~Label() { diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h index 3fe5111f..acd8b377 100644 --- a/src/displayapp/screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -1,6 +1,7 @@ #pragma once #include "displayapp/screens/Screen.h" +#include "displayapp/widgets/PageIndicator.h" #include <lvgl/lvgl.h> namespace Pinetime { @@ -14,10 +15,7 @@ namespace Pinetime { private: lv_obj_t* labelText = nullptr; - lv_point_t pageIndicatorBasePoints[2]; - lv_point_t pageIndicatorPoints[2]; - lv_obj_t* pageIndicatorBase; - lv_obj_t* pageIndicator; + Widgets::PageIndicator pageIndicator; }; } } diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index 0bc7da80..f44825c7 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -16,37 +16,14 @@ List::List(uint8_t screenID, DisplayApp* app, Controllers::Settings& settingsController, std::array<Applications, MAXLISTITEMS>& applications) - : Screen(app), settingsController {settingsController} { + : Screen(app), settingsController {settingsController}, pageIndicator(screenID, numScreens) { // Set the background to Black lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0)); settingsController.SetSettingsMenu(screenID); - if (numScreens > 1) { - pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[0].y = 0; - pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[1].y = LV_VER_RES; - - pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - - const uint16_t indicatorSize = LV_VER_RES / numScreens; - const uint16_t indicatorPos = indicatorSize * screenID; - - pageIndicatorPoints[0].x = LV_HOR_RES - 1; - pageIndicatorPoints[0].y = indicatorPos; - pageIndicatorPoints[1].x = LV_HOR_RES - 1; - pageIndicatorPoints[1].y = indicatorPos + indicatorSize; - - pageIndicator = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); - } + pageIndicator.Create(); lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h index 88ef28ea..b5bc032c 100644 --- a/src/displayapp/screens/List.h +++ b/src/displayapp/screens/List.h @@ -4,6 +4,7 @@ #include <cstdint> #include <array> #include "displayapp/screens/Screen.h" +#include "displayapp/widgets/PageIndicator.h" #include "displayapp/Apps.h" #include "components/settings/Settings.h" @@ -35,10 +36,7 @@ namespace Pinetime { lv_obj_t* itemApps[MAXLISTITEMS]; - lv_point_t pageIndicatorBasePoints[2]; - lv_point_t pageIndicatorPoints[2]; - lv_obj_t* pageIndicatorBase; - lv_obj_t* pageIndicator; + Widgets::PageIndicator pageIndicator; }; } } diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 2ffc52dd..df87092b 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -1,5 +1,6 @@ #include "displayapp/screens/Metronome.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -12,7 +13,7 @@ namespace { lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x, uint8_t y) { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font); - lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); lv_label_set_text(label, name); lv_obj_align(label, reference, align, x, y); @@ -63,7 +64,8 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_obj_set_event_cb(playPause, eventHandler); lv_obj_set_size(playPause, 115, 50); lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); - lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); + lblPlayPause = lv_label_create(playPause, nullptr); + lv_label_set_text_static(lblPlayPause, Symbols::play); taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } @@ -125,12 +127,12 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { if (obj == playPause) { metronomeStarted = !metronomeStarted; if (metronomeStarted) { - lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::pause); + lv_label_set_text_static(lblPlayPause, Symbols::pause); systemTask.PushMessage(System::Messages::DisableSleeping); startTime = xTaskGetTickCount(); counter = 1; } else { - lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); + lv_label_set_text_static(lblPlayPause, Symbols::play); systemTask.PushMessage(System::Messages::EnableSleeping); } } diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 8933b17e..c062959c 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -31,6 +31,7 @@ namespace Pinetime { lv_obj_t *bpmArc, *bpmTap, *bpmValue; lv_obj_t *bpbDropdown, *currentBpbText; lv_obj_t* playPause; + lv_obj_t* lblPlayPause; lv_task_t* taskRefresh; }; diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index f7ffcc7c..c2dc4dac 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/Motion.h" #include <lvgl/lvgl.h> #include "displayapp/DisplayApp.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -19,7 +20,7 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr /*Add 3 data series*/ ser1 = lv_chart_add_series(chart, LV_COLOR_RED); - ser2 = lv_chart_add_series(chart, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + ser2 = lv_chart_add_series(chart, Colors::green); ser3 = lv_chart_add_series(chart, LV_COLOR_YELLOW); lv_chart_init_points(chart, ser1, 0); diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index 5779df3a..f6389734 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -19,6 +19,7 @@ #include <cstdint> #include "displayapp/DisplayApp.h" #include "components/ble/NavigationService.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -192,7 +193,7 @@ void Navigation::Refresh() { if (progress > 90) { lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); } else { - lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::orange); } } } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 1479cf5d..90a010f5 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -4,6 +4,7 @@ #include "components/ble/AlertNotificationService.h" #include "displayapp/screens/Symbols.h" #include <algorithm> +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; extern lv_font_t jetbrains_mono_extrabold_compressed; @@ -257,7 +258,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_set_style_local_border_width(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); subject_container = lv_cont_create(container, nullptr); - lv_obj_set_style_local_bg_color(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38)); + lv_obj_set_style_local_bg_color(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_style_local_pad_all(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); lv_obj_set_style_local_pad_inner(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); lv_obj_set_style_local_border_width(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); @@ -272,7 +273,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_align(alert_count, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 16); lv_obj_t* alert_type = lv_label_create(container, nullptr); - lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange); if (title == nullptr) { lv_label_set_text_static(alert_type, "Notification"); } else { @@ -289,21 +290,16 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_set_width(alert_type, 180); lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16); - ///////// + lv_obj_t* alert_subject = lv_label_create(subject_container, nullptr); + lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK); + lv_obj_set_width(alert_subject, LV_HOR_RES - 20); + switch (category) { - default: { - lv_obj_t* alert_subject = lv_label_create(subject_container, nullptr); - lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0)); - lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK); - lv_obj_set_width(alert_subject, LV_HOR_RES - 20); + default: lv_label_set_text(alert_subject, msg); - } break; + break; case Controllers::NotificationManager::Categories::IncomingCall: { lv_obj_set_height(subject_container, 108); - lv_obj_t* alert_subject = lv_label_create(subject_container, nullptr); - lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0)); - lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK); - lv_obj_set_width(alert_subject, LV_HOR_RES - 20); lv_label_set_text_static(alert_subject, "Incoming call from"); lv_obj_t* alert_caller = lv_label_create(subject_container, nullptr); @@ -319,7 +315,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); label_accept = lv_label_create(bt_accept, nullptr); lv_label_set_text_static(label_accept, Symbols::phone); - lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight); bt_reject = lv_btn_create(container, nullptr); bt_reject->user_data = this; @@ -337,7 +333,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text_static(label_mute, Symbols::volumMute); - lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); } break; } } diff --git a/src/displayapp/screens/PassKey.cpp b/src/displayapp/screens/PassKey.cpp index 4057a7eb..5d255e44 100644 --- a/src/displayapp/screens/PassKey.cpp +++ b/src/displayapp/screens/PassKey.cpp @@ -5,7 +5,7 @@ using namespace Pinetime::Applications::Screens; PassKey::PassKey(Pinetime::Applications::DisplayApp* app, uint32_t key) : Screen(app) { passkeyLabel = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFF00)); + lv_obj_set_style_local_text_color(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_set_style_local_text_font(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_fmt(passkeyLabel, "%06u", key); lv_obj_align(passkeyLabel, nullptr, LV_ALIGN_CENTER, 0, -20); diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index 0dcdcf59..10ccf1aa 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -20,7 +20,7 @@ Steps::Steps(Pinetime::Applications::DisplayApp* app, lv_obj_set_style_local_bg_opa(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, LV_OPA_0); lv_obj_set_style_local_border_width(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 2); lv_obj_set_style_local_radius(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0); - lv_obj_set_style_local_line_color(stepsArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0x0000FF)); + lv_obj_set_style_local_line_color(stepsArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); lv_arc_set_end_angle(stepsArc, 200); lv_obj_set_size(stepsArc, 240, 240); lv_arc_set_range(stepsArc, 0, 500); @@ -32,7 +32,7 @@ Steps::Steps(Pinetime::Applications::DisplayApp* app, lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal())); lSteps = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); + lv_obj_set_style_local_text_color(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME); lv_obj_set_style_local_text_font(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_fmt(lSteps, "%li", stepsCount); lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -40); diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index d0db59c0..c68cd854 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -1,10 +1,7 @@ #include "displayapp/screens/StopWatch.h" -#include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" -#include <lvgl/lvgl.h> -#include <FreeRTOS.h> -#include <task.h> +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -30,25 +27,17 @@ namespace { } } -StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) - : Screen(app), - systemTask {systemTask}, - currentState {States::Init}, - startTime {}, - oldTimeElapsed {}, - currentTimeSeparated {}, - lapBuffer {}, - lapNr {} { +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, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + 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, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + 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); @@ -65,24 +54,15 @@ StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler); lv_obj_set_size(btnStopLap, 115, 50); lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); - lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_MAKE(0x18, 0x18, 0x18)); txtStopLap = lv_label_create(btnStopLap, nullptr); - lv_obj_set_style_local_text_color(txtStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); lv_label_set_text_static(txtStopLap, Symbols::stop); lv_obj_set_state(btnStopLap, LV_STATE_DISABLED); lv_obj_set_state(txtStopLap, LV_STATE_DISABLED); - lapOneText = lv_label_create(lv_scr_act(), nullptr); - // lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); - lv_obj_set_style_local_text_color(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); - lv_obj_align(lapOneText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30); - lv_label_set_text_static(lapOneText, ""); - - lapTwoText = lv_label_create(lv_scr_act(), nullptr); - // lv_obj_set_style_local_text_font(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); - lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); - lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55); - lv_label_set_text_static(lapTwoText, ""); + 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, ""); taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } @@ -96,16 +76,14 @@ StopWatch::~StopWatch() { 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_MAKE(0xb0, 0xb0, 0xb0)); - lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + 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); lv_label_set_text_static(time, "00:00"); lv_label_set_text_static(msecTime, "00"); - lv_label_set_text_static(lapOneText, ""); - lv_label_set_text_static(lapTwoText, ""); - lapBuffer.clearBuffer(); - lapNr = 0; + lv_label_set_text_static(lapText, ""); + lapsDone = 0; lv_obj_set_state(btnStopLap, LV_STATE_DISABLED); lv_obj_set_state(txtStopLap, LV_STATE_DISABLED); } @@ -113,8 +91,8 @@ void StopWatch::Reset() { 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_MAKE(0x0, 0xb0, 0x0)); - lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + 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(); @@ -125,7 +103,7 @@ void StopWatch::Start() { void StopWatch::Pause() { startTime = 0; // Store the current time elapsed in cache - oldTimeElapsed += timeElapsed; + oldTimeElapsed = laps[lapsDone]; currentState = States::Halted; lv_label_set_text_static(txtPlayPause, Symbols::play); lv_label_set_text_static(txtStopLap, Symbols::stop); @@ -136,9 +114,9 @@ void StopWatch::Pause() { void StopWatch::Refresh() { if (currentState == States::Running) { - timeElapsed = xTaskGetTickCount() - startTime; - currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed)); + laps[lapsDone] = oldTimeElapsed + xTaskGetTickCount() - startTime; + 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); } @@ -163,18 +141,17 @@ void StopWatch::stopLapBtnEventHandler(lv_event_t event) { } // 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); + lv_label_set_text(lapText, ""); + lapsDone = std::min(lapsDone + 1, maxLapCount); + for (int i = lapsDone - displayedLaps; i < lapsDone; i++) { + if (i < 0) { + lv_label_ins_text(lapText, LV_LABEL_POS_LAST, "\n"); + continue; + } + TimeSeparated_t times = convertTicksToTimeSegments(laps[i]); + char buffer[16]; + sprintf(buffer, "#%2d %2d:%02d.%02d\n", i + 1, times.mins, times.secs, times.hundredths); + lv_label_ins_text(lapText, LV_LABEL_POS_LAST, buffer); } } else if (currentState == States::Halted) { Reset(); diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index ef55e2d2..f2f57110 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -1,13 +1,11 @@ #pragma once #include "displayapp/screens/Screen.h" -#include "components/datetime/DateTimeController.h" -#include "displayapp/LittleVgl.h" +#include <lvgl/lvgl.h> #include <FreeRTOS.h> #include "portmacro_cmsis.h" -#include <array> #include "systemtask/SystemTask.h" namespace Pinetime::Applications::Screens { @@ -20,46 +18,6 @@ namespace Pinetime::Applications::Screens { int hundredths; }; - // A simple buffer to hold the latest two laps - template <int N> struct LapTextBuffer_t { - LapTextBuffer_t() : buffer {}, currentSize {}, capacity {N}, head {-1} { - } - - void addLaps(const TimeSeparated_t& timeVal) { - head++; - head %= capacity; - buffer[head] = timeVal; - - if (currentSize < capacity) { - currentSize++; - } - } - - void clearBuffer() { - buffer = {}; - currentSize = 0; - head = -1; - } - - TimeSeparated_t* operator[](std::size_t idx) { - // Sanity check for out-of-bounds - if (idx >= 0 && idx < capacity) { - if (idx < currentSize) { - // This transformation is to ensure that head is always pointing to index 0. - const auto transformed_idx = (head - idx) % capacity; - return (&buffer[transformed_idx]); - } - } - return nullptr; - } - - private: - std::array<TimeSeparated_t, N> buffer; - uint8_t currentSize; - uint8_t capacity; - int8_t head; - }; - class StopWatch : public Screen { public: StopWatch(DisplayApp* app, System::SystemTask& systemTask); @@ -76,15 +34,15 @@ namespace Pinetime::Applications::Screens { private: Pinetime::System::SystemTask& systemTask; - TickType_t timeElapsed; - States currentState; + States currentState = States::Init; TickType_t startTime; - TickType_t oldTimeElapsed; - TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs - LapTextBuffer_t<2> lapBuffer; - int lapNr = 0; + TickType_t oldTimeElapsed = 0; + static constexpr int maxLapCount = 20; + TickType_t laps[maxLapCount + 1]; + static constexpr int displayedLaps = 2; + int lapsDone = 0; lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap; - lv_obj_t *lapOneText, *lapTwoText; + lv_obj_t* lapText; lv_task_t* taskRefresh; }; diff --git a/src/displayapp/screens/Styles.cpp b/src/displayapp/screens/Styles.cpp index bcfd584f..cebdc70c 100644 --- a/src/displayapp/screens/Styles.cpp +++ b/src/displayapp/screens/Styles.cpp @@ -1,8 +1,9 @@ #include "Styles.h" +#include "displayapp/InfiniTimeTheme.h" void Pinetime::Applications::Screens::SetRadioButtonStyle(lv_obj_t* checkbox) { lv_obj_set_style_local_radius(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); lv_obj_set_style_local_border_width(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, 9); - lv_obj_set_style_local_border_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_border_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, Colors::highlight); lv_obj_set_style_local_bg_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, LV_COLOR_WHITE); } diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h index f9731816..1180ec6f 100644 --- a/src/displayapp/screens/Symbols.h +++ b/src/displayapp/screens/Symbols.h @@ -37,19 +37,19 @@ namespace Pinetime { static constexpr const char* chartLine = "\xEF\x88\x81"; static constexpr const char* eye = "\xEF\x81\xAE"; static constexpr const char* home = "\xEF\x80\x95"; + static constexpr const char* sleep = "\xEE\xBD\x84"; // lv_font_sys_48.c - static constexpr const char* settings = "\xEE\xA4\x82"; // e902 + static constexpr const char* settings = "\xEE\xA2\xB8"; - static constexpr const char* brightnessHigh = "\xEE\xA4\x84"; // e904 - static constexpr const char* brightnessLow = "\xEE\xA4\x85"; // e905 - static constexpr const char* brightnessMedium = "\xEE\xA4\x86"; // e906 + static constexpr const char* brightnessLow = "\xEE\x8E\xAA"; + static constexpr const char* brightnessMedium = "\xEE\x8E\xAB"; + static constexpr const char* brightnessHigh = "\xEE\x8E\xAC"; - static constexpr const char* notificationsOff = "\xEE\xA4\x8B"; // e90b - static constexpr const char* notificationsOn = "\xEE\xA4\x8C"; // e90c - - static constexpr const char* highlight = "\xEE\xA4\x87"; // e907 + static constexpr const char* notificationsOff = "\xEE\x9F\xB6"; + static constexpr const char* notificationsOn = "\xEE\x9F\xB7"; + static constexpr const char* flashlight = "\xEF\x80\x8B"; } } } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index e3983d7c..01c35195 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -12,6 +12,7 @@ #include "components/datetime/DateTimeController.h" #include "components/motion/MotionController.h" #include "drivers/Watchdog.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -136,20 +137,25 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() { uptimeSeconds = uptimeSeconds % secondsInAMinute; // TODO handle more than 100 days of uptime +#ifndef TARGET_DEVICE_NAME + #define TARGET_DEVICE_NAME "UNKNOWN" +#endif + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); lv_label_set_text_fmt(label, - "#808080 Date# %02d/%02d/%04d\n" + "#808080 Date# %04d-%02d-%02d\n" "#808080 Time# %02d:%02d:%02d\n" "#808080 Uptime#\n %02lud %02lu:%02lu:%02lu\n" "#808080 Battery# %d%%/%03imV\n" "#808080 Backlight# %s\n" "#808080 Last reset# %s\n" "#808080 Accel.# %s\n" - "#808080 Touch.# %x.%x.%x\n", - dateTimeController.Day(), - static_cast<uint8_t>(dateTimeController.Month()), + "#808080 Touch.# %x.%x.%x\n" + "#808080 Model# %s", dateTimeController.Year(), + static_cast<uint8_t>(dateTimeController.Month()), + dateTimeController.Day(), dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), @@ -164,7 +170,8 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() { ToString(motionController.DeviceType()), touchPanel.GetChipId(), touchPanel.GetVendorId(), - touchPanel.GetFwVersion()); + touchPanel.GetFwVersion(), + TARGET_DEVICE_NAME); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::make_unique<Screens::Label>(1, 5, app, label); } @@ -212,7 +219,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen4() { lv_table_set_col_cnt(infoTask, 4); lv_table_set_row_cnt(infoTask, maxTaskCount + 1); lv_obj_set_style_local_pad_all(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, 0); - lv_obj_set_style_local_border_color(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); + lv_obj_set_style_local_border_color(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, Colors::lightGray); lv_table_set_cell_value(infoTask, 0, 0, "#"); lv_table_set_col_width(infoTask, 0, 30); diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index cce1d2ed..a60076ed 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -1,6 +1,8 @@ #include "displayapp/screens/Tile.h" #include "displayapp/DisplayApp.h" #include "displayapp/screens/BatteryIcon.h" +#include "components/ble/BleController.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -26,46 +28,26 @@ Tile::Tile(uint8_t screenID, uint8_t numScreens, DisplayApp* app, Controllers::Settings& settingsController, - Pinetime::Controllers::Battery& batteryController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, std::array<Applications, 6>& applications) - : Screen(app), batteryController {batteryController}, dateTimeController {dateTimeController} { + : Screen(app), + dateTimeController {dateTimeController}, + pageIndicator(screenID, numScreens), + statusIcons(batteryController, bleController) { settingsController.SetAppMenu(screenID); + statusIcons.Create(); + lv_obj_align(statusIcons.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -8, 0); + // Time label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); - // Battery - batteryIcon.Create(lv_scr_act()); - lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, -8, 0); - - if (numScreens > 1) { - pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[0].y = 0; - pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[1].y = LV_VER_RES; - - pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - - const uint16_t indicatorSize = LV_VER_RES / numScreens; - const uint16_t indicatorPos = indicatorSize * screenID; - - pageIndicatorPoints[0].x = LV_HOR_RES - 1; - pageIndicatorPoints[0].y = indicatorPos; - pageIndicatorPoints[1].x = LV_HOR_RES - 1; - pageIndicatorPoints[1].y = indicatorPos + indicatorSize; - - pageIndicator = lv_line_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0)); - lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); - } + pageIndicator.Create(); uint8_t btIndex = 0; for (uint8_t i = 0; i < 6; i++) { @@ -90,7 +72,7 @@ Tile::Tile(uint8_t screenID, lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_OPA_50); lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_COLOR_AQUA); lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_50); - lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, Colors::bgDark); lv_obj_set_style_local_pad_all(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 0); lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 10); @@ -116,7 +98,7 @@ Tile::~Tile() { void Tile::UpdateScreen() { lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str()); - batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining()); + statusIcons.Update(); } void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 48747144..d8a68128 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -7,9 +7,9 @@ #include "displayapp/Apps.h" #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" -#include "components/datetime/DateTimeController.h" #include "components/battery/BatteryController.h" -#include <displayapp/screens/BatteryIcon.h> +#include "displayapp/widgets/PageIndicator.h" +#include "displayapp/widgets/StatusIcons.h" namespace Pinetime { namespace Applications { @@ -25,7 +25,8 @@ namespace Pinetime { uint8_t numScreens, DisplayApp* app, Controllers::Settings& settingsController, - Pinetime::Controllers::Battery& batteryController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, std::array<Applications, 6>& applications); @@ -35,19 +36,15 @@ namespace Pinetime { void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId); private: - Pinetime::Controllers::Battery& batteryController; Controllers::DateTime& dateTimeController; lv_task_t* taskUpdate; lv_obj_t* label_time; - lv_point_t pageIndicatorBasePoints[2]; - lv_point_t pageIndicatorPoints[2]; - lv_obj_t* pageIndicatorBase; - lv_obj_t* pageIndicator; lv_obj_t* btnm1; - BatteryIcon batteryIcon; + Widgets::PageIndicator pageIndicator; + Widgets::StatusIcons statusIcons; const char* btnmMap[8]; Pinetime::Applications::Apps apps[6]; diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index a1df662a..136d6b52 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -1,13 +1,20 @@ #include "displayapp/screens/Timer.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" #include <lvgl/lvgl.h> using namespace Pinetime::Applications::Screens; static void btnEventHandler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<Timer*>(obj->user_data); - screen->OnButtonEvent(obj, event); + if (event == LV_EVENT_PRESSED) { + screen->ButtonPressed(); + } else if (event == LV_EVENT_RELEASED || event == LV_EVENT_PRESS_LOST) { + screen->MaskReset(); + } else if (event == LV_EVENT_SHORT_CLICKED) { + screen->ToggleRunning(); + } } Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : Screen(app), timerController {timerController} { @@ -23,14 +30,37 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : S lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); lv_obj_align(secondCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); - btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); + highlightObjectMask = lv_objmask_create(lv_scr_act(), nullptr); + lv_obj_set_size(highlightObjectMask, 240, 50); + lv_obj_align(highlightObjectMask, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + lv_draw_mask_line_param_t tmpMaskLine; + + lv_draw_mask_line_points_init(&tmpMaskLine, 0, 0, 0, 240, LV_DRAW_MASK_LINE_SIDE_LEFT); + highlightMask = lv_objmask_add_mask(highlightObjectMask, &tmpMaskLine); + + lv_obj_t* btnHighlight = lv_obj_create(highlightObjectMask, nullptr); + lv_obj_set_style_local_radius(btnHighlight, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_obj_set_style_local_bg_color(btnHighlight, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_obj_set_size(btnHighlight, LV_HOR_RES, 50); + lv_obj_align(btnHighlight, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + btnObjectMask = lv_objmask_create(lv_scr_act(), nullptr); + lv_obj_set_size(btnObjectMask, 240, 50); + lv_obj_align(btnObjectMask, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + lv_draw_mask_line_points_init(&tmpMaskLine, 0, 0, 0, 240, LV_DRAW_MASK_LINE_SIDE_RIGHT); + btnMask = lv_objmask_add_mask(btnObjectMask, &tmpMaskLine); + + btnPlayPause = lv_btn_create(btnObjectMask, nullptr); btnPlayPause->user_data = this; lv_obj_set_style_local_radius(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38)); + lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_event_cb(btnPlayPause, btnEventHandler); lv_obj_set_size(btnPlayPause, LV_HOR_RES, 50); - lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); - txtPlayPause = lv_label_create(btnPlayPause, nullptr); + + txtPlayPause = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(txtPlayPause, btnPlayPause, LV_ALIGN_CENTER, 0, 0); if (timerController.IsRunning()) { SetTimerRunning(); @@ -46,11 +76,46 @@ Timer::~Timer() { lv_obj_clean(lv_scr_act()); } +void Timer::ButtonPressed() { + pressTime = xTaskGetTickCount(); + buttonPressing = true; +} + +void Timer::MaskReset() { + buttonPressing = false; + // A click event is processed before a release event, + // so the release event would override the "Pause" text without this check + if (!timerController.IsRunning()) { + lv_label_set_text_static(txtPlayPause, "Start"); + } + maskPosition = 0; + UpdateMask(); +} + +void Timer::UpdateMask() { + lv_draw_mask_line_param_t maskLine; + + lv_draw_mask_line_points_init(&maskLine, maskPosition, 0, maskPosition, 240, LV_DRAW_MASK_LINE_SIDE_LEFT); + lv_objmask_update_mask(highlightObjectMask, highlightMask, &maskLine); + + lv_draw_mask_line_points_init(&maskLine, maskPosition, 0, maskPosition, 240, LV_DRAW_MASK_LINE_SIDE_RIGHT); + lv_objmask_update_mask(btnObjectMask, btnMask, &maskLine); +} + void Timer::Refresh() { if (timerController.IsRunning()) { uint32_t seconds = timerController.GetTimeRemaining() / 1000; minuteCounter.SetValue(seconds / 60); secondCounter.SetValue(seconds % 60); + } else if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) { + lv_label_set_text_static(txtPlayPause, "Reset"); + maskPosition += 15; + if (maskPosition > 240) { + MaskReset(); + Reset(); + } else { + UpdateMask(); + } } } @@ -66,25 +131,21 @@ void Timer::SetTimerStopped() { lv_label_set_text_static(txtPlayPause, "Start"); } -void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { - if (event == LV_EVENT_CLICKED) { - if (obj == btnPlayPause) { - if (timerController.IsRunning()) { - uint32_t seconds = timerController.GetTimeRemaining() / 1000; - minuteCounter.SetValue(seconds / 60); - secondCounter.SetValue(seconds % 60); - timerController.StopTimer(); - SetTimerStopped(); - } else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) { - timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000); - Refresh(); - SetTimerRunning(); - } - } +void Timer::ToggleRunning() { + if (timerController.IsRunning()) { + uint32_t seconds = timerController.GetTimeRemaining() / 1000; + minuteCounter.SetValue(seconds / 60); + secondCounter.SetValue(seconds % 60); + timerController.StopTimer(); + SetTimerStopped(); + } else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) { + timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000); + Refresh(); + SetTimerRunning(); } } -void Timer::SetDone() { +void Timer::Reset() { minuteCounter.SetValue(0); secondCounter.SetValue(0); SetTimerStopped(); diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index 2797a4fa..a6b60a17 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -5,29 +5,42 @@ #include "systemtask/SystemTask.h" #include "displayapp/LittleVgl.h" #include "displayapp/widgets/Counter.h" +#include <lvgl/lvgl.h> #include "components/timer/TimerController.h" namespace Pinetime::Applications::Screens { class Timer : public Screen { public: - enum class Modes { Normal, Done }; - Timer(DisplayApp* app, Controllers::TimerController& timerController); ~Timer() override; void Refresh() override; - void SetDone(); - void OnButtonEvent(lv_obj_t* obj, lv_event_t event); + void Reset(); + void ToggleRunning(); + void ButtonPressed(); + void MaskReset(); private: void SetTimerRunning(); void SetTimerStopped(); + void UpdateMask(); Controllers::TimerController& timerController; + lv_obj_t* msecTime; lv_obj_t* btnPlayPause; lv_obj_t* txtPlayPause; + + lv_obj_t* btnObjectMask; + lv_obj_t* highlightObjectMask; + lv_objmask_mask_t* btnMask; + lv_objmask_mask_t* highlightMask; + lv_task_t* taskRefresh; - Widgets::Counter minuteCounter = Widgets::Counter(0, 59); - Widgets::Counter secondCounter = Widgets::Counter(0, 59); + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76); + Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76); + + bool buttonPressing = false; + int maskPosition = 0; + TickType_t pressTime; }; } diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index 7e465fcd..9e7418c8 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -1,80 +1,56 @@ #include "displayapp/screens/Twos.h" -#include <array> #include <cstdio> #include <cstdlib> #include <lvgl/lvgl.h> -#include <utility> -#include <vector> using namespace Pinetime::Applications::Screens; Twos::Twos(Pinetime::Applications::DisplayApp* app) : Screen(app) { - // create styles to apply to different valued tiles - lv_style_init(&style_cell1); - lv_style_init(&style_cell2); - lv_style_init(&style_cell3); - lv_style_init(&style_cell4); - lv_style_init(&style_cell5); + struct colorPair { + lv_color_t bg; + lv_color_t fg; + }; - lv_style_set_border_color(&style_cell1, LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); - lv_style_set_border_width(&style_cell1, LV_STATE_DEFAULT, 3); - lv_style_set_bg_opa(&style_cell1, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&style_cell1, LV_STATE_DEFAULT, lv_color_hex(0xcdc0b4)); - lv_style_set_pad_top(&style_cell1, LV_STATE_DEFAULT, 25); - lv_style_set_text_color(&style_cell1, LV_STATE_DEFAULT, LV_COLOR_BLACK); + static constexpr colorPair colors[nColors] = { + {LV_COLOR_MAKE(0xcd, 0xc0, 0xb4), LV_COLOR_BLACK}, + {LV_COLOR_MAKE(0xef, 0xdf, 0xc6), LV_COLOR_BLACK}, + {LV_COLOR_MAKE(0xef, 0x92, 0x63), LV_COLOR_WHITE}, + {LV_COLOR_MAKE(0xf7, 0x61, 0x42), LV_COLOR_WHITE}, + {LV_COLOR_MAKE(0x00, 0x7d, 0xc5), LV_COLOR_WHITE}, + }; - lv_style_set_border_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); - lv_style_set_border_width(&style_cell2, LV_STATE_DEFAULT, 3); - lv_style_set_bg_opa(&style_cell2, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xefdfc6)); - lv_style_set_pad_top(&style_cell2, LV_STATE_DEFAULT, 25); - lv_style_set_text_color(&style_cell2, LV_STATE_DEFAULT, LV_COLOR_BLACK); - - lv_style_set_border_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); - lv_style_set_border_width(&style_cell3, LV_STATE_DEFAULT, 3); - lv_style_set_bg_opa(&style_cell3, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xef9263)); - lv_style_set_pad_top(&style_cell3, LV_STATE_DEFAULT, 25); - - lv_style_set_border_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); - lv_style_set_border_width(&style_cell4, LV_STATE_DEFAULT, 3); - lv_style_set_bg_opa(&style_cell4, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xf76142)); - lv_style_set_pad_top(&style_cell4, LV_STATE_DEFAULT, 25); - - lv_style_set_border_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); - lv_style_set_border_width(&style_cell5, LV_STATE_DEFAULT, 3); - lv_style_set_bg_opa(&style_cell5, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0x007dc5)); - lv_style_set_pad_top(&style_cell5, LV_STATE_DEFAULT, 25); + gridDisplay = lv_table_create(lv_scr_act(), nullptr); - // format grid display + for (size_t i = 0; i < nColors; i++) { + lv_style_init(&cellStyles[i]); - gridDisplay = lv_table_create(lv_scr_act(), nullptr); - lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL1, &style_cell1); - lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL2, &style_cell2); - lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL3, &style_cell3); - lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4, &style_cell4); - lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4 + 1, &style_cell5); - lv_table_set_col_cnt(gridDisplay, 4); - lv_table_set_row_cnt(gridDisplay, 4); - lv_table_set_col_width(gridDisplay, 0, LV_HOR_RES / 4); - lv_table_set_col_width(gridDisplay, 1, LV_HOR_RES / 4); - lv_table_set_col_width(gridDisplay, 2, LV_HOR_RES / 4); - lv_table_set_col_width(gridDisplay, 3, LV_HOR_RES / 4); - lv_obj_align(gridDisplay, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_style_set_border_color(&cellStyles[i], LV_STATE_DEFAULT, lv_color_hex(0xbbada0)); + lv_style_set_border_width(&cellStyles[i], LV_STATE_DEFAULT, 3); + lv_style_set_bg_opa(&cellStyles[i], LV_STATE_DEFAULT, LV_OPA_COVER); + lv_style_set_bg_color(&cellStyles[i], LV_STATE_DEFAULT, colors[i].bg); + lv_style_set_pad_top(&cellStyles[i], LV_STATE_DEFAULT, 29); + lv_style_set_text_color(&cellStyles[i], LV_STATE_DEFAULT, colors[i].fg); - lv_obj_clean_style_list(gridDisplay, LV_TABLE_PART_BG); + lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL1 + i, &cellStyles[i]); + } - // initialize grid - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { + lv_table_set_col_cnt(gridDisplay, nCols); + lv_table_set_row_cnt(gridDisplay, nRows); + for (int col = 0; col < nCols; col++) { + static constexpr int colWidth = LV_HOR_RES_MAX / nCols; + lv_table_set_col_width(gridDisplay, col, colWidth); + for (int row = 0; row < nRows; row++) { grid[row][col].value = 0; lv_table_set_cell_type(gridDisplay, row, col, 1); lv_table_set_cell_align(gridDisplay, row, col, LV_LABEL_ALIGN_CENTER); } } + // Move one pixel down to remove a gap + lv_obj_align(gridDisplay, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 1); + + lv_obj_clean_style_list(gridDisplay, LV_TABLE_PART_BG); + placeNewTile(); placeNewTile(); @@ -82,54 +58,51 @@ Twos::Twos(Pinetime::Applications::DisplayApp* app) : Screen(app) { scoreText = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_width(scoreText, LV_HOR_RES); lv_label_set_align(scoreText, LV_ALIGN_IN_LEFT_MID); - lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 10); + lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); lv_label_set_recolor(scoreText, true); lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score); } Twos::~Twos() { - lv_style_reset(&style_cell1); - lv_style_reset(&style_cell2); - lv_style_reset(&style_cell3); - lv_style_reset(&style_cell4); - lv_style_reset(&style_cell5); + for (lv_style_t cellStyle : cellStyles) { + lv_style_reset(&cellStyle); + } lv_obj_clean(lv_scr_act()); } bool Twos::placeNewTile() { - std::vector<std::pair<int, int>> availableCells; - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { - if (!grid[row][col].value) { - availableCells.push_back(std::make_pair(row, col)); - } + unsigned int emptyCells[nCells]; + unsigned int nEmpty = 0; + for (unsigned int i = 0; i < nCells; i++) { + const unsigned int row = i / nCols; + const unsigned int col = i % nCols; + if (grid[row][col].value == 0) { + emptyCells[nEmpty] = i; + nEmpty++; } } - if (availableCells.size() == 0) { + if (nEmpty == 0) { return false; // game lost } - auto it = availableCells.cbegin(); - int random = rand() % availableCells.size(); - std::advance(it, random); - std::pair<int, int> newCell = *it; + int random = rand() % nEmpty; - if ((rand() % 100) < 90) - grid[newCell.first][newCell.second].value = 2; - else - grid[newCell.first][newCell.second].value = 4; - updateGridDisplay(grid); + if ((rand() % 100) < 90) { + grid[emptyCells[random] / nCols][emptyCells[random] % nCols].value = 2; + } else { + grid[emptyCells[random] / nCols][emptyCells[random] % nCols].value = 4; + } + updateGridDisplay(); return true; } -bool Twos::tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, int oldCol) { +bool Twos::tryMerge(int newRow, int newCol, int oldRow, int oldCol) { if (grid[newRow][newCol].value == grid[oldRow][oldCol].value) { if ((newCol != oldCol) || (newRow != oldRow)) { if (!grid[newRow][newCol].merged) { - unsigned int newVal = grid[oldRow][oldCol].value *= 2; - grid[newRow][newCol].value = newVal; - score += newVal; + grid[newRow][newCol].value *= 2; + score += grid[newRow][newCol].value; lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score); grid[oldRow][oldCol].value = 0; grid[newRow][newCol].merged = true; @@ -140,7 +113,7 @@ bool Twos::tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, in return false; } -bool Twos::tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int oldCol) { +bool Twos::tryMove(int newRow, int newCol, int oldRow, int oldCol) { if (((newCol >= 0) && (newCol != oldCol)) || ((newRow >= 0) && (newRow != oldRow))) { grid[newRow][newCol].value = grid[oldRow][oldCol].value; grid[oldRow][oldCol].value = 0; @@ -151,28 +124,30 @@ bool Twos::tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int o bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { bool validMove = false; - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { - grid[row][col].merged = false; // reinitialize merge state - } + for (unsigned int i = 0; i < nCells; i++) { + const unsigned int row = i / nCols; + const unsigned int col = i % nCols; + grid[row][col].merged = false; // reinitialize merge state } switch (event) { case TouchEvents::SwipeLeft: - for (int col = 1; col < 4; col++) { // ignore tiles already on far left - for (int row = 0; row < 4; row++) { - if (grid[row][col].value) { + for (int col = 1; col < nCols; col++) { // ignore tiles already on far left + for (int row = 0; row < nRows; row++) { + if (grid[row][col].value > 0) { int newCol = -1; for (int potentialNewCol = col - 1; potentialNewCol >= 0; potentialNewCol--) { - if (!grid[row][potentialNewCol].value) { + if (grid[row][potentialNewCol].value == 0) { newCol = potentialNewCol; } else { // blocked by another tile - if (tryMerge(grid, row, potentialNewCol, row, col)) + if (tryMerge(row, potentialNewCol, row, col)) { validMove = true; + } break; } } - if (tryMove(grid, row, newCol, row, col)) + if (tryMove(row, newCol, row, col)) { validMove = true; + } } } } @@ -181,21 +156,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return true; case TouchEvents::SwipeRight: - for (int col = 2; col >= 0; col--) { // ignore tiles already on far right - for (int row = 0; row < 4; row++) { - if (grid[row][col].value) { + for (int col = nCols - 2; col >= 0; col--) { // ignore tiles already on far right + for (int row = 0; row < nRows; row++) { + if (grid[row][col].value > 0) { int newCol = -1; - for (int potentialNewCol = col + 1; potentialNewCol < 4; potentialNewCol++) { - if (!grid[row][potentialNewCol].value) { + for (int potentialNewCol = col + 1; potentialNewCol < nCols; potentialNewCol++) { + if (grid[row][potentialNewCol].value == 0) { newCol = potentialNewCol; } else { // blocked by another tile - if (tryMerge(grid, row, potentialNewCol, row, col)) + if (tryMerge(row, potentialNewCol, row, col)) { validMove = true; + } break; } } - if (tryMove(grid, row, newCol, row, col)) + if (tryMove(row, newCol, row, col)) { validMove = true; + } } } } @@ -204,21 +181,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return true; case TouchEvents::SwipeUp: - for (int row = 1; row < 4; row++) { // ignore tiles already on top - for (int col = 0; col < 4; col++) { - if (grid[row][col].value) { + for (int row = 1; row < nRows; row++) { // ignore tiles already on top + for (int col = 0; col < nCols; col++) { + if (grid[row][col].value > 0) { int newRow = -1; for (int potentialNewRow = row - 1; potentialNewRow >= 0; potentialNewRow--) { - if (!grid[potentialNewRow][col].value) { + if (grid[potentialNewRow][col].value == 0) { newRow = potentialNewRow; } else { // blocked by another tile - if (tryMerge(grid, potentialNewRow, col, row, col)) + if (tryMerge(potentialNewRow, col, row, col)) { validMove = true; + } break; } } - if (tryMove(grid, newRow, col, row, col)) + if (tryMove(newRow, col, row, col)) { validMove = true; + } } } } @@ -227,21 +206,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return true; case TouchEvents::SwipeDown: - for (int row = 2; row >= 0; row--) { // ignore tiles already on bottom - for (int col = 0; col < 4; col++) { - if (grid[row][col].value) { + for (int row = nRows - 2; row >= 0; row--) { // ignore tiles already on bottom + for (int col = 0; col < nCols; col++) { + if (grid[row][col].value > 0) { int newRow = -1; - for (int potentialNewRow = row + 1; potentialNewRow < 4; potentialNewRow++) { - if (!grid[potentialNewRow][col].value) { + for (int potentialNewRow = row + 1; potentialNewRow < nRows; potentialNewRow++) { + if (grid[potentialNewRow][col].value == 0) { newRow = potentialNewRow; } else { // blocked by another tile - if (tryMerge(grid, potentialNewRow, col, row, col)) + if (tryMerge(potentialNewRow, col, row, col)) { validMove = true; + } break; } } - if (tryMove(grid, newRow, col, row, col)) + if (tryMove(newRow, col, row, col)) { validMove = true; + } } } } @@ -255,36 +236,36 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return false; } -void Twos::updateGridDisplay(TwosTile grid[][4]) { - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { - if (grid[row][col].value) { - char buffer[7]; - sprintf(buffer, "%d", grid[row][col].value); - lv_table_set_cell_value(gridDisplay, row, col, buffer); - } else { - lv_table_set_cell_value(gridDisplay, row, col, ""); - } - switch (grid[row][col].value) { - case 0: - lv_table_set_cell_type(gridDisplay, row, col, 1); - break; - case 2: - case 4: - lv_table_set_cell_type(gridDisplay, row, col, 2); - break; - case 8: - case 16: - lv_table_set_cell_type(gridDisplay, row, col, 3); - break; - case 32: - case 64: - lv_table_set_cell_type(gridDisplay, row, col, 4); - break; - default: - lv_table_set_cell_type(gridDisplay, row, col, 5); - break; - } +void Twos::updateGridDisplay() { + for (unsigned int i = 0; i < nCells; i++) { + const unsigned int row = i / nCols; + const unsigned int col = i % nCols; + if (grid[row][col].value > 0) { + char buffer[7]; + sprintf(buffer, "%d", grid[row][col].value); + lv_table_set_cell_value(gridDisplay, row, col, buffer); + } else { + lv_table_set_cell_value(gridDisplay, row, col, ""); + } + switch (grid[row][col].value) { + case 0: + lv_table_set_cell_type(gridDisplay, row, col, 1); + break; + case 2: + case 4: + lv_table_set_cell_type(gridDisplay, row, col, 2); + break; + case 8: + case 16: + lv_table_set_cell_type(gridDisplay, row, col, 3); + break; + case 32: + case 64: + lv_table_set_cell_type(gridDisplay, row, col, 4); + break; + default: + lv_table_set_cell_type(gridDisplay, row, col, 5); + break; } } } diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index 5a0c4350..da935724 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -18,19 +18,19 @@ namespace Pinetime { bool OnTouchEvent(TouchEvents event) override; private: - lv_style_t style_cell1; - lv_style_t style_cell2; - lv_style_t style_cell3; - lv_style_t style_cell4; - lv_style_t style_cell5; + static constexpr int nColors = 5; + lv_style_t cellStyles[nColors]; lv_obj_t* scoreText; lv_obj_t* gridDisplay; - TwosTile grid[4][4]; + static constexpr int nCols = 4; + static constexpr int nRows = 4; + static constexpr int nCells = nCols * nRows; + TwosTile grid[nRows][nCols]; unsigned int score = 0; - void updateGridDisplay(TwosTile grid[][4]); - bool tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, int oldCol); - bool tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int oldCol); + void updateGridDisplay(); + bool tryMerge(int newRow, int newCol, int oldRow, int oldCol); + bool tryMove(int newRow, int newCol, int oldRow, int oldCol); bool placeNewTile(); }; } diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 251a560f..5e5317ee 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -6,6 +6,7 @@ #include "displayapp/screens/Symbols.h" #include "displayapp/screens/NotificationIcon.h" #include "components/settings/Settings.h" +#include "displayapp/InfiniTimeTheme.h" LV_IMG_DECLARE(bg_clock); @@ -69,18 +70,17 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, plugIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(plugIcon, Symbols::plug); - lv_obj_set_style_local_text_color(plugIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); lv_obj_align(plugIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 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_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME); lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); // Date - Day / Week day label_date_day = lv_label_create(lv_scr_act(), NULL); - lv_obj_set_style_local_text_color(label_date_day, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0)); + lv_obj_set_style_local_text_color(label_date_day, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange); lv_label_set_text_fmt(label_date_day, "%s\n%02i", dateTimeController.DayOfWeekShortToString(), dateTimeController.Day()); lv_label_set_align(label_date_day, LV_LABEL_ALIGN_CENTER); lv_obj_align(label_date_day, NULL, LV_ALIGN_CENTER, 50, 0); diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp index f0e6e88e..ad124ea1 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp @@ -22,7 +22,8 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app, Controllers::NotificationManager& notificatioManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController) + Controllers::MotionController& motionController, + Controllers::FS& filesystem) : Screen(app), currentDateTime {{}}, dateTimeController {dateTimeController}, @@ -33,6 +34,19 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app, heartRateController {heartRateController}, motionController {motionController} { + lfs_file f = {}; + if (filesystem.FileOpen(&f, "/fonts/lv_font_dots_40.bin", LFS_O_RDONLY) >= 0) { + font_dot40 = lv_font_load("F:/fonts/lv_font_dots_40.bin"); + } + + if (filesystem.FileOpen(&f, "/fonts/7segments_40.bin", LFS_O_RDONLY) >= 0) { + font_segment40 = lv_font_load("F:/fonts/7segments_40.bin"); + } + + if (filesystem.FileOpen(&f, "/fonts/7segments_115.bin", LFS_O_RDONLY) >= 0) { + font_segment115 = lv_font_load("F:/fonts/7segments_115.bin"); + } + label_battery_vallue = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_battery_vallue, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); lv_obj_set_style_local_text_color(label_battery_vallue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); @@ -60,19 +74,19 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app, label_day_of_week = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_day_of_week, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 64); lv_obj_set_style_local_text_color(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_dots_40); + lv_obj_set_style_local_text_font(label_day_of_week, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); lv_label_set_text_static(label_day_of_week, "SUN"); label_week_number = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_week_number, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 22); lv_obj_set_style_local_text_color(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_dots_40); + lv_obj_set_style_local_text_font(label_week_number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_dot40); lv_label_set_text_static(label_week_number, "WK26"); label_day_of_year = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_day_of_year, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 30); lv_obj_set_style_local_text_color(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_40); + lv_obj_set_style_local_text_font(label_day_of_year, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_day_of_year, "181-184"); lv_style_init(&style_line); @@ -103,7 +117,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app, label_date = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 100, 70); lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_40); + lv_obj_set_style_local_text_font(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment40); lv_label_set_text_static(label_date, "6-30"); line_date = lv_line_create(lv_scr_act(), nullptr); @@ -113,7 +127,7 @@ WatchFaceCasioStyleG7710::WatchFaceCasioStyleG7710(DisplayApp* app, label_time = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color_text); - lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_7segment_115); + lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_segment115); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 40); line_time = lv_line_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.h b/src/displayapp/screens/WatchFaceCasioStyleG7710.h index 9cc909a6..c3821205 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.h +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.h @@ -31,7 +31,8 @@ namespace Pinetime { Controllers::NotificationManager& notificatioManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController); + Controllers::MotionController& motionController, + Controllers::FS& filesystem); ~WatchFaceCasioStyleG7710() override; void Refresh() override; @@ -99,6 +100,9 @@ namespace Pinetime { Controllers::MotionController& motionController; lv_task_t* taskRefresh; + lv_font_t* font_dot40 = nullptr; + lv_font_t* font_segment40 = nullptr; + lv_font_t* font_segment115 = nullptr; }; } } diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index d10f8532..705272f7 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -3,8 +3,6 @@ #include <date/date.h> #include <lvgl/lvgl.h> #include <cstdio> -#include "displayapp/screens/BatteryIcon.h" -#include "displayapp/screens/BleIcon.h" #include "displayapp/screens/NotificationIcon.h" #include "displayapp/screens/Symbols.h" #include "components/battery/BatteryController.h" @@ -13,6 +11,7 @@ #include "components/heartrate/HeartRateController.h" #include "components/motion/MotionController.h" #include "components/settings/Settings.h" + using namespace Pinetime::Applications::Screens; WatchFaceDigital::WatchFaceDigital(DisplayApp* app, @@ -26,28 +25,16 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, : Screen(app), currentDateTime {{}}, dateTimeController {dateTimeController}, - batteryController {batteryController}, - bleController {bleController}, notificatioManager {notificatioManager}, settingsController {settingsController}, heartRateController {heartRateController}, - motionController {motionController} { - - batteryIcon.Create(lv_scr_act()); - lv_obj_align(batteryIcon.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + motionController {motionController}, + statusIcons(batteryController, bleController) { - 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_static(batteryPlug, Symbols::plug); - lv_obj_align(batteryPlug, batteryIcon.GetObject(), 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(0x0082FC)); - lv_label_set_text_static(bleIcon, Symbols::bluetooth); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + statusIcons.Create(); notificationIcon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); + lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME); lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); @@ -94,24 +81,7 @@ WatchFaceDigital::~WatchFaceDigital() { } void WatchFaceDigital::Refresh() { - powerPresent = batteryController.IsPowerPresent(); - if (powerPresent.IsUpdated()) { - lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get())); - } - - batteryPercentRemaining = batteryController.PercentRemaining(); - if (batteryPercentRemaining.IsUpdated()) { - auto batteryPercent = batteryPercentRemaining.Get(); - batteryIcon.SetBatteryPercentage(batteryPercent); - } - - bleState = bleController.IsConnected(); - bleRadioEnabled = bleController.IsRadioEnabled(); - if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) { - lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get())); - } - lv_obj_realign(batteryPlug); - lv_obj_realign(bleIcon); + statusIcons.Update(); notificationState = notificatioManager.AreNewNotificationsAvailable(); if (notificationState.IsUpdated()) { diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index bd27806f..49935792 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -1,6 +1,5 @@ #pragma once -#include <displayapp/screens/BatteryIcon.h> #include <lvgl/src/lv_core/lv_obj.h> #include <chrono> #include <cstdint> @@ -8,6 +7,7 @@ #include "displayapp/screens/Screen.h" #include "components/datetime/DateTimeController.h" #include "components/ble/BleController.h" +#include "displayapp/widgets/StatusIcons.h" namespace Pinetime { namespace Controllers { @@ -59,25 +59,20 @@ namespace Pinetime { lv_obj_t* label_time; lv_obj_t* label_time_ampm; lv_obj_t* label_date; - lv_obj_t* bleIcon; - lv_obj_t* batteryPlug; lv_obj_t* heartbeatIcon; lv_obj_t* heartbeatValue; lv_obj_t* stepIcon; lv_obj_t* stepValue; lv_obj_t* notificationIcon; - BatteryIcon batteryIcon; - Controllers::DateTime& dateTimeController; - Controllers::Battery& batteryController; - Controllers::Ble& bleController; Controllers::NotificationManager& notificatioManager; Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; lv_task_t* taskRefresh; + Widgets::StatusIcons statusIcons; }; } } diff --git a/src/displayapp/screens/WatchFaceInfineat.cpp b/src/displayapp/screens/WatchFaceInfineat.cpp new file mode 100644 index 00000000..e3ed1bf7 --- /dev/null +++ b/src/displayapp/screens/WatchFaceInfineat.cpp @@ -0,0 +1,605 @@ +#include "displayapp/screens/WatchFaceInfineat.h" + +#include <date/date.h> +#include <lvgl/lvgl.h> +#include <cstdio> +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/BleIcon.h" +#include "components/settings/Settings.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/ble/NotificationManager.h" +#include "components/motion/MotionController.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast<WatchFaceInfineat*>(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +WatchFaceInfineat::WatchFaceInfineat(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController, + Controllers::NotificationManager& notificationManager, + Controllers::Settings& settingsController, + Controllers::MotionController& motionController, + Controllers::FS& fs) + : Screen(app), + currentDateTime {{}}, + dateTimeController {dateTimeController}, + batteryController {batteryController}, + bleController {bleController}, + notificationManager {notificationManager}, + settingsController {settingsController}, + motionController {motionController} { + lfs_file f = {}; + if (fs.FileOpen(&f, "/fonts/teko.bin", LFS_O_RDONLY) >= 0) { + font_teko = lv_font_load("F:/fonts/teko.bin"); + } + + if (fs.FileOpen(&f, "/fonts/bebas.bin", LFS_O_RDONLY) >= 0) { + font_bebas = lv_font_load("F:/fonts/bebas.bin"); + } + + // Black background covering the whole screen + background = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_size(background, 240, 240); + lv_obj_align(background, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0); + + // Side Cover + line0 = lv_line_create(lv_scr_act(), nullptr); + line1 = lv_line_create(lv_scr_act(), nullptr); + line2 = lv_line_create(lv_scr_act(), nullptr); + line3 = lv_line_create(lv_scr_act(), nullptr); + line4 = lv_line_create(lv_scr_act(), nullptr); + line5 = lv_line_create(lv_scr_act(), nullptr); + line6 = lv_line_create(lv_scr_act(), nullptr); + line7 = lv_line_create(lv_scr_act(), nullptr); + line8 = lv_line_create(lv_scr_act(), nullptr); + lineBattery = lv_line_create(lv_scr_act(), nullptr); + + lv_style_init(&line0Style); + lv_style_set_line_width(&line0Style, LV_STATE_DEFAULT, 18); + lv_style_set_line_color(&line0Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines])); + lv_obj_add_style(line0, LV_LINE_PART_MAIN, &line0Style); + line0Points[0] = {30, 25}; + line0Points[1] = {68, -8}; + lv_line_set_points(line0, line0Points, 2); + + lv_style_init(&line1Style); + lv_style_set_line_width(&line1Style, LV_STATE_DEFAULT, 15); + lv_style_set_line_color(&line1Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 1])); + lv_obj_add_style(line1, LV_LINE_PART_MAIN, &line1Style); + line1Points[0] = {26, 167}; + line1Points[1] = {43, 216}; + lv_line_set_points(line1, line1Points, 2); + + lv_style_init(&line2Style); + lv_style_set_line_width(&line2Style, LV_STATE_DEFAULT, 14); + lv_style_set_line_color(&line2Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 2])); + lv_obj_add_style(line2, LV_LINE_PART_MAIN, &line2Style); + line2Points[0] = {27, 40}; + line2Points[1] = {27, 196}; + lv_line_set_points(line2, line2Points, 2); + + lv_style_init(&line3Style); + lv_style_set_line_width(&line3Style, LV_STATE_DEFAULT, 22); + lv_style_set_line_color(&line3Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 3])); + lv_obj_add_style(line3, LV_LINE_PART_MAIN, &line3Style); + line3Points[0] = {12, 182}; + line3Points[1] = {65, 249}; + lv_line_set_points(line3, line3Points, 2); + + lv_style_init(&line4Style); + lv_style_set_line_width(&line4Style, LV_STATE_DEFAULT, 20); + lv_style_set_line_color(&line4Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 4])); + lv_obj_add_style(line4, LV_LINE_PART_MAIN, &line4Style); + line4Points[0] = {17, 99}; + line4Points[1] = {17, 144}; + lv_line_set_points(line4, line4Points, 2); + + lv_style_init(&line5Style); + lv_style_set_line_width(&line5Style, LV_STATE_DEFAULT, 18); + lv_style_set_line_color(&line5Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 5])); + lv_obj_add_style(line5, LV_LINE_PART_MAIN, &line5Style); + line5Points[0] = {14, 81}; + line5Points[1] = {40, 127}; + lv_line_set_points(line5, line5Points, 2); + + lv_style_init(&line6Style); + lv_style_set_line_width(&line6Style, LV_STATE_DEFAULT, 18); + lv_style_set_line_color(&line6Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 6])); + lv_obj_add_style(line6, LV_LINE_PART_MAIN, &line6Style); + line6Points[0] = {14, 163}; + line6Points[1] = {40, 118}; + lv_line_set_points(line6, line6Points, 2); + + lv_style_init(&line7Style); + lv_style_set_line_width(&line7Style, LV_STATE_DEFAULT, 52); + lv_style_set_line_color(&line7Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 7])); + lv_obj_add_style(line7, LV_LINE_PART_MAIN, &line7Style); + line7Points[0] = {-20, 124}; + line7Points[1] = {25, -11}; + lv_line_set_points(line7, line7Points, 2); + + lv_style_init(&line8Style); + lv_style_set_line_width(&line8Style, LV_STATE_DEFAULT, 48); + lv_style_set_line_color(&line8Style, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 8])); + lv_obj_add_style(line8, LV_LINE_PART_MAIN, &line8Style); + line8Points[0] = {-29, 89}; + line8Points[1] = {27, 254}; + lv_line_set_points(line8, line8Points, 2); + + logoPine = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_src(logoPine, "F:/images/pine_small.bin"); + lv_obj_set_pos(logoPine, 15, 106); + + lv_style_init(&lineBatteryStyle); + lv_style_set_line_width(&lineBatteryStyle, LV_STATE_DEFAULT, 24); + lv_style_set_line_color(&lineBatteryStyle, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 4])); + lv_style_set_line_opa(&lineBatteryStyle, LV_STATE_DEFAULT, 190); + lv_obj_add_style(lineBattery, LV_LINE_PART_MAIN, &lineBatteryStyle); + lineBatteryPoints[0] = {27, 105}; + lineBatteryPoints[1] = {27, 106}; + lv_line_set_points(lineBattery, lineBatteryPoints, 2); + lv_obj_move_foreground(lineBattery); + + notificationIcon = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(notificationIcon, + LV_BTN_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 7])); + lv_obj_set_style_local_radius(notificationIcon, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_obj_set_size(notificationIcon, 13, 13); + lv_obj_set_hidden(notificationIcon, true); + + if (!settingsController.GetInfineatShowSideCover()) { + ToggleBatteryIndicatorColor(false); + lv_obj_set_hidden(line0, true); + lv_obj_set_hidden(line1, true); + lv_obj_set_hidden(line2, true); + lv_obj_set_hidden(line3, true); + lv_obj_set_hidden(line4, true); + lv_obj_set_hidden(line5, true); + lv_obj_set_hidden(line6, true); + lv_obj_set_hidden(line7, true); + lv_obj_set_hidden(line8, true); + } + + timeContainer = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_opa(timeContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + if (font_bebas != nullptr) { + lv_obj_set_size(timeContainer, 185, 185); + lv_obj_align(timeContainer, lv_scr_act(), LV_ALIGN_CENTER, 0, -10); + } else { + lv_obj_set_size(timeContainer, 110, 145); + lv_obj_align(timeContainer, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + } + + labelHour = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(labelHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); + lv_label_set_text(labelHour, "01"); + if (font_bebas != nullptr) { + lv_obj_set_style_local_text_font(labelHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas); + lv_obj_align(labelHour, timeContainer, LV_ALIGN_IN_TOP_MID, 0, 0); + } else { + lv_obj_set_style_local_text_font(labelHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); + lv_obj_align(labelHour, timeContainer, LV_ALIGN_IN_TOP_MID, 0, 5); + } + + labelMinutes = lv_label_create(lv_scr_act(), nullptr); + if (font_bebas != nullptr) { + lv_obj_set_style_local_text_font(labelMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas); + } else { + lv_obj_set_style_local_text_font(labelMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); + } + lv_label_set_text(labelMinutes, "00"); + lv_obj_align(labelMinutes, timeContainer, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + labelTimeAmPm = lv_label_create(lv_scr_act(), nullptr); + if (font_teko != nullptr) { + lv_obj_set_style_local_text_font(labelTimeAmPm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); + } else { + lv_obj_set_style_local_text_font(labelTimeAmPm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + } + + lv_label_set_text(labelTimeAmPm, ""); + lv_obj_align(labelTimeAmPm, timeContainer, LV_ALIGN_OUT_RIGHT_TOP, 0, 15); + + dateContainer = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_opa(dateContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_size(dateContainer, 60, 30); + lv_obj_align(dateContainer, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 5); + + labelDate = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999)); + if (font_teko != nullptr) { + lv_obj_set_style_local_text_font(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); + } else { + lv_obj_set_style_local_text_font(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + } + lv_obj_align(labelDate, dateContainer, LV_ALIGN_IN_TOP_MID, 0, 0); + lv_label_set_text(labelDate, "Mon 01"); + + 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(0x999999)); + lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_obj_align(bleIcon, dateContainer, LV_ALIGN_OUT_BOTTOM_MID, 0, 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(0x999999)); + if (font_teko != nullptr) { + lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); + } else { + lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + } + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 10, 0); + lv_label_set_text(stepValue, "0"); + + 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(0x999999)); + lv_label_set_text(stepIcon, Symbols::shoe); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + // Setting buttons + btnClose = lv_btn_create(lv_scr_act(), nullptr); + btnClose->user_data = this; + lv_obj_set_size(btnClose, 60, 60); + lv_obj_align(btnClose, lv_scr_act(), LV_ALIGN_CENTER, 0, -80); + lv_obj_set_style_local_bg_opa(btnClose, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70); + lv_obj_set_style_local_value_str(btnClose, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "X"); + lv_obj_set_event_cb(btnClose, event_handler); + lv_obj_set_hidden(btnClose, true); + + btnNextColor = lv_btn_create(lv_scr_act(), nullptr); + btnNextColor->user_data = this; + lv_obj_set_size(btnNextColor, 60, 60); + lv_obj_align(btnNextColor, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 0); + lv_obj_set_style_local_bg_opa(btnNextColor, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70); + lv_obj_set_style_local_value_str(btnNextColor, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextColor, event_handler); + lv_obj_set_hidden(btnNextColor, true); + + btnPrevColor = lv_btn_create(lv_scr_act(), nullptr); + btnPrevColor->user_data = this; + lv_obj_set_size(btnPrevColor, 60, 60); + lv_obj_align(btnPrevColor, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 0); + lv_obj_set_style_local_bg_opa(btnPrevColor, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70); + lv_obj_set_style_local_value_str(btnPrevColor, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevColor, event_handler); + lv_obj_set_hidden(btnPrevColor, true); + + btnToggleCover = lv_btn_create(lv_scr_act(), nullptr); + btnToggleCover->user_data = this; + lv_obj_set_size(btnToggleCover, 60, 60); + lv_obj_align(btnToggleCover, lv_scr_act(), LV_ALIGN_CENTER, 0, 80); + lv_obj_set_style_local_bg_opa(btnToggleCover, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70); + const char* labelToggle = settingsController.GetInfineatShowSideCover() ? "ON" : "OFF"; + lv_obj_set_style_local_value_str(btnToggleCover, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, labelToggle); + lv_obj_set_event_cb(btnToggleCover, event_handler); + lv_obj_set_hidden(btnToggleCover, true); + + // Button to access the settings + btnSettings = lv_btn_create(lv_scr_act(), nullptr); + btnSettings->user_data = this; + lv_obj_set_size(btnSettings, 150, 150); + lv_obj_align(btnSettings, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_radius(btnSettings, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30); + lv_obj_set_style_local_bg_opa(btnSettings, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70); + lv_obj_set_event_cb(btnSettings, event_handler); + labelBtnSettings = lv_label_create(btnSettings, nullptr); + lv_obj_set_style_local_text_font(labelBtnSettings, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + lv_label_set_text_static(labelBtnSettings, Symbols::settings); + lv_obj_set_hidden(btnSettings, true); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); + Refresh(); +} + +WatchFaceInfineat::~WatchFaceInfineat() { + lv_task_del(taskRefresh); + + lv_style_reset(&line0Style); + lv_style_reset(&line1Style); + lv_style_reset(&line2Style); + lv_style_reset(&line3Style); + lv_style_reset(&line4Style); + lv_style_reset(&line5Style); + lv_style_reset(&line6Style); + lv_style_reset(&line7Style); + lv_style_reset(&line8Style); + lv_style_reset(&lineBatteryStyle); + + if (font_bebas != nullptr) { + lv_font_free(font_bebas); + } + if (font_teko != nullptr) { + lv_font_free(font_teko); + } + + lv_obj_clean(lv_scr_act()); +} + +bool WatchFaceInfineat::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + if ((event == Pinetime::Applications::TouchEvents::LongTap) && lv_obj_get_hidden(btnSettings)) { + lv_obj_set_hidden(btnSettings, false); + savedTick = lv_tick_get(); + return true; + } + // Prevent screen from sleeping when double tapping with settings on + if ((event == Pinetime::Applications::TouchEvents::DoubleTap) && !lv_obj_get_hidden(btnClose)) { + return true; + } + return false; +} + +void WatchFaceInfineat::CloseMenu() { + settingsController.SaveSettings(); + lv_obj_set_hidden(btnClose, true); + lv_obj_set_hidden(btnNextColor, true); + lv_obj_set_hidden(btnPrevColor, true); + lv_obj_set_hidden(btnToggleCover, true); +} + +bool WatchFaceInfineat::OnButtonPushed() { + if (!lv_obj_get_hidden(btnClose)) { + CloseMenu(); + return true; + } + return false; +} + +void WatchFaceInfineat::UpdateSelected(lv_obj_t* object, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + bool showSideCover = settingsController.GetInfineatShowSideCover(); + int colorIndex = settingsController.GetInfineatColorIndex(); + + if (object == btnSettings) { + lv_obj_set_hidden(btnSettings, true); + lv_obj_set_hidden(btnClose, false); + lv_obj_set_hidden(btnNextColor, !showSideCover); + lv_obj_set_hidden(btnPrevColor, !showSideCover); + lv_obj_set_hidden(btnToggleCover, false); + } + if (object == btnClose) { + CloseMenu(); + } + if (object == btnToggleCover) { + settingsController.SetInfineatShowSideCover(!showSideCover); + ToggleBatteryIndicatorColor(!showSideCover); + lv_obj_set_hidden(line0, showSideCover); + lv_obj_set_hidden(line1, showSideCover); + lv_obj_set_hidden(line2, showSideCover); + lv_obj_set_hidden(line3, showSideCover); + lv_obj_set_hidden(line4, showSideCover); + lv_obj_set_hidden(line5, showSideCover); + lv_obj_set_hidden(line6, showSideCover); + lv_obj_set_hidden(line7, showSideCover); + lv_obj_set_hidden(line8, showSideCover); + lv_obj_set_hidden(btnNextColor, showSideCover); + lv_obj_set_hidden(btnPrevColor, showSideCover); + const char* labelToggle = showSideCover ? "OFF" : "ON"; + lv_obj_set_style_local_value_str(btnToggleCover, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, labelToggle); + } + if (object == btnNextColor) { + colorIndex = (colorIndex + 1) % nColors; + settingsController.SetInfineatColorIndex(colorIndex); + } + if (object == btnPrevColor) { + colorIndex -= 1; + if (colorIndex < 0) + colorIndex = nColors - 1; + settingsController.SetInfineatColorIndex(colorIndex); + } + if (object == btnNextColor || object == btnPrevColor) { + lv_obj_set_style_local_line_color(line0, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 0])); + lv_obj_set_style_local_line_color(line1, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 1])); + lv_obj_set_style_local_line_color(line2, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 2])); + lv_obj_set_style_local_line_color(line3, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 3])); + lv_obj_set_style_local_line_color(line4, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 4])); + lv_obj_set_style_local_line_color(line5, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 5])); + lv_obj_set_style_local_line_color(line6, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 6])); + lv_obj_set_style_local_line_color(line7, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 7])); + lv_obj_set_style_local_line_color(line8, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 8])); + lv_obj_set_style_local_line_color(lineBattery, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 4])); + lv_obj_set_style_local_bg_color(notificationIcon, + LV_BTN_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + 7])); + } + } +} + +void WatchFaceInfineat::Refresh() { + notificationState = notificationManager.AreNewNotificationsAvailable(); + if (notificationState.IsUpdated()) { + lv_obj_set_hidden(notificationIcon, !notificationState.Get()); + lv_obj_align(notificationIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + } + + currentDateTime = dateTimeController.CurrentDateTime(); + + if (currentDateTime.IsUpdated()) { + auto newDateTime = currentDateTime.Get(); + + auto dp = date::floor<date::days>(newDateTime); + auto time = date::make_time(newDateTime - dp); + auto yearMonthDay = date::year_month_day(dp); + + auto year = static_cast<int>(yearMonthDay.year()); + auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month())); + auto day = static_cast<unsigned>(yearMonthDay.day()); + auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding()); + + int hour = time.hours().count(); + auto minute = time.minutes().count(); + + char minutesChar[3]; + sprintf(minutesChar, "%02d", static_cast<int>(minute)); + + char hoursChar[3]; + char ampmChar[3]; + + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + if (hour < 12) { + if (hour == 0) { + hour = 12; + } + sprintf(ampmChar, "AM"); + } else { // hour >= 12 + if (hour != 12) { + hour = hour - 12; + } + sprintf(ampmChar, "PM"); + } + } + 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]; + + lv_label_set_text_fmt(labelHour, "%s", hoursChar); + lv_label_set_text_fmt(labelMinutes, "%s", minutesChar); + } + + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + lv_label_set_text(labelTimeAmPm, ampmChar); + lv_obj_align(labelTimeAmPm, timeContainer, LV_ALIGN_OUT_RIGHT_TOP, 0, 10); + lv_obj_align(labelHour, timeContainer, LV_ALIGN_IN_TOP_MID, 0, 5); + lv_obj_align(labelMinutes, timeContainer, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + } + + if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { + lv_label_set_text_fmt(labelDate, "%s %02d", dateTimeController.DayOfWeekShortToStringLow(), day); + lv_obj_realign(labelDate); + + currentYear = year; + currentMonth = month; + currentDayOfWeek = dayOfWeek; + currentDay = day; + } + } + + batteryPercentRemaining = batteryController.PercentRemaining(); + isCharging = batteryController.IsCharging(); + // We store if battery and charging are updated before calling Get(), + // since Get() sets isUpdated to false. + bool isBatteryUpdated = batteryPercentRemaining.IsUpdated(); + bool isChargingUpdated = isCharging.IsUpdated(); + if (isCharging.Get()) { // Charging battery animation + chargingBatteryPercent += 1; + if (chargingBatteryPercent > 100) { + chargingBatteryPercent = batteryPercentRemaining.Get(); + } + SetBatteryLevel(chargingBatteryPercent); + } else if (isChargingUpdated || isBatteryUpdated) { + chargingBatteryPercent = batteryPercentRemaining.Get(); + SetBatteryLevel(chargingBatteryPercent); + } + + bleState = bleController.IsConnected(); + bleRadioEnabled = bleController.IsRadioEnabled(); + if (bleState.IsUpdated()) { + lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); + lv_obj_align(bleIcon, dateContainer, LV_ALIGN_OUT_BOTTOM_MID, 0, 3); + } + + stepCount = motionController.NbSteps(); + motionSensorOk = motionController.IsSensorOk(); + if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) { + lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 10, 0); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + } + + if (!lv_obj_get_hidden(btnSettings)) { + if ((savedTick > 0) && (lv_tick_get() - savedTick > 3000)) { + lv_obj_set_hidden(btnSettings, true); + savedTick = 0; + } + } +} + +void WatchFaceInfineat::SetBatteryLevel(uint8_t batteryPercent) { + // starting point (y) + Pine64 logo height * (100 - batteryPercent) / 100 + lineBatteryPoints[1] = {27, static_cast<lv_coord_t>(105 + 32 * (100 - batteryPercent) / 100)}; + lv_line_set_points(lineBattery, lineBatteryPoints, 2); +} + +void WatchFaceInfineat::ToggleBatteryIndicatorColor(bool showSideCover) { + if (!showSideCover) { // make indicator and notification icon color white + lv_obj_set_style_local_image_recolor_opa(logoPine, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100); + lv_obj_set_style_local_image_recolor(logoPine, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + lv_obj_set_style_local_line_color(lineBattery, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_bg_color(notificationIcon, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + } else { + lv_obj_set_style_local_image_recolor_opa(logoPine, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0); + lv_obj_set_style_local_line_color(lineBattery, + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 4])); + lv_obj_set_style_local_bg_color(notificationIcon, + LV_BTN_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + 7])); + } +} diff --git a/src/displayapp/screens/WatchFaceInfineat.h b/src/displayapp/screens/WatchFaceInfineat.h new file mode 100644 index 00000000..4a7dbebd --- /dev/null +++ b/src/displayapp/screens/WatchFaceInfineat.h @@ -0,0 +1,144 @@ +#pragma once + +#include <lvgl/lvgl.h> +#include <chrono> +#include <cstdint> +#include <memory> +#include "displayapp/screens/Screen.h" +#include "components/datetime/DateTimeController.h" + +namespace Pinetime { + namespace Controllers { + class Settings; + class Battery; + class Ble; + class NotificationManager; + class MotionController; + } + + namespace Applications { + namespace Screens { + + class WatchFaceInfineat : public Screen { + public: + WatchFaceInfineat(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController, + Controllers::NotificationManager& notificationManager, + Controllers::Settings& settingsController, + Controllers::MotionController& motionController, + Controllers::FS& fs); + + ~WatchFaceInfineat() override; + + bool OnTouchEvent(TouchEvents event) override; + bool OnButtonPushed() override; + void UpdateSelected(lv_obj_t* object, lv_event_t event); + void CloseMenu(); + + void Refresh() override; + + private: + char displayedChar[5] {}; + + uint16_t currentYear = 1970; + Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; + Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; + uint8_t currentDay = 0; + uint32_t savedTick = 0; + uint8_t chargingBatteryPercent = 101; // not a mistake ;) + + DirtyValue<uint8_t> batteryPercentRemaining {}; + DirtyValue<bool> isCharging {}; + DirtyValue<bool> bleState {}; + DirtyValue<bool> bleRadioEnabled {}; + DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {}; + DirtyValue<bool> motionSensorOk {}; + DirtyValue<uint32_t> stepCount {}; + DirtyValue<bool> notificationState {}; + + lv_obj_t* background; + + // Lines making up the side cover + lv_obj_t* line0; + lv_obj_t* line1; + lv_obj_t* line2; + lv_obj_t* line3; + lv_obj_t* line4; + lv_obj_t* line5; + lv_obj_t* line6; + lv_obj_t* line7; + lv_obj_t* line8; + lv_obj_t* lineBattery; + + lv_style_t line0Style; + lv_style_t line1Style; + lv_style_t line2Style; + lv_style_t line3Style; + lv_style_t line4Style; + lv_style_t line5Style; + lv_style_t line6Style; + lv_style_t line7Style; + lv_style_t line8Style; + lv_style_t lineBatteryStyle; + + lv_point_t line0Points[2]; + lv_point_t line1Points[2]; + lv_point_t line2Points[2]; + lv_point_t line3Points[2]; + lv_point_t line4Points[2]; + lv_point_t line5Points[2]; + lv_point_t line6Points[2]; + lv_point_t line7Points[2]; + lv_point_t line8Points[2]; + lv_point_t lineBatteryPoints[2]; + + lv_obj_t* logoPine; + + lv_obj_t* timeContainer; + lv_obj_t* labelHour; + lv_obj_t* labelMinutes; + lv_obj_t* labelTimeAmPm; + lv_obj_t* dateContainer; + lv_obj_t* labelDate; + lv_obj_t* bleIcon; + lv_obj_t* stepIcon; + lv_obj_t* stepValue; + lv_obj_t* notificationIcon; + lv_obj_t* btnClose; + lv_obj_t* btnNextColor; + lv_obj_t* btnToggleCover; + lv_obj_t* btnPrevColor; + lv_obj_t* btnSettings; + lv_obj_t* labelBtnSettings; + + static constexpr int nLines = 9; + static constexpr int nColors = 7; // must match number of colors in InfineatColors + struct InfineatColors { + int orange[nLines] = {0xfd872b, 0xdb3316, 0x6f1000, 0xfd7a0a, 0xffffff, 0xffffff, 0xffffff, 0xe85102, 0xea1c00}; + int blue[nLines] = {0xe7f8ff, 0x2232d0, 0x182a8b, 0xe7f8ff, 0xffffff, 0xffffff, 0xffffff, 0x5991ff, 0x1636ff}; + int green[nLines] = {0xb8ff9b, 0x088608, 0x004a00, 0xb8ff9b, 0xffffff, 0xffffff, 0xffffff, 0x62d515, 0x007400}; + int rainbow[nLines] = {0x2da400, 0xac09c4, 0xfe0303, 0x0d57ff, 0xffffff, 0xffffff, 0xffffff, 0xe0b900, 0xe85102}; + int gray[nLines] = {0xeeeeee, 0x98959b, 0x191919, 0xeeeeee, 0xffffff, 0xffffff, 0xffffff, 0x919191, 0x3a3a3a}; + int nordBlue[nLines] = {0xc3daf2, 0x4d78ce, 0x153451, 0xc3daf2, 0xffffff, 0xffffff, 0xffffff, 0x5d8ad2, 0x21518a}; + int nordGreen[nLines] = {0xd5f0e9, 0x238373, 0x1d413f, 0xd5f0e9, 0xffffff, 0xffffff, 0xffffff, 0x2fb8a2, 0x11705a}; + } infineatColors; + + Controllers::DateTime& dateTimeController; + Controllers::Battery& batteryController; + Controllers::Ble& bleController; + Controllers::NotificationManager& notificationManager; + Controllers::Settings& settingsController; + Controllers::MotionController& motionController; + + void SetBatteryLevel(uint8_t batteryPercent); + void ToggleBatteryIndicatorColor(bool showSideCover); + + lv_task_t* taskRefresh; + lv_font_t* font_teko = nullptr; + lv_font_t* font_bebas = nullptr; + }; + } + } +} diff --git a/src/displayapp/screens/WatchFacePineTimeStyle.cpp b/src/displayapp/screens/WatchFacePineTimeStyle.cpp index 63b421da..002ac887 100644 --- a/src/displayapp/screens/WatchFacePineTimeStyle.cpp +++ b/src/displayapp/screens/WatchFacePineTimeStyle.cpp @@ -104,11 +104,11 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_align(plugIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); 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(0x000000)); + lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); lv_label_set_text_static(bleIcon, ""); notificationIcon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); lv_label_set_text_static(notificationIcon, ""); // Calendar icon @@ -196,7 +196,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnNextTime, 60, 60); lv_obj_align(btnNextTime, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, -80); lv_obj_set_style_local_bg_opa(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_t* lblNextTime = lv_label_create(btnNextTime, nullptr); + lv_label_set_text_static(lblNextTime, ">"); lv_obj_set_event_cb(btnNextTime, event_handler); lv_obj_set_hidden(btnNextTime, true); @@ -205,7 +206,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnPrevTime, 60, 60); lv_obj_align(btnPrevTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, -80); lv_obj_set_style_local_bg_opa(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_t* lblPrevTime = lv_label_create(btnPrevTime, nullptr); + lv_label_set_text_static(lblPrevTime, "<"); lv_obj_set_event_cb(btnPrevTime, event_handler); lv_obj_set_hidden(btnPrevTime, true); @@ -214,7 +216,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnNextBar, 60, 60); lv_obj_align(btnNextBar, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 0); lv_obj_set_style_local_bg_opa(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_t* lblNextBar = lv_label_create(btnNextBar, nullptr); + lv_label_set_text_static(lblNextBar, ">"); lv_obj_set_event_cb(btnNextBar, event_handler); lv_obj_set_hidden(btnNextBar, true); @@ -223,7 +226,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnPrevBar, 60, 60); lv_obj_align(btnPrevBar, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 0); lv_obj_set_style_local_bg_opa(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_t* lblPrevBar = lv_label_create(btnPrevBar, nullptr); + lv_label_set_text_static(lblPrevBar, "<"); lv_obj_set_event_cb(btnPrevBar, event_handler); lv_obj_set_hidden(btnPrevBar, true); @@ -232,7 +236,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnNextBG, 60, 60); lv_obj_align(btnNextBG, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 80); lv_obj_set_style_local_bg_opa(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_t* lblNextBG = lv_label_create(btnNextBG, nullptr); + lv_label_set_text_static(lblNextBG, ">"); lv_obj_set_event_cb(btnNextBG, event_handler); lv_obj_set_hidden(btnNextBG, true); @@ -241,7 +246,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnPrevBG, 60, 60); lv_obj_align(btnPrevBG, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 80); lv_obj_set_style_local_bg_opa(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_t* lblPrevBG = lv_label_create(btnPrevBG, nullptr); + lv_label_set_text_static(lblPrevBG, "<"); lv_obj_set_event_cb(btnPrevBG, event_handler); lv_obj_set_hidden(btnPrevBG, true); @@ -250,7 +256,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnReset, 60, 60); lv_obj_align(btnReset, lv_scr_act(), LV_ALIGN_CENTER, 0, 80); lv_obj_set_style_local_bg_opa(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rst"); + lv_obj_t* lblReset = lv_label_create(btnReset, nullptr); + lv_label_set_text_static(lblReset, "Rst"); lv_obj_set_event_cb(btnReset, event_handler); lv_obj_set_hidden(btnReset, true); @@ -259,7 +266,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnRandom, 60, 60); lv_obj_align(btnRandom, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); lv_obj_set_style_local_bg_opa(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rnd"); + lv_obj_t* lblRandom = lv_label_create(btnRandom, nullptr); + lv_label_set_text_static(lblRandom, "Rnd"); lv_obj_set_event_cb(btnRandom, event_handler); lv_obj_set_hidden(btnRandom, true); @@ -268,7 +276,8 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app, lv_obj_set_size(btnClose, 60, 60); lv_obj_align(btnClose, lv_scr_act(), LV_ALIGN_CENTER, 0, -80); lv_obj_set_style_local_bg_opa(btnClose, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_value_str(btnClose, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "X"); + lv_obj_t* lblClose = lv_label_create(btnClose, nullptr); + lv_label_set_text_static(lblClose, "X"); lv_obj_set_event_cb(btnClose, event_handler); lv_obj_set_hidden(btnClose, true); @@ -570,7 +579,7 @@ void WatchFacePineTimeStyle::UpdateSelected(lv_obj_t* object, lv_event_t event) Pinetime::Controllers::Settings::Colors WatchFacePineTimeStyle::GetNext(Pinetime::Controllers::Settings::Colors color) { auto colorAsInt = static_cast<uint8_t>(color); Pinetime::Controllers::Settings::Colors nextColor; - if (colorAsInt < 16) { + if (colorAsInt < 17) { nextColor = static_cast<Controllers::Settings::Colors>(colorAsInt + 1); } else { nextColor = static_cast<Controllers::Settings::Colors>(0); @@ -585,7 +594,7 @@ Pinetime::Controllers::Settings::Colors WatchFacePineTimeStyle::GetPrevious(Pine if (colorAsInt > 0) { prevColor = static_cast<Controllers::Settings::Colors>(colorAsInt - 1); } else { - prevColor = static_cast<Controllers::Settings::Colors>(16); + prevColor = static_cast<Controllers::Settings::Colors>(17); } return prevColor; } diff --git a/src/displayapp/screens/WatchFaceTerminal.cpp b/src/displayapp/screens/WatchFaceTerminal.cpp index c899648c..f5490b44 100644 --- a/src/displayapp/screens/WatchFaceTerminal.cpp +++ b/src/displayapp/screens/WatchFaceTerminal.cpp @@ -149,7 +149,7 @@ void WatchFaceTerminal::Refresh() { } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d.%02d.%02d#", short(year), char(month), char(day)); + lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d-%02d-%02d#", short(year), char(month), char(day)); currentYear = year; currentMonth = month; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 708d5109..b76affc9 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -2,19 +2,29 @@ #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" #include "displayapp/screens/BatteryIcon.h" +#include "components/ble/BleController.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; namespace { void ButtonEventHandler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<QuickSettings*>(obj->user_data); - screen->OnButtonEvent(obj, event); + if (event == LV_EVENT_CLICKED) { + screen->OnButtonEvent(obj); + } } void lv_update_task(struct _lv_task_t* task) { auto* user_data = static_cast<QuickSettings*>(task->user_data); user_data->UpdateScreen(); } + + enum class ButtonState : lv_state_t { + NotificationsOn = LV_STATE_CHECKED, + NotificationsOff = LV_STATE_DEFAULT, + Sleep = 0x40, + }; } QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, @@ -22,13 +32,16 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, Controllers::DateTime& dateTimeController, Controllers::BrightnessController& brightness, Controllers::MotorController& motorController, - Pinetime::Controllers::Settings& settingsController) + Pinetime::Controllers::Settings& settingsController, + Controllers::Ble& bleController) : Screen(app), - batteryController {batteryController}, dateTimeController {dateTimeController}, brightness {brightness}, motorController {motorController}, - settingsController {settingsController} { + settingsController {settingsController}, + statusIcons(batteryController, bleController) { + + statusIcons.Create(); // This is the distance (padding) between all objects on this screen. static constexpr uint8_t innerDistance = 10; @@ -38,9 +51,6 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0); - batteryIcon.Create(lv_scr_act()); - lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); - static constexpr uint8_t barHeight = 20 + innerDistance; static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2; static constexpr uint8_t buttonWidth = (LV_HOR_RES_MAX - innerDistance) / 2; // wide buttons @@ -49,7 +59,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_style_init(&btn_style); lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, buttonHeight / 4); - lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38)); + lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, Colors::bgAlt); btn1 = lv_btn_create(lv_scr_act(), nullptr); btn1->user_data = this; @@ -72,25 +82,29 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_obj_t* lbl_btn; lbl_btn = lv_label_create(btn2, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); - lv_label_set_text_static(lbl_btn, Symbols::highlight); + lv_label_set_text_static(lbl_btn, Symbols::flashlight); btn3 = lv_btn_create(lv_scr_act(), nullptr); btn3->user_data = this; lv_obj_set_event_cb(btn3, ButtonEventHandler); - lv_btn_set_checkable(btn3, true); lv_obj_add_style(btn3, LV_BTN_PART_MAIN, &btn_style); - lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, static_cast<lv_state_t>(ButtonState::NotificationsOff), LV_COLOR_RED); + static constexpr lv_color_t violet = LV_COLOR_MAKE(0x60, 0x00, 0xff); + lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, static_cast<lv_state_t>(ButtonState::Sleep), violet); lv_obj_set_size(btn3, buttonWidth, buttonHeight); lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, buttonXOffset, 0); btn3_lvl = lv_label_create(btn3, nullptr); lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); - if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::ON) { - lv_obj_add_state(btn3, LV_STATE_CHECKED); + if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::On) { lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); - } else { + lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOn)); + } else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Off) { lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); + } else { + lv_label_set_text_static(btn3_lvl, Symbols::sleep); + lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::Sleep)); } btn4 = lv_btn_create(lv_scr_act(), nullptr); @@ -118,34 +132,36 @@ QuickSettings::~QuickSettings() { void QuickSettings::UpdateScreen() { lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str()); - batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining()); + statusIcons.Update(); } -void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == btn2 && event == LV_EVENT_CLICKED) { - - running = false; +void QuickSettings::OnButtonEvent(lv_obj_t* object) { + if (object == btn2) { app->StartApp(Apps::FlashLight, DisplayApp::FullRefreshDirections::Up); - - } else if (object == btn1 && event == LV_EVENT_CLICKED) { + } else if (object == btn1) { brightness.Step(); lv_label_set_text_static(btn1_lvl, brightness.GetIcon()); settingsController.SetBrightness(brightness.Level()); - } else if (object == btn3 && event == LV_EVENT_VALUE_CHANGED) { + } else if (object == btn3) { - if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { - settingsController.SetNotificationStatus(Controllers::Settings::Notification::ON); - motorController.RunForDuration(35); - lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); - } else { - settingsController.SetNotificationStatus(Controllers::Settings::Notification::OFF); + if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::On) { + settingsController.SetNotificationStatus(Controllers::Settings::Notification::Off); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); + lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOff)); + } else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Off) { + settingsController.SetNotificationStatus(Controllers::Settings::Notification::Sleep); + lv_label_set_text_static(btn3_lvl, Symbols::sleep); + lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::Sleep)); + } else { + settingsController.SetNotificationStatus(Controllers::Settings::Notification::On); + lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); + lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOn)); + motorController.RunForDuration(35); } - } else if (object == btn4 && event == LV_EVENT_CLICKED) { - running = false; + } else if (object == btn4) { settingsController.SetSettingsMenu(0); app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up); } diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h index 40a2a2ef..f555d034 100644 --- a/src/displayapp/screens/settings/QuickSettings.h +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -8,7 +8,7 @@ #include "components/motor/MotorController.h" #include "components/settings/Settings.h" #include "components/battery/BatteryController.h" -#include <displayapp/screens/BatteryIcon.h> +#include "displayapp/widgets/StatusIcons.h" namespace Pinetime { @@ -22,16 +22,16 @@ namespace Pinetime { Controllers::DateTime& dateTimeController, Controllers::BrightnessController& brightness, Controllers::MotorController& motorController, - Pinetime::Controllers::Settings& settingsController); + Pinetime::Controllers::Settings& settingsController, + Controllers::Ble& bleController); ~QuickSettings() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); + void OnButtonEvent(lv_obj_t* object); void UpdateScreen(); private: - Pinetime::Controllers::Battery& batteryController; Controllers::DateTime& dateTimeController; Controllers::BrightnessController& brightness; Controllers::MotorController& motorController; @@ -49,7 +49,7 @@ namespace Pinetime { lv_obj_t* btn3_lvl; lv_obj_t* btn4; - BatteryIcon batteryIcon; + Widgets::StatusIcons statusIcons; }; } } diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index bf2087ab..e044a85a 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -15,7 +15,7 @@ namespace { } } -constexpr std::array<uint16_t, 4> SettingDisplay::options; +constexpr std::array<uint16_t, 6> SettingDisplay::options; SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) : Screen(app), settingsController {settingsController} { @@ -30,7 +30,7 @@ SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime lv_obj_set_pos(container1, 10, 60); lv_obj_set_width(container1, LV_HOR_RES - 20); lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + lv_cont_set_layout(container1, LV_LAYOUT_PRETTY_TOP); lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Display timeout"); @@ -46,7 +46,7 @@ SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime char buffer[12]; for (unsigned int i = 0; i < options.size(); i++) { cbOption[i] = lv_checkbox_create(container1, nullptr); - sprintf(buffer, "%3d seconds", options[i] / 1000); + sprintf(buffer, "%2ds", options[i] / 1000); lv_checkbox_set_text(cbOption[i], buffer); cbOption[i]->user_data = this; lv_obj_set_event_cb(cbOption[i], event_handler); diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h index dc56419d..eeddaef8 100644 --- a/src/displayapp/screens/settings/SettingDisplay.h +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -20,7 +20,7 @@ namespace Pinetime { void UpdateSelected(lv_obj_t* object, lv_event_t event); private: - static constexpr std::array<uint16_t, 4> options = {5000, 15000, 20000, 30000}; + static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000}; Controllers::Settings& settingsController; lv_obj_t* cbOption[options.size()]; diff --git a/src/displayapp/screens/settings/SettingSetDate.cpp b/src/displayapp/screens/settings/SettingSetDate.cpp index 7acf0c19..421aef02 100644 --- a/src/displayapp/screens/settings/SettingSetDate.cpp +++ b/src/displayapp/screens/settings/SettingSetDate.cpp @@ -11,13 +11,36 @@ namespace { constexpr int16_t POS_X_DAY = -72; constexpr int16_t POS_X_MONTH = 0; constexpr int16_t POS_X_YEAR = 72; - constexpr int16_t POS_Y_PLUS = -50; constexpr int16_t POS_Y_TEXT = -6; - constexpr int16_t POS_Y_MINUS = 40; void event_handler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<SettingSetDate*>(obj->user_data); - screen->HandleButtonPress(obj, event); + if (event == LV_EVENT_CLICKED) { + screen->HandleButtonPress(); + } + } + + void ValueChangedHandler(void* userData) { + auto* screen = static_cast<SettingSetDate*>(userData); + screen->CheckDay(); + } + + int MaximumDayOfMonth(uint8_t month, uint16_t year) { + switch (month) { + case 2: { + if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) { + return 29; + } + return 28; + } + case 4: + case 6: + case 9: + case 11: + return 30; + default: + return 31; + } } } @@ -35,164 +58,58 @@ SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, Pinetime lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); - dayValue = static_cast<int>(dateTimeController.Day()); - lblDay = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_fmt(lblDay, "%d", dayValue); - lv_label_set_align(lblDay, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblDay, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT); - lv_obj_set_auto_realign(lblDay, true); - - monthValue = static_cast<int>(dateTimeController.Month()); - lblMonth = lv_label_create(lv_scr_act(), nullptr); - UpdateMonthLabel(); - lv_label_set_align(lblMonth, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblMonth, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_TEXT); - lv_obj_set_auto_realign(lblMonth, true); - - yearValue = static_cast<int>(dateTimeController.Year()); - if (yearValue < 2021) - yearValue = 2021; - lblYear = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_fmt(lblYear, "%d", yearValue); - lv_label_set_align(lblYear, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblYear, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_TEXT); - lv_obj_set_auto_realign(lblYear, true); - - btnDayPlus = lv_btn_create(lv_scr_act(), nullptr); - btnDayPlus->user_data = this; - lv_obj_set_size(btnDayPlus, 50, 40); - lv_obj_align(btnDayPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_PLUS); - lv_obj_set_style_local_value_str(btnDayPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); - lv_obj_set_event_cb(btnDayPlus, event_handler); - - btnDayMinus = lv_btn_create(lv_scr_act(), nullptr); - btnDayMinus->user_data = this; - lv_obj_set_size(btnDayMinus, 50, 40); - lv_obj_align(btnDayMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_MINUS); - lv_obj_set_style_local_value_str(btnDayMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - lv_obj_set_event_cb(btnDayMinus, event_handler); - - btnMonthPlus = lv_btn_create(lv_scr_act(), nullptr); - btnMonthPlus->user_data = this; - lv_obj_set_size(btnMonthPlus, 50, 40); - lv_obj_align(btnMonthPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_PLUS); - lv_obj_set_style_local_value_str(btnMonthPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); - lv_obj_set_event_cb(btnMonthPlus, event_handler); + dayCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + dayCounter.Create(); + dayCounter.SetValue(dateTimeController.Day()); + lv_obj_align(dayCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT); - btnMonthMinus = lv_btn_create(lv_scr_act(), nullptr); - btnMonthMinus->user_data = this; - lv_obj_set_size(btnMonthMinus, 50, 40); - lv_obj_align(btnMonthMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_MINUS); - lv_obj_set_style_local_value_str(btnMonthMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - lv_obj_set_event_cb(btnMonthMinus, event_handler); + monthCounter.EnableMonthMode(); + monthCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + monthCounter.Create(); + monthCounter.SetValue(static_cast<int>(dateTimeController.Month())); + lv_obj_align(monthCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_TEXT); - btnYearPlus = lv_btn_create(lv_scr_act(), nullptr); - btnYearPlus->user_data = this; - lv_obj_set_size(btnYearPlus, 50, 40); - lv_obj_align(btnYearPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_PLUS); - lv_obj_set_style_local_value_str(btnYearPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); - lv_obj_set_event_cb(btnYearPlus, event_handler); - - btnYearMinus = lv_btn_create(lv_scr_act(), nullptr); - btnYearMinus->user_data = this; - lv_obj_set_size(btnYearMinus, 50, 40); - lv_obj_align(btnYearMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_MINUS); - lv_obj_set_style_local_value_str(btnYearMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - lv_obj_set_event_cb(btnYearMinus, event_handler); + yearCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + yearCounter.Create(); + yearCounter.SetValue(dateTimeController.Year()); + lv_obj_align(yearCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_TEXT); btnSetTime = lv_btn_create(lv_scr_act(), nullptr); btnSetTime->user_data = this; lv_obj_set_size(btnSetTime, 120, 48); lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); - lv_obj_set_style_local_value_str(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Set"); + lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38)); + lblSetTime = lv_label_create(btnSetTime, nullptr); + lv_label_set_text_static(lblSetTime, "Set"); lv_obj_set_event_cb(btnSetTime, event_handler); + lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED); + lv_obj_set_state(lblSetTime, LV_STATE_DISABLED); } SettingSetDate::~SettingSetDate() { lv_obj_clean(lv_scr_act()); } -void SettingSetDate::HandleButtonPress(lv_obj_t* object, lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; - - if (object == btnDayPlus) { - dayValue++; - if (dayValue > MaximumDayOfMonth()) - dayValue = 1; - lv_label_set_text_fmt(lblDay, "%d", dayValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnDayMinus) { - dayValue--; - if (dayValue < 1) - dayValue = MaximumDayOfMonth(); - lv_label_set_text_fmt(lblDay, "%d", dayValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnMonthPlus) { - monthValue++; - if (monthValue > 12) - monthValue = 1; - UpdateMonthLabel(); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - CheckDay(); - } else if (object == btnMonthMinus) { - monthValue--; - if (monthValue < 1) - monthValue = 12; - UpdateMonthLabel(); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - CheckDay(); - } else if (object == btnYearPlus) { - yearValue++; - lv_label_set_text_fmt(lblYear, "%d", yearValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - CheckDay(); - } else if (object == btnYearMinus) { - yearValue--; - lv_label_set_text_fmt(lblYear, "%d", yearValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - CheckDay(); - } else if (object == btnSetTime) { - NRF_LOG_INFO("Setting date (manually) to %04d-%02d-%02d", yearValue, monthValue, dayValue); - dateTimeController.SetTime(static_cast<uint16_t>(yearValue), - static_cast<uint8_t>(monthValue), - static_cast<uint8_t>(dayValue), - 0, - dateTimeController.Hours(), - dateTimeController.Minutes(), - dateTimeController.Seconds(), - nrf_rtc_counter_get(portNRF_RTC_REG)); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED); - } -} - -int SettingSetDate::MaximumDayOfMonth() const { - switch (monthValue) { - case 2: - if ((((yearValue % 4) == 0) && ((yearValue % 100) != 0)) || ((yearValue % 400) == 0)) - return 29; - return 28; - case 4: - case 6: - case 9: - case 11: - return 30; - default: - return 31; - } +void SettingSetDate::HandleButtonPress() { + const uint16_t yearValue = yearCounter.GetValue(); + const uint8_t monthValue = monthCounter.GetValue(); + const uint8_t dayValue = dayCounter.GetValue(); + NRF_LOG_INFO("Setting date (manually) to %04d-%02d-%02d", yearValue, monthValue, dayValue); + dateTimeController.SetTime(yearValue, + monthValue, + dayValue, + 0, + dateTimeController.Hours(), + dateTimeController.Minutes(), + dateTimeController.Seconds(), + nrf_rtc_counter_get(portNRF_RTC_REG)); + lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED); + lv_obj_set_state(lblSetTime, LV_STATE_DISABLED); } void SettingSetDate::CheckDay() { - int maxDay = MaximumDayOfMonth(); - if (dayValue > maxDay) { - dayValue = maxDay; - lv_label_set_text_fmt(lblDay, "%d", dayValue); - lv_obj_align(lblDay, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT); - } -} - -void SettingSetDate::UpdateMonthLabel() { - lv_label_set_text_static( - lblMonth, - Pinetime::Controllers::DateTime::MonthShortToStringLow(static_cast<Pinetime::Controllers::DateTime::Months>(monthValue))); + const int maxDay = MaximumDayOfMonth(monthCounter.GetValue(), yearCounter.GetValue()); + dayCounter.SetMax(maxDay); + lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); + lv_obj_set_state(lblSetTime, LV_STATE_DEFAULT); } diff --git a/src/displayapp/screens/settings/SettingSetDate.h b/src/displayapp/screens/settings/SettingSetDate.h index a1795942..a0ffc683 100644 --- a/src/displayapp/screens/settings/SettingSetDate.h +++ b/src/displayapp/screens/settings/SettingSetDate.h @@ -4,6 +4,7 @@ #include <lvgl/lvgl.h> #include "components/datetime/DateTimeController.h" #include "displayapp/screens/Screen.h" +#include "displayapp/widgets/Counter.h" namespace Pinetime { namespace Applications { @@ -13,28 +14,18 @@ namespace Pinetime { SettingSetDate(DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController); ~SettingSetDate() override; - void HandleButtonPress(lv_obj_t* object, lv_event_t event); + void HandleButtonPress(); + void CheckDay(); private: Controllers::DateTime& dateTimeController; - int dayValue; - int monthValue; - int yearValue; - lv_obj_t* lblDay; - lv_obj_t* lblMonth; - lv_obj_t* lblYear; - lv_obj_t* btnDayPlus; - lv_obj_t* btnDayMinus; - lv_obj_t* btnMonthPlus; - lv_obj_t* btnMonthMinus; - lv_obj_t* btnYearPlus; - lv_obj_t* btnYearMinus; lv_obj_t* btnSetTime; + lv_obj_t* lblSetTime; - int MaximumDayOfMonth() const; - void CheckDay(); - void UpdateMonthLabel(); + Widgets::Counter dayCounter = Widgets::Counter(1, 31, jetbrains_mono_bold_20); + Widgets::Counter monthCounter = Widgets::Counter(1, 12, jetbrains_mono_bold_20); + Widgets::Counter yearCounter = Widgets::Counter(1970, 9999, jetbrains_mono_bold_20); }; } } diff --git a/src/displayapp/screens/settings/SettingSetTime.cpp b/src/displayapp/screens/settings/SettingSetTime.cpp index 037611f3..e7d824fd 100644 --- a/src/displayapp/screens/settings/SettingSetTime.cpp +++ b/src/displayapp/screens/settings/SettingSetTime.cpp @@ -5,21 +5,22 @@ #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" #include "components/settings/Settings.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; namespace { - constexpr int16_t POS_X_HOURS = -72; - constexpr int16_t POS_X_MINUTES = 0; - constexpr int16_t POS_X_SECONDS = 72; - constexpr int16_t POS_Y_PLUS = -50; - constexpr int16_t POS_Y_TEXT = -6; - constexpr int16_t POS_Y_MINUS = 40; - constexpr int16_t OFS_Y_COLON = -2; + constexpr int16_t POS_Y_TEXT = -7; - void event_handler(lv_obj_t* obj, lv_event_t event) { + void SetTimeEventHandler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<SettingSetTime*>(obj->user_data); - screen->HandleButtonPress(obj, event); + if (event == LV_EVENT_CLICKED) { + screen->SetTime(); + } + } + void ValueChangedHandler(void* userData) { + auto* screen = static_cast<SettingSetTime*>(userData); + screen->UpdateScreen(); } } @@ -27,6 +28,7 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController, Pinetime::Controllers::Settings& settingsController) : Screen(app), dateTimeController {dateTimeController}, settingsController {settingsController} { + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Set current time"); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); @@ -34,160 +36,76 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app, lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - lv_label_set_text_static(icon, Symbols::clock); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); - hoursValue = static_cast<int>(dateTimeController.Hours()); - lblHours = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblHours, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - lv_label_set_text_fmt(lblHours, "%02d", hoursValue); - lv_label_set_align(lblHours, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblHours, lv_scr_act(), LV_ALIGN_CENTER, POS_X_HOURS, POS_Y_TEXT); - lv_obj_set_auto_realign(lblHours, true); - - lv_obj_t* lblColon1 = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblColon1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - lv_label_set_text_static(lblColon1, ":"); - lv_label_set_align(lblColon1, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblColon1, lv_scr_act(), LV_ALIGN_CENTER, (POS_X_HOURS + POS_X_MINUTES) / 2, POS_Y_TEXT + OFS_Y_COLON); + lv_obj_t* staticLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(staticLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); + lv_label_set_text_static(staticLabel, "00:00:00"); + lv_obj_align(staticLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, POS_Y_TEXT); - minutesValue = static_cast<int>(dateTimeController.Minutes()); - lblMinutes = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue); - lv_label_set_align(lblMinutes, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblMinutes, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MINUTES, POS_Y_TEXT); - lv_obj_set_auto_realign(lblMinutes, true); - - lv_obj_t* lblColon2 = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblColon2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - lv_label_set_text_static(lblColon2, ":"); - lv_label_set_align(lblColon2, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblColon2, lv_scr_act(), LV_ALIGN_CENTER, (POS_X_MINUTES + POS_X_SECONDS) / 2, POS_Y_TEXT + OFS_Y_COLON); + hourCounter.Create(); + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + hourCounter.EnableTwelveHourMode(); + } + hourCounter.SetValue(dateTimeController.Hours()); + lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_CENTER, -75, POS_Y_TEXT); + hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler); - lv_obj_t* lblSeconds = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lblSeconds, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - lv_label_set_text_static(lblSeconds, "00"); - lv_label_set_align(lblSeconds, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblSeconds, lv_scr_act(), LV_ALIGN_CENTER, POS_X_SECONDS, POS_Y_TEXT); + minuteCounter.Create(); + minuteCounter.SetValue(dateTimeController.Minutes()); + lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_CENTER, 0, POS_Y_TEXT); + minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler); lblampm = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); lv_label_set_text_static(lblampm, " "); - lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER); - lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, POS_X_SECONDS, POS_Y_PLUS); - - btnHoursPlus = lv_btn_create(lv_scr_act(), nullptr); - btnHoursPlus->user_data = this; - lv_obj_set_size(btnHoursPlus, 50, 40); - lv_obj_align(btnHoursPlus, lv_scr_act(), LV_ALIGN_CENTER, -72, -50); - lv_obj_set_style_local_value_str(btnHoursPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); - lv_obj_set_event_cb(btnHoursPlus, event_handler); - - btnHoursMinus = lv_btn_create(lv_scr_act(), nullptr); - btnHoursMinus->user_data = this; - lv_obj_set_size(btnHoursMinus, 50, 40); - lv_obj_align(btnHoursMinus, lv_scr_act(), LV_ALIGN_CENTER, -72, 40); - lv_obj_set_style_local_value_str(btnHoursMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - lv_obj_set_event_cb(btnHoursMinus, event_handler); - - btnMinutesPlus = lv_btn_create(lv_scr_act(), nullptr); - btnMinutesPlus->user_data = this; - lv_obj_set_size(btnMinutesPlus, 50, 40); - lv_obj_align(btnMinutesPlus, lv_scr_act(), LV_ALIGN_CENTER, 0, -50); - lv_obj_set_style_local_value_str(btnMinutesPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); - lv_obj_set_event_cb(btnMinutesPlus, event_handler); - - btnMinutesMinus = lv_btn_create(lv_scr_act(), nullptr); - btnMinutesMinus->user_data = this; - lv_obj_set_size(btnMinutesMinus, 50, 40); - lv_obj_align(btnMinutesMinus, lv_scr_act(), LV_ALIGN_CENTER, 0, 40); - lv_obj_set_style_local_value_str(btnMinutesMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - lv_obj_set_event_cb(btnMinutesMinus, event_handler); + lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 75, -50); btnSetTime = lv_btn_create(lv_scr_act(), nullptr); btnSetTime->user_data = this; - lv_obj_set_size(btnSetTime, 120, 48); + lv_obj_set_size(btnSetTime, 120, 50); lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); - lv_obj_set_style_local_value_str(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Set"); - lv_obj_set_event_cb(btnSetTime, event_handler); - - SetHourLabels(); + lblSetTime = lv_label_create(btnSetTime, nullptr); + lv_label_set_text_static(lblSetTime, "Set"); + lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); + lv_obj_set_style_local_text_color(lblSetTime, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_GRAY); + lv_obj_set_event_cb(btnSetTime, SetTimeEventHandler); + + UpdateScreen(); + lv_obj_set_state(btnSetTime, LV_STATE_DISABLED); + lv_obj_set_state(lblSetTime, LV_STATE_DISABLED); } SettingSetTime::~SettingSetTime() { lv_obj_clean(lv_scr_act()); } -void SettingSetTime::SetHourLabels() { +void SettingSetTime::UpdateScreen() { if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { - switch (hoursValue) { - case 0: - lv_label_set_text_static(lblHours, "12"); - lv_label_set_text_static(lblampm, "AM"); - break; - case 1 ... 11: - lv_label_set_text_fmt(lblHours, "%02d", hoursValue); - lv_label_set_text_static(lblampm, "AM"); - break; - case 12: - lv_label_set_text_static(lblHours, "12"); - lv_label_set_text_static(lblampm, "PM"); - break; - case 13 ... 23: - lv_label_set_text_fmt(lblHours, "%02d", hoursValue - 12); - lv_label_set_text_static(lblampm, "PM"); - break; + if (hourCounter.GetValue() >= 12) { + lv_label_set_text_static(lblampm, "PM"); + } else { + lv_label_set_text_static(lblampm, "AM"); } - } else { - lv_label_set_text_fmt(lblHours, "%02d", hoursValue); } + lv_obj_set_state(btnSetTime, LV_STATE_DEFAULT); + lv_obj_set_state(lblSetTime, LV_STATE_DEFAULT); } -void SettingSetTime::HandleButtonPress(lv_obj_t* object, lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; - - if (object == btnHoursPlus) { - hoursValue++; - if (hoursValue > 23) { - hoursValue = 0; - } - SetHourLabels(); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnHoursMinus) { - hoursValue--; - if (hoursValue < 0) { - hoursValue = 23; - } - SetHourLabels(); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnMinutesPlus) { - minutesValue++; - if (minutesValue > 59) { - minutesValue = 0; - } - lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnMinutesMinus) { - minutesValue--; - if (minutesValue < 0) { - minutesValue = 59; - } - lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED); - } else if (object == btnSetTime) { - NRF_LOG_INFO("Setting time (manually) to %02d:%02d:00", hoursValue, minutesValue); - dateTimeController.SetTime(dateTimeController.Year(), - static_cast<uint8_t>(dateTimeController.Month()), - dateTimeController.Day(), - static_cast<uint8_t>(dateTimeController.DayOfWeek()), - static_cast<uint8_t>(hoursValue), - static_cast<uint8_t>(minutesValue), - 0, - nrf_rtc_counter_get(portNRF_RTC_REG)); - lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED); - } +void SettingSetTime::SetTime() { + const int hoursValue = hourCounter.GetValue(); + const int minutesValue = minuteCounter.GetValue(); + NRF_LOG_INFO("Setting time (manually) to %02d:%02d:00", hoursValue, minutesValue); + dateTimeController.SetTime(dateTimeController.Year(), + static_cast<uint8_t>(dateTimeController.Month()), + dateTimeController.Day(), + static_cast<uint8_t>(dateTimeController.DayOfWeek()), + static_cast<uint8_t>(hoursValue), + static_cast<uint8_t>(minutesValue), + 0, + nrf_rtc_counter_get(portNRF_RTC_REG)); + lv_obj_set_state(btnSetTime, LV_STATE_DISABLED); + lv_obj_set_state(lblSetTime, LV_STATE_DISABLED); } diff --git a/src/displayapp/screens/settings/SettingSetTime.h b/src/displayapp/screens/settings/SettingSetTime.h index d02c332e..b61962c1 100644 --- a/src/displayapp/screens/settings/SettingSetTime.h +++ b/src/displayapp/screens/settings/SettingSetTime.h @@ -4,6 +4,7 @@ #include <lvgl/lvgl.h> #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" +#include "displayapp/widgets/Counter.h" #include "displayapp/screens/Screen.h" namespace Pinetime { @@ -16,24 +17,18 @@ namespace Pinetime { Pinetime::Controllers::Settings& settingsController); ~SettingSetTime() override; - void HandleButtonPress(lv_obj_t* object, lv_event_t event); + void SetTime(); + void UpdateScreen(); private: Controllers::DateTime& dateTimeController; Controllers::Settings& settingsController; - void SetHourLabels(); - - int hoursValue; - int minutesValue; - lv_obj_t* lblHours; - lv_obj_t* lblMinutes; lv_obj_t* lblampm; - lv_obj_t* btnHoursPlus; - lv_obj_t* btnHoursMinus; - lv_obj_t* btnMinutesPlus; - lv_obj_t* btnMinutesMinus; lv_obj_t* btnSetTime; + lv_obj_t* lblSetTime; + Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_42); + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_42); }; } } diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.cpp b/src/displayapp/screens/settings/SettingShakeThreshold.cpp index aac1eaff..de46f7de 100644 --- a/src/displayapp/screens/settings/SettingShakeThreshold.cpp +++ b/src/displayapp/screens/settings/SettingShakeThreshold.cpp @@ -3,6 +3,7 @@ #include "displayapp/DisplayApp.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -123,8 +124,7 @@ void SettingShakeThreshold::UpdateSelected(lv_obj_t* object, lv_event_t event) { vCalTime = xTaskGetTickCount(); lv_label_set_text_static(calLabel, "Ready!"); lv_obj_set_click(positionArc, false); - lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); - lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0)); + lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, Colors::highlight); } else if (lv_btn_get_state(calButton) == LV_BTN_STATE_RELEASED) { calibrating = 0; lv_obj_set_click(positionArc, true); diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp index e92600c2..a6b6f4a8 100644 --- a/src/displayapp/screens/settings/SettingSteps.cpp +++ b/src/displayapp/screens/settings/SettingSteps.cpp @@ -17,7 +17,6 @@ SettingSteps::SettingSteps(Pinetime::Applications::DisplayApp* app, Pinetime::Co lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - // lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); @@ -49,7 +48,8 @@ SettingSteps::SettingSteps(Pinetime::Applications::DisplayApp* app, Pinetime::Co btnPlus->user_data = this; lv_obj_set_size(btnPlus, 80, 50); lv_obj_align(btnPlus, lv_scr_act(), LV_ALIGN_CENTER, 55, 80); - lv_obj_set_style_local_value_str(btnPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+"); + lv_obj_t* lblPlus = lv_label_create(btnPlus, nullptr); + lv_label_set_text_static(lblPlus, "+"); lv_obj_set_event_cb(btnPlus, event_handler); btnMinus = lv_btn_create(lv_scr_act(), nullptr); @@ -57,7 +57,8 @@ SettingSteps::SettingSteps(Pinetime::Applications::DisplayApp* app, Pinetime::Co lv_obj_set_size(btnMinus, 80, 50); lv_obj_set_event_cb(btnMinus, event_handler); lv_obj_align(btnMinus, lv_scr_act(), LV_ALIGN_CENTER, -55, 80); - lv_obj_set_style_local_value_str(btnMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); + lv_obj_t* lblMinus = lv_label_create(btnMinus, nullptr); + lv_label_set_text_static(lblMinus, "-"); } SettingSteps::~SettingSteps() { diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h index 818edf0c..01ca2c9b 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.h +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -20,7 +20,7 @@ namespace Pinetime { void UpdateSelected(lv_obj_t* object, lv_event_t event); private: - static constexpr std::array<const char*, 2> options = {" 12-hour", " 24-hour"}; + static constexpr std::array<const char*, 2> options = {"12-hour", "24-hour"}; Controllers::Settings& settingsController; lv_obj_t* cbOption[options.size()]; }; diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 4a4b60f8..59275e2f 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -42,7 +42,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: optionsTotal = 0; cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap"); + lv_checkbox_set_text_static(cbOption[optionsTotal], "Single Tap"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)) { @@ -50,7 +50,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: } optionsTotal++; cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap"); + lv_checkbox_set_text_static(cbOption[optionsTotal], "Double Tap"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { @@ -58,7 +58,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: } optionsTotal++; cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist"); + lv_checkbox_set_text_static(cbOption[optionsTotal], "Raise Wrist"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) { @@ -66,7 +66,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: } optionsTotal++; cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Shake Wake"); + lv_checkbox_set_text_static(cbOption[optionsTotal], "Shake Wake"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)) { diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index 52ea5d9e..411cc898 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -36,13 +36,27 @@ bool SettingWatchFace::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } std::unique_ptr<Screen> SettingWatchFace::CreateScreen1() { - std::array<const char*, 4> watchfaces {" Digital face", " Analog face", " PineTimeStyle", " Terminal"}; - return std::make_unique<Screens::CheckboxList>( - 0, 2, app, settingsController, title, symbol, &Controllers::Settings::SetClockFace, &Controllers::Settings::GetClockFace, watchfaces); + std::array<const char*, 4> watchfaces {"Digital face", "Analog face", "PineTimeStyle", "Terminal"}; + return std::make_unique<Screens::CheckboxList>(0, + 2, + app, + settingsController, + title, + symbol, + &Controllers::Settings::SetClockFace, + &Controllers::Settings::GetClockFace, + watchfaces); } std::unique_ptr<Screen> SettingWatchFace::CreateScreen2() { - std::array<const char*, 4> watchfaces {" Casio G7710", "", "", ""}; - return std::make_unique<Screens::CheckboxList>( - 1, 2, app, settingsController, title, symbol, &Controllers::Settings::SetClockFace, &Controllers::Settings::GetClockFace, watchfaces); + std::array<const char*, 4> watchfaces {"Infineat face", "Casio G7710", "", ""}; + return std::make_unique<Screens::CheckboxList>(1, + 2, + app, + settingsController, + title, + symbol, + &Controllers::Settings::SetClockFace, + &Controllers::Settings::GetClockFace, + watchfaces); } |