diff options
Diffstat (limited to 'src/displayapp')
65 files changed, 718 insertions, 857 deletions
diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index 8aad9535..89b05d87 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -34,8 +34,7 @@ namespace Pinetime { SettingDisplay, SettingWakeUp, SettingSteps, - SettingSetDate, - SettingSetTime, + SettingSetDateTime, SettingChimes, SettingShakeThreshold, SettingBluetooth, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 108e380d..725caaf4 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -43,8 +43,7 @@ #include "displayapp/screens/settings/SettingWakeUp.h" #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" -#include "displayapp/screens/settings/SettingSetDate.h" -#include "displayapp/screens/settings/SettingSetTime.h" +#include "displayapp/screens/settings/SettingSetDateTime.h" #include "displayapp/screens/settings/SettingChimes.h" #include "displayapp/screens/settings/SettingShakeThreshold.h" #include "displayapp/screens/settings/SettingBluetooth.h" @@ -102,9 +101,9 @@ void DisplayApp::Start(System::BootErrors error) { bootError = error; if (error == System::BootErrors::TouchController) { - LoadApp(Apps::Error, DisplayApp::FullRefreshDirections::None); + LoadNewScreen(Apps::Error, DisplayApp::FullRefreshDirections::None); } else { - LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None); + LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None); } if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) { @@ -132,7 +131,25 @@ void DisplayApp::InitHw() { void DisplayApp::Refresh() { auto LoadPreviousScreen = [this]() { - LoadApp(returnToApp, returnDirection); + FullRefreshDirections returnDirection; + switch (appStackDirections.Pop()) { + case FullRefreshDirections::Up: + returnDirection = FullRefreshDirections::Down; + break; + case FullRefreshDirections::Down: + returnDirection = FullRefreshDirections::Up; + break; + case FullRefreshDirections::LeftAnim: + returnDirection = FullRefreshDirections::RightAnim; + break; + case FullRefreshDirections::RightAnim: + returnDirection = FullRefreshDirections::LeftAnim; + break; + default: + returnDirection = FullRefreshDirections::None; + break; + } + LoadScreen(returnAppStack.Pop(), returnDirection); }; TickType_t queueTimeout; @@ -152,7 +169,7 @@ void DisplayApp::Refresh() { } Messages msg; - if (xQueueReceive(msgQueue, &msg, queueTimeout)) { + if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) { switch (msg) { case Messages::DimScreen: brightnessController.Set(Controllers::BrightnessController::Levels::Low); @@ -180,14 +197,14 @@ void DisplayApp::Refresh() { // Screens::Clock::BleConnectionStates::NotConnected); break; case Messages::NewNotification: - LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); break; case Messages::TimerDone: if (currentApp == Apps::Timer) { auto* timer = static_cast<Screens::Timer*>(currentScreen.get()); timer->Reset(); } else { - LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up); } break; case Messages::AlarmTriggered: @@ -195,11 +212,11 @@ void DisplayApp::Refresh() { auto* alarm = static_cast<Screens::Alarm*>(currentScreen.get()); alarm->SetAlerting(); } else { - LoadApp(Apps::Alarm, DisplayApp::FullRefreshDirections::None); + LoadNewScreen(Apps::Alarm, DisplayApp::FullRefreshDirections::None); } break; case Messages::ShowPairingKey: - LoadApp(Apps::PassKey, DisplayApp::FullRefreshDirections::Up); + LoadNewScreen(Apps::PassKey, DisplayApp::FullRefreshDirections::Up); break; case Messages::TouchEvent: { if (state != States::Running) { @@ -209,17 +226,30 @@ void DisplayApp::Refresh() { if (gesture == TouchEvents::None) { break; } + auto LoadDirToReturnSwipe = [](DisplayApp::FullRefreshDirections refreshDirection) { + switch (refreshDirection) { + default: + case DisplayApp::FullRefreshDirections::Up: + return TouchEvents::SwipeDown; + case DisplayApp::FullRefreshDirections::Down: + return TouchEvents::SwipeUp; + case DisplayApp::FullRefreshDirections::LeftAnim: + return TouchEvents::SwipeRight; + case DisplayApp::FullRefreshDirections::RightAnim: + return TouchEvents::SwipeLeft; + } + }; if (!currentScreen->OnTouchEvent(gesture)) { if (currentApp == Apps::Clock) { switch (gesture) { case TouchEvents::SwipeUp: - LoadApp(Apps::Launcher, DisplayApp::FullRefreshDirections::Up); + LoadNewScreen(Apps::Launcher, DisplayApp::FullRefreshDirections::Up); break; case TouchEvents::SwipeDown: - LoadApp(Apps::Notifications, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::Notifications, DisplayApp::FullRefreshDirections::Down); break; case TouchEvents::SwipeRight: - LoadApp(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim); + LoadNewScreen(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim); break; case TouchEvents::DoubleTap: PushMessageToSystemTask(System::Messages::GoToSleep); @@ -227,7 +257,7 @@ void DisplayApp::Refresh() { default: break; } - } else if (returnTouchEvent == gesture) { + } else if (gesture == LoadDirToReturnSwipe(appStackDirections.Top())) { LoadPreviousScreen(); } } else { @@ -246,26 +276,28 @@ void DisplayApp::Refresh() { case Messages::ButtonLongPressed: if (currentApp != Apps::Clock) { if (currentApp == Apps::Notifications) { - LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::Up); + LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::Up); } else if (currentApp == Apps::QuickSettings) { - LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::LeftAnim); + LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::LeftAnim); } else { - LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::Down); } + appStackDirections.Reset(); + returnAppStack.Reset(); } break; case Messages::ButtonLongerPressed: // Create reboot app and open it instead - LoadApp(Apps::SysInfo, DisplayApp::FullRefreshDirections::Up); + LoadNewScreen(Apps::SysInfo, DisplayApp::FullRefreshDirections::Up); break; case Messages::ButtonDoubleClicked: if (currentApp != Apps::Notifications && currentApp != Apps::NotificationsPreview) { - LoadApp(Apps::Notifications, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::Notifications, DisplayApp::FullRefreshDirections::Down); } break; case Messages::BleFirmwareUpdateStarted: - LoadApp(Apps::FirmwareUpdate, DisplayApp::FullRefreshDirections::Down); + LoadNewScreen(Apps::FirmwareUpdate, DisplayApp::FullRefreshDirections::Down); break; case Messages::BleRadioEnableToggle: PushMessageToSystemTask(System::Messages::BleRadioEnableToggle); @@ -275,7 +307,7 @@ void DisplayApp::Refresh() { // What should happen here? break; case Messages::Clock: - LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None); + LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None); break; } } @@ -285,7 +317,7 @@ void DisplayApp::Refresh() { } if (nextApp != Apps::None) { - LoadApp(nextApp, nextDirection); + LoadNewScreen(nextApp, nextDirection); nextApp = Apps::None; } } @@ -295,27 +327,28 @@ void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction) nextDirection = direction; } -void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent) { - returnToApp = app; - returnDirection = direction; - returnTouchEvent = touchEvent; +void DisplayApp::LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction) { + // Don't add the same screen to the stack back to back. + // This is mainly to fix an issue with receiving two notifications at the same time + // and shouldn't happen otherwise. + if (app != currentApp) { + returnAppStack.Push(currentApp); + appStackDirections.Push(direction); + } + LoadScreen(app, direction); } -void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) { +void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction) { touchHandler.CancelTap(); ApplyBrightness(); currentScreen.reset(nullptr); SetFullRefresh(direction); - // default return to launcher - ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::SwipeDown); - switch (app) { case Apps::Launcher: currentScreen = std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, bleController, dateTimeController); - ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::None: case Apps::Clock: @@ -332,21 +365,17 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Error: currentScreen = std::make_unique<Screens::Error>(this, bootError); - ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::FirmwareValidation: currentScreen = std::make_unique<Screens::FirmwareValidation>(this, validator); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::FirmwareUpdate: currentScreen = std::make_unique<Screens::FirmwareUpdate>(this, bleController); - ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::PassKey: currentScreen = std::make_unique<Screens::PassKey>(this, bleController.GetPairingKey()); - ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::Notifications: @@ -356,7 +385,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) motorController, *systemTask, Screens::Notifications::Modes::Normal); - ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique<Screens::Notifications>(this, @@ -365,7 +393,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) motorController, *systemTask, Screens::Notifications::Modes::Preview); - ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::Timer: currentScreen = std::make_unique<Screens::Timer>(this, timerController); @@ -383,55 +410,39 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) motorController, settingsController, bleController); - ReturnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft); break; case Apps::Settings: currentScreen = std::make_unique<Screens::Settings>(this, settingsController); - ReturnApp(Apps::QuickSettings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingWatchFace: currentScreen = std::make_unique<Screens::SettingWatchFace>(this, settingsController, filesystem); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingTimeFormat: currentScreen = std::make_unique<Screens::SettingTimeFormat>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingWakeUp: currentScreen = std::make_unique<Screens::SettingWakeUp>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingDisplay: currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingSteps: currentScreen = std::make_unique<Screens::SettingSteps>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; - case Apps::SettingSetDate: - currentScreen = std::make_unique<Screens::SettingSetDate>(this, dateTimeController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); - break; - case Apps::SettingSetTime: - currentScreen = std::make_unique<Screens::SettingSetTime>(this, dateTimeController, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + case Apps::SettingSetDateTime: + currentScreen = std::make_unique<Screens::SettingSetDateTime>(this, dateTimeController, settingsController); break; case Apps::SettingChimes: currentScreen = std::make_unique<Screens::SettingChimes>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingShakeThreshold: currentScreen = std::make_unique<Screens::SettingShakeThreshold>(this, settingsController, motionController, *systemTask); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingBluetooth: currentScreen = std::make_unique<Screens::SettingBluetooth>(this, settingsController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::BatteryInfo: currentScreen = std::make_unique<Screens::BatteryInfo>(this, batteryController); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SysInfo: currentScreen = std::make_unique<Screens::SystemInfo>(this, @@ -442,11 +453,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) watchdog, motionController, touchPanel); - ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::FlashLight: currentScreen = std::make_unique<Screens::FlashLight>(this, *systemTask, brightnessController); - ReturnApp(Apps::QuickSettings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::StopWatch: currentScreen = std::make_unique<Screens::StopWatch>(this, *systemTask); @@ -471,7 +480,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::Metronome: currentScreen = std::make_unique<Screens::Metronome>(this, motorController, *systemTask); - ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Motion: currentScreen = std::make_unique<Screens::Motion>(this, motionController); @@ -485,10 +493,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) void DisplayApp::PushMessage(Messages msg) { if (in_isr()) { - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { + if (xHigherPriorityTaskWoken == pdTRUE) { portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } else { @@ -530,10 +537,10 @@ void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) { void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { this->systemTask = systemTask; } + void DisplayApp::ApplyBrightness() { auto brightness = settingsController.GetBrightness(); - if(brightness != Controllers::BrightnessController::Levels::Low && - brightness != Controllers::BrightnessController::Levels::Medium && + if (brightness != Controllers::BrightnessController::Levels::Low && brightness != Controllers::BrightnessController::Levels::Medium && brightness != Controllers::BrightnessController::Levels::High) { brightness = Controllers::BrightnessController::Levels::High; } diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 4c54e227..c1d04cc9 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -20,6 +20,8 @@ #include "displayapp/Messages.h" #include "BootErrors.h" +#include "StaticStack.h" + namespace Pinetime { namespace Drivers { @@ -27,6 +29,7 @@ namespace Pinetime { class Cst816S; class WatchdogView; } + namespace Controllers { class Settings; class Battery; @@ -41,6 +44,7 @@ namespace Pinetime { namespace System { class SystemTask; }; + namespace Applications { class DisplayApp { public: @@ -114,14 +118,18 @@ namespace Pinetime { static void Process(void* instance); void InitHw(); void Refresh(); - void ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent); - void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction); + void LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction); + void LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction); void PushMessageToSystemTask(Pinetime::System::Messages message); Apps nextApp = Apps::None; DisplayApp::FullRefreshDirections nextDirection; System::BootErrors bootError; void ApplyBrightness(); + + static constexpr size_t returnAppStackSize = 10; + StaticStack<Apps, returnAppStackSize> returnAppStack; + StaticStack<FullRefreshDirections, returnAppStackSize> appStackDirections; }; } } diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index e553aa87..ecc01e9b 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -11,22 +11,22 @@ using namespace Pinetime::Applications; DisplayApp::DisplayApp(Drivers::St7789& lcd, - Components::LittleVgl& lvgl, - Drivers::Cst816S& touchPanel, - Controllers::Battery& batteryController, + Components::LittleVgl& /*lvgl*/, + Drivers::Cst816S& /*touchPanel*/, + Controllers::Battery& /*batteryController*/, Controllers::Ble& bleController, - Controllers::DateTime& dateTimeController, - Drivers::WatchdogView& watchdog, - Pinetime::Controllers::NotificationManager& notificationManager, - Pinetime::Controllers::HeartRateController& heartRateController, - Controllers::Settings& settingsController, - Pinetime::Controllers::MotorController& motorController, - Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController, - Pinetime::Controllers::AlarmController& alarmController, - Pinetime::Controllers::BrightnessController& brightnessController, - Pinetime::Controllers::TouchHandler& touchHandler, - Pinetime::Controllers::FS& filesystem) + Controllers::DateTime& /*dateTimeController*/, + Drivers::WatchdogView& /*watchdog*/, + Pinetime::Controllers::NotificationManager& /*notificationManager*/, + Pinetime::Controllers::HeartRateController& /*heartRateController*/, + Controllers::Settings& /*settingsController*/, + Pinetime::Controllers::MotorController& /*motorController*/, + Pinetime::Controllers::MotionController& /*motionController*/, + Pinetime::Controllers::TimerController& /*timerController*/, + Pinetime::Controllers::AlarmController& /*alarmController*/, + Pinetime::Controllers::BrightnessController& /*brightnessController*/, + Pinetime::Controllers::TouchHandler& /*touchHandler*/, + Pinetime::Controllers::FS& /*filesystem*/) : lcd {lcd}, bleController {bleController} { } @@ -121,5 +121,5 @@ void DisplayApp::PushMessage(Display::Messages msg) { } } -void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { +void DisplayApp::Register(Pinetime::System::SystemTask* /*systemTask*/) { } diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 7d4f0fd0..97aaca88 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -22,6 +22,7 @@ namespace Pinetime { class Cst816S; class WatchdogView; } + namespace Controllers { class Settings; class Battery; @@ -63,9 +64,11 @@ namespace Pinetime { Pinetime::Controllers::TouchHandler& touchHandler, Pinetime::Controllers::FS& filesystem); void Start(); + void Start(Pinetime::System::BootErrors) { Start(); }; + void PushMessage(Pinetime::Applications::Display::Messages msg); void Register(Pinetime::System::SystemTask* systemTask); diff --git a/src/displayapp/DummyLittleVgl.h b/src/displayapp/DummyLittleVgl.h index 05355a97..7a8ae999 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -11,6 +11,7 @@ namespace Pinetime { class LittleVgl { public: enum class FullRefreshDirections { None, Up, Down }; + LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) { } @@ -24,13 +25,17 @@ namespace Pinetime { void FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { } + bool GetTouchPadInfo(lv_indev_data_t* ptr) { return false; } + void SetFullRefresh(FullRefreshDirections direction) { } + void SetNewTapEvent(uint16_t x, uint16_t y) { } + void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { } }; diff --git a/src/displayapp/InfiniTimeTheme.cpp b/src/displayapp/InfiniTimeTheme.cpp index 4290d87f..6795647e 100644 --- a/src/displayapp/InfiniTimeTheme.cpp +++ b/src/displayapp/InfiniTimeTheme.cpp @@ -1,4 +1,17 @@ #include "displayapp/InfiniTimeTheme.h" +#include <algorithm> + +// Replace LV_DPX with a constexpr version using a constant LV_DPI +#undef LV_DPX + +namespace { + constexpr int LV_DPX(int n) { + if (n == 0) { + return 0; + } + return std::max(((LV_DPI * n + 80) / 160), 1); /*+80 for rounding*/ + } +} static void theme_apply(lv_obj_t* obj, lv_theme_style_t name); @@ -47,7 +60,6 @@ static void basic_init() { style_init_reset(&style_box); lv_style_set_bg_opa(&style_box, LV_STATE_DEFAULT, LV_OPA_COVER); lv_style_set_radius(&style_box, LV_STATE_DEFAULT, 10); - lv_style_set_value_color(&style_box, LV_STATE_DEFAULT, Colors::bg); lv_style_set_value_font(&style_box, LV_STATE_DEFAULT, theme.font_normal); style_init_reset(&style_label_white); @@ -60,25 +72,12 @@ static void basic_init() { lv_style_set_bg_color(&style_btn, LV_STATE_DEFAULT, Colors::bg); lv_style_set_bg_color(&style_btn, LV_STATE_CHECKED, Colors::highlight); lv_style_set_bg_color(&style_btn, LV_STATE_DISABLED, Colors::bgDark); - lv_style_set_border_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_border_width(&style_btn, LV_STATE_DEFAULT, 0); lv_style_set_text_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_style_set_text_color(&style_btn, LV_STATE_DISABLED, LV_COLOR_GRAY); - lv_style_set_value_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_value_color(&style_btn, LV_STATE_DISABLED, LV_COLOR_GRAY); - - lv_style_set_pad_left(&style_btn, LV_STATE_DEFAULT, LV_DPX(20)); - lv_style_set_pad_right(&style_btn, LV_STATE_DEFAULT, LV_DPX(20)); - lv_style_set_pad_top(&style_btn, LV_STATE_DEFAULT, LV_DPX(20)); - lv_style_set_pad_bottom(&style_btn, LV_STATE_DEFAULT, LV_DPX(20)); + lv_style_set_pad_all(&style_btn, LV_STATE_DEFAULT, LV_DPX(20)); lv_style_set_pad_inner(&style_btn, LV_STATE_DEFAULT, LV_DPX(15)); - lv_style_set_outline_width(&style_btn, LV_STATE_DEFAULT, LV_DPX(2)); - lv_style_set_outline_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_0); - lv_style_set_outline_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_transition_time(&style_btn, LV_STATE_DEFAULT, 0); - lv_style_set_transition_delay(&style_btn, LV_STATE_DEFAULT, 0); style_init_reset(&style_icon); lv_style_set_text_color(&style_icon, LV_STATE_DEFAULT, LV_COLOR_WHITE); @@ -132,10 +131,7 @@ static void basic_init() { lv_style_set_bg_color(&style_sw_knob, LV_STATE_DEFAULT, LV_COLOR_SILVER); lv_style_set_bg_color(&style_sw_knob, LV_STATE_CHECKED, LV_COLOR_WHITE); lv_style_set_radius(&style_sw_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_style_set_pad_top(&style_sw_knob, LV_STATE_DEFAULT, -4); - lv_style_set_pad_bottom(&style_sw_knob, LV_STATE_DEFAULT, -4); - lv_style_set_pad_left(&style_sw_knob, LV_STATE_DEFAULT, -4); - lv_style_set_pad_right(&style_sw_knob, LV_STATE_DEFAULT, -4); + lv_style_set_pad_all(&style_sw_knob, LV_STATE_DEFAULT, -4); style_init_reset(&style_slider_knob); lv_style_set_bg_opa(&style_slider_knob, LV_STATE_DEFAULT, LV_OPA_COVER); @@ -143,14 +139,8 @@ static void basic_init() { lv_style_set_border_color(&style_slider_knob, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_style_set_border_width(&style_slider_knob, LV_STATE_DEFAULT, 6); lv_style_set_radius(&style_slider_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_style_set_pad_top(&style_slider_knob, LV_STATE_DEFAULT, 10); - lv_style_set_pad_bottom(&style_slider_knob, LV_STATE_DEFAULT, 10); - lv_style_set_pad_left(&style_slider_knob, LV_STATE_DEFAULT, 10); - lv_style_set_pad_right(&style_slider_knob, LV_STATE_DEFAULT, 10); - lv_style_set_pad_top(&style_slider_knob, LV_STATE_PRESSED, 14); - lv_style_set_pad_bottom(&style_slider_knob, LV_STATE_PRESSED, 14); - lv_style_set_pad_left(&style_slider_knob, LV_STATE_PRESSED, 14); - lv_style_set_pad_right(&style_slider_knob, LV_STATE_PRESSED, 14); + lv_style_set_pad_all(&style_slider_knob, LV_STATE_DEFAULT, 10); + lv_style_set_pad_all(&style_slider_knob, LV_STATE_PRESSED, 14); style_init_reset(&style_arc_indic); lv_style_set_line_color(&style_arc_indic, LV_STATE_DEFAULT, Colors::lightGray); @@ -180,10 +170,7 @@ static void basic_init() { style_init_reset(&style_pad_small); lv_style_int_t pad_small_value = 10; - lv_style_set_pad_left(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); - lv_style_set_pad_right(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); - lv_style_set_pad_top(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); - lv_style_set_pad_bottom(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); + lv_style_set_pad_all(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); lv_style_set_pad_inner(&style_pad_small, LV_STATE_DEFAULT, pad_small_value); style_init_reset(&style_lmeter); @@ -209,20 +196,12 @@ static void basic_init() { lv_style_reset(&style_cb_bg); lv_style_set_radius(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(4)); lv_style_set_pad_inner(&style_cb_bg, LV_STATE_DEFAULT, 18); - lv_style_set_outline_color(&style_cb_bg, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_outline_width(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(2)); - lv_style_set_outline_pad(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(20)); - lv_style_set_transition_time(&style_cb_bg, LV_STATE_DEFAULT, 0); - lv_style_set_transition_prop_6(&style_cb_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA); lv_style_reset(&style_cb_bullet); lv_style_set_radius(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(4)); lv_style_set_pattern_image(&style_cb_bullet, LV_STATE_CHECKED, LV_SYMBOL_OK); lv_style_set_pattern_recolor(&style_cb_bullet, LV_STATE_CHECKED, LV_COLOR_WHITE); - lv_style_set_pad_left(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); - lv_style_set_pad_right(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); - lv_style_set_pad_top(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); - lv_style_set_pad_bottom(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); + lv_style_set_pad_all(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); } /** @@ -236,20 +215,14 @@ static void basic_init() { * @param font_title pointer to a extra large font * @return a pointer to reference this theme later */ -lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary, - lv_color_t color_secondary, - uint32_t flags, - const lv_font_t* font_small, - const lv_font_t* font_normal, - const lv_font_t* font_subtitle, - const lv_font_t* font_title) { - theme.color_primary = color_primary; - theme.color_secondary = color_secondary; - theme.font_small = font_small; - theme.font_normal = font_normal; - theme.font_subtitle = font_subtitle; - theme.font_title = font_title; - theme.flags = flags; +lv_theme_t* lv_pinetime_theme_init() { + theme.color_primary = LV_COLOR_WHITE; + theme.color_secondary = LV_COLOR_GRAY; + theme.font_small = &jetbrains_mono_bold_20; + theme.font_normal = &jetbrains_mono_bold_20; + theme.font_subtitle = &jetbrains_mono_bold_20; + theme.font_title = &jetbrains_mono_bold_20; + theme.flags = 0; basic_init(); diff --git a/src/displayapp/InfiniTimeTheme.h b/src/displayapp/InfiniTimeTheme.h index 5709b007..52c339dd 100644 --- a/src/displayapp/InfiniTimeTheme.h +++ b/src/displayapp/InfiniTimeTheme.h @@ -24,10 +24,4 @@ namespace Colors { * @param font_title pointer to a extra large font * @return a pointer to reference this theme later */ -lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary, - lv_color_t color_secondary, - uint32_t flags, - const lv_font_t* font_small, - const lv_font_t* font_normal, - const lv_font_t* font_subtitle, - const lv_font_t* font_title); +lv_theme_t* lv_pinetime_theme_init(); diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index d5f31848..e3d564a3 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -3,13 +3,17 @@ #include <FreeRTOS.h> #include <task.h> -//#include <projdefs.h> #include "drivers/Cst816s.h" #include "drivers/St7789.h" using namespace Pinetime::Components; -lv_style_t* LabelBigStyle = nullptr; +namespace { + void InitTheme() { + lv_theme_t* theme = lv_pinetime_theme_init(); + lv_theme_set_act(theme); + } +} static void disp_flush(lv_disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p) { auto* lvgl = static_cast<LittleVgl*>(disp_drv->user_data); @@ -192,16 +196,3 @@ bool LittleVgl::GetTouchPadInfo(lv_indev_data_t* ptr) { } return false; } - -void LittleVgl::InitTheme() { - - lv_theme_t* th = lv_pinetime_theme_init(LV_COLOR_WHITE, - LV_COLOR_SILVER, - 0, - &jetbrains_mono_bold_20, - &jetbrains_mono_bold_20, - &jetbrains_mono_bold_20, - &jetbrains_mono_bold_20); - - lv_theme_set_act(th); -} diff --git a/src/displayapp/LittleVgl.h b/src/displayapp/LittleVgl.h index 45826165..7bd0198c 100644 --- a/src/displayapp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -37,7 +37,6 @@ namespace Pinetime { private: void InitDisplay(); void InitTouchpad(); - void InitTheme(); Pinetime::Drivers::St7789& lcd; Pinetime::Drivers::Cst816S& touchPanel; @@ -52,9 +51,11 @@ namespace Pinetime { static constexpr uint8_t nbWriteLines = 4; static constexpr uint16_t totalNbLines = 320; static constexpr uint16_t visibleNbLines = 240; + static constexpr uint8_t MaxScrollOffset() { return LV_VER_RES_MAX - nbWriteLines; } + FullRefreshDirections scrollDirection = FullRefreshDirections::None; uint16_t writeOffset = 0; uint16_t scrollOffset = 0; diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index 58df4556..afa7709a 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -1,5 +1,6 @@ #pragma once #include <cstdint> + namespace Pinetime { namespace Applications { namespace Display { diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 9febda61..87d1f2e1 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -59,7 +59,7 @@ void BatteryInfo::Refresh() { } else if (batteryPercent == 100) { lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); lv_label_set_text_static(status, "Fully charged"); - } else if (batteryPercent < 10) { + } else if (batteryController.BatteryIsLow()) { 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 { diff --git a/src/displayapp/screens/CheckboxList.cpp b/src/displayapp/screens/CheckboxList.cpp index c189b075..928b2e61 100644 --- a/src/displayapp/screens/CheckboxList.cpp +++ b/src/displayapp/screens/CheckboxList.cpp @@ -28,7 +28,9 @@ CheckboxList::CheckboxList(const uint8_t screenID, // Set the background to Black lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - pageIndicator.Create(); + if (numScreens > 1) { + pageIndicator.Create(); + } lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/CheckboxList.h b/src/displayapp/screens/CheckboxList.h index 48125d4b..359b835e 100644 --- a/src/displayapp/screens/CheckboxList.h +++ b/src/displayapp/screens/CheckboxList.h @@ -15,6 +15,7 @@ namespace Pinetime { class CheckboxList : public Screen { public: static constexpr size_t MaxItems = 4; + struct Item { const char* name; bool enabled; diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index 5156b7ea..cc3b09b2 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -8,6 +8,7 @@ namespace Pinetime { namespace Controllers { class Ble; } + namespace Applications { namespace Screens { diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index a2314690..bda6d68d 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -32,16 +32,16 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK); lv_obj_set_width(labelIsValidated, 240); - if (validator.IsValidated()) + if (validator.IsValidated()) { lv_label_set_text_static(labelIsValidated, "You have already\n#00ff00 validated# this firmware#"); - else { + } else { lv_label_set_text_static(labelIsValidated, "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); buttonValidate = lv_btn_create(lv_scr_act(), nullptr); buttonValidate->user_data = this; lv_obj_set_size(buttonValidate, 115, 50); - lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_align(buttonValidate, nullptr, 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, Colors::highlight); diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 305e0c4b..71bf86ca 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -64,8 +64,9 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app, label_startStop = lv_label_create(btn_startStop, nullptr); UpdateStartStopButton(isHrRunning); - if (isHrRunning) + if (isHrRunning) { systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + } taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); } @@ -110,8 +111,9 @@ void HeartRate::OnStartStopEvent(lv_event_t event) { } void HeartRate::UpdateStartStopButton(bool isRunning) { - if (isRunning) + if (isRunning) { lv_label_set_text_static(label_startStop, "Stop"); - else + } else { lv_label_set_text_static(label_startStop, "Start"); + } } diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index 2ad00351..d68133ad 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -11,6 +11,7 @@ namespace Pinetime { namespace Controllers { class HeartRateController; } + namespace Applications { namespace Screens { diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 8c427402..a6b6eb18 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -10,6 +10,7 @@ namespace Pinetime { namespace Components { class LittleVgl; } + namespace Applications { namespace Screens { diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index f44825c7..3f219ea1 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -1,6 +1,7 @@ #include "displayapp/screens/List.h" #include "displayapp/DisplayApp.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -25,41 +26,44 @@ List::List(uint8_t screenID, pageIndicator.Create(); - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + lv_obj_t* container = lv_cont_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); - lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 4); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + static constexpr int innerPad = 4; + lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, innerPad); + lv_obj_set_style_local_border_width(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - lv_obj_set_pos(container1, 0, 0); - lv_obj_set_width(container1, LV_HOR_RES - 8); - lv_obj_set_height(container1, LV_VER_RES); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* labelBt; - lv_obj_t* labelBtIco; + lv_obj_set_pos(container, 0, 0); + lv_obj_set_width(container, LV_HOR_RES - 8); + lv_obj_set_height(container, LV_VER_RES); + lv_cont_set_layout(container, LV_LAYOUT_COLUMN_LEFT); for (int i = 0; i < MAXLISTITEMS; i++) { apps[i] = applications[i].application; if (applications[i].application != Apps::None) { - itemApps[i] = lv_btn_create(container1, nullptr); - lv_obj_set_style_local_bg_opa(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50); - lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 57); - lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - + static constexpr int btnHeight = (LV_HOR_RES_MAX - ((MAXLISTITEMS - 1) * innerPad)) / MAXLISTITEMS; + itemApps[i] = lv_btn_create(container, nullptr); + lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, btnHeight / 3); + lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); lv_obj_set_width(itemApps[i], LV_HOR_RES - 8); - lv_obj_set_height(itemApps[i], 57); + lv_obj_set_height(itemApps[i], btnHeight); lv_obj_set_event_cb(itemApps[i], ButtonEventHandler); - lv_btn_set_layout(itemApps[i], LV_LAYOUT_ROW_MID); + lv_btn_set_layout(itemApps[i], LV_LAYOUT_OFF); itemApps[i]->user_data = this; + lv_obj_set_style_local_clip_corner(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, true); - labelBtIco = lv_label_create(itemApps[i], nullptr); - lv_obj_set_style_local_text_color(labelBtIco, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); - lv_label_set_text_static(labelBtIco, applications[i].icon); + lv_obj_t* icon = lv_label_create(itemApps[i], nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + lv_label_set_text_static(icon, applications[i].icon); + lv_label_set_long_mode(icon, LV_LABEL_LONG_CROP); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_set_width(icon, btnHeight); + lv_obj_align(icon, nullptr, LV_ALIGN_IN_LEFT_MID, 0, 0); - labelBt = lv_label_create(itemApps[i], nullptr); - lv_label_set_text_fmt(labelBt, " %s", applications[i].name); + lv_obj_t* text = lv_label_create(itemApps[i], nullptr); + lv_label_set_text_fmt(text, "%s", applications[i].name); + lv_obj_align(text, icon, LV_ALIGN_OUT_RIGHT_MID, 0, 0); } } } diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index df87092b..40456ab8 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -146,7 +146,6 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { bool Metronome::OnTouchEvent(TouchEvents event) { if (event == TouchEvents::SwipeDown && allowExit) { running = false; - return true; } - return false; + return true; } diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index c2dc4dac..e3689599 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -7,9 +7,9 @@ using namespace Pinetime::Applications::Screens; Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionController& motionController) : Screen(app), motionController {motionController} { - chart = lv_chart_create(lv_scr_act(), NULL); + chart = lv_chart_create(lv_scr_act(), nullptr); lv_obj_set_size(chart, 240, 240); - lv_obj_align(chart, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); + lv_obj_align(chart, nullptr, LV_ALIGN_IN_TOP_MID, 0, 0); lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/ // lv_chart_set_series_opa(chart, LV_OPA_70); /*Opacity of the data series*/ // lv_chart_set_series_width(chart, 4); /*Line width and point radious*/ @@ -28,13 +28,13 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr lv_chart_init_points(chart, ser3, 0); lv_chart_refresh(chart); /*Required after direct set*/ - label = lv_label_create(lv_scr_act(), NULL); + label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_fmt(label, "X #FF0000 %d# Y #00B000 %d# Z #FFFF00 %d#", 0, 0, 0); lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); - lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); + lv_obj_align(label, nullptr, LV_ALIGN_IN_TOP_MID, 0, 10); lv_label_set_recolor(label, true); - labelStep = lv_label_create(lv_scr_act(), NULL); + labelStep = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(labelStep, chart, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_label_set_text_static(labelStep, "Steps ---"); @@ -58,5 +58,5 @@ void Motion::Refresh() { motionController.X() / 0x10, motionController.Y() / 0x10, motionController.Z() / 0x10); - lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); + lv_obj_align(label, nullptr, LV_ALIGN_IN_TOP_MID, 0, 10); } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 90a010f5..6c68c70d 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -79,9 +79,12 @@ void Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } - } - if (dismissingNotification) { + } else if (mode == Modes::Preview && dismissingNotification) { + running = false; + currentItem = std::make_unique<NotificationItem>(alertNotificationService, motorController); + + } else if (dismissingNotification) { dismissingNotification = false; auto notification = notificationManager.Get(currentId); if (!notification.valid) { @@ -126,12 +129,34 @@ void Notifications::OnPreviewInteraction() { } } +void Notifications::DismissToBlack() { + currentItem.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::RightAnim); + // create black transition screen to let the notification dismiss to blackness + lv_obj_t* blackBox = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_size(blackBox, LV_HOR_RES, LV_VER_RES); + lv_obj_set_style_local_bg_color(blackBox, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + dismissingNotification = true; +} + +void Notifications::OnPreviewDismiss() { + notificationManager.Dismiss(currentId); + if (timeoutLine != nullptr) { + lv_obj_del(timeoutLine); + timeoutLine = nullptr; + } + DismissToBlack(); +} + bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { if (mode != Modes::Normal) { if (!interacted && event == TouchEvents::Tap) { interacted = true; OnPreviewInteraction(); return true; + } else if (event == Pinetime::Applications::TouchEvents::SwipeRight) { + OnPreviewDismiss(); + return true; } return false; } @@ -139,15 +164,9 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { case Pinetime::Applications::TouchEvents::SwipeRight: if (validDisplay) { - Controllers::NotificationManager::Notification previousNotification; auto previousMessage = notificationManager.GetPrevious(currentId); auto nextMessage = notificationManager.GetNext(currentId); - if (!previousMessage.valid) { - // dismissed last message (like 5/5), need to go one message down (like 4/4) - afterDismissNextMessageFromAbove = false; // show next message coming from below - } else { - afterDismissNextMessageFromAbove = true; // show next message coming from above - } + afterDismissNextMessageFromAbove = previousMessage.valid; notificationManager.Dismiss(currentId); if (previousMessage.valid) { currentId = previousMessage.id; @@ -156,13 +175,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } else { // don't update id, won't be found be refresh and try to load latest message or no message box } - currentItem.reset(nullptr); - app->SetFullRefresh(DisplayApp::FullRefreshDirections::RightAnim); - // create black transition screen to let the notification dismiss to blackness - lv_obj_t* blackBox = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_size(blackBox, LV_HOR_RES, LV_VER_RES); - lv_obj_set_style_local_bg_color(blackBox, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - dismissingNotification = true; + DismissToBlack(); return true; } return false; @@ -270,7 +283,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_obj_t* alert_count = lv_label_create(container, nullptr); lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb); - lv_obj_align(alert_count, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 16); + lv_obj_align(alert_count, nullptr, 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, Colors::orange); @@ -288,7 +301,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, } lv_label_set_long_mode(alert_type, LV_LABEL_LONG_SROLL_CIRC); lv_obj_set_width(alert_type, 180); - lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16); + lv_obj_align(alert_type, nullptr, 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); @@ -312,7 +325,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_accept->user_data = this; lv_obj_set_event_cb(bt_accept, CallEventHandler); lv_obj_set_size(bt_accept, 76, 76); - lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_align(bt_accept, nullptr, 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, Colors::highlight); @@ -321,7 +334,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_reject->user_data = this; lv_obj_set_event_cb(bt_reject, CallEventHandler); lv_obj_set_size(bt_reject, 76, 76); - lv_obj_align(bt_reject, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_obj_align(bt_reject, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); label_reject = lv_label_create(bt_reject, nullptr); lv_label_set_text_static(label_reject, Symbols::phoneSlash); lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); @@ -330,7 +343,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_mute->user_data = this; lv_obj_set_event_cb(bt_mute, CallEventHandler); lv_obj_set_size(bt_mute, 76, 76); - lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_align(bt_mute, nullptr, 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, Colors::lightGray); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 9d843a9b..a4d2709b 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -13,6 +13,7 @@ namespace Pinetime { namespace Controllers { class AlertNotificationService; } + namespace Applications { namespace Screens { @@ -29,7 +30,9 @@ namespace Pinetime { void Refresh() override; bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; + void DismissToBlack(); void OnPreviewInteraction(); + void OnPreviewDismiss(); class NotificationItem { public: @@ -43,9 +46,11 @@ namespace Pinetime { Pinetime::Controllers::AlertNotificationService& alertNotificationService, Pinetime::Controllers::MotorController& motorController); ~NotificationItem(); + bool IsRunning() const { return running; } + void OnCallButtonEvent(lv_obj_t*, lv_event_t event); private: diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index 1fb25085..dc973957 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -79,11 +79,11 @@ void Paddle::Refresh() { lv_label_set_text_fmt(points, "%04d", score); } -bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents event) { +bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents /*event*/) { return true; } -bool Paddle::OnTouchEvent(uint16_t x, uint16_t y) { +bool Paddle::OnTouchEvent(uint16_t /*x*/, uint16_t y) { // sets the center paddle pos. (30px offset) with the the y_coordinate of the finger // but clamp it such that the paddle never clips off screen if (y < 31) { diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index 3a30eee6..d62550c4 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -8,6 +8,7 @@ namespace Pinetime { namespace Components { class LittleVgl; } + namespace Applications { namespace Screens { diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index e72a2368..4cf134d2 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -7,13 +7,16 @@ namespace Pinetime { namespace Applications { class DisplayApp; + namespace Screens { template <class T> class DirtyValue { public: DirtyValue() = default; // Use NSDMI + explicit DirtyValue(T const& v) : value {v} { } // Use MIL and const-lvalue-ref + bool IsUpdated() { if (this->isUpdated) { this->isUpdated = false; @@ -21,10 +24,12 @@ namespace Pinetime { } return false; } + T const& Get() { this->isUpdated = false; return value; } // never expose a non-const lvalue-ref + DirtyValue& operator=(const T& other) { if (this->value != other) { this->value = other; @@ -46,6 +51,7 @@ namespace Pinetime { public: explicit Screen(DisplayApp* app) : app {app} { } + virtual ~Screen() = default; static void RefreshTaskCallback(lv_task_t* task); @@ -61,10 +67,11 @@ namespace Pinetime { /** @return false if the event hasn't been handled by the app, true if it has been handled */ // Returning true will cancel lvgl tap - virtual bool OnTouchEvent(TouchEvents event) { + virtual bool OnTouchEvent(TouchEvents /*event*/) { return false; } - virtual bool OnTouchEvent(uint16_t x, uint16_t y) { + + virtual bool OnTouchEvent(uint16_t /*x*/, uint16_t /*y*/) { return false; } diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index ad882948..6c9a2218 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -11,6 +11,7 @@ namespace Pinetime { namespace Screens { enum class ScreenListModes { UpDown, RightLeft, LongPress }; + template <size_t N> class ScreenList : public Screen { public: ScreenList(DisplayApp* app, diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index f109e0f2..32ad40bd 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -29,7 +29,6 @@ namespace Pinetime { uint32_t currentTripSteps = 0; lv_obj_t* lSteps; - lv_obj_t* lStepsIcon; lv_obj_t* stepsArc; lv_obj_t* resetBtn; lv_obj_t* resetButtonLabel; diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 01c35195..b5b17347 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -99,7 +99,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen1() { std::unique_ptr<Screen> SystemInfo::CreateScreen2() { auto batteryPercent = batteryController.PercentRemaining(); - auto resetReason = [this]() { + const auto* resetReason = [this]() { switch (watchdog.ResetReason()) { case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg"; @@ -182,7 +182,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen3() { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(label, true); - auto& bleAddr = bleController.Address(); + const auto& bleAddr = bleController.Address(); lv_label_set_text_fmt(label, "#808080 BLE MAC#\n" " %02x:%02x:%02x:%02x:%02x:%02x" diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index a60076ed..681f9c9f 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -51,8 +51,9 @@ Tile::Tile(uint8_t screenID, uint8_t btIndex = 0; for (uint8_t i = 0; i < 6; i++) { - if (i == 3) + if (i == 3) { btnmMap[btIndex++] = "\n"; + } if (applications[i].application == Apps::None) { btnmMap[btIndex] = " "; } else { @@ -66,7 +67,7 @@ Tile::Tile(uint8_t screenID, btnm1 = lv_btnmatrix_create(lv_scr_act(), nullptr); lv_btnmatrix_set_map(btnm1, btnmMap); lv_obj_set_size(btnm1, LV_HOR_RES - 16, LV_VER_RES - 60); - lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 10); + lv_obj_align(btnm1, nullptr, LV_ALIGN_CENTER, 0, 10); lv_obj_set_style_local_radius(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, 20); lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_OPA_50); @@ -102,8 +103,9 @@ void Tile::UpdateScreen() { } void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { - if (obj != btnm1) + if (obj != btnm1) { return; + } app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Up); running = false; diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index a6b60a17..306281d7 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -26,7 +26,6 @@ namespace Pinetime::Applications::Screens { void UpdateMask(); Controllers::TimerController& timerController; - lv_obj_t* msecTime; lv_obj_t* btnPlayPause; lv_obj_t* txtPlayPause; @@ -40,7 +39,7 @@ namespace Pinetime::Applications::Screens { Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76); bool buttonPressing = false; - int maskPosition = 0; - TickType_t pressTime; + lv_coord_t maskPosition = 0; + TickType_t pressTime = 0; }; } diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index da935724..15017581 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -9,6 +9,7 @@ namespace Pinetime { bool merged = false; unsigned int value = 0; }; + namespace Screens { class Twos : public Screen { public: diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 5e5317ee..b36c29d3 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -61,9 +61,9 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, sMinute = 99; sSecond = 99; - lv_obj_t* bg_clock_img = lv_img_create(lv_scr_act(), NULL); + lv_obj_t* bg_clock_img = lv_img_create(lv_scr_act(), nullptr); lv_img_set_src(bg_clock_img, &bg_clock); - lv_obj_align(bg_clock_img, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(bg_clock_img, nullptr, LV_ALIGN_CENTER, 0, 0); batteryIcon.Create(lv_scr_act()); lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); @@ -72,24 +72,24 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, lv_label_set_text_static(plugIcon, Symbols::plug); lv_obj_align(plugIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); - notificationIcon = lv_label_create(lv_scr_act(), NULL); + 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_LIME); lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); // Date - Day / Week day - label_date_day = lv_label_create(lv_scr_act(), NULL); + label_date_day = lv_label_create(lv_scr_act(), nullptr); 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); + lv_obj_align(label_date_day, nullptr, LV_ALIGN_CENTER, 50, 0); - minute_body = lv_line_create(lv_scr_act(), NULL); - minute_body_trace = lv_line_create(lv_scr_act(), NULL); - hour_body = lv_line_create(lv_scr_act(), NULL); - hour_body_trace = lv_line_create(lv_scr_act(), NULL); - second_body = lv_line_create(lv_scr_act(), NULL); + minute_body = lv_line_create(lv_scr_act(), nullptr); + minute_body_trace = lv_line_create(lv_scr_act(), nullptr); + hour_body = lv_line_create(lv_scr_act(), nullptr); + hour_body_trace = lv_line_create(lv_scr_act(), nullptr); + second_body = lv_line_create(lv_scr_act(), nullptr); lv_style_init(&second_line_style); lv_style_set_line_width(&second_line_style, LV_STATE_DEFAULT, 3); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 04d9e711..6e4e88a3 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -18,6 +18,7 @@ namespace Pinetime { class Ble; class NotificationManager; } + namespace Applications { namespace Screens { diff --git a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp index bdae0d42..94b6a405 100644 --- a/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp +++ b/src/displayapp/screens/WatchFaceCasioStyleG7710.cpp @@ -333,6 +333,7 @@ void WatchFaceCasioStyleG7710::Refresh() { lv_obj_realign(stepIcon); } } + bool WatchFaceCasioStyleG7710::IsAvailable(Pinetime::Controllers::FS& filesystem) { lfs_file file = {}; diff --git a/src/displayapp/screens/WatchFaceInfineat.cpp b/src/displayapp/screens/WatchFaceInfineat.cpp index bd4e4ac8..ddf3cbcc 100644 --- a/src/displayapp/screens/WatchFaceInfineat.cpp +++ b/src/displayapp/screens/WatchFaceInfineat.cpp @@ -47,125 +47,40 @@ WatchFaceInfineat::WatchFaceInfineat(DisplayApp* app, 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); + static constexpr lv_point_t linePoints[nLines][2] = {{{30, 25}, {68, -8}}, + {{26, 167}, {43, 216}}, + {{27, 40}, {27, 196}}, + {{12, 182}, {65, 249}}, + {{17, 99}, {17, 144}}, + {{14, 81}, {40, 127}}, + {{14, 163}, {40, 118}}, + {{-20, 124}, {25, -11}}, + {{-29, 89}, {27, 254}}}; - 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); + static constexpr lv_style_int_t lineWidths[nLines] = {18, 15, 14, 22, 20, 18, 18, 52, 48}; - 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); + for (int i = 0; i < nLines; i++) { + lines[i] = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(lines[i], LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lineWidths[i]); + lv_obj_set_style_local_line_color(lines[i], + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[settingsController.GetInfineatColorIndex() * nLines + i])); + lv_line_set_points(lines[i], linePoints[i], 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); + lineBattery = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(lineBattery, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 24); + 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_line_opa(lineBattery, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 190); lineBatteryPoints[0] = {27, 105}; lineBatteryPoints[1] = {27, 106}; lv_line_set_points(lineBattery, lineBatteryPoints, 2); @@ -182,55 +97,30 @@ WatchFaceInfineat::WatchFaceInfineat(DisplayApp* app, 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); + for (auto& line : lines) { + lv_obj_set_hidden(line, 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); - } + lv_obj_set_size(timeContainer, 185, 185); + lv_obj_align(timeContainer, lv_scr_act(), LV_ALIGN_CENTER, 0, -10); 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); - } + lv_label_set_text_static(labelHour, "01"); + 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); 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_set_style_local_text_font(labelMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_bebas); + lv_label_set_text_static(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_obj_set_style_local_text_font(labelTimeAmPm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); - lv_label_set_text(labelTimeAmPm, ""); + lv_label_set_text_static(labelTimeAmPm, ""); lv_obj_align(labelTimeAmPm, timeContainer, LV_ALIGN_OUT_RIGHT_TOP, 0, 15); dateContainer = lv_obj_create(lv_scr_act(), nullptr); @@ -240,32 +130,24 @@ WatchFaceInfineat::WatchFaceInfineat(DisplayApp* app, 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_set_style_local_text_font(labelDate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); lv_obj_align(labelDate, dateContainer, LV_ALIGN_IN_TOP_MID, 0, 0); - lv_label_set_text(labelDate, "Mon 01"); + lv_label_set_text_static(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_label_set_text_static(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_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_teko); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 10, 0); - lv_label_set_text(stepValue, "0"); + lv_label_set_text_static(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_label_set_text_static(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); // Setting buttons @@ -330,17 +212,6 @@ WatchFaceInfineat::WatchFaceInfineat(DisplayApp* app, 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); } @@ -398,15 +269,9 @@ void WatchFaceInfineat::UpdateSelected(lv_obj_t* object, lv_event_t event) { 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); + for (auto& line : lines) { + lv_obj_set_hidden(line, showSideCover); + } lv_obj_set_hidden(btnNextColor, showSideCover); lv_obj_set_hidden(btnPrevColor, showSideCover); const char* labelToggle = showSideCover ? "OFF" : "ON"; @@ -423,42 +288,12 @@ void WatchFaceInfineat::UpdateSelected(lv_obj_t* object, lv_event_t event) { 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])); + for (int i = 0; i < nLines; i++) { + lv_obj_set_style_local_line_color(lines[i], + LV_LINE_PART_MAIN, + LV_STATE_DEFAULT, + lv_color_hex(infineatColors.orange[colorIndex * nLines + i])); + } lv_obj_set_style_local_line_color(lineBattery, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, @@ -547,17 +382,13 @@ void WatchFaceInfineat::Refresh() { 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 + if (batteryController.IsCharging()) { // Charging battery animation chargingBatteryPercent += 1; if (chargingBatteryPercent > 100) { chargingBatteryPercent = batteryPercentRemaining.Get(); } SetBatteryLevel(chargingBatteryPercent); - } else if (isChargingUpdated || isBatteryUpdated) { + } else if (isCharging.IsUpdated() || batteryPercentRemaining.IsUpdated()) { chargingBatteryPercent = batteryPercentRemaining.Get(); SetBatteryLevel(chargingBatteryPercent); } @@ -565,7 +396,7 @@ void WatchFaceInfineat::Refresh() { bleState = bleController.IsConnected(); bleRadioEnabled = bleController.IsRadioEnabled(); if (bleState.IsUpdated()) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); + lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get())); lv_obj_align(bleIcon, dateContainer, LV_ALIGN_OUT_BOTTOM_MID, 0, 3); } diff --git a/src/displayapp/screens/WatchFaceInfineat.h b/src/displayapp/screens/WatchFaceInfineat.h index 6c3c30ba..dfa0b38b 100644 --- a/src/displayapp/screens/WatchFaceInfineat.h +++ b/src/displayapp/screens/WatchFaceInfineat.h @@ -60,40 +60,9 @@ namespace Pinetime { 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; @@ -118,6 +87,9 @@ namespace Pinetime { static constexpr int nLines = 9; static constexpr int nColors = 7; // must match number of colors in InfineatColors + + lv_obj_t* lines[nLines]; + 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}; diff --git a/src/displayapp/screens/WatchFacePineTimeStyle.h b/src/displayapp/screens/WatchFacePineTimeStyle.h index 3085a1ae..b2cb0736 100644 --- a/src/displayapp/screens/WatchFacePineTimeStyle.h +++ b/src/displayapp/screens/WatchFacePineTimeStyle.h @@ -5,10 +5,10 @@ #include <cstdint> #include <memory> #include "displayapp/screens/Screen.h" +#include "displayapp/screens/BatteryIcon.h" #include "displayapp/Colors.h" #include "components/datetime/DateTimeController.h" #include "components/ble/BleController.h" -#include <displayapp/screens/BatteryIcon.h> namespace Pinetime { namespace Controllers { diff --git a/src/displayapp/screens/WatchFaceTerminal.cpp b/src/displayapp/screens/WatchFaceTerminal.cpp index 92189737..d04cc517 100644 --- a/src/displayapp/screens/WatchFaceTerminal.cpp +++ b/src/displayapp/screens/WatchFaceTerminal.cpp @@ -30,8 +30,6 @@ WatchFaceTerminal::WatchFaceTerminal(DisplayApp* app, settingsController {settingsController}, heartRateController {heartRateController}, motionController {motionController} { - settingsController.SetClockFace(3); - batteryValue = lv_label_create(lv_scr_act(), nullptr); lv_label_set_recolor(batteryValue, true); lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20); diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 1d0a83bd..ff067db8 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -27,7 +27,6 @@ using namespace Pinetime::Applications::Screens; Weather::Weather(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::WeatherService& weather) : Screen(app), - dateTimeController {dateTimeController}, weatherService(weather), screens {app, 0, diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 34f95fce..21b05bd8 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -25,7 +25,6 @@ namespace Pinetime { private: bool running = true; - Pinetime::Controllers::DateTime& dateTimeController; Controllers::WeatherService& weatherService; ScreenList<5> screens; diff --git a/src/displayapp/screens/settings/SettingBluetooth.cpp b/src/displayapp/screens/settings/SettingBluetooth.cpp index c66be3e9..fd07be88 100644 --- a/src/displayapp/screens/settings/SettingBluetooth.cpp +++ b/src/displayapp/screens/settings/SettingBluetooth.cpp @@ -9,84 +9,52 @@ using namespace Pinetime::Applications::Screens; namespace { - void OnBluetoothDisabledEvent(lv_obj_t* obj, lv_event_t event) { - auto* screen = static_cast<SettingBluetooth*>(obj->user_data); - screen->OnBluetoothDisabled(obj, event); - } + struct Option { + const char* name; + bool radioEnabled; + }; - void OnBluetoothEnabledEvent(lv_obj_t* obj, lv_event_t event) { - auto* screen = static_cast<SettingBluetooth*>(obj->user_data); - screen->OnBluetoothEnabled(obj, event); - } + constexpr std::array<Option, 2> options = {{ + {"Enabled", true}, + {"Disabled", false}, + }}; + + std::array<CheckboxList::Item, CheckboxList::MaxItems> CreateOptionArray() { + std::array<Pinetime::Applications::Screens::CheckboxList::Item, CheckboxList::MaxItems> optionArray; + for (size_t i = 0; i < CheckboxList::MaxItems; i++) { + if (i >= options.size()) { + optionArray[i].name = ""; + optionArray[i].enabled = false; + } else { + optionArray[i].name = options[i].name; + optionArray[i].enabled = true; + } + } + return optionArray; + }; } SettingBluetooth::SettingBluetooth(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - 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); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - - 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_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Bluetooth"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); - - 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::bluetooth); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); - - cbEnabled = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text(cbEnabled, " Enabled"); - cbEnabled->user_data = this; - lv_obj_set_event_cb(cbEnabled, OnBluetoothEnabledEvent); - SetRadioButtonStyle(cbEnabled); - - cbDisabled = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text(cbDisabled, " Disabled"); - cbDisabled->user_data = this; - lv_obj_set_event_cb(cbDisabled, OnBluetoothDisabledEvent); - SetRadioButtonStyle(cbDisabled); - - if (settingsController.GetBleRadioEnabled()) { - lv_checkbox_set_checked(cbEnabled, true); - priorMode = true; - } else { - lv_checkbox_set_checked(cbDisabled, true); - priorMode = false; - } + : Screen(app), + checkboxList( + 0, + 1, + app, + "Bluetooth", + Symbols::bluetooth, + settingsController.GetBleRadioEnabled() ? 0 : 1, + [&settings = settingsController](uint32_t index) { + const bool priorMode = settings.GetBleRadioEnabled(); + const bool newMode = options[index].radioEnabled; + if (newMode != priorMode) { + settings.SetBleRadioEnabled(newMode); + } + }, + CreateOptionArray()) { } SettingBluetooth::~SettingBluetooth() { lv_obj_clean(lv_scr_act()); - // Do not call SaveSettings - see src/components/settings/Settings.h - if (priorMode != settingsController.GetBleRadioEnabled()) { - app->PushMessage(Pinetime::Applications::Display::Messages::BleRadioEnableToggle); - } -} - -void SettingBluetooth::OnBluetoothDisabled(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - lv_checkbox_set_checked(cbEnabled, false); - lv_checkbox_set_checked(cbDisabled, true); - settingsController.SetBleRadioEnabled(false); - } -} - -void SettingBluetooth::OnBluetoothEnabled(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - lv_checkbox_set_checked(cbEnabled, true); - lv_checkbox_set_checked(cbDisabled, false); - settingsController.SetBleRadioEnabled(true); - } + // Pushing the message in the OnValueChanged function causes a freeze? + app->PushMessage(Pinetime::Applications::Display::Messages::BleRadioEnableToggle); } diff --git a/src/displayapp/screens/settings/SettingBluetooth.h b/src/displayapp/screens/settings/SettingBluetooth.h index 12bb459a..611a0d5c 100644 --- a/src/displayapp/screens/settings/SettingBluetooth.h +++ b/src/displayapp/screens/settings/SettingBluetooth.h @@ -6,6 +6,7 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckboxList.h" namespace Pinetime { @@ -17,14 +18,8 @@ namespace Pinetime { SettingBluetooth(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingBluetooth() override; - void OnBluetoothEnabled(lv_obj_t* object, lv_event_t event); - void OnBluetoothDisabled(lv_obj_t* object, lv_event_t event); - private: - Controllers::Settings& settingsController; - lv_obj_t* cbEnabled; - lv_obj_t* cbDisabled; - bool priorMode; + CheckboxList checkboxList; }; } } diff --git a/src/displayapp/screens/settings/SettingChimes.cpp b/src/displayapp/screens/settings/SettingChimes.cpp index 7f519f75..6e12fb88 100644 --- a/src/displayapp/screens/settings/SettingChimes.cpp +++ b/src/displayapp/screens/settings/SettingChimes.cpp @@ -4,70 +4,62 @@ #include "displayapp/screens/Styles.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" +#include <array> using namespace Pinetime::Applications::Screens; namespace { - void event_handler(lv_obj_t* obj, lv_event_t event) { - auto* screen = static_cast<SettingChimes*>(obj->user_data); - screen->UpdateSelected(obj, event); - } -} - -constexpr std::array<SettingChimes::Option, 3> SettingChimes::options; - -SettingChimes::SettingChimes(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + struct Option { + Pinetime::Controllers::Settings::ChimesOption chimesOption; + const char* name; + }; - 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); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + constexpr std::array<Option, 3> options = {{ + {Pinetime::Controllers::Settings::ChimesOption::None, "Off"}, + {Pinetime::Controllers::Settings::ChimesOption::Hours, "Every hour"}, + {Pinetime::Controllers::Settings::ChimesOption::HalfHours, "Every 30 mins"}, + }}; - 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_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Chimes"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); - - 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); + std::array<CheckboxList::Item, CheckboxList::MaxItems> CreateOptionArray() { + std::array<Pinetime::Applications::Screens::CheckboxList::Item, CheckboxList::MaxItems> optionArray; + for (size_t i = 0; i < CheckboxList::MaxItems; i++) { + if (i >= options.size()) { + optionArray[i].name = ""; + optionArray[i].enabled = false; + } else { + optionArray[i].name = options[i].name; + optionArray[i].enabled = true; + } + } + return optionArray; + } - for (unsigned int i = 0; i < options.size(); i++) { - cbOption[i] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text(cbOption[i], options[i].name); - if (settingsController.GetChimeOption() == options[i].chimesOption) { - lv_checkbox_set_checked(cbOption[i], true); + uint32_t GetDefaultOption(Pinetime::Controllers::Settings::ChimesOption currentOption) { + for (size_t i = 0; i < options.size(); i++) { + if (options[i].chimesOption == currentOption) { + return i; + } } - cbOption[i]->user_data = this; - lv_obj_set_event_cb(cbOption[i], event_handler); - SetRadioButtonStyle(cbOption[i]); + return 0; } } -SettingChimes::~SettingChimes() { - lv_obj_clean(lv_scr_act()); - settingsController.SaveSettings(); +SettingChimes::SettingChimes(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), + checkboxList( + 0, + 1, + app, + "Chimes", + Symbols::clock, + GetDefaultOption(settingsController.GetChimeOption()), + [&settings = settingsController](uint32_t index) { + settings.SetChimeOption(options[index].chimesOption); + settings.SaveSettings(); + }, + CreateOptionArray()) { } -void SettingChimes::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (uint8_t i = 0; i < options.size(); i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - settingsController.SetChimeOption(options[i].chimesOption); - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } +SettingChimes::~SettingChimes() { + lv_obj_clean(lv_scr_act()); } diff --git a/src/displayapp/screens/settings/SettingChimes.h b/src/displayapp/screens/settings/SettingChimes.h index e48432c6..a306e81d 100644 --- a/src/displayapp/screens/settings/SettingChimes.h +++ b/src/displayapp/screens/settings/SettingChimes.h @@ -2,9 +2,10 @@ #include <cstdint> #include <lvgl/lvgl.h> + #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" -#include <array> +#include "displayapp/screens/CheckboxList.h" namespace Pinetime { @@ -19,19 +20,7 @@ namespace Pinetime { void UpdateSelected(lv_obj_t* object, lv_event_t event); private: - struct Option { - Controllers::Settings::ChimesOption chimesOption; - const char* name; - }; - static constexpr std::array<Option, 3> options = {{ - {Controllers::Settings::ChimesOption::None, " Off"}, - {Controllers::Settings::ChimesOption::Hours, " Every hour"}, - {Controllers::Settings::ChimesOption::HalfHours, " Every 30 mins"} - }}; - - std::array<lv_obj_t*, options.size()> cbOption; - - Controllers::Settings& settingsController; + CheckboxList checkboxList; }; } } diff --git a/src/displayapp/screens/settings/SettingSetDate.cpp b/src/displayapp/screens/settings/SettingSetDate.cpp index 421aef02..c58f6fca 100644 --- a/src/displayapp/screens/settings/SettingSetDate.cpp +++ b/src/displayapp/screens/settings/SettingSetDate.cpp @@ -1,4 +1,5 @@ #include "displayapp/screens/settings/SettingSetDate.h" +#include "displayapp/screens/settings/SettingSetDateTime.h" #include <lvgl/lvgl.h> #include <hal/nrf_rtc.h> #include <nrf_log.h> @@ -44,8 +45,11 @@ namespace { } } -SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController) - : Screen(app), dateTimeController {dateTimeController} { +SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime) + : Screen(app), dateTimeController {dateTimeController}, settingSetDateTime {settingSetDateTime} { + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Set current date"); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); @@ -82,8 +86,6 @@ SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, Pinetime 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() { @@ -98,18 +100,14 @@ void SettingSetDate::HandleButtonPress() { 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); + settingSetDateTime.Advance(); } void SettingSetDate::CheckDay() { 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 a0ffc683..dfb0e0d2 100644 --- a/src/displayapp/screens/settings/SettingSetDate.h +++ b/src/displayapp/screens/settings/SettingSetDate.h @@ -5,13 +5,17 @@ #include "components/datetime/DateTimeController.h" #include "displayapp/screens/Screen.h" #include "displayapp/widgets/Counter.h" +#include "displayapp/widgets/DotIndicator.h" +#include "displayapp/screens/settings/SettingSetDateTime.h" namespace Pinetime { namespace Applications { namespace Screens { class SettingSetDate : public Screen { public: - SettingSetDate(DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController); + SettingSetDate(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime); ~SettingSetDate() override; void HandleButtonPress(); @@ -19,6 +23,7 @@ namespace Pinetime { private: Controllers::DateTime& dateTimeController; + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime; lv_obj_t* btnSetTime; lv_obj_t* lblSetTime; diff --git a/src/displayapp/screens/settings/SettingSetDateTime.cpp b/src/displayapp/screens/settings/SettingSetDateTime.cpp new file mode 100644 index 00000000..905a76ab --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetDateTime.cpp @@ -0,0 +1,54 @@ +#include "displayapp/screens/settings/SettingSetDateTime.h" +#include "displayapp/screens/settings/SettingSetDate.h" +#include "displayapp/screens/settings/SettingSetTime.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/ScreenList.h" +#include "components/settings/Settings.h" +#include "displayapp/widgets/DotIndicator.h" + +using namespace Pinetime::Applications::Screens; + +bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController) + : Screen(app), + dateTimeController {dateTimeController}, + settingsController {settingsController}, + screens {app, + 0, + {[this]() -> std::unique_ptr<Screen> { + return screenSetDate(); + }, + [this]() -> std::unique_ptr<Screen> { + return screenSetTime(); + }}, + Screens::ScreenListModes::UpDown} { +} + +std::unique_ptr<Screen> SettingSetDateTime::screenSetDate() { + Widgets::DotIndicator dotIndicator(0, 2); + dotIndicator.Create(); + return std::make_unique<Screens::SettingSetDate>(app, dateTimeController, *this); +} + +std::unique_ptr<Screen> SettingSetDateTime::screenSetTime() { + Widgets::DotIndicator dotIndicator(1, 2); + dotIndicator.Create(); + return std::make_unique<Screens::SettingSetTime>(app, dateTimeController, settingsController, *this); +} + +SettingSetDateTime::~SettingSetDateTime() { + lv_obj_clean(lv_scr_act()); +} + +void SettingSetDateTime::Advance() { + screens.OnTouchEvent(Pinetime::Applications::TouchEvents::SwipeUp); +} + +void SettingSetDateTime::Quit() { + running = false; +} diff --git a/src/displayapp/screens/settings/SettingSetDateTime.h b/src/displayapp/screens/settings/SettingSetDateTime.h new file mode 100644 index 00000000..dea283f8 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetDateTime.h @@ -0,0 +1,32 @@ +#pragma once + +#include <cstdint> +#include <lvgl/lvgl.h> +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class SettingSetDateTime : public Screen { + public: + SettingSetDateTime(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController); + ~SettingSetDateTime() override; + + bool OnTouchEvent(TouchEvents event) override; + void Advance(); + void Quit(); + + private: + Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + + ScreenList<2> screens; + std::unique_ptr<Screen> screenSetDate(); + std::unique_ptr<Screen> screenSetTime(); + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingSetTime.cpp b/src/displayapp/screens/settings/SettingSetTime.cpp index e7d824fd..67ea7afa 100644 --- a/src/displayapp/screens/settings/SettingSetTime.cpp +++ b/src/displayapp/screens/settings/SettingSetTime.cpp @@ -18,6 +18,7 @@ namespace { screen->SetTime(); } } + void ValueChangedHandler(void* userData) { auto* screen = static_cast<SettingSetTime*>(userData); screen->UpdateScreen(); @@ -26,8 +27,9 @@ namespace { SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController, - Pinetime::Controllers::Settings& settingsController) - : Screen(app), dateTimeController {dateTimeController}, settingsController {settingsController} { + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime) + : Screen(app), dateTimeController {dateTimeController}, settingsController {settingsController}, settingSetDateTime {settingSetDateTime} { lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Set current time"); @@ -74,8 +76,6 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app, 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() { @@ -90,8 +90,6 @@ void SettingSetTime::UpdateScreen() { lv_label_set_text_static(lblampm, "AM"); } } - lv_obj_set_state(btnSetTime, LV_STATE_DEFAULT); - lv_obj_set_state(lblSetTime, LV_STATE_DEFAULT); } void SettingSetTime::SetTime() { @@ -101,11 +99,9 @@ void SettingSetTime::SetTime() { 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); + settingSetDateTime.Quit(); } diff --git a/src/displayapp/screens/settings/SettingSetTime.h b/src/displayapp/screens/settings/SettingSetTime.h index b61962c1..edd89b16 100644 --- a/src/displayapp/screens/settings/SettingSetTime.h +++ b/src/displayapp/screens/settings/SettingSetTime.h @@ -6,6 +6,8 @@ #include "components/settings/Settings.h" #include "displayapp/widgets/Counter.h" #include "displayapp/screens/Screen.h" +#include "displayapp/widgets/DotIndicator.h" +#include "displayapp/screens/settings/SettingSetDateTime.h" namespace Pinetime { namespace Applications { @@ -14,7 +16,8 @@ namespace Pinetime { public: SettingSetTime(DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController, - Pinetime::Controllers::Settings& settingsController); + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime); ~SettingSetTime() override; void SetTime(); @@ -23,6 +26,7 @@ namespace Pinetime { private: Controllers::DateTime& dateTimeController; Controllers::Settings& settingsController; + Pinetime::Applications::Screens::SettingSetDateTime& settingSetDateTime; lv_obj_t* lblampm; lv_obj_t* btnSetTime; diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.cpp b/src/displayapp/screens/settings/SettingShakeThreshold.cpp index de46f7de..e7edee9a 100644 --- a/src/displayapp/screens/settings/SettingShakeThreshold.cpp +++ b/src/displayapp/screens/settings/SettingShakeThreshold.cpp @@ -57,7 +57,7 @@ SettingShakeThreshold::SettingShakeThreshold(DisplayApp* app, lv_obj_set_width(calButton, 200); lv_obj_align(calButton, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); lv_btn_set_checkable(calButton, true); - calLabel = lv_label_create(calButton, NULL); + calLabel = lv_label_create(calButton, nullptr); lv_label_set_text_static(calLabel, "Calibrate"); lv_arc_set_value(positionArc, settingsController.GetShakeThreshold()); @@ -102,7 +102,7 @@ void SettingShakeThreshold::Refresh() { } if (xTaskGetTickCount() - vCalTime > pdMS_TO_TICKS(7500)) { lv_btn_set_state(calButton, LV_STATE_DEFAULT); - lv_event_send(calButton, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(calButton, LV_EVENT_VALUE_CHANGED, nullptr); } } if (motionController.currentShakeSpeed() - 300 > lv_arc_get_value(animArc)) { diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.h b/src/displayapp/screens/settings/SettingShakeThreshold.h index 43319468..d0979fa6 100644 --- a/src/displayapp/screens/settings/SettingShakeThreshold.h +++ b/src/displayapp/screens/settings/SettingShakeThreshold.h @@ -6,6 +6,7 @@ #include "displayapp/screens/Screen.h" #include <components/motion/MotionController.h> #include "systemtask/SystemTask.h" + namespace Pinetime { namespace Applications { diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp index 5502794b..824a10b2 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.cpp +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -8,76 +8,56 @@ using namespace Pinetime::Applications::Screens; namespace { - void event_handler(lv_obj_t* obj, lv_event_t event) { - auto* screen = static_cast<SettingTimeFormat*>(obj->user_data); - screen->UpdateSelected(obj, event); - } -} - -constexpr std::array<const char*, 2> SettingTimeFormat::options; - -SettingTimeFormat::SettingTimeFormat(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - 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); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + struct Option { + Pinetime::Controllers::Settings::ClockType clockType; + const char* name; + }; - 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); + constexpr std::array<Option, 2> options = {{ + {Pinetime::Controllers::Settings::ClockType::H12, "12-hour"}, + {Pinetime::Controllers::Settings::ClockType::H24, "24-hour"}, + }}; - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Time format"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); - - 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); - - for (unsigned int i = 0; i < options.size(); i++) { - cbOption[i] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text(cbOption[i], options[i]); - cbOption[i]->user_data = this; - lv_obj_set_event_cb(cbOption[i], event_handler); - SetRadioButtonStyle(cbOption[i]); + std::array<CheckboxList::Item, CheckboxList::MaxItems> CreateOptionArray() { + std::array<Pinetime::Applications::Screens::CheckboxList::Item, CheckboxList::MaxItems> optionArray; + for (size_t i = 0; i < CheckboxList::MaxItems; i++) { + if (i >= options.size()) { + optionArray[i].name = ""; + optionArray[i].enabled = false; + } else { + optionArray[i].name = options[i].name; + optionArray[i].enabled = true; + } + } + return optionArray; } - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { - lv_checkbox_set_checked(cbOption[0], true); - } else if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - lv_checkbox_set_checked(cbOption[1], true); + uint32_t GetDefaultOption(Pinetime::Controllers::Settings::ClockType currentOption) { + for (size_t i = 0; i < options.size(); i++) { + if (options[i].clockType == currentOption) { + return i; + } + } + return 0; } } -SettingTimeFormat::~SettingTimeFormat() { - lv_obj_clean(lv_scr_act()); - settingsController.SaveSettings(); +SettingTimeFormat::SettingTimeFormat(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), + checkboxList( + 0, + 1, + app, + "Time format", + Symbols::clock, + GetDefaultOption(settingsController.GetClockType()), + [&settings = settingsController](uint32_t index) { + settings.SetClockType(options[index].clockType); + settings.SaveSettings(); + }, + CreateOptionArray()) { } -void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (unsigned int i = 0; i < options.size(); i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - - if (i == 0) { - settingsController.SetClockType(Controllers::Settings::ClockType::H12); - }; - if (i == 1) { - settingsController.SetClockType(Controllers::Settings::ClockType::H24); - }; - - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } +SettingTimeFormat::~SettingTimeFormat() { + lv_obj_clean(lv_scr_act()); } diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h index 01ca2c9b..de37f43e 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.h +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -6,6 +6,7 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckboxList.h" namespace Pinetime { @@ -17,12 +18,8 @@ namespace Pinetime { SettingTimeFormat(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingTimeFormat() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); - private: - static constexpr std::array<const char*, 2> options = {"12-hour", "24-hour"}; - Controllers::Settings& settingsController; - lv_obj_t* cbOption[options.size()]; + CheckboxList checkboxList; }; } } diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 59275e2f..620fe6e8 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -4,19 +4,23 @@ #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" #include "components/settings/Settings.h" +#include "displayapp/screens/Styles.h" using namespace Pinetime::Applications::Screens; +constexpr std::array<SettingWakeUp::Option, 4> SettingWakeUp::options; + namespace { void event_handler(lv_obj_t* obj, lv_event_t event) { auto* screen = static_cast<SettingWakeUp*>(obj->user_data); - screen->UpdateSelected(obj, event); + if (event == LV_EVENT_VALUE_CHANGED) { + screen->UpdateSelected(obj); + } } } SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) : Screen(app), settingsController {settingsController} { - ignoringEvents = false; lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); @@ -40,39 +44,15 @@ SettingWakeUp::SettingWakeUp(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); - optionsTotal = 0; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - 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)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - 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)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - 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)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - 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)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); + for (unsigned int i = 0; i < options.size(); i++) { + cbOption[i] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text(cbOption[i], options[i].name); + if (settingsController.isWakeUpModeOn(static_cast<Controllers::Settings::WakeUpMode>(i))) { + lv_checkbox_set_checked(cbOption[i], true); + } + cbOption[i]->user_data = this; + lv_obj_set_event_cb(cbOption[i], event_handler); } - optionsTotal++; } SettingWakeUp::~SettingWakeUp() { @@ -80,32 +60,21 @@ SettingWakeUp::~SettingWakeUp() { settingsController.SaveSettings(); } -void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) { - using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode; - if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) { - ignoringEvents = true; - - // Find the index of the checkbox that triggered the event - int index = 0; - for (; index < optionsTotal; ++index) { - if (cbOption[index] == object) { - break; - } - } - - // Toggle needed wakeup mode - auto mode = static_cast<WakeUpMode>(index); - auto currentState = settingsController.isWakeUpModeOn(mode); - settingsController.setWakeUpMode(mode, !currentState); - - // Update checkbox according to current wakeup modes. - // This is needed because we can have extra logic when setting or unsetting wakeup modes, - // for example, when setting SingleTap, DoubleTap is unset and vice versa. - auto modes = settingsController.getWakeUpModes(); - for (int i = 0; i < optionsTotal; ++i) { - lv_checkbox_set_checked(cbOption[i], modes[i]); +void SettingWakeUp::UpdateSelected(lv_obj_t* object) { + // Find the index of the checkbox that triggered the event + for (size_t i = 0; i < options.size(); i++) { + if (cbOption[i] == object) { + bool currentState = settingsController.isWakeUpModeOn(options[i].wakeUpMode); + settingsController.setWakeUpMode(options[i].wakeUpMode, !currentState); + break; } + } - ignoringEvents = false; + // Update checkbox according to current wakeup modes. + // This is needed because we can have extra logic when setting or unsetting wakeup modes, + // for example, when setting SingleTap, DoubleTap is unset and vice versa. + auto modes = settingsController.getWakeUpModes(); + for (size_t i = 0; i < options.size(); ++i) { + lv_checkbox_set_checked(cbOption[i], modes[i]); } } diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index cd244ae5..2a4e7509 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -1,5 +1,6 @@ #pragma once +#include <array> #include <cstdint> #include <lvgl/lvgl.h> #include "components/settings/Settings.h" @@ -15,17 +16,23 @@ namespace Pinetime { SettingWakeUp(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWakeUp() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); + void UpdateSelected(lv_obj_t* object); private: + struct Option { + Controllers::Settings::WakeUpMode wakeUpMode; + const char* name; + }; + Controllers::Settings& settingsController; - uint8_t optionsTotal; - lv_obj_t* cbOption[5]; - // When UpdateSelected is called, it uses lv_checkbox_set_checked, - // which can cause extra events to be fired, - // which might trigger UpdateSelected again, causing a loop. - // This variable is used as a mutex to prevent that. - bool ignoringEvents; + static constexpr std::array<Option, 4> options = {{ + {Controllers::Settings::WakeUpMode::SingleTap, "Single Tap"}, + {Controllers::Settings::WakeUpMode::DoubleTap, "Double Tap"}, + {Controllers::Settings::WakeUpMode::RaiseWrist, "Raise Wrist"}, + {Controllers::Settings::WakeUpMode::Shake, "Shake Wake"}, + }}; + + lv_obj_t* cbOption[options.size()]; }; } } diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index 217f97b8..da32b5ee 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -1,32 +1,31 @@ #include "displayapp/screens/settings/SettingWatchFace.h" #include <lvgl/lvgl.h> #include "displayapp/DisplayApp.h" -#include "displayapp/screens/CheckboxList.h" #include "displayapp/screens/Screen.h" #include "components/settings/Settings.h" -#include "displayapp/screens/WatchFaceInfineat.h" -#include "displayapp/screens/WatchFaceCasioStyleG7710.h" using namespace Pinetime::Applications::Screens; constexpr const char* SettingWatchFace::title; constexpr const char* SettingWatchFace::symbol; +auto SettingWatchFace::CreateScreenList() const { + std::array<std::function<std::unique_ptr<Screen>()>, nScreens> screens; + for (size_t i = 0; i < screens.size(); i++) { + screens[i] = [this, i]() -> std::unique_ptr<Screen> { + return CreateScreen(i); + }; + } + return screens; +} + SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::FS& filesystem) : Screen(app), settingsController {settingsController}, filesystem {filesystem}, - screens {app, - 0, - {[this]() -> std::unique_ptr<Screen> { - return CreateScreen1(); - }, - [this]() -> std::unique_ptr<Screen> { - return CreateScreen2(); - }}, - Screens::ScreenListModes::UpDown} { + screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} { } SettingWatchFace::~SettingWatchFace() { @@ -37,32 +36,15 @@ bool SettingWatchFace::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } -std::unique_ptr<Screen> SettingWatchFace::CreateScreen1() { - std::array<Screens::CheckboxList::Item, 4> watchfaces { - {{"Digital face", true}, {"Analog face", true}, {"PineTimeStyle", true}, {"Terminal", true}}}; - return std::make_unique<Screens::CheckboxList>( - 0, - 2, - app, - title, - symbol, - settingsController.GetClockFace(), - [&settings = settingsController](uint32_t clockFace) { - settings.SetClockFace(clockFace); - settings.SaveSettings(); - }, - watchfaces); -} +std::unique_ptr<Screen> SettingWatchFace::CreateScreen(unsigned int screenNum) const { + std::array<Screens::CheckboxList::Item, settingsPerScreen> watchfacesOnThisScreen; + for (int i = 0; i < settingsPerScreen; i++) { + watchfacesOnThisScreen[i] = watchfaces[screenNum * settingsPerScreen + i]; + } -std::unique_ptr<Screen> SettingWatchFace::CreateScreen2() { - std::array<Screens::CheckboxList::Item, 4> watchfaces { - {{"Infineat face", Applications::Screens::WatchFaceInfineat::IsAvailable(filesystem)}, - {"Casio G7710", Applications::Screens::WatchFaceCasioStyleG7710::IsAvailable(filesystem)}, - {"", false}, - {"", false}}}; return std::make_unique<Screens::CheckboxList>( - 1, - 2, + screenNum, + nScreens, app, title, symbol, @@ -71,5 +53,5 @@ std::unique_ptr<Screen> SettingWatchFace::CreateScreen2() { settings.SetClockFace(clockFace); settings.SaveSettings(); }, - watchfaces); + watchfacesOnThisScreen); } diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 158397f8..7b8cdcdc 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -8,6 +8,9 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" +#include "displayapp/screens/CheckboxList.h" +#include "displayapp/screens/WatchFaceInfineat.h" +#include "displayapp/screens/WatchFaceCasioStyleG7710.h" namespace Pinetime { @@ -22,14 +25,30 @@ namespace Pinetime { bool OnTouchEvent(TouchEvents event) override; private: + auto CreateScreenList() const; + std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const; + Controllers::Settings& settingsController; Pinetime::Controllers::FS& filesystem; - ScreenList<2> screens; static constexpr const char* title = "Watch face"; static constexpr const char* symbol = Symbols::home; - std::unique_ptr<Screen> CreateScreen1(); - std::unique_ptr<Screen> CreateScreen2(); + + static constexpr int settingsPerScreen = 4; + + // Increment this when more space is needed + static constexpr int nScreens = 2; + + std::array<Screens::CheckboxList::Item, settingsPerScreen * nScreens> watchfaces { + {{"Digital face", true}, + {"Analog face", true}, + {"PineTimeStyle", true}, + {"Terminal", true}, + {"Infineat face", Applications::Screens::WatchFaceInfineat::IsAvailable(filesystem)}, + {"Casio G7710", Applications::Screens::WatchFaceCasioStyleG7710::IsAvailable(filesystem)}, + {"", false}, + {"", false}}}; + ScreenList<nScreens> screens; }; } } diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index a86db44f..b88c13b7 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -28,7 +28,7 @@ namespace Pinetime { static constexpr int entriesPerScreen = 4; // Increment this when more space is needed - static constexpr int nScreens = 4; + static constexpr int nScreens = 3; static constexpr std::array<List::Applications, entriesPerScreen * nScreens> entries {{ {Symbols::sun, "Display", Apps::SettingDisplay}, @@ -37,19 +37,20 @@ namespace Pinetime { {Symbols::home, "Watch face", Apps::SettingWatchFace}, {Symbols::shoe, "Steps", Apps::SettingSteps}, - {Symbols::clock, "Set date", Apps::SettingSetDate}, - {Symbols::clock, "Set time", Apps::SettingSetTime}, + {Symbols::clock, "Date&Time", Apps::SettingSetDateTime}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, - {Symbols::clock, "Chimes", Apps::SettingChimes}, + {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, {Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth}, - {Symbols::list, "About", Apps::SysInfo}, - {Symbols::none, "None", Apps::None}, - {Symbols::none, "None", Apps::None}, - {Symbols::none, "None", Apps::None}, + + // {Symbols::none, "None", Apps::None}, + // {Symbols::none, "None", Apps::None}, + // {Symbols::none, "None", Apps::None}, + // {Symbols::none, "None", Apps::None}, + }}; ScreenList<nScreens> screens; }; diff --git a/src/displayapp/widgets/Counter.cpp b/src/displayapp/widgets/Counter.cpp index e95178ec..b486e372 100644 --- a/src/displayapp/widgets/Counter.cpp +++ b/src/displayapp/widgets/Counter.cpp @@ -18,6 +18,7 @@ namespace { widget->DownBtnPressed(); } } + constexpr int digitCount(int number) { int digitCount = 0; while (number > 0) { @@ -28,7 +29,7 @@ namespace { } } -Counter::Counter(int min, int max, lv_font_t& font) : min {min}, max {max}, value {min}, font {font}, leadingZeroCount {digitCount(max)} { +Counter::Counter(int min, int max, lv_font_t& font) : min {min}, max {max}, value {min}, leadingZeroCount {digitCount(max)}, font {font} { } void Counter::UpBtnPressed() { @@ -67,6 +68,7 @@ void Counter::HideControls() { lv_obj_set_hidden(lowerLine, true); lv_obj_set_style_local_bg_opa(counterContainer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); } + void Counter::ShowControls() { lv_obj_set_hidden(upBtn, false); lv_obj_set_hidden(downBtn, false); diff --git a/src/displayapp/widgets/DotIndicator.cpp b/src/displayapp/widgets/DotIndicator.cpp new file mode 100644 index 00000000..209b43bd --- /dev/null +++ b/src/displayapp/widgets/DotIndicator.cpp @@ -0,0 +1,28 @@ +#include "displayapp/widgets/DotIndicator.h" +#include "displayapp/InfiniTimeTheme.h" + +using namespace Pinetime::Applications::Widgets; + +DotIndicator::DotIndicator(uint8_t nCurrentScreen, uint8_t nScreens) : nCurrentScreen {nCurrentScreen}, nScreens {nScreens} { +} + +void DotIndicator::Create() { + lv_obj_t* dotIndicator[nScreens]; + static constexpr uint8_t dotSize = 12; + + lv_obj_t* container = lv_cont_create(lv_scr_act(), nullptr); + lv_cont_set_layout(container, LV_LAYOUT_COLUMN_LEFT); + lv_cont_set_fit(container, LV_FIT_TIGHT); + lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, dotSize); + lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + + for (int i = 0; i < nScreens; i++) { + dotIndicator[i] = lv_obj_create(container, nullptr); + lv_obj_set_size(dotIndicator[i], dotSize, dotSize); + lv_obj_set_style_local_bg_color(dotIndicator[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + } + + lv_obj_set_style_local_bg_color(dotIndicator[nCurrentScreen], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + + lv_obj_align(container, nullptr, LV_ALIGN_IN_RIGHT_MID, 0, 0); +} diff --git a/src/displayapp/widgets/DotIndicator.h b/src/displayapp/widgets/DotIndicator.h new file mode 100644 index 00000000..49cdca26 --- /dev/null +++ b/src/displayapp/widgets/DotIndicator.h @@ -0,0 +1,18 @@ +#pragma once +#include <lvgl/lvgl.h> + +namespace Pinetime { + namespace Applications { + namespace Widgets { + class DotIndicator { + public: + DotIndicator(uint8_t nCurrentScreen, uint8_t nScreens); + void Create(); + + private: + uint8_t nCurrentScreen; + uint8_t nScreens; + }; + } + } +} diff --git a/src/displayapp/widgets/StatusIcons.h b/src/displayapp/widgets/StatusIcons.h index f4a30a80..7d9e3ae3 100644 --- a/src/displayapp/widgets/StatusIcons.h +++ b/src/displayapp/widgets/StatusIcons.h @@ -15,9 +15,11 @@ namespace Pinetime { StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController); void Align(); void Create(); + lv_obj_t* GetObject() { return container; } + void Update(); private: |
