diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 18b0af4c..42fea38b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -418,6 +418,7 @@ list(APPEND SOURCE_FILES displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp + displayapp/Colors.cpp ## Settings displayapp/screens/settings/QuickSettings.cpp @@ -427,6 +428,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingWakeUp.cpp displayapp/screens/settings/SettingDisplay.cpp displayapp/screens/settings/SettingSteps.cpp + displayapp/screens/settings/SettingPineTimeStyle.cpp ## Watch faces displayapp/icons/bg_clock.c @@ -495,6 +497,8 @@ list(APPEND SOURCE_FILES components/heartrate/Biquad.cpp components/heartrate/Ptagc.cpp components/heartrate/HeartRateController.cpp + + touchhandler/TouchHandler.cpp ) list(APPEND RECOVERY_SOURCE_FILES @@ -552,6 +556,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/heartrate/Ptagc.cpp components/motor/MotorController.cpp components/fs/FS.cpp + touchhandler/TouchHandler.cpp ) list(APPEND RECOVERYLOADER_SOURCE_FILES @@ -607,6 +612,7 @@ set(INCLUDE_FILES displayapp/screens/Metronome.h displayapp/screens/Motion.h displayapp/screens/Timer.h + displayapp/Colors.h drivers/St7789.h drivers/SpiNorFlash.h drivers/SpiMaster.h @@ -661,6 +667,7 @@ set(INCLUDE_FILES components/heartrate/Ptagc.h components/heartrate/HeartRateController.h components/motor/MotorController.h + touchhandler/TouchHandler.h ) include_directories( diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 93d6d217..a294ab78 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -17,6 +17,14 @@ namespace Pinetime { DoubleTap = 1, RaiseWrist = 2, }; + enum class Colors : uint8_t { + White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange + }; + struct PineTimeStyle { + Colors ColorTime = Colors::Teal; + Colors ColorBar = Colors::Teal; + Colors ColorBG = Colors::Black; + }; Settings(Pinetime::Controllers::FS& fs); @@ -33,10 +41,38 @@ namespace Pinetime { return settings.clockFace; }; + void SetPTSColorTime(Colors colorTime) { + if (colorTime != settings.PTS.ColorTime) + settingsChanged = true; + settings.PTS.ColorTime = colorTime; + }; + Colors GetPTSColorTime() const { + return settings.PTS.ColorTime; + }; + + void SetPTSColorBar(Colors colorBar) { + if (colorBar != settings.PTS.ColorBar) + settingsChanged = true; + settings.PTS.ColorBar = colorBar; + }; + Colors GetPTSColorBar() const { + return settings.PTS.ColorBar; + }; + + void SetPTSColorBG(Colors colorBG) { + if (colorBG != settings.PTS.ColorBG) + settingsChanged = true; + settings.PTS.ColorBG = colorBG; + }; + Colors GetPTSColorBG() const { + return settings.PTS.ColorBG; + }; + void SetAppMenu(uint8_t menu) { appMenu = menu; }; - uint8_t GetAppMenu() { + + uint8_t GetAppMenu() const { return appMenu; }; @@ -127,9 +163,8 @@ namespace Pinetime { private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0001; + static constexpr uint32_t settingsVersion = 0x0002; struct SettingsData { - uint32_t version = settingsVersion; uint32_t stepsGoal = 10000; uint32_t screenTimeOut = 15000; @@ -139,6 +174,8 @@ namespace Pinetime { uint8_t clockFace = 0; + PineTimeStyle PTS; + std::bitset<3> wakeUpMode {0}; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index 684e3a46..dd51fdb4 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -30,7 +30,8 @@ namespace Pinetime { SettingTimeFormat, SettingDisplay, SettingWakeUp, - SettingSteps + SettingSteps, + SettingPineTimeStyle }; } } diff --git a/src/displayapp/Colors.cpp b/src/displayapp/Colors.cpp new file mode 100644 index 00000000..f45f0722 --- /dev/null +++ b/src/displayapp/Colors.cpp @@ -0,0 +1,27 @@ +#include "Colors.h" + +using namespace Pinetime::Applications; +using namespace Pinetime::Controllers; + +lv_color_t Pinetime::Applications::Convert(Pinetime::Controllers::Settings::Colors color) { + switch (color) { + case Pinetime::Controllers::Settings::Colors::White: return LV_COLOR_WHITE; + case Pinetime::Controllers::Settings::Colors::Silver: return LV_COLOR_SILVER; + case Pinetime::Controllers::Settings::Colors::Gray: return LV_COLOR_GRAY; + case Pinetime::Controllers::Settings::Colors::Black: return LV_COLOR_BLACK; + case Pinetime::Controllers::Settings::Colors::Red: return LV_COLOR_RED; + case Pinetime::Controllers::Settings::Colors::Maroon: return LV_COLOR_MAROON; + case Pinetime::Controllers::Settings::Colors::Yellow: return LV_COLOR_YELLOW; + case Pinetime::Controllers::Settings::Colors::Olive: return LV_COLOR_OLIVE; + case Pinetime::Controllers::Settings::Colors::Lime: return LV_COLOR_LIME; + case Pinetime::Controllers::Settings::Colors::Green: return LV_COLOR_GREEN; + case Pinetime::Controllers::Settings::Colors::Cyan: return LV_COLOR_CYAN; + case Pinetime::Controllers::Settings::Colors::Teal: return LV_COLOR_TEAL; + case Pinetime::Controllers::Settings::Colors::Blue: return LV_COLOR_BLUE; + case Pinetime::Controllers::Settings::Colors::Navy: return LV_COLOR_NAVY; + case Pinetime::Controllers::Settings::Colors::Magenta: return LV_COLOR_MAGENTA; + case Pinetime::Controllers::Settings::Colors::Purple: return LV_COLOR_PURPLE; + case Pinetime::Controllers::Settings::Colors::Orange: return LV_COLOR_ORANGE; + default: return LV_COLOR_WHITE; + } +} diff --git a/src/displayapp/Colors.h b/src/displayapp/Colors.h new file mode 100644 index 00000000..9db7dd20 --- /dev/null +++ b/src/displayapp/Colors.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +namespace Pinetime { + namespace Applications { + lv_color_t Convert(Controllers::Settings::Colors color); + } +} \ No newline at end of file diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 5150162a..d6100ece 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -42,6 +42,7 @@ #include "displayapp/screens/settings/SettingWakeUp.h" #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" +#include "displayapp/screens/settings/SettingPineTimeStyle.h" #include "libs/lv_conf.h" @@ -53,29 +54,26 @@ namespace { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; } - TouchEvents Convert(Pinetime::Drivers::Cst816S::TouchInfos info) { - if (info.isTouch) { - switch (info.gesture) { - case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - return TouchEvents::Tap; - case Pinetime::Drivers::Cst816S::Gestures::LongPress: - return TouchEvents::LongTap; - case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: - return TouchEvents::DoubleTap; - case Pinetime::Drivers::Cst816S::Gestures::SlideRight: - return TouchEvents::SwipeRight; - case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: - return TouchEvents::SwipeLeft; - case Pinetime::Drivers::Cst816S::Gestures::SlideDown: - return TouchEvents::SwipeDown; - case Pinetime::Drivers::Cst816S::Gestures::SlideUp: - return TouchEvents::SwipeUp; - case Pinetime::Drivers::Cst816S::Gestures::None: - default: - return TouchEvents::None; - } + TouchEvents ConvertGesture(Pinetime::Drivers::Cst816S::Gestures gesture) { + switch (gesture) { + case Pinetime::Drivers::Cst816S::Gestures::SingleTap: + return TouchEvents::Tap; + case Pinetime::Drivers::Cst816S::Gestures::LongPress: + return TouchEvents::LongTap; + case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: + return TouchEvents::DoubleTap; + case Pinetime::Drivers::Cst816S::Gestures::SlideRight: + return TouchEvents::SwipeRight; + case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: + return TouchEvents::SwipeLeft; + case Pinetime::Drivers::Cst816S::Gestures::SlideDown: + return TouchEvents::SwipeDown; + case Pinetime::Drivers::Cst816S::Gestures::SlideUp: + return TouchEvents::SwipeUp; + case Pinetime::Drivers::Cst816S::Gestures::None: + default: + return TouchEvents::None; } - return TouchEvents::None; } } @@ -91,7 +89,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController) + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, lvgl {lvgl}, touchPanel {touchPanel}, @@ -104,7 +103,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, settingsController {settingsController}, motorController {motorController}, motionController {motionController}, - timerController {timerController} { + timerController {timerController}, + touchHandler {touchHandler} { } void DisplayApp::Start() { @@ -212,8 +212,7 @@ void DisplayApp::Refresh() { if (state != States::Running) { break; } - auto info = touchPanel.GetTouchInfo(); - auto gesture = Convert(info); + auto gesture = ConvertGesture(touchHandler.GestureGet()); if (gesture == TouchEvents::None) { break; } @@ -239,11 +238,9 @@ void DisplayApp::Refresh() { LoadApp(returnToApp, returnDirection); brightnessController.Set(settingsController.GetBrightness()); brightnessController.Backup(); - } else if (touchMode == TouchModes::Gestures) { - if (gesture == TouchEvents::Tap) { - lvgl.SetNewTapEvent(info.x, info.y); - } } + } else { + touchHandler.CancelTap(); } } break; case Messages::ButtonPushed: @@ -273,18 +270,13 @@ void DisplayApp::Refresh() { nextApp = Apps::None; } - if (state != States::Idle && touchMode == TouchModes::Polling) { - auto info = touchPanel.GetTouchInfo(); - if (info.action == 2) { // 2 = contact - if (!currentScreen->OnTouchEvent(info.x, info.y)) { - lvgl.SetNewTapEvent(info.x, info.y); - } - } + if (touchHandler.IsTouching()) { + currentScreen->OnTouchEvent(touchHandler.GetX(), touchHandler.GetY()); } } void DisplayApp::RunningState() { - if (!currentScreen->Refresh()) { + if (!currentScreen->IsRunning()) { LoadApp(returnToApp, returnDirection); } lv_task_handler(); @@ -302,6 +294,7 @@ void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction } void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) { + touchHandler.CancelTap(); currentScreen.reset(nullptr); SetFullRefresh(direction); @@ -378,6 +371,10 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; + case Apps::SettingPineTimeStyle: + currentScreen = std::make_unique(this, settingsController); + ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; case Apps::BatteryInfo: currentScreen = std::make_unique(this, batteryController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); @@ -467,10 +464,6 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { } } -void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { - touchMode = mode; -} - void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) { if (systemTask != nullptr) systemTask->PushMessage(message); diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 574be63f..96951d1c 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -14,6 +14,7 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" #include "components/timer/TimerController.h" +#include "touchhandler/TouchHandler.h" #include "Messages.h" namespace Pinetime { @@ -31,6 +32,7 @@ namespace Pinetime { class NotificationManager; class HeartRateController; class MotionController; + class TouchHandler; } namespace System { @@ -41,7 +43,6 @@ namespace Pinetime { public: enum class States { Idle, Running }; enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; - enum class TouchModes { Gestures, Polling }; DisplayApp(Drivers::St7789& lcd, Components::LittleVgl& lvgl, @@ -55,14 +56,14 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController); + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Display::Messages msg); void StartApp(Apps app, DisplayApp::FullRefreshDirections direction); void SetFullRefresh(FullRefreshDirections direction); - void SetTouchMode(TouchModes mode); void Register(Pinetime::System::SystemTask* systemTask); @@ -81,6 +82,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController; Pinetime::Controllers::MotionController& motionController; Pinetime::Controllers::TimerController& timerController; + Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::FirmwareValidator validator; Controllers::BrightnessController brightnessController; @@ -100,8 +102,7 @@ namespace Pinetime { FullRefreshDirections returnDirection = FullRefreshDirections::None; TouchEvents returnTouchEvent = TouchEvents::None; - TouchModes touchMode = TouchModes::Gestures; - + TouchEvents GetGesture(); void RunningState(); void IdleState(); static void Process(void* instance); diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index fd517b11..17612ef0 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "displayapp/icons/infinitime/infinitime-nb.c" using namespace Pinetime::Applications; @@ -19,7 +20,8 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController) + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, bleController {bleController} { } diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 638c0071..8b2bc7f5 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -29,6 +29,9 @@ namespace Pinetime { namespace System { class SystemTask; }; + namespace Controllers { + class TouchHandler; + } namespace Applications { class DisplayApp { public: @@ -44,7 +47,8 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, - Pinetime::Controllers::TimerController& timerController); + Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::TouchHandler& touchHandler); void 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 016165b8..1db51343 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -32,6 +32,9 @@ namespace Pinetime { } void SetNewTapEvent(uint16_t x, uint16_t y) { } + void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { + + } }; } } diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index c069afa2..2bd5e57b 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -166,43 +166,21 @@ void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { lv_disp_flush_ready(&disp_drv); } -void LittleVgl::SetNewTapEvent(uint16_t x, uint16_t y) { +void LittleVgl::SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { tap_x = x; tap_y = y; - tapped = true; + tapped = contact; } bool LittleVgl::GetTouchPadInfo(lv_indev_data_t* ptr) { + ptr->point.x = tap_x; + ptr->point.y = tap_y; if (tapped) { - ptr->point.x = tap_x; - ptr->point.y = tap_y; ptr->state = LV_INDEV_STATE_PR; - tapped = false; } else { ptr->state = LV_INDEV_STATE_REL; } return false; - /* - auto info = touchPanel.GetTouchInfo(); - - if((previousClick.x != info.x || previousClick.y != info.y) && - (info.gesture == Drivers::Cst816S::Gestures::SingleTap)) { - // TODO For an unknown reason, the first touch is taken twice into account. - // 'firstTouch' is a quite'n'dirty workaound until I find a better solution - if(firstTouch) ptr->state = LV_INDEV_STATE_REL; - else ptr->state = LV_INDEV_STATE_PR; - firstTouch = false; - previousClick.x = info.x; - previousClick.y = info.y; - } - else { - ptr->state = LV_INDEV_STATE_REL; - } - - ptr->point.x = info.x; - ptr->point.y = info.y; - return false; - */ } void LittleVgl::InitTheme() { diff --git a/src/displayapp/LittleVgl.h b/src/displayapp/LittleVgl.h index 41f934a7..1f8a3d79 100644 --- a/src/displayapp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -24,7 +24,7 @@ namespace Pinetime { void FlushDisplay(const lv_area_t* area, lv_color_t* color_p); bool GetTouchPadInfo(lv_indev_data_t* ptr); void SetFullRefresh(FullRefreshDirections direction); - void SetNewTapEvent(uint16_t x, uint16_t y); + void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact); private: void InitDisplay(); diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index d6c3970b..6e7bbb74 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -34,12 +34,6 @@ ApplicationList::~ApplicationList() { lv_obj_clean(lv_scr_act()); } -bool ApplicationList::Refresh() { - if (running) - running = screens.Refresh(); - return running; -} - bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 88534ec4..103c38ae 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -18,7 +18,6 @@ namespace Pinetime { Pinetime::Controllers::Battery& batteryController, Controllers::DateTime& dateTimeController); ~ApplicationList() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; private: @@ -33,4 +32,4 @@ namespace Pinetime { }; } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 0ab47ebf..91c26512 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -4,11 +4,6 @@ using namespace Pinetime::Applications::Screens; -static void lv_update_task(struct _lv_task_t* task) { - auto user_data = static_cast(task->user_data); - user_data->UpdateScreen(); -} - BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Battery& batteryController) : Screen(app), batteryController {batteryController} { @@ -49,16 +44,16 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); - taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_LOW, this); - UpdateScreen(); + taskRefresh = lv_task_create(RefreshTaskCallback, 5000, LV_TASK_PRIO_MID, this); + Refresh(); } BatteryInfo::~BatteryInfo() { - lv_task_del(taskUpdate); + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -void BatteryInfo::UpdateScreen() { +void BatteryInfo::Refresh() { batteryController.Update(); @@ -85,7 +80,3 @@ void BatteryInfo::UpdateScreen() { lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); } - -bool BatteryInfo::Refresh() { - return running; -} diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 69793244..63454a26 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -19,9 +19,7 @@ namespace Pinetime { BatteryInfo(DisplayApp* app, Pinetime::Controllers::Battery& batteryController); ~BatteryInfo() override; - bool Refresh() override; - - void UpdateScreen(); + void Refresh() override; private: Pinetime::Controllers::Battery& batteryController; @@ -31,7 +29,7 @@ namespace Pinetime { lv_obj_t* charging_bar; lv_obj_t* status; - lv_task_t* taskUpdate; + lv_task_t* taskRefresh; uint8_t batteryPercent = 0; uint16_t batteryVoltage = 0; diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 47c10561..1278cd62 100644 --- a/src/displayapp/screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -30,10 +30,6 @@ Brightness::~Brightness() { lv_obj_clean(lv_scr_act()); } -bool Brightness::Refresh() { - return running; -} - const char* Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { switch (level) { case Pinetime::Controllers::BrightnessController::Levels::Off: diff --git a/src/displayapp/screens/Brightness.h b/src/displayapp/screens/Brightness.h index 9ee33753..14e48592 100644 --- a/src/displayapp/screens/Brightness.h +++ b/src/displayapp/screens/Brightness.h @@ -12,7 +12,6 @@ namespace Pinetime { public: Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); ~Brightness() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; @@ -31,4 +30,4 @@ namespace Pinetime { }; } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 86afee0c..5a5cd18b 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -50,11 +50,6 @@ Clock::~Clock() { lv_obj_clean(lv_scr_act()); } -bool Clock::Refresh() { - screen->Refresh(); - return running; -} - bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screen->OnTouchEvent(event); } @@ -83,4 +78,4 @@ std::unique_ptr Clock::PineTimeStyleScreen() { notificatioManager, settingsController, motionController); -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 7968cced..648f72da 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -31,8 +31,6 @@ namespace Pinetime { Controllers::MotionController& motionController); ~Clock() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; private: diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index edb2e49d..79bda0ba 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -30,14 +30,16 @@ FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp* app, Pinetime lv_label_set_text(percentLabel, "Waiting..."); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); startTime = xTaskGetTickCount(); } FirmwareUpdate::~FirmwareUpdate() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool FirmwareUpdate::Refresh() { +void FirmwareUpdate::Refresh() { switch (bleController.State()) { default: case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: @@ -73,7 +75,6 @@ bool FirmwareUpdate::Refresh() { } break; } - return running; } void FirmwareUpdate::DisplayProgression() const { diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index 90c99f4c..8fc86d8c 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -16,7 +16,7 @@ namespace Pinetime { FirmwareUpdate(DisplayApp* app, Pinetime::Controllers::Ble& bleController); ~FirmwareUpdate() override; - bool Refresh() override; + void Refresh() override; private: enum class States { Idle, Running, Validated, Error }; @@ -36,6 +36,7 @@ namespace Pinetime { void UpdateError(); + lv_task_t* taskRefresh; TickType_t startTime; }; } diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index 233ebd5b..eef8f919 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -63,15 +63,11 @@ FirmwareValidation::~FirmwareValidation() { lv_obj_clean(lv_scr_act()); } -bool FirmwareValidation::Refresh() { - return running; -} - void FirmwareValidation::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == buttonValidate && event == LV_EVENT_PRESSED) { + if (object == buttonValidate && event == LV_EVENT_CLICKED) { validator.Validate(); running = false; - } else if (object == buttonReset && event == LV_EVENT_PRESSED) { + } else if (object == buttonReset && event == LV_EVENT_CLICKED) { validator.Reset(); } } diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h index 1ef5ba0a..bfdb096d 100644 --- a/src/displayapp/screens/FirmwareValidation.h +++ b/src/displayapp/screens/FirmwareValidation.h @@ -16,8 +16,6 @@ namespace Pinetime { FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator); ~FirmwareValidation() override; - bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index 63b2345e..4bc5b558 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -65,10 +65,6 @@ void FlashLight::OnClickEvent(lv_obj_t* obj, lv_event_t event) { } } -bool FlashLight::Refresh() { - return running; -} - bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return false; } diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h index a862ffdb..7f5ca6c5 100644 --- a/src/displayapp/screens/FlashLight.h +++ b/src/displayapp/screens/FlashLight.h @@ -16,8 +16,6 @@ namespace Pinetime { FlashLight(DisplayApp* app, System::SystemTask& systemTask, Controllers::BrightnessController& brightness); ~FlashLight() override; - bool Refresh() override; - bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; void OnClickEvent(lv_obj_t* obj, lv_event_t event); diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 5689b63e..b6ece27f 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -64,14 +64,17 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app, UpdateStartStopButton(isHrRunning); if (isHrRunning) systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + + taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); } HeartRate::~HeartRate() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } -bool HeartRate::Refresh() { +void HeartRate::Refresh() { auto state = heartRateController.State(); switch (state) { @@ -86,8 +89,6 @@ bool HeartRate::Refresh() { lv_label_set_text(label_status, ToString(state)); lv_obj_align(label_status, label_hr, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); - - return running; } void HeartRate::OnStartStopEvent(lv_event_t event) { diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index a23c5af8..7f7d3ad3 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -20,7 +20,7 @@ namespace Pinetime { HeartRate(DisplayApp* app, Controllers::HeartRateController& HeartRateController, System::SystemTask& systemTask); ~HeartRate() override; - bool Refresh() override; + void Refresh() override; void OnStartStopEvent(lv_event_t event); @@ -33,6 +33,8 @@ namespace Pinetime { lv_obj_t* label_status; lv_obj_t* btn_startStop; lv_obj_t* label_startStop; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index 32240084..85a5e826 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -5,20 +5,13 @@ using namespace Pinetime::Applications::Screens; InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} { - app->SetTouchMode(DisplayApp::TouchModes::Polling); std::fill(b, b + bufferSize, selectColor); } InfiniPaint::~InfiniPaint() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); lv_obj_clean(lv_scr_act()); } -bool InfiniPaint::Refresh() { - return running; -} - bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { case Pinetime::Applications::TouchEvents::LongTap: diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 6251752a..0a70e033 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -17,8 +17,6 @@ namespace Pinetime { ~InfiniPaint() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index f724fd48..1761a7b5 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -36,7 +36,3 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ Label::~Label() { lv_obj_clean(lv_scr_act()); } - -bool Label::Refresh() { - return running; -} diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h index 834f8c88..f1e49079 100644 --- a/src/displayapp/screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -12,8 +12,6 @@ namespace Pinetime { Label(uint8_t screenID, uint8_t numScreens, DisplayApp* app, lv_obj_t* labelText); ~Label() override; - bool Refresh() override; - private: lv_obj_t* labelText = nullptr; lv_point_t pageIndicatorBasePoints[2]; diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index eb53820b..064b47a6 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -98,13 +98,8 @@ List::~List() { lv_obj_clean(lv_scr_act()); } -bool List::Refresh() { - - return running; -} - void List::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_RELEASED) { + if (event == LV_EVENT_CLICKED) { for (int i = 0; i < MAXLISTITEMS; i++) { if (apps[i] != Apps::None && object == itemApps[i]) { app->StartApp(apps[i], DisplayApp::FullRefreshDirections::Up); diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h index a45fd1d3..d9f61f29 100644 --- a/src/displayapp/screens/List.h +++ b/src/displayapp/screens/List.h @@ -27,8 +27,6 @@ namespace Pinetime { std::array& applications); ~List() override; - bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index e0dbdfad..57cde9cf 100644 --- a/src/displayapp/screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -20,17 +20,17 @@ Meter::Meter(Pinetime::Applications::DisplayApp* app) : Screen(app) { lv_obj_set_size(lmeter, 200, 200); lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Meter::~Meter() { - + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Meter::Refresh() { +void Meter::Refresh() { lv_linemeter_set_value(lmeter, value++); /*Set the current value*/ if (value >= 60) value = 0; - - return running; } diff --git a/src/displayapp/screens/Meter.h b/src/displayapp/screens/Meter.h index 24af15ad..9b3d1d48 100644 --- a/src/displayapp/screens/Meter.h +++ b/src/displayapp/screens/Meter.h @@ -14,13 +14,15 @@ namespace Pinetime { Meter(DisplayApp* app); ~Meter() override; - bool Refresh() override; + void Refresh() override; private: lv_style_t style_lmeter; lv_obj_t* lmeter; uint32_t value = 0; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 66f8f621..884a4a51 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -67,16 +67,16 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); - app->SetTouchMode(DisplayApp::TouchModes::Polling); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Metronome::~Metronome() { - app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_task_del(taskRefresh); systemTask.PushMessage(System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } -bool Metronome::Refresh() { +void Metronome::Refresh() { if (metronomeStarted) { if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) { startTime += 60 * configTICK_RATE_HZ / bpm; @@ -89,7 +89,6 @@ bool Metronome::Refresh() { } } } - return running; } void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index a4baa096..f3a84dc8 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -11,7 +11,7 @@ namespace Pinetime { public: Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); ~Metronome() override; - bool Refresh() override; + void Refresh() override; void OnEvent(lv_obj_t* obj, lv_event_t event); private: @@ -28,6 +28,8 @@ namespace Pinetime { lv_obj_t *bpmArc, *bpmTap, *bpmValue; lv_obj_t *bpbDropdown, *currentBpbText; lv_obj_t *playPause; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index 43a5575e..2f1f7c21 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -36,13 +36,16 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr labelStep = lv_label_create(lv_scr_act(), NULL); lv_obj_align(labelStep, chart, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_label_set_text(labelStep, "Steps ---"); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Motion::~Motion() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Motion::Refresh() { +void Motion::Refresh() { lv_chart_set_next(chart, ser1, motionController.X()); lv_chart_set_next(chart, ser2, motionController.Y()); lv_chart_set_next(chart, ser3, motionController.Z()); @@ -55,6 +58,4 @@ bool Motion::Refresh() { motionController.Y() / 0x10, motionController.Z() / 0x10); lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10); - - return running; } diff --git a/src/displayapp/screens/Motion.h b/src/displayapp/screens/Motion.h index 7e65197b..20a18d02 100644 --- a/src/displayapp/screens/Motion.h +++ b/src/displayapp/screens/Motion.h @@ -17,7 +17,7 @@ namespace Pinetime { Motion(DisplayApp* app, Controllers::MotionController& motionController); ~Motion() override; - bool Refresh() override; + void Refresh() override; private: Controllers::MotionController& motionController; @@ -28,6 +28,7 @@ namespace Pinetime { lv_obj_t* label; lv_obj_t* labelStep; + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index 257e9aea..47ddb655 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -139,14 +139,17 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus frameB = false; musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Music::~Music() { + lv_task_del(taskRefresh); lv_style_reset(&btn_style); lv_obj_clean(lv_scr_act()); } -bool Music::Refresh() { +void Music::Refresh() { if (artist != musicService.getArtist()) { artist = musicService.getArtist(); currentLength = 0; @@ -210,8 +213,6 @@ bool Music::Refresh() { } else { lv_label_set_text(txtPlayPause, Symbols::play); } - - return running; } void Music::UpdateLength() { diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index 00d3ad92..6f2d80a0 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -35,7 +35,7 @@ namespace Pinetime { ~Music() override; - bool Refresh() override; + void Refresh() override; void OnObjectEvent(lv_obj_t* obj, lv_event_t event); @@ -79,6 +79,8 @@ namespace Pinetime { bool playing; + lv_task_t* taskRefresh; + /** Watchapp */ }; } diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index 79b04e21..d437cc6d 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -161,13 +161,16 @@ Navigation::Navigation(Pinetime::Applications::DisplayApp* app, Pinetime::Contro lv_bar_set_anim_time(barProgress, 500); lv_bar_set_range(barProgress, 0, 100); lv_bar_set_value(barProgress, 0, LV_ANIM_OFF); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Navigation::~Navigation() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Navigation::Refresh() { +void Navigation::Refresh() { if (flag != navService.getFlag()) { flag = navService.getFlag(); lv_label_set_text(imgFlag, iconForName(flag)); @@ -192,8 +195,4 @@ bool Navigation::Refresh() { lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_ORANGE); } } - - return running; } - - diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index eb7e00c4..48f00a76 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -35,7 +35,7 @@ namespace Pinetime { Navigation(DisplayApp* app, Pinetime::Controllers::NavigationService& nav); ~Navigation() override; - bool Refresh() override; + void Refresh() override; private: lv_obj_t* imgFlag; @@ -49,6 +49,8 @@ namespace Pinetime { std::string narrative; std::string manDist; int progress; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index c061c146..fd0b86da 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -52,15 +52,18 @@ Notifications::Notifications(DisplayApp* app, timeoutTickCountEnd = timeoutTickCountStart + (5 * 1024); } } + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Notifications::~Notifications() { + lv_task_del(taskRefresh); // make sure we stop any vibrations before exiting Controllers::MotorController::StopRinging(); lv_obj_clean(lv_scr_act()); } -bool Notifications::Refresh() { +void Notifications::Refresh() { if (mode == Modes::Preview && timeoutLine != nullptr) { auto tick = xTaskGetTickCount(); int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240)); @@ -70,7 +73,7 @@ bool Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } - return running && currentItem->IsRunning(); + running = currentItem->IsRunning(); } bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index a02d9b46..f6f8b4c3 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -24,7 +24,7 @@ namespace Pinetime { Modes mode); ~Notifications() override; - bool Refresh() override; + void Refresh() override; bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; class NotificationItem { @@ -79,6 +79,8 @@ namespace Pinetime { lv_obj_t* timeoutLine = nullptr; uint32_t timeoutTickCountStart; uint32_t timeoutTickCountEnd; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index 5a939ac7..3b6d60e3 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -5,8 +5,6 @@ using namespace Pinetime::Applications::Screens; Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} { - app->SetTouchMode(DisplayApp::TouchModes::Polling); - background = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_size(background, LV_HOR_RES + 1, LV_VER_RES); lv_obj_set_pos(background, -1, 0); @@ -29,15 +27,16 @@ Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::Li lv_obj_set_style_local_bg_color(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_obj_set_style_local_radius(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); lv_obj_set_size(ball, ballSize, ballSize); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Paddle::~Paddle() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Paddle::Refresh() { +void Paddle::Refresh() { ballX += dx; ballY += dy; @@ -69,7 +68,6 @@ bool Paddle::Refresh() { } } lv_label_set_text_fmt(points, "%04d", score); - return running; } bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents event) { diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index 30ab8f94..fc2131a1 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -16,7 +16,7 @@ namespace Pinetime { Paddle(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); ~Paddle() override; - bool Refresh() override; + void Refresh() override; bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; @@ -40,6 +40,8 @@ namespace Pinetime { lv_obj_t* paddle; lv_obj_t* ball; lv_obj_t* background; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp index 98fd976c..7a712f43 100644 --- a/src/displayapp/screens/PineTimeStyle.cpp +++ b/src/displayapp/screens/PineTimeStyle.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "BatteryIcon.h" #include "BleIcon.h" #include "NotificationIcon.h" @@ -51,7 +52,8 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, notificatioManager {notificatioManager}, settingsController {settingsController}, motionController {motionController} { - /* This sets the watchface number to return to after leaving the menu */ + + // This sets the watchface number to return to after leaving the menu settingsController.SetClockFace(2); displayedChar[0] = 0; @@ -60,40 +62,40 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, displayedChar[3] = 0; displayedChar[4] = 0; - /* Create a 200px wide background rectangle */ + //Create a 200px wide background rectangle timebar = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBG())); lv_obj_set_style_local_radius(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_size(timebar, 200, 240); lv_obj_align(timebar, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 0); - /* Display the time */ + // Display the time timeDD1 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); - lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_label_set_text(timeDD1, "12"); lv_obj_align(timeDD1, timebar, LV_ALIGN_IN_TOP_MID, 5, 5); timeDD2 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); - lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_label_set_text(timeDD2, "34"); lv_obj_align(timeDD2, timebar, LV_ALIGN_IN_BOTTOM_MID, 5, -5); timeAMPM = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_obj_set_style_local_text_line_space(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -3); lv_label_set_text(timeAMPM, ""); lv_obj_align(timeAMPM, timebar, LV_ALIGN_IN_BOTTOM_LEFT, 2, -20); - /* Create a 40px wide bar down the right side of the screen */ + // Create a 40px wide bar down the right side of the screen sidebar = lv_obj_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x008080)); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBar())); lv_obj_set_style_local_radius(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_size(sidebar, 40, 240); lv_obj_align(sidebar, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); - /* Display icons */ + // Display icons batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_label_set_text(batteryIcon, Symbols::batteryFull); @@ -111,7 +113,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_align(notificationIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 40); - /* Calendar icon */ + // Calendar icon calendarOuter = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_style_local_bg_color(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_radius(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); @@ -148,7 +150,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_size(calendarCrossBar2, 8, 3); lv_obj_align(calendarCrossBar2, calendarBar2, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - /* Display date */ + // Display date dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_label_set_text(dateDayOfWeek, "THU"); @@ -184,7 +186,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_pad_inner(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); backgroundLabel = lv_label_create(lv_scr_act(), nullptr); @@ -193,13 +195,17 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text(backgroundLabel, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); + Refresh(); } PineTimeStyle::~PineTimeStyle() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool PineTimeStyle::Refresh() { +void PineTimeStyle::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); @@ -303,6 +309,4 @@ bool PineTimeStyle::Refresh() { lv_obj_set_style_local_scale_grad_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); } } - - return running; -} \ No newline at end of file +} diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index f4cd28e4..cb74ead5 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -30,7 +30,7 @@ namespace Pinetime { Controllers::MotionController& motionController); ~PineTimeStyle() override; - bool Refresh() override; + void Refresh() override; private: char displayedChar[5]; @@ -75,6 +75,8 @@ namespace Pinetime { Controllers::NotificationManager& notificatioManager; Controllers::Settings& settingsController; Controllers::MotionController& motionController; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/Screen.cpp b/src/displayapp/screens/Screen.cpp index 1467df33..6ae5b7bb 100644 --- a/src/displayapp/screens/Screen.cpp +++ b/src/displayapp/screens/Screen.cpp @@ -1,2 +1,6 @@ #include "Screen.h" -using namespace Pinetime::Applications::Screens; \ No newline at end of file +using namespace Pinetime::Applications::Screens; + +void Screen::RefreshTaskCallback(lv_task_t* task) { + static_cast(task->user_data)->Refresh(); +} diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index 6c9110c6..ce5741b2 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -2,6 +2,7 @@ #include #include "../TouchEvents.h" +#include namespace Pinetime { namespace Applications { @@ -38,25 +39,20 @@ namespace Pinetime { }; class Screen { + private: + virtual void Refresh() { + } + public: explicit Screen(DisplayApp* app) : app {app} { } virtual ~Screen() = default; - /** - * Most of the time, apps only react to events (touch events, for example). - * In this case you don't need to do anything in this method. - * - * For example, InfiniPaint does nothing in Refresh(). - * But, if you want to update your display periodically, draw an animation... - * you cannot do it in a touch event handler because these handlers are not - * called if the user does not touch the screen. - * - * That's why Refresh() is there: update the display periodically. - * - * @return false if the app can be closed, true if it must continue to run - **/ - virtual bool Refresh() = 0; + static void RefreshTaskCallback(lv_task_t* task); + + bool IsRunning() const { + return running; + } /** @return false if the button hasn't been handled by the app, true if it has been handled */ virtual bool OnButtonPushed() { @@ -64,6 +60,7 @@ 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) { return false; } diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index ea66bfb2..a9d747aa 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -30,11 +30,6 @@ namespace Pinetime { lv_obj_clean(lv_scr_act()); } - bool Refresh() override { - running = current->Refresh(); - return running; - } - bool OnTouchEvent(TouchEvents event) override { if (mode == ScreenListModes::UpDown) { @@ -110,4 +105,4 @@ namespace Pinetime { }; } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index d72e8333..c41163ab 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -47,20 +47,20 @@ Steps::Steps(Pinetime::Applications::DisplayApp* app, lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); } Steps::~Steps() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool Steps::Refresh() { - +void Steps::Refresh() { stepsCount = motionController.NbSteps(); lv_label_set_text_fmt(lSteps, "%li", stepsCount); lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20); lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal())); - - return running; } diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index 9c135e26..d7cf31e1 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -15,24 +15,23 @@ namespace Pinetime { namespace Screens { class Steps : public Screen { - public: - Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings &settingsController); - ~Steps() override; + public: + Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController); + ~Steps() override; - bool Refresh() override; - + void Refresh() override; - private: + private: + Controllers::MotionController& motionController; + Controllers::Settings& settingsController; - Controllers::MotionController& motionController; - Controllers::Settings& settingsController; + lv_obj_t* lSteps; + lv_obj_t* lStepsIcon; + lv_obj_t* stepsArc; - lv_obj_t * lSteps; - lv_obj_t * lStepsIcon; - lv_obj_t * stepsArc; - - uint32_t stepsCount; + uint32_t stepsCount; + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index f4db5d6e..9b27a89d 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -48,7 +48,6 @@ static void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) { StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) : Screen(app), systemTask {systemTask}, - running {true}, currentState {States::Init}, startTime {}, oldTimeElapsed {}, @@ -101,9 +100,12 @@ StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55); lv_label_set_text(lapTwoText, ""); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } StopWatch::~StopWatch() { + lv_task_del(taskRefresh); systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -149,7 +151,7 @@ void StopWatch::pause() { systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } -bool StopWatch::Refresh() { +void StopWatch::Refresh() { if (currentState == States::Running) { timeElapsed = calculateDelta(startTime, xTaskGetTickCount()); currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed)); @@ -157,11 +159,10 @@ bool StopWatch::Refresh() { lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs); lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths); } - return running; } void StopWatch::playPauseBtnEventHandler(lv_event_t event) { - if (event != LV_EVENT_PRESSED) { + if (event != LV_EVENT_CLICKED) { return; } if (currentState == States::Init) { @@ -174,7 +175,7 @@ void StopWatch::playPauseBtnEventHandler(lv_event_t event) { } void StopWatch::stopLapBtnEventHandler(lv_event_t event) { - if (event != LV_EVENT_PRESSED) { + if (event != LV_EVENT_CLICKED) { return; } // If running, then this button is used to save laps @@ -196,8 +197,7 @@ void StopWatch::stopLapBtnEventHandler(lv_event_t event) { bool StopWatch::OnButtonPushed() { if (currentState == States::Running) { pause(); - } else { - running = false; + return true; } - return true; + return false; } diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index e132f158..25634e92 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -64,7 +64,7 @@ namespace Pinetime::Applications::Screens { public: StopWatch(DisplayApp* app, System::SystemTask& systemTask); ~StopWatch() override; - bool Refresh() override; + void Refresh() override; void playPauseBtnEventHandler(lv_event_t event); void stopLapBtnEventHandler(lv_event_t event); @@ -77,7 +77,6 @@ namespace Pinetime::Applications::Screens { private: Pinetime::System::SystemTask& systemTask; TickType_t timeElapsed; - bool running; States currentState; TickType_t startTime; TickType_t oldTimeElapsed; @@ -86,5 +85,7 @@ namespace Pinetime::Applications::Screens { int lapNr = 0; lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap; lv_obj_t *lapOneText, *lapTwoText; + + lv_task_t* taskRefresh; }; } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index e7c5b65a..b7a4fc60 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -65,13 +65,6 @@ SystemInfo::~SystemInfo() { lv_obj_clean(lv_scr_act()); } -bool SystemInfo::Refresh() { - if (running) { - screens.Refresh(); - } - return running; -} - bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } @@ -207,7 +200,7 @@ bool SystemInfo::sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { } std::unique_ptr SystemInfo::CreateScreen4() { - TaskStatus_t tasksStatus[7]; + TaskStatus_t tasksStatus[10]; lv_obj_t* infoTask = lv_table_create(lv_scr_act(), NULL); lv_table_set_col_cnt(infoTask, 4); lv_table_set_row_cnt(infoTask, 8); @@ -222,9 +215,9 @@ std::unique_ptr SystemInfo::CreateScreen4() { lv_table_set_cell_value(infoTask, 0, 3, "Free"); lv_table_set_col_width(infoTask, 3, 90); - auto nb = uxTaskGetSystemState(tasksStatus, 7, nullptr); + auto nb = uxTaskGetSystemState(tasksStatus, sizeof(tasksStatus) / sizeof(tasksStatus[0]), nullptr); std::sort(tasksStatus, tasksStatus + nb, sortById); - for (uint8_t i = 0; i < nb; i++) { + for (uint8_t i = 0; i < nb && i < 7; i++) { lv_table_set_cell_value(infoTask, i + 1, 0, std::to_string(tasksStatus[i].xTaskNumber).c_str()); char state[2] = {0}; diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index a9ad652d..5eb7054d 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -30,7 +30,6 @@ namespace Pinetime { Pinetime::Drivers::WatchdogView& watchdog, Pinetime::Controllers::MotionController& motionController); ~SystemInfo() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; private: diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 777b5bb7..1d4f0d0e 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -95,6 +95,7 @@ Tile::Tile(uint8_t screenID, lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 10); for (uint8_t i = 0; i < 6; i++) { + lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_CLICK_TRIG); if (applications[i].application == Apps::None) { lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_DISABLED); } @@ -122,10 +123,6 @@ void Tile::UpdateScreen() { lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); } -bool Tile::Refresh() { - return running; -} - void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { if(obj != btnm1) return; diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 765a8def..83d3fdf5 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -30,7 +30,6 @@ namespace Pinetime { ~Tile() override; - bool Refresh() override; void UpdateScreen(); void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId); diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index 99e979ba..ff3099d5 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -4,10 +4,8 @@ #include "Symbols.h" #include "lvgl/lvgl.h" - using namespace Pinetime::Applications::Screens; - static void btnEventHandler(lv_obj_t* obj, lv_event_t event) { Timer* screen = static_cast(obj->user_data); screen->OnButtonEvent(obj, event); @@ -22,7 +20,7 @@ void Timer::createButtons() { lv_obj_set_width(btnMinutesUp, 60); txtMUp = lv_label_create(btnMinutesUp, nullptr); lv_label_set_text(txtMUp, "+"); - + btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); btnMinutesDown->user_data = this; lv_obj_set_event_cb(btnMinutesDown, btnEventHandler); @@ -31,7 +29,7 @@ void Timer::createButtons() { lv_obj_set_width(btnMinutesDown, 60); txtMDown = lv_label_create(btnMinutesDown, nullptr); lv_label_set_text(txtMDown, "-"); - + btnSecondsUp = lv_btn_create(lv_scr_act(), nullptr); btnSecondsUp->user_data = this; lv_obj_set_event_cb(btnSecondsUp, btnEventHandler); @@ -40,7 +38,7 @@ void Timer::createButtons() { lv_obj_set_width(btnSecondsUp, 60); txtSUp = lv_label_create(btnSecondsUp, nullptr); lv_label_set_text(txtSUp, "+"); - + btnSecondsDown = lv_btn_create(lv_scr_act(), nullptr); btnSecondsDown->user_data = this; lv_obj_set_event_cb(btnSecondsDown, btnEventHandler); @@ -49,24 +47,20 @@ void Timer::createButtons() { lv_obj_set_width(btnSecondsDown, 60); txtSDown = lv_label_create(btnSecondsDown, nullptr); lv_label_set_text(txtSDown, "-"); - } - Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) - : Screen(app), - running{true}, - timerController{timerController} { - + : Screen(app), running {true}, timerController {timerController} { + time = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - + uint32_t seconds = timerController.GetTimeRemaining() / 1000; lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60); lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20); - + btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; lv_obj_set_event_cb(btnPlayPause, btnEventHandler); @@ -79,20 +73,20 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) lv_label_set_text(txtPlayPause, Symbols::play); createButtons(); } - + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } Timer::~Timer() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); - } -bool Timer::Refresh() { +void Timer::Refresh() { if (timerController.IsRunning()) { uint32_t seconds = timerController.GetTimeRemaining() / 1000; lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60); } - return running; } void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { @@ -105,11 +99,11 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet = seconds % 60; timerController.StopTimer(); createButtons(); - + } else if (secondsToSet + minutesToSet > 0) { lv_label_set_text(txtPlayPause, Symbols::pause); timerController.StartTimer((secondsToSet + minutesToSet * 60) * 1000); - + lv_obj_del(btnSecondsDown); btnSecondsDown = nullptr; lv_obj_del(btnSecondsUp); @@ -118,7 +112,6 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { btnMinutesDown = nullptr; lv_obj_del(btnMinutesUp); btnMinutesUp = nullptr; - } } else { if (!timerController.IsRunning()) { @@ -129,7 +122,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { minutesToSet++; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnMinutesDown) { if (minutesToSet == 0) { minutesToSet = 59; @@ -137,7 +130,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { minutesToSet--; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnSecondsUp) { if (secondsToSet >= 59) { secondsToSet = 0; @@ -145,7 +138,7 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet++; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - + } else if (obj == btnSecondsDown) { if (secondsToSet == 0) { secondsToSet = 59; @@ -153,21 +146,16 @@ void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { secondsToSet--; } lv_label_set_text_fmt(time, "%02d:%02d", minutesToSet, secondsToSet); - } } - } - } - } - void Timer::setDone() { lv_label_set_text(time, "00:00"); lv_label_set_text(txtPlayPause, Symbols::play); secondsToSet = 0; minutesToSet = 0; createButtons(); -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index 0d66f2d4..d0fc8ed1 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -8,35 +8,32 @@ #include "components/timer/TimerController.h" namespace Pinetime::Applications::Screens { - - + class Timer : public Screen { public: - - enum class Modes { - Normal, Done - }; - + enum class Modes { Normal, Done }; + Timer(DisplayApp* app, Controllers::TimerController& timerController); - + ~Timer() override; - - bool Refresh() override; - + + void Refresh() override; + void setDone(); - + void OnButtonEvent(lv_obj_t* obj, lv_event_t event); - + private: - bool running; uint8_t secondsToSet = 0; uint8_t minutesToSet = 0; Controllers::TimerController& timerController; - + void createButtons(); - - lv_obj_t* time, * msecTime, * btnPlayPause, * txtPlayPause, * btnMinutesUp, * btnMinutesDown, * btnSecondsUp, * btnSecondsDown, * txtMUp, - * txtMDown, * txtSUp, * txtSDown; + + lv_obj_t *time, *msecTime, *btnPlayPause, *txtPlayPause, *btnMinutesUp, *btnMinutesDown, *btnSecondsUp, *btnSecondsDown, *txtMUp, + *txtMDown, *txtSUp, *txtSDown; + + lv_task_t* taskRefresh; }; -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index eb268077..4201d501 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -102,10 +102,6 @@ Twos::~Twos() { lv_obj_clean(lv_scr_act()); } -bool Twos::Refresh() { - return running; -} - bool Twos::placeNewTile() { std::vector> availableCells; for (int row = 0; row < 4; row++) { @@ -295,4 +291,4 @@ void Twos::updateGridDisplay(Tile grid[][4]) { } } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index 3367618f..6d85cff6 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -14,7 +14,6 @@ namespace Pinetime { public: Twos(DisplayApp* app); ~Twos() override; - bool Refresh() override; bool OnTouchEvent(TouchEvents event) override; @@ -36,4 +35,4 @@ namespace Pinetime { }; } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 1410fc28..75e35c1b 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -118,10 +118,13 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, lv_style_set_line_rounded(&hour_line_style_trace, LV_STATE_DEFAULT, false); lv_obj_add_style(hour_body_trace, LV_LINE_PART_MAIN, &hour_line_style_trace); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); UpdateClock(); } WatchFaceAnalog::~WatchFaceAnalog() { + lv_task_del(taskRefresh); + lv_style_reset(&hour_line_style); lv_style_reset(&hour_line_style_trace); lv_style_reset(&minute_line_style); @@ -173,7 +176,7 @@ void WatchFaceAnalog::UpdateClock() { } } -bool WatchFaceAnalog::Refresh() { +void WatchFaceAnalog::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); @@ -203,6 +206,4 @@ bool WatchFaceAnalog::Refresh() { currentDay = day; } } - - return true; } diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 5d8c6a24..406f4d50 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -32,7 +32,7 @@ namespace Pinetime { ~WatchFaceAnalog() override; - bool Refresh() override; + void Refresh() override; private: uint8_t sHour, sMinute, sSecond; @@ -81,6 +81,8 @@ namespace Pinetime { Controllers::Settings& settingsController; void UpdateClock(); + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 2b902b3b..58ab6190 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -91,13 +91,17 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); lv_label_set_text(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); + Refresh(); } WatchFaceDigital::~WatchFaceDigital() { + lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } -bool WatchFaceDigital::Refresh() { +void WatchFaceDigital::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); @@ -219,6 +223,4 @@ bool WatchFaceDigital::Refresh() { lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); } - - return running; } diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 6a6e1ac6..48dc1373 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -33,7 +33,7 @@ namespace Pinetime { Controllers::MotionController& motionController); ~WatchFaceDigital() override; - bool Refresh() override; + void Refresh() override; private: char displayedChar[5] {}; @@ -72,6 +72,8 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + + lv_task_t* taskRefresh; }; } } diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 54e2f3e2..22b56360 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -128,12 +128,12 @@ void QuickSettings::UpdateScreen() { } void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == btn2 && event == LV_EVENT_PRESSED) { + if (object == btn2 && event == LV_EVENT_CLICKED) { running = false; app->StartApp(Apps::FlashLight, DisplayApp::FullRefreshDirections::None); - } else if (object == btn1 && event == LV_EVENT_PRESSED) { + } else if (object == btn1 && event == LV_EVENT_CLICKED) { brightness.Step(); lv_label_set_text_static(btn1_lvl, brightness.GetIcon()); @@ -150,13 +150,9 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); } - } else if (object == btn4 && event == LV_EVENT_PRESSED) { + } else if (object == btn4 && event == LV_EVENT_CLICKED) { running = false; settingsController.SetSettingsMenu(0); app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up); } } - -bool QuickSettings::Refresh() { - return running; -} diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h index 2eefe1a7..c036fa5c 100644 --- a/src/displayapp/screens/settings/QuickSettings.h +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -27,8 +27,6 @@ namespace Pinetime { ~QuickSettings() override; - bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); void UpdateScreen(); diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index 4954185d..d8d6c767 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -80,12 +80,8 @@ SettingDisplay::~SettingDisplay() { settingsController.SaveSettings(); } -bool SettingDisplay::Refresh() { - return running; -} - void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { + if (event == LV_EVENT_CLICKED) { for (int i = 0; i < optionsTotal; i++) { if (object == cbOption[i]) { lv_checkbox_set_checked(cbOption[i], true); @@ -110,4 +106,4 @@ void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { } } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h index b8ed87ec..51b23aca 100644 --- a/src/displayapp/screens/settings/SettingDisplay.h +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingDisplay() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingPineTimeStyle.cpp b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp new file mode 100644 index 00000000..c9af19b6 --- /dev/null +++ b/src/displayapp/screens/settings/SettingPineTimeStyle.cpp @@ -0,0 +1,318 @@ +#include "SettingPineTimeStyle.h" +#include +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t* obj, lv_event_t event) { + SettingPineTimeStyle* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingPineTimeStyle::SettingPineTimeStyle(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), settingsController {settingsController} { + timebar = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBG())); + lv_obj_set_style_local_radius(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(timebar, 200, 240); + lv_obj_align(timebar, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 5, 0); + + // Display the time + + timeDD1 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_label_set_text(timeDD1, "12"); + lv_obj_align(timeDD1, timebar, LV_ALIGN_IN_TOP_MID, 5, 5); + + timeDD2 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_label_set_text(timeDD2, "34"); + lv_obj_align(timeDD2, timebar, LV_ALIGN_IN_BOTTOM_MID, 5, -5); + + timeAMPM = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); + lv_obj_set_style_local_text_line_space(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -3); + lv_label_set_text(timeAMPM, "A\nM"); + lv_obj_align(timeAMPM, timebar, LV_ALIGN_IN_BOTTOM_LEFT, 2, -20); + + // Create a 40px wide bar down the right side of the screen + + sidebar = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBar())); + lv_obj_set_style_local_radius(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(sidebar, 40, 240); + lv_obj_align(sidebar, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + + // Display icons + + batteryIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); + + bleIcon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_obj_align(bleIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 25); + + // Calendar icon + + calendarOuter = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarOuter, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarOuter, 34, 34); + lv_obj_align(calendarOuter, sidebar, LV_ALIGN_CENTER, 0, 0); + + calendarInner = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarInner, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xffffff)); + lv_obj_set_style_local_radius(calendarInner, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarInner, 27, 27); + lv_obj_align(calendarInner, calendarOuter, LV_ALIGN_CENTER, 0, 0); + + calendarBar1 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarBar1, 3, 12); + lv_obj_align(calendarBar1, calendarOuter, LV_ALIGN_IN_TOP_MID, -6, -3); + + calendarBar2 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarBar2, 3, 12); + lv_obj_align(calendarBar2, calendarOuter, LV_ALIGN_IN_TOP_MID, 6, -3); + + calendarCrossBar1 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarCrossBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarCrossBar1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarCrossBar1, 8, 3); + lv_obj_align(calendarCrossBar1, calendarBar1, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + calendarCrossBar2 = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_color(calendarCrossBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_radius(calendarCrossBar2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0); + lv_obj_set_size(calendarCrossBar2, 8, 3); + lv_obj_align(calendarCrossBar2, calendarBar2, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + // Display date + + dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateDayOfWeek, "THU"); + lv_obj_align(dateDayOfWeek, sidebar, LV_ALIGN_CENTER, 0, -34); + + dateDay = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateDay, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateDay, "25"); + lv_obj_align(dateDay, sidebar, LV_ALIGN_CENTER, 0, 3); + + dateMonth = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(dateMonth, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_label_set_text(dateMonth, "MAR"); + lv_obj_align(dateMonth, sidebar, LV_ALIGN_CENTER, 0, 32); + + // Step count gauge + needle_colors[0] = LV_COLOR_WHITE; + stepGauge = lv_gauge_create(lv_scr_act(), nullptr); + lv_gauge_set_needle_count(stepGauge, 1, needle_colors); + lv_obj_set_size(stepGauge, 40, 40); + lv_obj_align(stepGauge, sidebar, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_gauge_set_scale(stepGauge, 360, 11, 0); + lv_gauge_set_angle_offset(stepGauge, 180); + lv_gauge_set_critical_value(stepGauge, (100)); + lv_gauge_set_range(stepGauge, 0, (100)); + lv_gauge_set_value(stepGauge, 0, 0); + + lv_obj_set_style_local_pad_right(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_left(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_bottom(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_scale_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_line_opa(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_line_width(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_pad_inner(stepGauge, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, 4); + + backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_click(backgroundLabel, true); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); + + btnNextTime = lv_btn_create(lv_scr_act(), nullptr); + btnNextTime->user_data = this; + lv_obj_set_size(btnNextTime, 60, 60); + lv_obj_align(btnNextTime, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, -80); + lv_obj_set_style_local_bg_opa(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextTime, event_handler); + + btnPrevTime = lv_btn_create(lv_scr_act(), nullptr); + btnPrevTime->user_data = this; + lv_obj_set_size(btnPrevTime, 60, 60); + lv_obj_align(btnPrevTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, -80); + lv_obj_set_style_local_bg_opa(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevTime, event_handler); + + btnNextBar = lv_btn_create(lv_scr_act(), nullptr); + btnNextBar->user_data = this; + lv_obj_set_size(btnNextBar, 60, 60); + lv_obj_align(btnNextBar, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 0); + lv_obj_set_style_local_bg_opa(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextBar, event_handler); + + btnPrevBar = lv_btn_create(lv_scr_act(), nullptr); + btnPrevBar->user_data = this; + lv_obj_set_size(btnPrevBar, 60, 60); + lv_obj_align(btnPrevBar, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 0); + lv_obj_set_style_local_bg_opa(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevBar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevBar, event_handler); + + btnNextBG = lv_btn_create(lv_scr_act(), nullptr); + btnNextBG->user_data = this; + lv_obj_set_size(btnNextBG, 60, 60); + lv_obj_align(btnNextBG, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -15, 80); + lv_obj_set_style_local_bg_opa(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnNextBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, ">"); + lv_obj_set_event_cb(btnNextBG, event_handler); + + btnPrevBG = lv_btn_create(lv_scr_act(), nullptr); + btnPrevBG->user_data = this; + lv_obj_set_size(btnPrevBG, 60, 60); + lv_obj_align(btnPrevBG, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 15, 80); + lv_obj_set_style_local_bg_opa(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnPrevBG, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "<"); + lv_obj_set_event_cb(btnPrevBG, event_handler); + + btnReset = lv_btn_create(lv_scr_act(), nullptr); + btnReset->user_data = this; + lv_obj_set_size(btnReset, 60, 60); + lv_obj_align(btnReset, lv_scr_act(), LV_ALIGN_CENTER, 0, 80); + lv_obj_set_style_local_bg_opa(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnReset, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rst"); + lv_obj_set_event_cb(btnReset, event_handler); + + btnRandom = lv_btn_create(lv_scr_act(), nullptr); + btnRandom->user_data = this; + lv_obj_set_size(btnRandom, 60, 60); + lv_obj_align(btnRandom, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30); + lv_obj_set_style_local_value_str(btnRandom, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Rnd"); + lv_obj_set_event_cb(btnRandom, event_handler); +} + +SettingPineTimeStyle::~SettingPineTimeStyle() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingPineTimeStyle::UpdateSelected(lv_obj_t* object, lv_event_t event) { + auto valueTime = settingsController.GetPTSColorTime(); + auto valueBar = settingsController.GetPTSColorBar(); + auto valueBG = settingsController.GetPTSColorBG(); + + if (event == LV_EVENT_CLICKED) { + if (object == btnNextTime) { + valueTime = GetNext(valueTime); + + settingsController.SetPTSColorTime(valueTime); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + } + if (object == btnPrevTime) { + valueTime = GetPrevious(valueTime); + settingsController.SetPTSColorTime(valueTime); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(valueTime)); + } + if (object == btnNextBar) { + valueBar = GetNext(valueBar); + if(valueBar == Controllers::Settings::Colors::Black) + valueBar = GetNext(valueBar); + settingsController.SetPTSColorBar(valueBar); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBar)); + } + if (object == btnPrevBar) { + valueBar = GetPrevious(valueBar); + if(valueBar == Controllers::Settings::Colors::Black) + valueBar = GetPrevious(valueBar); + settingsController.SetPTSColorBar(valueBar); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBar)); + } + if (object == btnNextBG) { + valueBG = GetNext(valueBG); + settingsController.SetPTSColorBG(valueBG); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBG)); + } + if (object == btnPrevBG) { + valueBG = GetPrevious(valueBG); + settingsController.SetPTSColorBG(valueBG); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(valueBG)); + } + if (object == btnReset) { + settingsController.SetPTSColorTime(Controllers::Settings::Colors::Teal); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + settingsController.SetPTSColorBar(Controllers::Settings::Colors::Teal); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Teal)); + settingsController.SetPTSColorBG(Controllers::Settings::Colors::Black); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(Controllers::Settings::Colors::Black)); + } + if (object == btnRandom) { + uint8_t randTime = rand() % 17; + uint8_t randBar = rand() % 17; + uint8_t randBG = rand() % 17; + // Check if the time color is the same as its background, or if the sidebar is black. If so, change them to more useful values. + if (randTime == randBG) { + randBG += 1; + } + if (randBar == 3) { + randBar -= 1; + } + settingsController.SetPTSColorTime(static_cast(randTime)); + lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast(randTime))); + lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast(randTime))); + lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast(randTime))); + settingsController.SetPTSColorBar(static_cast(randBar)); + lv_obj_set_style_local_bg_color(sidebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast(randBar))); + settingsController.SetPTSColorBG(static_cast(randBG)); + lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(static_cast(randBG))); + } + } +} + +Pinetime::Controllers::Settings::Colors SettingPineTimeStyle::GetNext(Pinetime::Controllers::Settings::Colors color) { + auto colorAsInt = static_cast(color); + Pinetime::Controllers::Settings::Colors nextColor; + if (colorAsInt < 16) { + nextColor = static_cast(colorAsInt + 1); + } else { + nextColor = static_cast(0); + } + return nextColor; +} + +Pinetime::Controllers::Settings::Colors SettingPineTimeStyle::GetPrevious(Pinetime::Controllers::Settings::Colors color) { + auto colorAsInt = static_cast(color); + Pinetime::Controllers::Settings::Colors prevColor; + + if (colorAsInt > 0) { + prevColor = static_cast(colorAsInt - 1); + } else { + prevColor = static_cast(16); + } + return prevColor; +} diff --git a/src/displayapp/screens/settings/SettingPineTimeStyle.h b/src/displayapp/screens/settings/SettingPineTimeStyle.h new file mode 100644 index 00000000..397bd86d --- /dev/null +++ b/src/displayapp/screens/settings/SettingPineTimeStyle.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingPineTimeStyle : public Screen{ + public: + SettingPineTimeStyle(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingPineTimeStyle() override; + + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + Controllers::Settings& settingsController; + + Pinetime::Controllers::Settings::Colors GetNext(Controllers::Settings::Colors color); + Pinetime::Controllers::Settings::Colors GetPrevious(Controllers::Settings::Colors color); + + lv_obj_t * btnNextTime; + lv_obj_t * btnPrevTime; + lv_obj_t * btnNextBar; + lv_obj_t * btnPrevBar; + lv_obj_t * btnNextBG; + lv_obj_t * btnPrevBG; + lv_obj_t * btnReset; + lv_obj_t * btnRandom; + lv_obj_t * timebar; + lv_obj_t * sidebar; + lv_obj_t * timeDD1; + lv_obj_t * timeDD2; + lv_obj_t * timeAMPM; + lv_obj_t * dateDayOfWeek; + lv_obj_t * dateDay; + lv_obj_t * dateMonth; + lv_obj_t * backgroundLabel; + lv_obj_t * batteryIcon; + lv_obj_t * bleIcon; + lv_obj_t * calendarOuter; + lv_obj_t * calendarInner; + lv_obj_t * calendarBar1; + lv_obj_t * calendarBar2; + lv_obj_t * calendarCrossBar1; + lv_obj_t * calendarCrossBar2; + lv_obj_t * stepGauge; + lv_color_t needle_colors[1]; + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp index faa843e6..bec7972b 100644 --- a/src/displayapp/screens/settings/SettingSteps.cpp +++ b/src/displayapp/screens/settings/SettingSteps.cpp @@ -70,11 +70,6 @@ SettingSteps::~SettingSteps() { settingsController.SaveSettings(); } -bool SettingSteps::Refresh() { - return running; -} - - void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) { uint32_t value = settingsController.GetStepsGoal(); if(object == btnPlus && (event == LV_EVENT_PRESSED)) { @@ -95,4 +90,4 @@ void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) { } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingSteps.h b/src/displayapp/screens/settings/SettingSteps.h index 0a4c2056..5fc05dee 100644 --- a/src/displayapp/screens/settings/SettingSteps.h +++ b/src/displayapp/screens/settings/SettingSteps.h @@ -10,22 +10,19 @@ namespace Pinetime { namespace Applications { namespace Screens { - class SettingSteps : public Screen{ - public: - SettingSteps(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); - ~SettingSteps() override; + class SettingSteps : public Screen { + public: + SettingSteps(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + ~SettingSteps() override; - bool Refresh() override; - void UpdateSelected(lv_obj_t *object, lv_event_t event); - - private: + void UpdateSelected(lv_obj_t* object, lv_event_t event); - Controllers::Settings& settingsController; + private: + Controllers::Settings& settingsController; - lv_obj_t * stepValue; - lv_obj_t * btnPlus; - lv_obj_t * btnMinus; - + lv_obj_t* stepValue; + lv_obj_t* btnPlus; + lv_obj_t* btnMinus; }; } } diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp index 031a2a72..c99e3a0e 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.cpp +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -64,10 +64,6 @@ SettingTimeFormat::~SettingTimeFormat() { settingsController.SaveSettings(); } -bool SettingTimeFormat::Refresh() { - return running; -} - void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (event == LV_EVENT_VALUE_CHANGED) { for (int i = 0; i < optionsTotal; i++) { @@ -86,4 +82,4 @@ void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { } } } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h index 9203b45b..eac4bdc9 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.h +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingTimeFormat(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingTimeFormat() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index cce9a60d..d999004b 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -72,10 +72,6 @@ SettingWakeUp::~SettingWakeUp() { settingsController.SaveSettings(); } -bool SettingWakeUp::Refresh() { - return running; -} - void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) { using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode; if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) { diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 248dd9ac..b9a31dc9 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingWakeUp(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWakeUp() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index 02b90816..cdec704c 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -75,10 +75,6 @@ SettingWatchFace::~SettingWatchFace() { settingsController.SaveSettings(); } -bool SettingWatchFace::Refresh() { - return running; -} - void SettingWatchFace::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (event == LV_EVENT_VALUE_CHANGED) { for (uint8_t i = 0; i < optionsTotal; i++) { diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 1930a228..d4a96c6d 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -15,7 +15,6 @@ namespace Pinetime { SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWatchFace() override; - bool Refresh() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); private: diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index 0ab21377..f82b03c1 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -18,6 +18,9 @@ Settings::Settings(Pinetime::Applications::DisplayApp* app, Pinetime::Controller }, [this]() -> std::unique_ptr { return CreateScreen2(); + }, + [this]() -> std::unique_ptr { + return CreateScreen3(); }}, Screens::ScreenListModes::UpDown} { } @@ -26,13 +29,6 @@ Settings::~Settings() { lv_obj_clean(lv_scr_act()); } -bool Settings::Refresh() { - - if (running) - running = screens.Refresh(); - return running; -} - bool Settings::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } @@ -46,7 +42,7 @@ std::unique_ptr Settings::CreateScreen1() { {Symbols::home, "Watch face", Apps::SettingWatchFace}, }}; - return std::make_unique(0, 2, app, settingsController, applications); + return std::make_unique(0, 3, app, settingsController, applications); } std::unique_ptr Settings::CreateScreen2() { @@ -58,5 +54,17 @@ std::unique_ptr Settings::CreateScreen2() { {Symbols::list, "About", Apps::SysInfo}, }}; - return std::make_unique(1, 2, app, settingsController, applications); + return std::make_unique(1, 3, app, settingsController, applications); +} + +std::unique_ptr Settings::CreateScreen3() { + + std::array applications {{ + {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None}, + }}; + + return std::make_unique(2, 3, app, settingsController, applications); } diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index 711a6be6..6c54cdeb 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -14,17 +14,16 @@ namespace Pinetime { Settings(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~Settings() override; - bool Refresh() override; - bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; private: Controllers::Settings& settingsController; - ScreenList<2> screens; + ScreenList<3> screens; std::unique_ptr CreateScreen1(); std::unique_ptr CreateScreen2(); + std::unique_ptr CreateScreen3(); }; } } diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index b039ab0f..1ff163b0 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -41,38 +41,40 @@ void Cst816S::Init() { */ static constexpr uint8_t motionMask = 0b00000101; twiMaster.Write(twiAddress, 0xEC, &motionMask, 1); + + /* + [7] EnTest - Interrupt pin to test, enable automatic periodic issued after a low pulse. + [6] EnTouch - When a touch is detected, a periodic pulsed Low. + [5] EnChange - Upon detecting a touch state changes, pulsed Low. + [4] EnMotion - When the detected gesture is pulsed Low. + [0] OnceWLP - Press gesture only issue a pulse signal is low. + */ + static constexpr uint8_t irqCtl = 0b01110000; + twiMaster.Write(twiAddress, 0xFA, &irqCtl, 1); } Cst816S::TouchInfos Cst816S::GetTouchInfo() { Cst816S::TouchInfos info; auto ret = twiMaster.Read(twiAddress, 0, touchData, sizeof(touchData)); - if (ret != TwiMaster::ErrorCodes::NoError) - return {}; + if (ret != TwiMaster::ErrorCodes::NoError) { + info.isValid = false; + return info; + } auto nbTouchPoints = touchData[2] & 0x0f; - uint8_t i = 0; - - uint8_t pointId = (touchData[touchIdIndex + (touchStep * i)]) >> 4; - if (nbTouchPoints == 0 && pointId == lastTouchId) - return info; - - info.isTouch = true; - - auto xHigh = touchData[touchXHighIndex + (touchStep * i)] & 0x0f; - auto xLow = touchData[touchXLowIndex + (touchStep * i)]; + auto xHigh = touchData[touchXHighIndex] & 0x0f; + auto xLow = touchData[touchXLowIndex]; uint16_t x = (xHigh << 8) | xLow; - auto yHigh = touchData[touchYHighIndex + (touchStep * i)] & 0x0f; - auto yLow = touchData[touchYLowIndex + (touchStep * i)]; + auto yHigh = touchData[touchYHighIndex] & 0x0f; + auto yLow = touchData[touchYLowIndex]; uint16_t y = (yHigh << 8) | yLow; - auto action = touchData[touchEventIndex + (touchStep * i)] >> 6; /* 0 = Down, 1 = Up, 2 = contact*/ - info.x = x; info.y = y; - info.action = action; + info.touching = (nbTouchPoints > 0); info.gesture = static_cast(touchData[gestureIndex]); return info; @@ -91,4 +93,4 @@ void Cst816S::Sleep() { void Cst816S::Wakeup() { Init(); NRF_LOG_INFO("[TOUCHPANEL] Wakeup"); -} \ No newline at end of file +} diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index b6215104..7b46c5d5 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -19,12 +19,9 @@ namespace Pinetime { struct TouchInfos { uint16_t x = 0; uint16_t y = 0; - uint8_t action = 0; - uint8_t finger = 0; - uint8_t pressure = 0; - uint8_t area = 0; Gestures gesture = Gestures::None; - bool isTouch = false; + bool touching = false; + bool isValid = true; }; Cst816S(TwiMaster& twiMaster, uint8_t twiAddress); @@ -39,23 +36,23 @@ namespace Pinetime { void Wakeup(); private: - static constexpr uint8_t lastTouchId = 0x0f; + // Unused/Unavailable commented out + static constexpr uint8_t gestureIndex = 1; static constexpr uint8_t touchPointNumIndex = 2; - static constexpr uint8_t touchMiscIndex = 8; - static constexpr uint8_t touchXYIndex = 7; - static constexpr uint8_t touchEventIndex = 3; + //static constexpr uint8_t touchEventIndex = 3; static constexpr uint8_t touchXHighIndex = 3; static constexpr uint8_t touchXLowIndex = 4; + //static constexpr uint8_t touchIdIndex = 5; static constexpr uint8_t touchYHighIndex = 5; static constexpr uint8_t touchYLowIndex = 6; - static constexpr uint8_t touchIdIndex = 5; - static constexpr uint8_t touchStep = 6; - static constexpr uint8_t gestureIndex = 1; + //static constexpr uint8_t touchStep = 6; + //static constexpr uint8_t touchXYIndex = 7; + //static constexpr uint8_t touchMiscIndex = 8; - uint8_t touchData[10]; + uint8_t touchData[7]; TwiMaster& twiMaster; uint8_t twiAddress; }; } -} \ No newline at end of file +} diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index fc9edf81..76009278 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -8,45 +8,39 @@ using namespace Pinetime::Drivers; // TODO use shortcut to automatically send STOP when receive LastTX, for example // TODO use DMA/IRQ -TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} { +TwiMaster::TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl) + : module {module}, frequency {frequency}, pinSda {pinSda}, pinScl {pinScl} { +} + +void TwiMaster::ConfigurePins() const { + NRF_GPIO->PIN_CNF[pinScl] = + (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + + NRF_GPIO->PIN_CNF[pinSda] = + (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); } void TwiMaster::Init() { - if(mutex == nullptr) + if (mutex == nullptr) { mutex = xSemaphoreCreateBinary(); - - NRF_GPIO->PIN_CNF[params.pinScl] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - NRF_GPIO->PIN_CNF[params.pinSda] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - switch (module) { - case Modules::TWIM1: - twiBaseAddress = NRF_TWIM1; - break; - default: - return; } - switch (static_cast(params.frequency)) { - case Frequencies::Khz100: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100; - break; - case Frequencies::Khz250: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K250; - break; - case Frequencies::Khz400: - twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400; - break; - } + ConfigurePins(); - twiBaseAddress->PSEL.SCL = params.pinScl; - twiBaseAddress->PSEL.SDA = params.pinSda; + twiBaseAddress = module; + + twiBaseAddress->FREQUENCY = frequency; + + twiBaseAddress->PSEL.SCL = pinScl; + twiBaseAddress->PSEL.SDA = pinSda; twiBaseAddress->EVENTS_LASTRX = 0; twiBaseAddress->EVENTS_STOPPED = 0; twiBaseAddress->EVENTS_LASTTX = 0; @@ -57,19 +51,15 @@ void TwiMaster::Init() { twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); - /* // IRQ - NVIC_ClearPendingIRQ(_IRQn); - NVIC_SetPriority(_IRQn, 2); - NVIC_EnableIRQ(_IRQn); - */ - xSemaphoreGive(mutex); } TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, size_t size) { xSemaphoreTake(mutex, portMAX_DELAY); + Wakeup(); auto ret = Write(deviceAddress, ®isterAddress, 1, false); ret = Read(deviceAddress, data, size, true); + Sleep(); xSemaphoreGive(mutex); return ret; } @@ -77,9 +67,11 @@ TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAdd TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) { ASSERT(size <= maxDataSize); xSemaphoreTake(mutex, portMAX_DELAY); + Wakeup(); internalBuffer[0] = registerAddress; std::memcpy(internalBuffer + 1, data, size); auto ret = Write(deviceAddress, internalBuffer, size + 1, true); + Sleep(); xSemaphoreGive(mutex); return ret; } @@ -170,17 +162,11 @@ TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t* dat } void TwiMaster::Sleep() { - while (twiBaseAddress->ENABLE != 0) { - twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); - } - nrf_gpio_cfg_default(6); - nrf_gpio_cfg_default(7); - NRF_LOG_INFO("[TWIMASTER] Sleep"); + twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); } void TwiMaster::Wakeup() { - Init(); - NRF_LOG_INFO("[TWIMASTER] Wakeup"); + twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); } /* Sometimes, the TWIM device just freeze and never set the event EVENTS_LASTTX. @@ -190,20 +176,10 @@ void TwiMaster::Wakeup() { * */ void TwiMaster::FixHwFreezed() { NRF_LOG_INFO("I2C device frozen, reinitializing it!"); - // Disable I²C + uint32_t twi_state = NRF_TWI1->ENABLE; - twiBaseAddress->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; - NRF_GPIO->PIN_CNF[params.pinScl] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + Sleep(); - NRF_GPIO->PIN_CNF[params.pinSda] = - ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | - ((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - // Re-enable I²C twiBaseAddress->ENABLE = twi_state; -} \ No newline at end of file +} diff --git a/src/drivers/TwiMaster.h b/src/drivers/TwiMaster.h index 6175b99b..30ac6c5f 100644 --- a/src/drivers/TwiMaster.h +++ b/src/drivers/TwiMaster.h @@ -8,16 +8,9 @@ namespace Pinetime { namespace Drivers { class TwiMaster { public: - enum class Modules { TWIM1 }; - enum class Frequencies { Khz100, Khz250, Khz400 }; enum class ErrorCodes { NoError, TransactionFailed }; - struct Parameters { - uint32_t frequency; - uint8_t pinSda; - uint8_t pinScl; - }; - TwiMaster(const Modules module, const Parameters& params); + TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl); void Init(); ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); @@ -30,10 +23,14 @@ namespace Pinetime { ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); void FixHwFreezed(); + void ConfigurePins() const; + NRF_TWIM_Type* twiBaseAddress; SemaphoreHandle_t mutex = nullptr; - const Modules module; - const Parameters params; + NRF_TWIM_Type* module; + uint32_t frequency; + uint8_t pinSda; + uint8_t pinScl; static constexpr uint8_t maxDataSize {16}; static constexpr uint8_t registerSize {1}; uint8_t internalBuffer[maxDataSize + registerSize]; @@ -41,4 +38,4 @@ namespace Pinetime { static constexpr uint32_t HwFreezedDelay {161000}; }; } -} \ No newline at end of file +} diff --git a/src/main.cpp b/src/main.cpp index 4d16a6d5..441fbd95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ #include "drivers/PinMap.h" #include "systemtask/SystemTask.h" #include "drivers/PinMap.h" +#include "touchhandler/TouchHandler.h" #if NRF_LOG_ENABLED #include "logging/NrfLogger.h" @@ -77,8 +78,7 @@ Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // respecting correct timings. According to erratas heet, this magic value makes it run // at ~390Khz with correct timings. static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000}; -Pinetime::Drivers::TwiMaster twiMaster {Pinetime::Drivers::TwiMaster::Modules::TWIM1, - Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}}; +Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY static constexpr bool isFactory = true; @@ -111,6 +111,7 @@ Pinetime::Drivers::WatchdogView watchdogView(watchdog); Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; +Pinetime::Controllers::TouchHandler touchHandler(touchPanel, lvgl); Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::Settings settingsController {fs}; @@ -129,7 +130,8 @@ Pinetime::Applications::DisplayApp displayApp(lcd, settingsController, motorController, motionController, - timerController); + timerController, + touchHandler); Pinetime::System::SystemTask systemTask(spi, lcd, @@ -151,7 +153,8 @@ Pinetime::System::SystemTask systemTask(spi, heartRateController, displayApp, heartRateApp, - fs); + fs, + touchHandler); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == Pinetime::PinMap::Cst816sIrq) { @@ -316,6 +319,7 @@ int main(void) { lvgl.Init(); systemTask.Start(); + nimble_port_init(); vTaskStartScheduler(); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index c866d2fd..d48b559a 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -69,7 +69,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, Pinetime::Applications::HeartRateTask& heartRateApp, - Pinetime::Controllers::FS& fs) + Pinetime::Controllers::FS& fs, + Pinetime::Controllers::TouchHandler& touchHandler) : spi {spi}, lcd {lcd}, spiNorFlash {spiNorFlash}, @@ -81,18 +82,18 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, dateTimeController {dateTimeController}, timerController {timerController}, watchdog {watchdog}, - notificationManager{notificationManager}, + notificationManager {notificationManager}, motorController {motorController}, heartRateSensor {heartRateSensor}, motionSensor {motionSensor}, settingsController {settingsController}, - heartRateController{heartRateController}, - motionController{motionController}, - displayApp{displayApp}, + heartRateController {heartRateController}, + motionController {motionController}, + displayApp {displayApp}, heartRateApp(heartRateApp), - fs{fs}, + fs {fs}, + touchHandler {touchHandler}, nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { - } void SystemTask::Start() { @@ -118,7 +119,7 @@ void SystemTask::Work() { spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); - + fs.Init(); nimbleController.Init(); @@ -221,7 +222,6 @@ void SystemTask::Work() { break; case Messages::GoToRunning: spi.Wakeup(); - twiMaster.Wakeup(); // Double Tap needs the touch screen to be in normal mode if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { @@ -242,14 +242,14 @@ void SystemTask::Work() { isDimmed = false; break; case Messages::TouchWakeUp: { - twiMaster.Wakeup(); - auto touchInfo = touchPanel.GetTouchInfo(); - twiMaster.Sleep(); - if (touchInfo.isTouch and ((touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or - (touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) { - GoToRunning(); + if(touchHandler.GetNewTouchInfo()) { + auto gesture = touchHandler.GestureGet(); + if (gesture != Pinetime::Drivers::Cst816S::Gestures::None and ((gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or + (gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) { + GoToRunning(); + } } } break; case Messages::GoToSleep: @@ -296,6 +296,9 @@ void SystemTask::Work() { xTimerStart(dimTimer, 0); break; case Messages::OnTouchEvent: + if (touchHandler.GetNewTouchInfo()) { + touchHandler.UpdateLvglTouchPoint(); + } ReloadIdleTimer(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); break; @@ -316,7 +319,6 @@ void SystemTask::Work() { if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { touchPanel.Sleep(); } - twiMaster.Sleep(); isSleeping = true; isGoingToSleep = false; @@ -328,7 +330,7 @@ void SystemTask::Work() { break; case Messages::OnChargingEvent: motorController.RunForDuration(15); - // Battery level is updated on every message - there's no need to do anything + // Battery level is updated on every message - there's no need to do anything break; default: @@ -368,17 +370,12 @@ void SystemTask::UpdateMotion() { if (isSleeping && !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) return; - if (isSleeping) - twiMaster.Wakeup(); - if (stepCounterMustBeReset) { motionSensor.ResetStepCounter(); stepCounterMustBeReset = false; } auto motionValues = motionSensor.Process(); - if (isSleeping) - twiMaster.Sleep(); motionController.IsSensorOk(motionSensor.IsOk()); motionController.Update(motionValues.x, motionValues.y, motionValues.z, motionValues.steps); @@ -426,14 +423,13 @@ void SystemTask::PushMessage(System::Messages msg) { isGoingToSleep = true; } - if(in_isr()) { + if (in_isr()) { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { /* Actual macro used here is port specific. */ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } } else { xQueueSend(systemTasksMsgQueue, &msg, portMAX_DELAY); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index e4da6b1a..3bf72acd 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -18,6 +18,7 @@ #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" #include "components/fs/FS.h" +#include "touchhandler/TouchHandler.h" #ifdef PINETIME_IS_RECOVERY #include "displayapp/DisplayAppRecovery.h" @@ -25,7 +26,7 @@ #else #include "components/settings/Settings.h" #include "displayapp/DisplayApp.h" - #include "displayapp/LittleVgl.h" + #include "displayapp/LittleVgl.h" #endif #include "drivers/Watchdog.h" @@ -40,6 +41,9 @@ namespace Pinetime { class TwiMaster; class Hrs3300; } + namespace Controllers { + class TouchHandler; + } namespace System { class SystemTask { public: @@ -63,7 +67,8 @@ namespace Pinetime { Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, Pinetime::Applications::HeartRateTask& heartRateApp, - Pinetime::Controllers::FS& fs); + Pinetime::Controllers::FS& fs, + Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Messages msg); @@ -93,7 +98,6 @@ namespace Pinetime { Pinetime::Components::LittleVgl& lvgl; Pinetime::Controllers::Battery& batteryController; - Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::TimerController& timerController; @@ -114,6 +118,7 @@ namespace Pinetime { Pinetime::Applications::DisplayApp& displayApp; Pinetime::Applications::HeartRateTask& heartRateApp; Pinetime::Controllers::FS& fs; + Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::NimbleController nimbleController; static void Process(void* instance); diff --git a/src/touchhandler/TouchHandler.cpp b/src/touchhandler/TouchHandler.cpp new file mode 100644 index 00000000..735b311a --- /dev/null +++ b/src/touchhandler/TouchHandler.cpp @@ -0,0 +1,65 @@ +#include "TouchHandler.h" + +using namespace Pinetime::Controllers; + +TouchHandler::TouchHandler(Drivers::Cst816S& touchPanel, Components::LittleVgl& lvgl) : touchPanel {touchPanel}, lvgl {lvgl} { +} + +void TouchHandler::CancelTap() { + if (info.touching) { + isCancelled = true; + lvgl.SetNewTouchPoint(-1, -1, true); + } +} + +Pinetime::Drivers::Cst816S::Gestures TouchHandler::GestureGet() { + auto returnGesture = gesture; + gesture = Drivers::Cst816S::Gestures::None; + return returnGesture; +} + +bool TouchHandler::GetNewTouchInfo() { + info = touchPanel.GetTouchInfo(); + + if (!info.isValid) { + return false; + } + + if (info.gesture != Pinetime::Drivers::Cst816S::Gestures::None) { + if (gestureReleased) { + if (info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideDown || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideLeft || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideUp || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideRight || + info.gesture == Pinetime::Drivers::Cst816S::Gestures::LongPress) { + if (info.touching) { + gesture = info.gesture; + gestureReleased = false; + } + } else { + gesture = info.gesture; + } + } + } + + if (!info.touching) { + gestureReleased = true; + } + + return true; +} + +void TouchHandler::UpdateLvglTouchPoint() { + if (info.touching) { + if (!isCancelled) { + lvgl.SetNewTouchPoint(info.x, info.y, true); + } + } else { + if (isCancelled) { + lvgl.SetNewTouchPoint(-1, -1, false); + isCancelled = false; + } else { + lvgl.SetNewTouchPoint(info.x, info.y, false); + } + } +} diff --git a/src/touchhandler/TouchHandler.h b/src/touchhandler/TouchHandler.h new file mode 100644 index 00000000..f5442939 --- /dev/null +++ b/src/touchhandler/TouchHandler.h @@ -0,0 +1,45 @@ +#pragma once +#include "drivers/Cst816s.h" +#include "systemtask/SystemTask.h" +#include +#include + +namespace Pinetime { + namespace Components { + class LittleVgl; + } + namespace Drivers { + class Cst816S; + } + namespace System { + class SystemTask; + } + namespace Controllers { + class TouchHandler { + public: + explicit TouchHandler(Drivers::Cst816S&, Components::LittleVgl&); + void CancelTap(); + bool GetNewTouchInfo(); + void UpdateLvglTouchPoint(); + + bool IsTouching() const { + return info.touching; + } + uint8_t GetX() const { + return info.x; + } + uint8_t GetY() const { + return info.y; + } + Drivers::Cst816S::Gestures GestureGet(); + private: + + Pinetime::Drivers::Cst816S::TouchInfos info; + Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Drivers::Cst816S::Gestures gesture; + bool isCancelled = false; + bool gestureReleased = true; + }; + } +}