From d13dd6dee3e6194a2f3ed2a1adfbbd32ced525a3 Mon Sep 17 00:00:00 2001 From: Florian Kraupa Date: Wed, 12 May 2021 20:23:04 +0200 Subject: [PATCH 01/31] implemented continuous vibration pattern for incoming calls --- src/components/motor/MotorController.cpp | 36 ++++++++++++++--- src/components/motor/MotorController.h | 7 +++- src/displayapp/DisplayApp.cpp | 4 +- src/displayapp/screens/Notifications.cpp | 39 +++++++++++++------ src/displayapp/screens/Notifications.h | 8 +++- .../screens/settings/QuickSettings.cpp | 2 +- src/systemtask/SystemTask.cpp | 6 ++- 7 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index a834ab6b..2a14f4b5 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -3,7 +3,8 @@ #include "systemtask/SystemTask.h" #include "app_timer.h" -APP_TIMER_DEF(vibTimer); +APP_TIMER_DEF(shortVibTimer); +APP_TIMER_DEF(longVibTimer); using namespace Pinetime::Controllers; @@ -14,19 +15,42 @@ void MotorController::Init() { nrf_gpio_cfg_output(pinMotor); nrf_gpio_pin_set(pinMotor); app_timer_init(); - app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); + + app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); + app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, vibrate); + isBusy = false; } -void MotorController::SetDuration(uint8_t motorDuration) { +void MotorController::RunForDuration(uint8_t motorDuration) { - if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy) return; nrf_gpio_pin_clear(pinMotor); /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ - app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); + app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), NULL); +} + +void MotorController::startRunning(uint8_t motorDuration) { + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy ) + return; + //prevent other vibrations while running + isBusy = true; + nrf_gpio_pin_clear(pinMotor); + app_timer_start(longVibTimer, APP_TIMER_TICKS(motorDuration), NULL); +} + +void MotorController::stopRunning() { + + app_timer_stop(longVibTimer); + nrf_gpio_pin_set(pinMotor); + isBusy = false; } void MotorController::vibrate(void* p_context) { - nrf_gpio_pin_set(pinMotor); + if (nrf_gpio_pin_out_read(pinMotor) == 0) { + nrf_gpio_pin_set(pinMotor); + } else { + nrf_gpio_pin_clear(pinMotor); + } } \ No newline at end of file diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index df61af78..be076ad4 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -12,11 +12,14 @@ namespace Pinetime { public: MotorController(Controllers::Settings& settingsController); void Init(); - void SetDuration(uint8_t motorDuration); + void RunForDuration(uint8_t motorDuration); + void startRunning(uint8_t motorDuration); + void stopRunning(); private: Controllers::Settings& settingsController; static void vibrate(void* p_context); - }; + bool isBusy; + }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index a6c4a3ec..731f3d08 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -256,12 +256,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Notifications: currentScreen = std::make_unique( - this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique( - this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index f0fd2f66..482247e6 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -11,8 +11,13 @@ extern lv_font_t jetbrains_mono_bold_20; Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Controllers::MotorController& motorController, Modes mode) - : Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, mode {mode} { + : Screen(app), + notificationManager {notificationManager}, + alertNotificationService {alertNotificationService}, + motorController{motorController}, + mode {mode} { notificationManager.ClearNewNotificationFlag(); auto notification = notificationManager.GetLastNotification(); if (notification.valid) { @@ -23,7 +28,8 @@ Notifications::Notifications(DisplayApp* app, notification.category, notificationManager.NbNotifications(), mode, - alertNotificationService); + alertNotificationService, + motorController); validDisplay = true; } else { currentItem = std::make_unique("Notification", @@ -32,10 +38,13 @@ Notifications::Notifications(DisplayApp* app, notification.category, notificationManager.NbNotifications(), Modes::Preview, - alertNotificationService); + alertNotificationService, + motorController); } if (mode == Modes::Preview) { + + timeoutLine = lv_line_create(lv_scr_act(), nullptr); @@ -63,7 +72,10 @@ bool Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } - + //make sure we stop any vibrations before exiting + if (!running) { + motorController.stopRunning(); + } return running; } @@ -92,7 +104,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { previousNotification.category, notificationManager.NbNotifications(), mode, - alertNotificationService); + alertNotificationService, + motorController); } return true; case Pinetime::Applications::TouchEvents::SwipeUp: { @@ -117,7 +130,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { nextNotification.category, notificationManager.NbNotifications(), mode, - alertNotificationService); + alertNotificationService, + motorController); } return true; case Pinetime::Applications::TouchEvents::LongTap: { @@ -152,8 +166,9 @@ Notifications::NotificationItem::NotificationItem(const char* title, Controllers::NotificationManager::Categories category, uint8_t notifNb, Modes mode, - Pinetime::Controllers::AlertNotificationService& alertNotificationService) - : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { + Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Controllers::MotorController& motorController) + : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService}, motorController{motorController} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); @@ -236,8 +251,10 @@ Notifications::NotificationItem::NotificationItem(const char* title, label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text(label_mute, Symbols::volumMute); lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + } break; } + lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); @@ -249,21 +266,21 @@ Notifications::NotificationItem::NotificationItem(const char* title, void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - + motorController.stopRunning(); alertNotificationService.AcceptIncomingCall(); } void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - + motorController.stopRunning(); alertNotificationService.MuteIncomingCall(); } void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - + motorController.stopRunning(); alertNotificationService.RejectIncomingCall(); } diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 51ca81da..ae83e8ee 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -5,6 +5,7 @@ #include #include "Screen.h" #include "components/ble/NotificationManager.h" +#include "components/motor/MotorController.h" namespace Pinetime { namespace Controllers { @@ -19,6 +20,7 @@ namespace Pinetime { explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Controllers::MotorController& motorController, Modes mode); ~Notifications() override; @@ -33,7 +35,8 @@ namespace Pinetime { Controllers::NotificationManager::Categories, uint8_t notifNb, Modes mode, - Pinetime::Controllers::AlertNotificationService& alertNotificationService); + Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Controllers::MotorController& motorController); ~NotificationItem(); bool Refresh() { return false; @@ -60,6 +63,7 @@ namespace Pinetime { lv_obj_t* bottomPlaceholder; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; + Controllers::MotorController& motorController; }; private: @@ -72,6 +76,8 @@ namespace Pinetime { Modes mode = Modes::Normal; std::unique_ptr currentItem; Controllers::NotificationManager::Notification::Id currentId; + Controllers::MotorController& motorController; + bool validDisplay = false; lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}}; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 3994794d..7681546f 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -140,7 +140,7 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); - motorController.SetDuration(35); + motorController.RunForDuration(35); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); } else { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 6d695e2c..0d43b2f3 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -225,7 +225,11 @@ void SystemTask::Work() { case Messages::OnNewNotification: if (isSleeping && !isWakingUp) GoToRunning(); - motorController.SetDuration(35); + if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) { + motorController.startRunning(50); + } else { + motorController.RunForDuration(35); + } displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; case Messages::BleConnected: From 5da65494b3da1a69d08f7b7e6c5242f6ce666e32 Mon Sep 17 00:00:00 2001 From: Florian Kraupa Date: Thu, 13 May 2021 00:08:40 +0200 Subject: [PATCH 02/31] only activate the timeout on call notification previews after they have been interacted with --- src/displayapp/screens/Notifications.cpp | 35 ++++++++++++++++-------- src/displayapp/screens/Notifications.h | 8 ++++-- src/systemtask/SystemTask.cpp | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 482247e6..60349a64 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -29,7 +29,8 @@ Notifications::Notifications(DisplayApp* app, notificationManager.NbNotifications(), mode, alertNotificationService, - motorController); + motorController, + &timeoutTickCountEnd); validDisplay = true; } else { currentItem = std::make_unique("Notification", @@ -39,7 +40,8 @@ Notifications::Notifications(DisplayApp* app, notificationManager.NbNotifications(), Modes::Preview, alertNotificationService, - motorController); + motorController, + &timeoutTickCountEnd); } if (mode == Modes::Preview) { @@ -63,7 +65,7 @@ Notifications::~Notifications() { } bool Notifications::Refresh() { - if (mode == Modes::Preview) { + if (mode == Modes::Preview && !currentItem->timeoutOnHold) { auto tick = xTaskGetTickCount(); int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240)); if (pos < 0) @@ -105,7 +107,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { notificationManager.NbNotifications(), mode, alertNotificationService, - motorController); + motorController, + &timeoutTickCountEnd); } return true; case Pinetime::Applications::TouchEvents::SwipeUp: { @@ -131,7 +134,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { notificationManager.NbNotifications(), mode, alertNotificationService, - motorController); + motorController, + &timeoutTickCountEnd); } return true; case Pinetime::Applications::TouchEvents::LongTap: { @@ -167,8 +171,10 @@ Notifications::NotificationItem::NotificationItem(const char* title, uint8_t notifNb, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController) - : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService}, motorController{motorController} { + Controllers::MotorController& motorController, + uint32_t* timeoutEnd) + : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService}, + motorController{motorController}, timeoutEnd{timeoutEnd} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); @@ -251,7 +257,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text(label_mute, Symbols::volumMute); lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - + timeoutOnHold = true; } break; } @@ -266,24 +272,31 @@ Notifications::NotificationItem::NotificationItem(const char* title, void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - motorController.stopRunning(); + callPreviewInteraction(); alertNotificationService.AcceptIncomingCall(); } void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - motorController.stopRunning(); + callPreviewInteraction(); alertNotificationService.MuteIncomingCall(); } void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { if (event != LV_EVENT_CLICKED) return; - motorController.stopRunning(); + callPreviewInteraction(); alertNotificationService.RejectIncomingCall(); } +inline void Notifications::NotificationItem::callPreviewInteraction() { + *timeoutEnd = xTaskGetTickCount() + (5 * 1024); + timeoutOnHold = false; + motorController.stopRunning(); +} + + Notifications::NotificationItem::~NotificationItem() { lv_obj_clean(lv_scr_act()); } diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index ae83e8ee..89b676ec 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -36,7 +36,8 @@ namespace Pinetime { uint8_t notifNb, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController); + Controllers::MotorController& motorController, + uint32_t* timeoutEnd); ~NotificationItem(); bool Refresh() { return false; @@ -44,8 +45,10 @@ namespace Pinetime { void OnAcceptIncomingCall(lv_event_t event); void OnMuteIncomingCall(lv_event_t event); void OnRejectIncomingCall(lv_event_t event); - + bool timeoutOnHold = false; private: + void callPreviewInteraction(); + uint8_t notifNr = 0; uint8_t notifNb = 0; char pageText[4]; @@ -61,6 +64,7 @@ namespace Pinetime { lv_obj_t* label_mute; lv_obj_t* label_reject; lv_obj_t* bottomPlaceholder; + uint32_t* timeoutEnd; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; Controllers::MotorController& motorController; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 0d43b2f3..2b5e7bbb 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -226,7 +226,7 @@ void SystemTask::Work() { if (isSleeping && !isWakingUp) GoToRunning(); if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) { - motorController.startRunning(50); + motorController.startRunning(500); } else { motorController.RunForDuration(35); } From 56af4a0b830cd93ff12753042cdf105b65d0bcc8 Mon Sep 17 00:00:00 2001 From: Florian Kraupa Date: Thu, 13 May 2021 00:35:36 +0200 Subject: [PATCH 03/31] cleaned up the code and reduced the size of the diff by removing things like additional whitespaces --- src/components/motor/MotorController.cpp | 2 +- src/components/motor/MotorController.h | 2 +- src/displayapp/screens/Notifications.cpp | 23 ++++++++----------- src/displayapp/screens/Notifications.h | 2 +- .../screens/settings/QuickSettings.cpp | 2 +- src/systemtask/SystemTask.cpp | 2 +- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 2a14f4b5..6f02a583 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -21,7 +21,7 @@ void MotorController::Init() { isBusy = false; } -void MotorController::RunForDuration(uint8_t motorDuration) { +void MotorController::runForDuration(uint8_t motorDuration) { if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy) return; diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index be076ad4..5daeb8ce 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -12,7 +12,7 @@ namespace Pinetime { public: MotorController(Controllers::Settings& settingsController); void Init(); - void RunForDuration(uint8_t motorDuration); + void runForDuration(uint8_t motorDuration); void startRunning(uint8_t motorDuration); void stopRunning(); diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 60349a64..e4abc67b 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -13,11 +13,11 @@ Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Controllers::MotorController& motorController, Modes mode) - : Screen(app), - notificationManager {notificationManager}, - alertNotificationService {alertNotificationService}, - motorController{motorController}, - mode {mode} { + : Screen(app), + notificationManager{notificationManager}, + alertNotificationService{alertNotificationService}, + motorController{motorController}, + mode{mode} { notificationManager.ClearNewNotificationFlag(); auto notification = notificationManager.GetLastNotification(); if (notification.valid) { @@ -45,8 +45,6 @@ Notifications::Notifications(DisplayApp* app, } if (mode == Modes::Preview) { - - timeoutLine = lv_line_create(lv_scr_act(), nullptr); @@ -75,9 +73,8 @@ bool Notifications::Refresh() { lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } //make sure we stop any vibrations before exiting - if (!running) { + if (!running) motorController.stopRunning(); - } return running; } @@ -173,9 +170,8 @@ Notifications::NotificationItem::NotificationItem(const char* title, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Controllers::MotorController& motorController, uint32_t* timeoutEnd) - : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService}, - motorController{motorController}, timeoutEnd{timeoutEnd} { - + : notifNr{notifNr}, notifNb{notifNb}, mode{mode}, alertNotificationService{alertNotificationService}, + motorController{motorController}, timeoutEnd{timeoutEnd} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); @@ -260,7 +256,6 @@ Notifications::NotificationItem::NotificationItem(const char* title, timeoutOnHold = true; } break; } - lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); @@ -291,7 +286,7 @@ void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { } inline void Notifications::NotificationItem::callPreviewInteraction() { - *timeoutEnd = xTaskGetTickCount() + (5 * 1024); + *timeoutEnd = xTaskGetTickCount() + (5 * 1024); timeoutOnHold = false; motorController.stopRunning(); } diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 89b676ec..99c95a8e 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -45,6 +45,7 @@ namespace Pinetime { void OnAcceptIncomingCall(lv_event_t event); void OnMuteIncomingCall(lv_event_t event); void OnRejectIncomingCall(lv_event_t event); + bool timeoutOnHold = false; private: void callPreviewInteraction(); @@ -81,7 +82,6 @@ namespace Pinetime { std::unique_ptr currentItem; Controllers::NotificationManager::Notification::Id currentId; Controllers::MotorController& motorController; - bool validDisplay = false; lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}}; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 7681546f..501aee4f 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -140,7 +140,7 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); - motorController.RunForDuration(35); + motorController.runForDuration(35); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); } else { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 2b5e7bbb..24fe4f4c 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -228,7 +228,7 @@ void SystemTask::Work() { if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) { motorController.startRunning(500); } else { - motorController.RunForDuration(35); + motorController.runForDuration(35); } displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; From 9e8dd9a1e63523f4e3ed322978e5b5e079c50375 Mon Sep 17 00:00:00 2001 From: Florian Kraupa Date: Thu, 13 May 2021 01:51:43 +0200 Subject: [PATCH 04/31] NotificationItem now also redefines the start of the timeout --- src/displayapp/screens/Notifications.cpp | 20 +++++++++++++------- src/displayapp/screens/Notifications.h | 4 +++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index e4abc67b..e393e7b9 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -30,7 +30,8 @@ Notifications::Notifications(DisplayApp* app, mode, alertNotificationService, motorController, - &timeoutTickCountEnd); + &timeoutTickCountEnd, + &timeoutTickCountStart); validDisplay = true; } else { currentItem = std::make_unique("Notification", @@ -41,7 +42,8 @@ Notifications::Notifications(DisplayApp* app, Modes::Preview, alertNotificationService, motorController, - &timeoutTickCountEnd); + &timeoutTickCountEnd, + &timeoutTickCountStart); } if (mode == Modes::Preview) { @@ -105,7 +107,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { mode, alertNotificationService, motorController, - &timeoutTickCountEnd); + &timeoutTickCountEnd, + &timeoutTickCountStart); } return true; case Pinetime::Applications::TouchEvents::SwipeUp: { @@ -132,7 +135,8 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { mode, alertNotificationService, motorController, - &timeoutTickCountEnd); + &timeoutTickCountEnd, + &timeoutTickCountStart); } return true; case Pinetime::Applications::TouchEvents::LongTap: { @@ -169,9 +173,10 @@ Notifications::NotificationItem::NotificationItem(const char* title, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Controllers::MotorController& motorController, - uint32_t* timeoutEnd) + uint32_t* timeoutEnd, + uint32_t* timeoutStart) : notifNr{notifNr}, notifNb{notifNb}, mode{mode}, alertNotificationService{alertNotificationService}, - motorController{motorController}, timeoutEnd{timeoutEnd} { + motorController{motorController}, timeoutEnd{timeoutEnd}, timeoutStart{timeoutStart} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); @@ -286,7 +291,8 @@ void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { } inline void Notifications::NotificationItem::callPreviewInteraction() { - *timeoutEnd = xTaskGetTickCount() + (5 * 1024); + *timeoutStart = xTaskGetTickCount(); + *timeoutEnd = *timeoutStart + (5 * 1024); timeoutOnHold = false; motorController.stopRunning(); } diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 99c95a8e..32bd0770 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -37,7 +37,8 @@ namespace Pinetime { Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService, Controllers::MotorController& motorController, - uint32_t* timeoutEnd); + uint32_t* timeoutEnd, + uint32_t* timeoutStart); ~NotificationItem(); bool Refresh() { return false; @@ -66,6 +67,7 @@ namespace Pinetime { lv_obj_t* label_reject; lv_obj_t* bottomPlaceholder; uint32_t* timeoutEnd; + uint32_t* timeoutStart; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; Controllers::MotorController& motorController; From e6dcb3009fe6f847a7486dbb1b3143bbf49a15b9 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 1 Aug 2021 13:05:48 +0300 Subject: [PATCH 05/31] Improvements --- src/components/motor/MotorController.cpp | 40 +++---- src/components/motor/MotorController.h | 12 +- src/displayapp/DisplayApp.cpp | 4 +- src/displayapp/screens/Metronome.cpp | 4 +- src/displayapp/screens/Notifications.cpp | 103 +++++------------- src/displayapp/screens/Notifications.h | 27 ++--- .../screens/settings/QuickSettings.cpp | 2 +- src/systemtask/SystemTask.cpp | 9 +- 8 files changed, 70 insertions(+), 131 deletions(-) diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 80883025..b25e6bc8 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -16,41 +16,37 @@ void MotorController::Init() { nrf_gpio_pin_set(pinMotor); app_timer_init(); - app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); - app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, vibrate); - isBusy = false; + app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); + app_timer_create(&longVibTimer, APP_TIMER_MODE_REPEATED, Ring); } -void MotorController::runForDuration(uint8_t motorDuration) { +void MotorController::Ring(void* p_context) { + auto* motorController = static_cast(p_context); + motorController->RunForDuration(50); +} - if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy) +void MotorController::RunForDuration(uint8_t motorDuration) { + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; + } nrf_gpio_pin_clear(pinMotor); - /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ - app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), NULL); + app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); } -void MotorController::startRunning(uint8_t motorDuration) { - if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF || isBusy ) +void MotorController::StartRinging() { + if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) { return; - //prevent other vibrations while running - isBusy = true; - nrf_gpio_pin_clear(pinMotor); - app_timer_start(longVibTimer, APP_TIMER_TICKS(motorDuration), NULL); + } + Ring(this); + app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); } -void MotorController::stopRunning() { - +void MotorController::StopRinging() { app_timer_stop(longVibTimer); nrf_gpio_pin_set(pinMotor); - isBusy = false; } -void MotorController::vibrate(void* p_context) { - if (nrf_gpio_pin_out_read(pinMotor) == 0) { - nrf_gpio_pin_set(pinMotor); - } else { - nrf_gpio_pin_clear(pinMotor); - } +void MotorController::StopMotor(void* p_context) { + nrf_gpio_pin_set(pinMotor); } diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index 5daeb8ce..d2c9fe5f 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -12,14 +12,14 @@ namespace Pinetime { public: MotorController(Controllers::Settings& settingsController); void Init(); - void runForDuration(uint8_t motorDuration); - void startRunning(uint8_t motorDuration); - void stopRunning(); + void RunForDuration(uint8_t motorDuration); + void StartRinging(); + static void StopRinging(); private: + static void Ring(void* p_context); Controllers::Settings& settingsController; - static void vibrate(void* p_context); - bool isBusy; - }; + static void StopMotor(void* p_context); + }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index bdd703ee..d4a73f5e 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -336,12 +336,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Notifications: currentScreen = std::make_unique( - this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique( - this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::Timer: diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 7bfbccb7..16c34f45 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -109,9 +109,9 @@ bool Metronome::Refresh() { startTime = xTaskGetTickCount(); if (counter == 0) { counter = bpb; - motorController.SetDuration(90); + motorController.RunForDuration(90); } else { - motorController.SetDuration(30); + motorController.RunForDuration(30); } } break; diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 5eecb421..5096917e 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -11,13 +11,8 @@ extern lv_font_t jetbrains_mono_bold_20; Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController, Modes mode) - : Screen(app), - notificationManager{notificationManager}, - alertNotificationService{alertNotificationService}, - motorController{motorController}, - mode{mode} { + : Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, mode {mode} { notificationManager.ClearNewNotificationFlag(); auto notification = notificationManager.GetLastNotification(); if (notification.valid) { @@ -28,10 +23,7 @@ Notifications::Notifications(DisplayApp* app, notification.category, notificationManager.NbNotifications(), mode, - alertNotificationService, - motorController, - &timeoutTickCountEnd, - &timeoutTickCountStart); + alertNotificationService); validDisplay = true; } else { currentItem = std::make_unique("Notification", @@ -40,14 +32,10 @@ Notifications::Notifications(DisplayApp* app, notification.category, notificationManager.NbNotifications(), Modes::Preview, - alertNotificationService, - motorController, - &timeoutTickCountEnd, - &timeoutTickCountStart); + alertNotificationService); } - if (mode == Modes::Preview) { - + if (mode == Modes::Preview && notification.category != Controllers::NotificationManager::Categories::IncomingCall) { timeoutLine = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); @@ -61,11 +49,13 @@ Notifications::Notifications(DisplayApp* app, } Notifications::~Notifications() { + // make sure we stop any vibrations before exiting + Controllers::MotorController::StopRinging(); lv_obj_clean(lv_scr_act()); } bool Notifications::Refresh() { - if (mode == Modes::Preview && !currentItem->timeoutOnHold) { + if (mode == Modes::Preview && timeoutLine != nullptr) { auto tick = xTaskGetTickCount(); int32_t pos = 240 - ((tick - timeoutTickCountStart) / ((timeoutTickCountEnd - timeoutTickCountStart) / 240)); if (pos < 0) @@ -74,10 +64,7 @@ bool Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); } - //make sure we stop any vibrations before exiting - if (!running) - motorController.stopRunning(); - return running; + return running && currentItem->IsRunning(); } bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { @@ -105,10 +92,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { previousNotification.category, notificationManager.NbNotifications(), mode, - alertNotificationService, - motorController, - &timeoutTickCountEnd, - &timeoutTickCountStart); + alertNotificationService); } return true; case Pinetime::Applications::TouchEvents::SwipeUp: { @@ -133,10 +117,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { nextNotification.category, notificationManager.NbNotifications(), mode, - alertNotificationService, - motorController, - &timeoutTickCountEnd, - &timeoutTickCountStart); + alertNotificationService); } return true; case Pinetime::Applications::TouchEvents::LongTap: { @@ -149,19 +130,9 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } namespace { - static void AcceptIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { + void CallEventHandler(lv_obj_t* obj, lv_event_t event) { auto* item = static_cast(obj->user_data); - item->OnAcceptIncomingCall(event); - } - - static void MuteIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { - auto* item = static_cast(obj->user_data); - item->OnMuteIncomingCall(event); - } - - static void RejectIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { - auto* item = static_cast(obj->user_data); - item->OnRejectIncomingCall(event); + item->OnCallButtonEvent(obj, event); } } @@ -171,12 +142,8 @@ Notifications::NotificationItem::NotificationItem(const char* title, Controllers::NotificationManager::Categories category, uint8_t notifNb, Modes mode, - Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController, - uint32_t* timeoutEnd, - uint32_t* timeoutStart) - : notifNr{notifNr}, notifNb{notifNb}, mode{mode}, alertNotificationService{alertNotificationService}, - motorController{motorController}, timeoutEnd{timeoutEnd}, timeoutStart{timeoutStart} { + Pinetime::Controllers::AlertNotificationService& alertNotificationService) + : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); @@ -234,7 +201,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_accept = lv_btn_create(lv_scr_act(), nullptr); bt_accept->user_data = this; - lv_obj_set_event_cb(bt_accept, AcceptIncomingCallEventHandler); + lv_obj_set_event_cb(bt_accept, CallEventHandler); lv_obj_set_size(bt_accept, 76, 76); lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); label_accept = lv_label_create(bt_accept, nullptr); @@ -243,7 +210,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_reject = lv_btn_create(lv_scr_act(), nullptr); bt_reject->user_data = this; - lv_obj_set_event_cb(bt_reject, RejectIncomingCallEventHandler); + lv_obj_set_event_cb(bt_reject, CallEventHandler); lv_obj_set_size(bt_reject, 76, 76); lv_obj_align(bt_reject, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); label_reject = lv_label_create(bt_reject, nullptr); @@ -252,13 +219,12 @@ Notifications::NotificationItem::NotificationItem(const char* title, bt_mute = lv_btn_create(lv_scr_act(), nullptr); bt_mute->user_data = this; - lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler); + lv_obj_set_event_cb(bt_mute, CallEventHandler); lv_obj_set_size(bt_mute, 76, 76); lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text(label_mute, Symbols::volumMute); lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - timeoutOnHold = true; } break; } @@ -269,35 +235,24 @@ Notifications::NotificationItem::NotificationItem(const char* title, lv_label_set_text(backgroundLabel, ""); } -void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) +void Notifications::NotificationItem::OnCallButtonEvent(lv_obj_t* obj, lv_event_t event) { + if (event != LV_EVENT_CLICKED) { return; - callPreviewInteraction(); - alertNotificationService.AcceptIncomingCall(); -} + } -void Notifications::NotificationItem::OnMuteIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; - callPreviewInteraction(); - alertNotificationService.MuteIncomingCall(); -} + Controllers::MotorController::StopRinging(); -void Notifications::NotificationItem::OnRejectIncomingCall(lv_event_t event) { - if (event != LV_EVENT_CLICKED) - return; - callPreviewInteraction(); - alertNotificationService.RejectIncomingCall(); -} + if (obj == bt_accept) { + alertNotificationService.AcceptIncomingCall(); + } else if (obj == bt_reject) { + alertNotificationService.RejectIncomingCall(); + } else if (obj == bt_mute) { + alertNotificationService.MuteIncomingCall(); + } -inline void Notifications::NotificationItem::callPreviewInteraction() { - *timeoutStart = xTaskGetTickCount(); - *timeoutEnd = *timeoutStart + (5 * 1024); - timeoutOnHold = false; - motorController.stopRunning(); + running = false; } - Notifications::NotificationItem::~NotificationItem() { lv_obj_clean(lv_scr_act()); } diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 32bd0770..9244e9fa 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -5,7 +5,6 @@ #include #include "Screen.h" #include "components/ble/NotificationManager.h" -#include "components/motor/MotorController.h" namespace Pinetime { namespace Controllers { @@ -20,7 +19,6 @@ namespace Pinetime { explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController, Modes mode); ~Notifications() override; @@ -35,22 +33,14 @@ namespace Pinetime { Controllers::NotificationManager::Categories, uint8_t notifNb, Modes mode, - Pinetime::Controllers::AlertNotificationService& alertNotificationService, - Controllers::MotorController& motorController, - uint32_t* timeoutEnd, - uint32_t* timeoutStart); + Pinetime::Controllers::AlertNotificationService& alertNotificationService); ~NotificationItem(); - bool Refresh() { - return false; + bool IsRunning() const { + return running; } - void OnAcceptIncomingCall(lv_event_t event); - void OnMuteIncomingCall(lv_event_t event); - void OnRejectIncomingCall(lv_event_t event); - - bool timeoutOnHold = false; + void OnCallButtonEvent(lv_obj_t*, lv_event_t event); + private: - void callPreviewInteraction(); - uint8_t notifNr = 0; uint8_t notifNb = 0; char pageText[4]; @@ -66,11 +56,9 @@ namespace Pinetime { lv_obj_t* label_mute; lv_obj_t* label_reject; lv_obj_t* bottomPlaceholder; - uint32_t* timeoutEnd; - uint32_t* timeoutStart; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; - Controllers::MotorController& motorController; + bool running = true; }; private: @@ -83,11 +71,10 @@ namespace Pinetime { Modes mode = Modes::Normal; std::unique_ptr currentItem; Controllers::NotificationManager::Notification::Id currentId; - Controllers::MotorController& motorController; bool validDisplay = false; lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}}; - lv_obj_t* timeoutLine; + lv_obj_t* timeoutLine = nullptr; uint32_t timeoutTickCountStart; uint32_t timeoutTickCountEnd; }; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 5e46e2e5..0421d103 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -140,7 +140,7 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) { if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::ON); - motorController.runForDuration(35); + motorController.RunForDuration(35); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); } else { settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index f05ade65..7426ac2f 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -267,16 +267,17 @@ void SystemTask::Work() { GoToRunning(); } if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) { - motorController.startRunning(500); + motorController.StartRinging(); } else { - motorController.runForDuration(35); + motorController.RunForDuration(35); } displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); + break; case Messages::OnTimerDone: if (isSleeping && !isWakingUp) { GoToRunning(); } - motorController.runForDuration(35); + motorController.RunForDuration(35); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone); break; case Messages::BleConnected: @@ -329,7 +330,7 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: - motorController.SetDuration(15); + motorController.RunForDuration(15); // Battery level is updated on every message - there's no need to do anything break; From a618f43b4d8b1d0868c37e10193d3c95ce080040 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 1 Aug 2021 14:13:32 +0300 Subject: [PATCH 06/31] Fixes --- src/displayapp/DisplayApp.cpp | 4 ++-- src/displayapp/screens/Notifications.cpp | 27 +++++++++++++++--------- src/displayapp/screens/Notifications.h | 2 ++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index d4a73f5e..bdd703ee 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -336,12 +336,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Notifications: currentScreen = std::make_unique( - this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique( - this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::Timer: diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 5096917e..c061c146 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -11,6 +11,7 @@ extern lv_font_t jetbrains_mono_bold_20; Notifications::Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Pinetime::Controllers::MotorController& motorController, Modes mode) : Screen(app), notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, mode {mode} { notificationManager.ClearNewNotificationFlag(); @@ -35,16 +36,21 @@ Notifications::Notifications(DisplayApp* app, alertNotificationService); } - if (mode == Modes::Preview && notification.category != Controllers::NotificationManager::Categories::IncomingCall) { - timeoutLine = lv_line_create(lv_scr_act(), nullptr); + if (mode == Modes::Preview) { + if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) { + motorController.StartRinging(); + } else { + motorController.RunForDuration(35); + timeoutLine = lv_line_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_obj_set_style_local_line_rounded(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + lv_obj_set_style_local_line_rounded(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); - lv_line_set_points(timeoutLine, timeoutLinePoints, 2); - timeoutTickCountStart = xTaskGetTickCount(); - timeoutTickCountEnd = timeoutTickCountStart + (5 * 1024); + lv_line_set_points(timeoutLine, timeoutLinePoints, 2); + timeoutTickCountStart = xTaskGetTickCount(); + timeoutTickCountEnd = timeoutTickCountStart + (5 * 1024); + } } } @@ -68,8 +74,9 @@ bool Notifications::Refresh() { } bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - if (mode != Modes::Normal) - return true; + if (mode != Modes::Normal) { + return false; + } switch (event) { case Pinetime::Applications::TouchEvents::SwipeDown: { diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 9244e9fa..a02d9b46 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -5,6 +5,7 @@ #include #include "Screen.h" #include "components/ble/NotificationManager.h" +#include "components/motor/MotorController.h" namespace Pinetime { namespace Controllers { @@ -19,6 +20,7 @@ namespace Pinetime { explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, + Pinetime::Controllers::MotorController& motorController, Modes mode); ~Notifications() override; From f9319dfb91a38c773b4af221f2fd0d975cf061f2 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 1 Aug 2021 21:19:33 +0300 Subject: [PATCH 07/31] Remove leftover --- src/systemtask/SystemTask.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 7426ac2f..3553f449 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -266,11 +266,6 @@ void SystemTask::Work() { if (isSleeping && !isWakingUp) { GoToRunning(); } - if (notificationManager.GetLastNotification().category == Controllers::NotificationManager::Categories::IncomingCall) { - motorController.StartRinging(); - } else { - motorController.RunForDuration(35); - } displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; case Messages::OnTimerDone: From 65423b3c945002b5828f8be3b42e27bc9c83d8b4 Mon Sep 17 00:00:00 2001 From: Niall Cooling Date: Thu, 25 Feb 2021 16:18:08 +0000 Subject: [PATCH 08/31] added devcontainer files --- .devcontainer/Dockerfile | 43 ++++++++++++++++++ .devcontainer/build.sh | 78 +++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 32 ++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100755 .devcontainer/build.sh create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..c6a3588f --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,43 @@ +FROM ubuntu:18.04 + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update -qq \ + && apt-get install -y \ +# x86_64 / generic packages + bash \ + build-essential \ + cmake \ + git \ + make \ + python3 \ + python3-pip \ + tar \ + unzip \ + wget \ + curl \ +# aarch64 packages + libffi-dev \ + libssl-dev \ + python3-dev \ + rustc \ + && rm -rf /var/cache/apt/* /var/lib/apt/lists/*; + +RUN adduser infinitime + +RUN pip3 install adafruit-nrfutil +# required for McuBoot +RUN pip3 install setuptools_rust + +WORKDIR /opt/ +# build.sh knows how to compile +COPY build.sh . + +# Lets get each in a separate docker layer for better downloads +# GCC +RUN bash -c "source /opt/build.sh; GetGcc;" +# NrfSdk +RUN bash -c "source /opt/build.sh; GetNrfSdk;" +# McuBoot +RUN bash -c "source /opt/build.sh; GetMcuBoot;" + +ENV SOURCES_DIR /workspaces/Pinetime diff --git a/.devcontainer/build.sh b/.devcontainer/build.sh new file mode 100755 index 00000000..8f0d0fa9 --- /dev/null +++ b/.devcontainer/build.sh @@ -0,0 +1,78 @@ +#!/bin/bash +(return 0 2>/dev/null) && SOURCED="true" || SOURCED="false" +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 +set -x +set -e + +# Default locations if the var isn't already set +export TOOLS_DIR="${TOOLS_DIR:=/opt}" +export SOURCES_DIR="${SOURCES_DIR:=/sources}" +export BUILD_DIR="${BUILD_DIR:=$SOURCES_DIR/build}" +export OUTPUT_DIR="${OUTPUT_DIR:=$BUILD_DIR/output}" + +export BUILD_TYPE=${BUILD_TYPE:=Release} +export GCC_ARM_VER=${GCC_ARM_VER:="gcc-arm-none-eabi-9-2020-q2-update"} +export NRF_SDK_VER=${NRF_SDK_VER:="nRF5_SDK_15.3.0_59ac345"} + +MACHINE="$(uname -m)" +[[ "$MACHINE" == "arm64" ]] && MACHINE="aarch64" + +main() { + local target="$1" + + mkdir -p "$TOOLS_DIR" + + [[ ! -d "$TOOLS_DIR/$GCC_ARM_VER" ]] && GetGcc + [[ ! -d "$TOOLS_DIR/$NRF_SDK_VER" ]] && GetNrfSdk + [[ ! -d "$TOOLS_DIR/mcuboot" ]] && GetMcuBoot + + mkdir -p "$BUILD_DIR" + + CmakeGenerate + CmakeBuild $target + BUILD_RESULT=$? + if [ "$DISABLE_POSTBUILD" != "true" -a "$BUILD_RESULT" == 0 ]; then + source "$BUILD_DIR/post_build.sh" + fi +} + +GetGcc() { + GCC_SRC="$GCC_ARM_VER-$MACHINE-linux.tar.bz" + wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/$GCC_SRC -O - | tar -xj -C $TOOLS_DIR/ +} + +GetMcuBoot() { + git clone https://github.com/JuulLabs-OSS/mcuboot.git "$TOOLS_DIR/mcuboot" + pip3 install -r "$TOOLS_DIR/mcuboot/scripts/requirements.txt" +} + +GetNrfSdk() { + wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/$NRF_SDK_VER.zip" -O /tmp/$NRF_SDK_VER + unzip -q /tmp/$NRF_SDK_VER -d "$TOOLS_DIR/" + rm /tmp/$NRF_SDK_VER +} + +CmakeGenerate() { + # We can swap the CD and trailing SOURCES_DIR for -B and -S respectively + # once we go to newer CMake (Ubuntu 18.10 gives us CMake 3.10) + cd "$BUILD_DIR" + + cmake -G "Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -DUSE_OPENOCD=1 \ + -DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_VER" \ + -DNRF5_SDK_PATH="$TOOLS_DIR/$NRF_SDK_VER" \ + "$SOURCES_DIR" + cmake -L -N . +} + +CmakeBuild() { + local target="$1" + [[ -n "$target" ]] && target="--target $target" + if cmake --build "$BUILD_DIR" --config $BUILD_TYPE $target -- -j$(nproc) + then return 0; else return 1; + fi +} + +[[ $SOURCED == "false" ]] && main "$@" || echo "Sourced!" \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fb81d289 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,32 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.2/containers/cpp +{ + // "name": "Pinetime", + // "image": "feabhas/pinetime-dev" + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04 + // "args": { "VARIANT": "ubuntu-20.04" } + }, + "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"], + + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.cpptools" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "gcc -v", + + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" + "remoteUser": "infinitime" +} \ No newline at end of file From 273a94f298cc96a1415499d00559fed3a741af71 Mon Sep 17 00:00:00 2001 From: "AzureAD\\NiallCooling" Date: Thu, 25 Feb 2021 17:16:01 +0000 Subject: [PATCH 09/31] removed dependency on build.sh --- .devcontainer/Dockerfile | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c6a3588f..7e961528 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -22,8 +22,6 @@ RUN apt-get update -qq \ rustc \ && rm -rf /var/cache/apt/* /var/lib/apt/lists/*; -RUN adduser infinitime - RUN pip3 install adafruit-nrfutil # required for McuBoot RUN pip3 install setuptools_rust @@ -34,10 +32,19 @@ COPY build.sh . # Lets get each in a separate docker layer for better downloads # GCC -RUN bash -c "source /opt/build.sh; GetGcc;" +# RUN bash -c "source /opt/build.sh; GetGcc;" +RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O - | tar -xj -C /opt +# RUN rm gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 # NrfSdk -RUN bash -c "source /opt/build.sh; GetNrfSdk;" +# RUN bash -c "source /opt/build.sh; GetNrfSdk;" +RUN wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip" -O /tmp/nRF5_SDK_15.3.0_59ac345 +RUN unzip -q /tmp/nRF5_SDK_15.3.0_59ac345 -d /opt +RUN rm /tmp/nRF5_SDK_15.3.0_59ac345 # McuBoot -RUN bash -c "source /opt/build.sh; GetMcuBoot;" +# RUN bash -c "source /opt/build.sh; GetMcuBoot;" +RUN git clone https://github.com/JuulLabs-OSS/mcuboot.git +RUN pip3 install -r ./mcuboot/scripts/requirements.txt + +RUN adduser infinitime ENV SOURCES_DIR /workspaces/Pinetime From 382db668ed513836a52ff4fdc49b0ee7a08a1527 Mon Sep 17 00:00:00 2001 From: Niall Cooling Date: Thu, 25 Feb 2021 17:49:40 +0000 Subject: [PATCH 10/31] macOS and Win10 dockerfile --- .devcontainer/Dockerfile | 5 +++-- .devcontainer/create_build_openocd.sh | 3 +++ .devcontainer/devcontainer.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100755 .devcontainer/create_build_openocd.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7e961528..2c223bc1 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -27,14 +27,15 @@ RUN pip3 install adafruit-nrfutil RUN pip3 install setuptools_rust WORKDIR /opt/ -# build.sh knows how to compile +# build.sh knows how to compile but it problimatic on Win10 COPY build.sh . +# create_build_openocd.sh uses cmake to crate to build directory +COPY create_build_openocd.sh . # Lets get each in a separate docker layer for better downloads # GCC # RUN bash -c "source /opt/build.sh; GetGcc;" RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O - | tar -xj -C /opt -# RUN rm gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 # NrfSdk # RUN bash -c "source /opt/build.sh; GetNrfSdk;" RUN wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip" -O /tmp/nRF5_SDK_15.3.0_59ac345 diff --git a/.devcontainer/create_build_openocd.sh b/.devcontainer/create_build_openocd.sh new file mode 100755 index 00000000..860ffa1f --- /dev/null +++ b/.devcontainer/create_build_openocd.sh @@ -0,0 +1,3 @@ +#!/bin/bash +rm -rf build/ +cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 -S . -Bbuild \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fb81d289..1740a8e4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,7 +24,7 @@ // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "gcc -v", + // "postCreateCommand": "/opt/create_build_openocd.sh", // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // "remoteUser": "vscode" From 937d3e19335758ac76607a1d75c8844b49dd3c3e Mon Sep 17 00:00:00 2001 From: Niall Cooling Date: Fri, 26 Feb 2021 08:14:30 +0000 Subject: [PATCH 11/31] added dos2unix to docker for Win10 and default to release build --- .devcontainer/Dockerfile | 1 + .devcontainer/create_build_openocd.sh | 2 +- .devcontainer/devcontainer.json | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2c223bc1..bb7dddba 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get update -qq \ unzip \ wget \ curl \ + dos2unix \ # aarch64 packages libffi-dev \ libssl-dev \ diff --git a/.devcontainer/create_build_openocd.sh b/.devcontainer/create_build_openocd.sh index 860ffa1f..c5bff5c8 100755 --- a/.devcontainer/create_build_openocd.sh +++ b/.devcontainer/create_build_openocd.sh @@ -1,3 +1,3 @@ #!/bin/bash rm -rf build/ -cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 -S . -Bbuild \ No newline at end of file +cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 -S . -Bbuild \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1740a8e4..90b6eceb 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -17,14 +17,15 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "ms-vscode.cpptools" + "ms-vscode.cpptools", + "ms-vscode.cmake-tools", ], // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "/opt/create_build_openocd.sh", + // "postCreateCommand": "bash /opt/create_build_openocd.sh", // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // "remoteUser": "vscode" From c50f2b70c23ff36de8f290ab0e4408be7eeed62c Mon Sep 17 00:00:00 2001 From: Niall Cooling Date: Fri, 26 Feb 2021 15:09:58 +0000 Subject: [PATCH 12/31] added clang-tidy/format to container --- .devcontainer/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index bb7dddba..55f30136 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -16,6 +16,8 @@ RUN apt-get update -qq \ wget \ curl \ dos2unix \ + clang-format \ + clang-tidy \ # aarch64 packages libffi-dev \ libssl-dev \ From c0b84537b35fd358e929962a962c53e50019079e Mon Sep 17 00:00:00 2001 From: Niall Cooling Date: Fri, 26 Mar 2021 17:37:01 +0000 Subject: [PATCH 13/31] added extra .sh build files --- .devcontainer/build_app.sh | 2 ++ .devcontainer/make_build_dir.sh | 2 ++ .vscode/c_cpp_properties.json | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 .devcontainer/build_app.sh create mode 100644 .devcontainer/make_build_dir.sh create mode 100644 .vscode/c_cpp_properties.json diff --git a/.devcontainer/build_app.sh b/.devcontainer/build_app.sh new file mode 100644 index 00000000..0f578cc6 --- /dev/null +++ b/.devcontainer/build_app.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cmake --build /workspaces/Pinetime/build --config Release -- -j6 pinetime-app \ No newline at end of file diff --git a/.devcontainer/make_build_dir.sh b/.devcontainer/make_build_dir.sh new file mode 100644 index 00000000..0b86b307 --- /dev/null +++ b/.devcontainer/make_build_dir.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 /workspaces/Pinetime diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..b409ec98 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu11", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "compileCommands": "${workspaceFolder}/build/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file From f7643a4d828ec3c60f418b6d9a660097eb44e05e Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 25 Jul 2021 20:12:34 +0000 Subject: [PATCH 14/31] Added cmake variants --- .devcontainer/Dockerfile | 17 +++++-- .devcontainer/README.md | 60 +++++++++++++++++++++++++ .devcontainer/build.sh | 0 .devcontainer/create_build_openocd.sh | 0 .devcontainer/devcontainer.json | 1 + .devcontainer/make_build_dir.sh | 2 +- .gitignore | 2 +- .vscode/c_cpp_properties.json | 15 ++++--- .vscode/cmake-variants.json | 62 +++++++++++++++++++++++++ .vscode/launch.json | 46 +++++++++++++++++++ .vscode/settings.json | 65 +++------------------------ .vscode/tasks.json | 44 ++++++++++++++++++ 12 files changed, 245 insertions(+), 69 deletions(-) create mode 100644 .devcontainer/README.md mode change 100755 => 100644 .devcontainer/build.sh mode change 100755 => 100644 .devcontainer/create_build_openocd.sh create mode 100644 .vscode/cmake-variants.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 55f30136..4534c7e2 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:18.04 +FROM ubuntu:latest ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update -qq \ @@ -18,12 +18,20 @@ RUN apt-get update -qq \ dos2unix \ clang-format \ clang-tidy \ + locales \ + libncurses5 \ # aarch64 packages libffi-dev \ libssl-dev \ python3-dev \ rustc \ && rm -rf /var/cache/apt/* /var/lib/apt/lists/*; + +#SET LOCALE +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 RUN pip3 install adafruit-nrfutil # required for McuBoot @@ -32,9 +40,10 @@ RUN pip3 install setuptools_rust WORKDIR /opt/ # build.sh knows how to compile but it problimatic on Win10 COPY build.sh . +RUN chmod +x build.sh # create_build_openocd.sh uses cmake to crate to build directory COPY create_build_openocd.sh . - +RUN chmod +x create_build_openocd.sh # Lets get each in a separate docker layer for better downloads # GCC # RUN bash -c "source /opt/build.sh; GetGcc;" @@ -51,4 +60,6 @@ RUN pip3 install -r ./mcuboot/scripts/requirements.txt RUN adduser infinitime -ENV SOURCES_DIR /workspaces/Pinetime +ENV NRF5_SDK_PATH /opt/nRF5_SDK_15.3.0_59ac345 +ENV ARM_NONE_EABI_TOOLCHAIN_PATH /opt/gcc-arm-none-eabi-9-2020-q2-update +ENV SOURCES_DIR /workspaces/InfiniTime diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..ff9307b2 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,60 @@ +# VScode devcontainer +This is a docker-based interactive development environment using VSCode and Docker Devcontainers removing the need to install any tools locally* + + + +## Requirements + +- VScode + - [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension +- Docker +- OpenOCD - For debugging + +## Using + +### Code editing, and building. + +1. Clone InifiniTime and update submodules +2. Launch VSCode +3. Open InifiTime directory, +4. Allow VSCode to open folder with devcontainer. + +After this the environment will be built if you do not currently have a container setup, it will install all the necessary tools and extra VSCode extensions. + +In order to build InfiniTime we need to run the initial submodule init and Cmake commands. + +#### Manually + + You can use the VSCode terminal to run the CMake commands as outlined in the [build instructions](blob/develop/doc/buildAndProgram.md) + +#### Script + +The dev enviroment comes with some scripts to make this easier, They are located in /opt/. + +There are also VSCode tasks provided should you desire to use those. + +The task BuildInit will update submodules and configure for openocd + + + +### Build + +You can use the build.sh script located in /opt/ + +There will also eventually be a Build task. - Not written yet + + + +### Debugging + +Docker on windows does not support passing USB devices to the underlying WSL2 subsystem, To get around this we use openocd in server mode running on the host. + +`openocd -f -f ` + +This will launch openocd in server mode and attach it to the MCU. + +The default launch.json file expects openocd to be listening on port 3333, edit if needed + + +## Current Issues +Currently WSL2 Has some real performance issues with IO on a windows host. Accessing files on the virtualized filesystem is much faster. Using VSCodes "clone in container" feature of the Remote - Containers will get around this. After the container is built you will need to update the submodules and follow the build isntructions like normal \ No newline at end of file diff --git a/.devcontainer/build.sh b/.devcontainer/build.sh old mode 100755 new mode 100644 diff --git a/.devcontainer/create_build_openocd.sh b/.devcontainer/create_build_openocd.sh old mode 100755 new mode 100644 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 90b6eceb..223b651f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,6 +19,7 @@ "extensions": [ "ms-vscode.cpptools", "ms-vscode.cmake-tools", + "marus25.cortex-debug" ], // Use 'forwardPorts' to make a list of ports inside the container available locally. diff --git a/.devcontainer/make_build_dir.sh b/.devcontainer/make_build_dir.sh index 0b86b307..76240037 100644 --- a/.devcontainer/make_build_dir.sh +++ b/.devcontainer/make_build_dir.sh @@ -1,2 +1,2 @@ #!/bin/bash -cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 /workspaces/Pinetime +cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 ${SOURCES_DIR} diff --git a/.gitignore b/.gitignore index 2f9ac181..6de76a9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ # CMake cmake-build-* -cmake-* +cmake-*/ CMakeFiles **/CMakeCache.txt cmake_install.cmake diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index b409ec98..f5c74b3a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,15 +1,18 @@ { "configurations": [ { - "name": "Linux", + "name": "nrfCC", "includePath": [ - "${workspaceFolder}/**" + "${workspaceFolder}/**", + "${workspaceFolder}/src/**", + "${workspaceFolder}/src" ], "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "gnu11", - "cppStandard": "gnu++14", - "intelliSenseMode": "linux-gcc-x64", + "compilerPath": "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc", + "cStandard": "c11", + "cppStandard": "c++14", + "intelliSenseMode": "linux-gcc-arm", + "configurationProvider": "ms-vscode.cmake-tools", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], diff --git a/.vscode/cmake-variants.json b/.vscode/cmake-variants.json new file mode 100644 index 00000000..d00e638e --- /dev/null +++ b/.vscode/cmake-variants.json @@ -0,0 +1,62 @@ +{ + "buildType": { + "default": "release", + "choices": { + "debug": { + "short": "Debug", + "long": "Emit debug information without performing optimizations", + "buildType": "Debug" + }, + "release": { + "short": "Release", + "long": "Perform optimizations", + "buildType": "Release" + } + } + }, + "programmer":{ + "default": "OpenOCD", + "choices":{ + "OpenOCD":{ + "short":"OpenOCD", + "long": "Use OpenOCD", + "settings":{ + "USE_OPENOCD":1 + } + }, + "JLink":{ + "short":"JLink", + "long": "Use JLink", + "settings":{ + "USE_JLINK":1 + } + }, + "GDB":{ + "short":"GDB", + "long": "Use GDB", + "settings":{ + "USE_GDB_CLIENT":1 + } + } + } + }, + "DFU": { + "default": "no", + "choices": { + "no": { + "short": "No DFU", + "long": "Do not build DFU", + "settings": { + "BUILD_DFU":0 + } + }, + "yes": { + "short": "Build DFU", + "long": "Build DFU", + "settings": { + "BUILD_DFU":1 + } + } + } + } +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..78fc1180 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,46 @@ + { + "version": "0.1.0", + "configurations": [ + { + "name": "Debug - Openocd docker Remote", + "type":"cortex-debug", + "cortex-debug.armToolchainPath":"${env:COMPILER_DIR}/bin", + "cwd": "${workspaceRoot}", + "executable": "${command:cmake.launchTargetPath}", + "request": "launch", + "servertype": "external", + // This may need to be arm-none-eabi-gdb depending on your system + "gdbPath" : "${env:COMPILER_DIR}/bin/arm-none-eabi-gdb", + // Connect to an already running OpenOCD instance + "gdbTarget": "host.docker.internal:3333", + "svdFile": "${workspaceRoot}/nrf52.svd", + "runToMain": true, + // Work around for stopping at main on restart + "postRestartCommands": [ + "break main", + "continue" + ] + }, + { + "name": "Debug - Openocd Local", + "type":"cortex-debug", + "cortex-debug.armToolchainPath":"${env:COMPILER_DIR}/bin", + "cwd": "${workspaceRoot}", + "executable": "${command:cmake.launchTargetPath}", + "request": "launch", + "servertype": "openocd", + // This may need to be arm-none-eabi-gdb depending on your system + "gdbPath" : "${env:COMPILER_DIR}/bin/arm-none-eabi-gdb", + // Connect to an already running OpenOCD instance + "gdbTarget": "localhost:3333", + "svdFile": "${workspaceRoot}/nrf52.svd", + "runToMain": true, + // Work around for stopping at main on restart + "postRestartCommands": [ + "break main", + "continue" + ] + } + + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 05b11756..3b686626 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,59 +1,8 @@ { - "files.associations": { - "chrono": "cpp", - "list": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "netfwd": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "string": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp" - } -} \ No newline at end of file + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "cmake.configureArgs": [ + "-DARM_NONE_EABI_TOOLCHAIN_PATH=${env:ARM_NONE_EABI_TOOLCHAIN_PATH}", + "-DNRF5_SDK_PATH=${env:NRF5_SDK_PATH}", + ], + "cmake.generator": "Unix Makefiles" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..17f51f5e --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,44 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "create openocd build", + "type": "shell", + "command": "/opt/create_build_openocd.sh", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "update submodules", + "type": "shell", + "command": "git submodule update --init", + "options": { + "cwd": "${workspaceFolder}" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "BuildInit", + "dependsOn": [ + "update submodules", + "create openocd build" + ], + "problemMatcher": [] + } + ] +} \ No newline at end of file From e9248b225e78e36ff04f7c26244adf200e17020e Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 26 Jul 2021 01:14:23 +0000 Subject: [PATCH 15/31] Updated documentation --- .devcontainer/README.md | 4 ++-- .vscode/cmake-variants.json | 4 ++-- .vscode/extensions.json | 3 +++ .vscode/launch.json | 8 +++---- README.md | 1 + doc/buildWithVScode.md | 42 +++++++++++++++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 doc/buildWithVScode.md diff --git a/.devcontainer/README.md b/.devcontainer/README.md index ff9307b2..c8aef574 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -33,7 +33,7 @@ The dev enviroment comes with some scripts to make this easier, They are located There are also VSCode tasks provided should you desire to use those. -The task BuildInit will update submodules and configure for openocd +The task "update submodules" will update the git submodules @@ -41,7 +41,7 @@ The task BuildInit will update submodules and configure for openocd You can use the build.sh script located in /opt/ -There will also eventually be a Build task. - Not written yet +CMake is also configured and controlls for the CMake plugin are available in VSCode diff --git a/.vscode/cmake-variants.json b/.vscode/cmake-variants.json index d00e638e..9c95a631 100644 --- a/.vscode/cmake-variants.json +++ b/.vscode/cmake-variants.json @@ -47,14 +47,14 @@ "short": "No DFU", "long": "Do not build DFU", "settings": { - "BUILD_DFU":0 + "BUILD_DFU":"0" } }, "yes": { "short": "Build DFU", "long": "Build DFU", "settings": { - "BUILD_DFU":1 + "BUILD_DFU":"1" } } } diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..1cc05268 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["ms-vscode.cpptools","ms-vscode.cmake-tools","marus25.cortex-debug"] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 78fc1180..7cf3acd1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,13 +4,13 @@ { "name": "Debug - Openocd docker Remote", "type":"cortex-debug", - "cortex-debug.armToolchainPath":"${env:COMPILER_DIR}/bin", + "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin", "cwd": "${workspaceRoot}", "executable": "${command:cmake.launchTargetPath}", "request": "launch", "servertype": "external", // This may need to be arm-none-eabi-gdb depending on your system - "gdbPath" : "${env:COMPILER_DIR}/bin/arm-none-eabi-gdb", + "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb", // Connect to an already running OpenOCD instance "gdbTarget": "host.docker.internal:3333", "svdFile": "${workspaceRoot}/nrf52.svd", @@ -24,13 +24,13 @@ { "name": "Debug - Openocd Local", "type":"cortex-debug", - "cortex-debug.armToolchainPath":"${env:COMPILER_DIR}/bin", + "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin", "cwd": "${workspaceRoot}", "executable": "${command:cmake.launchTargetPath}", "request": "launch", "servertype": "openocd", // This may need to be arm-none-eabi-gdb depending on your system - "gdbPath" : "${env:COMPILER_DIR}/bin/arm-none-eabi-gdb", + "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb", // Connect to an already running OpenOCD instance "gdbTarget": "localhost:3333", "svdFile": "${workspaceRoot}/nrf52.svd", diff --git a/README.md b/README.md index bd23c867..4b067dce 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ As of now, here is the list of achievements of this project: - [Build the project](doc/buildAndProgram.md) - [Flash the firmware using OpenOCD and STLinkV2](doc/openOCD.md) - [Build the project with Docker](doc/buildWithDocker.md) + - [Build the project with VSCode](doc/buildWithVScode.md) - [Bootloader, OTA and DFU](./bootloader/README.md) - [Stub using NRF52-DK](./doc/PinetimeStubWithNrf52DK.md) - Logging with JLink RTT. diff --git a/doc/buildWithVScode.md b/doc/buildWithVScode.md new file mode 100644 index 00000000..31174d1c --- /dev/null +++ b/doc/buildWithVScode.md @@ -0,0 +1,42 @@ +# Build and Develop the project using VS Code + +The .VSCode folder contains configuration files for developing InfiniTime with VS Code. Effort was made to have these rely on Environment variables instead of hardcoded paths. + +## Environment Setup + +To support as many setups as possible the VS Code configuration files expect there to be certain environment variables to be set. + + Variable | Description | Example +----------|-------------|-------- +**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`export ARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update` +**NRF5_SDK_PATH**|path to the NRF52 SDK|`export NRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345` + +## VS Code Extensions + +We leverage a few VS Code extensions for ease of development. + +#### Required Extensions + +- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) - C/C++ IntelliSense, debugging, and code browsing. +- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) - Extended CMake support in Visual Studio Code + +#### Optional Extensions + +[Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) - ARM Cortex-M GDB Debugger support for VSCode + +Cortex-Debug is only required for interactive debugging using VS Codes built in GDB support. + + + +## VS Code/Docker DevContainer + +The .devcontainer folder contains the configuration and scripts for using a Docker dev container for building InfiniTime + +Using the [Remote-Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension is recommended. It will handle configuring the Docker virtual machine and setting everything up. + +More documentation is available in the [readme in .devcontainer](.devcontainer/readme.md) + + + + + From 7f2ee62aedd359d34af6569bc691e216a49a7f5d Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 26 Jul 2021 15:43:48 +0000 Subject: [PATCH 16/31] Typos for days --- .devcontainer/README.md | 32 ++++++++++++++++---------------- doc/buildWithVScode.md | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.devcontainer/README.md b/.devcontainer/README.md index c8aef574..1932a9d4 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -1,11 +1,11 @@ -# VScode devcontainer -This is a docker-based interactive development environment using VSCode and Docker Devcontainers removing the need to install any tools locally* +# VS Code Dev Container +This is a docker-based interactive development environment using VS Code and Docker Dev Containers removing the need to install any tools locally* ## Requirements -- VScode +- VS Code - [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension - Docker - OpenOCD - For debugging @@ -14,24 +14,24 @@ This is a docker-based interactive development environment using VSCode and Dock ### Code editing, and building. -1. Clone InifiniTime and update submodules -2. Launch VSCode -3. Open InifiTime directory, -4. Allow VSCode to open folder with devcontainer. +1. Clone InfiniTime and update submodules +2. Launch VS Code +3. Open InfiniTime directory, +4. Allow VS Code to open folder with devcontainer. After this the environment will be built if you do not currently have a container setup, it will install all the necessary tools and extra VSCode extensions. -In order to build InfiniTime we need to run the initial submodule init and Cmake commands. +In order to build InfiniTime we need to run the initial submodule init and CMake commands. #### Manually - You can use the VSCode terminal to run the CMake commands as outlined in the [build instructions](blob/develop/doc/buildAndProgram.md) + You can use the VS Code terminal to run the CMake commands as outlined in the [build instructions](blob/develop/doc/buildAndProgram.md) #### Script -The dev enviroment comes with some scripts to make this easier, They are located in /opt/. +The dev environment comes with some scripts to make this easier, They are located in /opt/. -There are also VSCode tasks provided should you desire to use those. +There are also VS Code tasks provided should you desire to use those. The task "update submodules" will update the git submodules @@ -41,20 +41,20 @@ The task "update submodules" will update the git submodules You can use the build.sh script located in /opt/ -CMake is also configured and controlls for the CMake plugin are available in VSCode +CMake is also configured and controls for the CMake plugin are available in VS Code ### Debugging -Docker on windows does not support passing USB devices to the underlying WSL2 subsystem, To get around this we use openocd in server mode running on the host. +Docker on windows does not support passing USB devices to the underlying WSL2 subsystem, To get around this we use OpenOCD in server mode running on the host. `openocd -f -f ` -This will launch openocd in server mode and attach it to the MCU. +This will launch OpenOCD in server mode and attach it to the MCU. -The default launch.json file expects openocd to be listening on port 3333, edit if needed +The default launch.json file expects OpenOCD to be listening on port 3333, edit if needed ## Current Issues -Currently WSL2 Has some real performance issues with IO on a windows host. Accessing files on the virtualized filesystem is much faster. Using VSCodes "clone in container" feature of the Remote - Containers will get around this. After the container is built you will need to update the submodules and follow the build isntructions like normal \ No newline at end of file +Currently WSL2 Has some real performance issues with IO on a windows host. Accessing files on the virtualized filesystem is much faster. Using VS Codes "clone in container" feature of the Remote - Containers will get around this. After the container is built you will need to update the submodules and follow the build instructions like normal \ No newline at end of file diff --git a/doc/buildWithVScode.md b/doc/buildWithVScode.md index 31174d1c..c1df17b7 100644 --- a/doc/buildWithVScode.md +++ b/doc/buildWithVScode.md @@ -1,6 +1,6 @@ # Build and Develop the project using VS Code -The .VSCode folder contains configuration files for developing InfiniTime with VS Code. Effort was made to have these rely on Environment variables instead of hardcoded paths. +The .VS Code folder contains configuration files for developing InfiniTime with VS Code. Effort was made to have these rely on Environment variables instead of hardcoded paths. ## Environment Setup @@ -22,7 +22,7 @@ We leverage a few VS Code extensions for ease of development. #### Optional Extensions -[Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) - ARM Cortex-M GDB Debugger support for VSCode +[Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) - ARM Cortex-M GDB Debugger support for VS Code Cortex-Debug is only required for interactive debugging using VS Codes built in GDB support. From d2dc719b318a256d3d6f2fea3bdcf30c5eb40969 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 8 Aug 2021 22:51:31 +0000 Subject: [PATCH 17/31] Fix intellisense --- .vscode/c_cpp_properties.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f5c74b3a..f8da48d5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -12,7 +12,7 @@ "cStandard": "c11", "cppStandard": "c++14", "intelliSenseMode": "linux-gcc-arm", - "configurationProvider": "ms-vscode.cmake-tools", + "configurationProvider": "ms-vscode.cpp-tools", "compileCommands": "${workspaceFolder}/build/compile_commands.json" } ], From 44889adda074af2a7a5fe61b19667521755dd24d Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 9 Aug 2021 00:16:17 +0000 Subject: [PATCH 18/31] Setup plugins for Clang-tidy/format --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 4 +++- .vscode/settings.json | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 4534c7e2..1dd68f24 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -16,7 +16,7 @@ RUN apt-get update -qq \ wget \ curl \ dos2unix \ - clang-format \ + clang-format-12 \ clang-tidy \ locales \ libncurses5 \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 223b651f..778fe9cb 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,7 +19,9 @@ "extensions": [ "ms-vscode.cpptools", "ms-vscode.cmake-tools", - "marus25.cortex-debug" + "marus25.cortex-debug", + "notskm.clang-tidy", + "mjohns.clang-format" ], // Use 'forwardPorts' to make a list of ports inside the container available locally. diff --git a/.vscode/settings.json b/.vscode/settings.json index 3b686626..8f0e63f4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,6 @@ "-DARM_NONE_EABI_TOOLCHAIN_PATH=${env:ARM_NONE_EABI_TOOLCHAIN_PATH}", "-DNRF5_SDK_PATH=${env:NRF5_SDK_PATH}", ], - "cmake.generator": "Unix Makefiles" + "cmake.generator": "Unix Makefiles", + "clang-tidy.buildPath": "build/compile_commands.json" } From f0e9d13329f5647a8e55b89d167f8306d58cb518 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sat, 14 Aug 2021 21:58:38 +0300 Subject: [PATCH 19/31] Update contribute.md (#475) * Update contribute.md * Add newlines and remove spaces * Replace CONTRIBUTING.md with doc/contribute.md --- CONTRIBUTING.md | 34 +-------------------------- doc/contribute.md | 59 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 52 deletions(-) mode change 100644 => 120000 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index a6fa6828..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,33 +0,0 @@ -This contribution guide is in progress, improvements are welcome. - -### Code style - -Any C++ code PRs should aim to follow the style of existing code in the project. - -Using an autoformatter is heavily recommended, but make sure it's configured properly. - -There's currently preconfigured autoformatter rules for: - - * CLion (IntelliJ) in .idea/codeStyles/Project.xml - -You can use those to configure your own IDE if it's not already on the list. - -#### Linting errors and compiler warnings - -Try to avoid any currently enabled warnings and try to reduce the amount of linter errors. - -#### Spelling - -Make sure you spellcheck your code before commiting it. - -#### TODO, FIXME - -Check before commiting that you haven't forgotten anything, preferably don't leave these in your commits. - -#### Licence headers - -You should add your name to the comma-space separated list of contributors if there's a license header. - -### License - -By contributing you agree to licence your code under the repository's general license (which is currently GPL-v3+). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 120000 index 00000000..15e2c684 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +doc/contribute.md \ No newline at end of file diff --git a/doc/contribute.md b/doc/contribute.md index 9f4c2154..0c34e2a5 100644 --- a/doc/contribute.md +++ b/doc/contribute.md @@ -1,68 +1,89 @@ # How to contribute? + ## Report bugs -You use your Pinetime and find a bug in the firmware? [Create an issue on Github](https://github.com/JF002/InfiniTime/issues) explaining the bug, how to reproduce it, the version of the firmware you use... + +Have you found a bug in the firmware? [Create an issue on Github](https://github.com/JF002/InfiniTime/issues) explaining the bug, how to reproduce it, the version of the firmware you use... + ## Write and improve documentation + Documentation might be incomplete, or not clear enough, and it is always possible to improve it with better wording, pictures, photo, video,... As the documentation is part of the source code, you can submit your improvements to the documentation by submitting a pull request (see below). + ## Fix bugs, add functionalities and improve the code + You want to fix a bug, add a cool new functionality or improve the code? See *How to submit a pull request below*. + ## Spread the word -The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open-source firmware for a smartwatch! + +The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open source firmware for a smartwatch! # How to submit a pull request ? ## TL;DR + - Create a branch from develop; - Work on a single subject in this branch. Create multiple branches/pulls-requests if you want to work on multiple subjects (bugs, features,...); - Test your modifications on the actual hardware; - Check the code formatting against our coding conventions and [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy); - Clean your code and remove files that are not needed; - - Write documentation related to your new feature is applicable; - - Create the pull-request and write a great description about it : what does your PR do, why, how,... Add pictures and video if possible; + - Write documentation related to your new feature if applicable; + - Create a pull request and write a great description about it : what does your PR do, why, how,... Add pictures and video if possible; - Wait for someone to review your PR and take part in the review process; - Your PR will eventually be merged :) -Your contribution is more than welcome! +Your contributions are more than welcome! -If you want to fix a bug, add a functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, **focus on only one topic, bug or feature**. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch per topic. +If you want to fix a bug, add functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, **focus on only one topic, bug or feature**. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch for each topic. When your feature branch is ready, **make sure it actually works** and **do not forget to write documentation** about it if it's relevant. -I **strongly discourage to create a PR containing modifications that haven't been tested**. If, for any reason, you cannot test your modifications but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedback about your code. +**Creating a pull request containing modifications that haven't been tested is strongly discouraged.** If, for any reason, you cannot test your modifications but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedback about your code. Also, before submitting your PR, check the coding style of your code against the **coding conventions** detailed below. This project also provides [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy) configuration files. You can use them to ensure correct formatting of your code. -Do not forget to check the files you are going to commit and remove those who are not necessary (config files from your IDE, for example). Remove old comments, commented code,... +Don't forget to check the files you are going to commit and remove those which aren't necessary (config files from your IDE, for example). Remove old comments, commented code,... -Then, you can submit a pull-request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how is it designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of your work. +Then, you can submit a pull request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how it is designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of your work. Other contributors can post comments about the pull request, maybe ask for more info or adjustments in the code. -Once the pull request is reviewed and accepted, it'll be merge in **develop** and will be released in the next release version of the firmware. +Once the pull request is reviewed and accepted, it'll be merged into **develop** and will be released in the next version of the firmware. ## Why all these rules? -Reviewing pull-requests is a **very time consuming task** for the creator of this project ([JF002](https://github.com/JF002)) and for other contributors who take the time to review them. Every little thing you do to make their lives easier will **increase the chances your PR will be merge quickly**. -When reviewing PR, the author and contributors will first look at the **description**. If it's easy to understand what the PR does, why the modification is needed or interesting and how it's done, a good part of the work is already done : we understand the PR and its context. +Reviewing pull requests is a **very time consuming task** for the creator of this project ([JF002](https://github.com/JF002)) and for other contributors who take the time to review them. Everything you do to make reviewing easier will **get your PR merged faster**. -Then, reviewing **a few files that were modified for a single purpose** is a lot more easier than to review 30 files modified for many reasons (bug fix, UI improvements, typos in doc,...), even if all these changes make sense. Also, it's possible that we agree on some modification but not on some other, and we won't be able to merge the PR because of the changes that are not accepted. +When reviewing PRs, the author and contributors will first look at the **description**. If it's easy to understand what the PR does, why the modification is needed or interesting and how it's done, a good part of the work is already done : we understand the PR and its context. -We do our best to keep the code as consistent as possible, and that means we pay attention to the **formatting** of the code. If the code formatting is not consistent with our code base, we'll ask you to review it, which will take more time. +Then, reviewing **a few files that were modified for a single purpose** is a lot more easier than to review 30 files modified for many reasons (bug fix, UI improvements, typos in doc,...), even if all these changes make sense. Also, it's possible that we agree on some modification but not on some other, so we won't be able to merge the PR because of the changes that are not accepted. -The last step of the review consists in **testing** the modification. If it doesn't work out of the box, we'll ask your to review your code and to ensure that it works as expected. +We do our best to keep the code as consistent as possible. If the formatting of the code in your PR is not consistent with our code base, we'll ask you to review it, which will take more time. -It's totally normal for a PR to need some more work even after it was created, that's why we review them. But every round trip takes time, and it's good practice to try to reduce them as much as possible by following those simple rules. +The last step of the review consists of **testing** the modification. If it doesn't work out of the box, we'll ask your to review your code and to ensure that it works as expected. + +It's totally normal for a PR to need some more work even after it was created, that's why we review them. But every round trip takes time, so it's good practice to try to reduce them as much as possible by following those simple rules. # Coding convention -## Language -The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction. -It's OK to include C code if this code comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK. +## Language + +The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction. + +C code is accepted if it comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK. ## Coding style + The most important rule to follow is to try to keep the code as easy to read and maintain as possible. +Using an autoformatter is highly recommended, but make sure it's configured properly. + +There are preconfigured autoformatter rules for: + + * CLion (IntelliJ) in .idea/codeStyles/Project.xml + +If there are no preconfigured rules for your IDE, you can use one of the existing ones to configure your IDE. + - **Indentation** : 2 spaces, no tabulation - **Opening brace** at the end of the line - **Naming** : Choose self-describing variable name From e51c3eee4ed50ccec55c105fd93a46b7715601b3 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Mon, 9 Aug 2021 21:49:35 +0300 Subject: [PATCH 20/31] Try to fix bootloop --- src/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ffbba5e7..a18c3942 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include // nimble #define min // workaround: nimble's min/max macros conflict with libstdc++ @@ -300,6 +301,14 @@ int main(void) { nrf_drv_clock_init(); + // Unblock i2c? + nrf_gpio_cfg_output(pinTwiScl); + for (uint8_t i = 0; i < 16; i++) { + nrf_gpio_pin_toggle(pinTwiScl); + nrf_delay_us(5); + } + nrf_gpio_cfg_default(pinTwiScl); + debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); From 10f610b2191ed0783a2f36a5e869019fc548aa24 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Mon, 9 Aug 2021 22:07:06 +0300 Subject: [PATCH 21/31] Better pin configuration --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index a18c3942..39d8906c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -302,7 +302,12 @@ int main(void) { nrf_drv_clock_init(); // Unblock i2c? - nrf_gpio_cfg_output(pinTwiScl); + nrf_gpio_cfg(pinTwiScl, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0D1, + NRF_GPIO_PIN_NOSENSE); for (uint8_t i = 0; i < 16; i++) { nrf_gpio_pin_toggle(pinTwiScl); nrf_delay_us(5); From 7c28de0b6fa7fa33ff10d09847742a35de26cf2b Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Mon, 9 Aug 2021 22:11:35 +0300 Subject: [PATCH 22/31] Set pin before loop --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 39d8906c..d301be67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -308,6 +308,7 @@ int main(void) { NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_pin_set(pinTwiScl); for (uint8_t i = 0; i < 16; i++) { nrf_gpio_pin_toggle(pinTwiScl); nrf_delay_us(5); From 61927751612a9dc8e53fe7882c1e576a90843bc4 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Fri, 13 Aug 2021 22:03:27 +0300 Subject: [PATCH 23/31] Improve metronome --- src/displayapp/DisplayApp.cpp | 1 + src/displayapp/screens/Metronome.cpp | 119 ++++++++++----------------- src/displayapp/screens/Metronome.h | 48 +++++------ 3 files changed, 69 insertions(+), 99 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index d4a73f5e..49a56a07 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -414,6 +414,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::Metronome: currentScreen = std::make_unique(this, motorController, *systemTask); + ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Motion: currentScreen = std::make_unique(this, motionController); diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 7bfbccb7..ce23cc3e 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -1,35 +1,15 @@ #include "Metronome.h" - -#include "Screen.h" #include "Symbols.h" -#include "lvgl/lvgl.h" -#include "FreeRTOSConfig.h" -#include "task.h" - -#include -#include using namespace Pinetime::Applications::Screens; namespace { - float calculateDelta(const TickType_t startTime, const TickType_t currentTime) { - TickType_t delta = 0; - // Take care of overflow - if (startTime > currentTime) { - delta = 0xffffffff - startTime; - delta += (currentTime + 1); - } else { - delta = currentTime - startTime; - } - return static_cast(delta) / static_cast(configTICK_RATE_HZ); - } - - static void eventHandler(lv_obj_t* obj, lv_event_t event) { - Metronome* screen = static_cast(obj->user_data); + void eventHandler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); screen->OnEvent(obj, event); } - lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x = 0, uint8_t y = 0) { + lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x, uint8_t y) { lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font); lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); @@ -41,7 +21,7 @@ namespace { } Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask) - : Screen(app), running {true}, currentState {States::Stopped}, startTime {}, motorController {motorController}, systemTask {systemTask} { + : Screen(app), motorController {motorController}, systemTask {systemTask} { bpmArc = lv_arc_create(lv_scr_act(), nullptr); bpmArc->user_data = this; @@ -52,10 +32,10 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_arc_set_value(bpmArc, bpm); lv_obj_set_size(bpmArc, 210, 210); lv_arc_set_adjustable(bpmArc, true); - lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 7); + lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); - bpmValue = createLabel(std::to_string(lv_arc_get_value(bpmArc)).c_str(), bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); - bpmLegend = createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); + bpmValue = createLabel("120", bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); + createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); bpmTap = lv_btn_create(lv_scr_act(), nullptr); bpmTap->user_data = this; @@ -69,20 +49,23 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl lv_obj_set_event_cb(bpbDropdown, eventHandler); lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_MAIN, LV_STATE_DEFAULT, 20); lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_LIST, LV_STATE_DEFAULT, 20); - lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 15, -4); + lv_obj_set_size(bpbDropdown, 115, 50); + lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_dropdown_set_options(bpbDropdown, "1\n2\n3\n4\n5\n6\n7\n8\n9"); lv_dropdown_set_selected(bpbDropdown, bpb - 1); - bpbLegend = lv_label_create(bpbDropdown, nullptr); - lv_label_set_text(bpbLegend, "bpb"); - lv_obj_align(bpbLegend, bpbDropdown, LV_ALIGN_IN_RIGHT_MID, -15, 0); + lv_dropdown_set_show_selected(bpbDropdown, false); + lv_dropdown_set_text(bpbDropdown, ""); + + currentBpbText = lv_label_create(bpbDropdown, nullptr); + lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb); + lv_obj_align(currentBpbText, bpbDropdown, LV_ALIGN_CENTER, 0, 0); playPause = lv_btn_create(lv_scr_act(), nullptr); playPause->user_data = this; lv_obj_set_event_cb(playPause, eventHandler); - lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_height(playPause, 39); - playPauseLabel = lv_label_create(playPause, nullptr); - lv_label_set_text(playPauseLabel, Symbols::play); + lv_obj_set_size(playPause, 115, 50); + lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); app->SetTouchMode(DisplayApp::TouchModes::Polling); } @@ -93,28 +76,17 @@ Metronome::~Metronome() { lv_obj_clean(lv_scr_act()); } -bool Metronome::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return true; -} - bool Metronome::Refresh() { - switch (currentState) { - case States::Stopped: { - break; - } - case States::Running: { - if (calculateDelta(startTime, xTaskGetTickCount()) >= (60.0 / bpm)) { - counter--; - startTime -= 60.0 / bpm; - startTime = xTaskGetTickCount(); - if (counter == 0) { - counter = bpb; - motorController.SetDuration(90); - } else { - motorController.SetDuration(30); - } + if (metronomeStarted) { + if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) { + startTime += 60 * configTICK_RATE_HZ / bpm; + counter--; + if (counter == 0) { + counter = bpb; + motorController.SetDuration(90); + } else { + motorController.SetDuration(30); } - break; } } return running; @@ -128,42 +100,39 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { lv_label_set_text_fmt(bpmValue, "%03d", bpm); } else if (obj == bpbDropdown) { bpb = lv_dropdown_get_selected(obj) + 1; + lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb); + lv_obj_realign(currentBpbText); } break; } case LV_EVENT_PRESSED: { if (obj == bpmTap) { - float timeDelta = calculateDelta(tappedTime, xTaskGetTickCount()); - if (tappedTime == 0 || timeDelta > 3) { - tappedTime = xTaskGetTickCount(); - } else { - bpm = ceil(60.0 / timeDelta); + TickType_t delta = xTaskGetTickCount() - tappedTime; + if (tappedTime != 0 && delta < configTICK_RATE_HZ * 3) { + bpm = configTICK_RATE_HZ * 60 / delta; lv_arc_set_value(bpmArc, bpm); lv_label_set_text_fmt(bpmValue, "%03d", bpm); - tappedTime = xTaskGetTickCount(); } + tappedTime = xTaskGetTickCount(); } break; } case LV_EVENT_CLICKED: { if (obj == playPause) { - currentState = (currentState == States::Stopped ? States::Running : States::Stopped); - switch (currentState) { - case States::Stopped: { - lv_label_set_text(playPauseLabel, Symbols::play); - systemTask.PushMessage(System::Messages::EnableSleeping); - break; - } - case States::Running: { - lv_label_set_text(playPauseLabel, Symbols::pause); - systemTask.PushMessage(System::Messages::DisableSleeping); - startTime = xTaskGetTickCount(); - counter = 1; - break; - } + metronomeStarted = !metronomeStarted; + if (metronomeStarted) { + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::pause); + systemTask.PushMessage(System::Messages::DisableSleeping); + startTime = xTaskGetTickCount(); + counter = 1; + } else { + lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play); + systemTask.PushMessage(System::Messages::EnableSleeping); } } break; } + default: + break; } } diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 3a1f1084..a4baa096 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -3,32 +3,32 @@ #include "systemtask/SystemTask.h" #include "components/motor/MotorController.h" -#include +namespace Pinetime { + namespace Applications { + namespace Screens { -namespace Pinetime::Applications::Screens { + class Metronome : public Screen { + public: + Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); + ~Metronome() override; + bool Refresh() override; + void OnEvent(lv_obj_t* obj, lv_event_t event); - class Metronome : public Screen { - public: - Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); - ~Metronome() override; - bool Refresh() override; - bool OnTouchEvent(TouchEvents event) override; - void OnEvent(lv_obj_t* obj, lv_event_t event); - enum class States { Running, Stopped }; + private: + TickType_t startTime = 0; + TickType_t tappedTime = 0; + Controllers::MotorController& motorController; + System::SystemTask& systemTask; + int16_t bpm = 120; + uint8_t bpb = 4; + uint8_t counter = 1; - private: - bool running; - States currentState; - TickType_t startTime; - TickType_t tappedTime = 0; - Controllers::MotorController& motorController; - System::SystemTask& systemTask; - uint16_t bpm = 120; - uint8_t bpb = 4; - uint8_t counter = 1; + bool metronomeStarted = false; - lv_obj_t *bpmArc, *bpmTap, *bpmValue, *bpmLegend; - lv_obj_t *bpbDropdown, *bpbLegend; - lv_obj_t *playPause, *playPauseLabel; - }; + lv_obj_t *bpmArc, *bpmTap, *bpmValue; + lv_obj_t *bpbDropdown, *currentBpbText; + lv_obj_t *playPause; + }; + } + } } From dec4bab33496527e43850742a4b3dafd753eab83 Mon Sep 17 00:00:00 2001 From: Martin Hub Date: Sat, 14 Aug 2021 21:24:26 +0200 Subject: [PATCH 24/31] Add VSCode ST-link debug config (#567) --- .vscode/launch.json | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7cf3acd1..3d9aa789 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -40,7 +40,25 @@ "break main", "continue" ] + }, + { + "cwd": "${workspaceRoot}", + // TODO: find better way to get latest build filename + "executable": "./build/src/pinetime-app-1.3.0.out", + "name": "Debug OpenOCD ST-LINK pinetime-app-1.3.0.out", + "request": "launch", + "type": "cortex-debug", + "showDevDebugOutput": false, + "servertype": "openocd", + "runToMain": true, + // Only use armToolchainPath if your arm-none-eabi-gdb is not in your path (some GCC packages does not contain arm-none-eabi-gdb) + "armToolchainPath": "${workspaceRoot}/../gcc-arm-none-eabi-9-2020-q2-update/bin", + "svdFile": "${workspaceRoot}/nrf52.svd", + "configFiles": [ + "interface/stlink.cfg", + "target/nrf52.cfg" + ], } ] -} \ No newline at end of file +} From e0d01411d7124abc5ad099360057ba683287c428 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 13 Jun 2021 12:47:12 +0300 Subject: [PATCH 25/31] Ui update --- doc/ui_guidelines.md | 14 ++++ src/displayapp/screens/FirmwareValidation.cpp | 4 +- src/displayapp/screens/List.cpp | 34 ++++------ src/displayapp/screens/Music.cpp | 68 +++++++++---------- src/displayapp/screens/Music.h | 3 +- src/displayapp/screens/Tile.cpp | 30 ++++---- src/displayapp/screens/WatchFaceAnalog.cpp | 4 +- src/displayapp/screens/WatchFaceDigital.cpp | 14 ++-- .../screens/settings/QuickSettings.cpp | 47 ++++++------- .../screens/settings/QuickSettings.h | 2 + 10 files changed, 113 insertions(+), 107 deletions(-) create mode 100644 doc/ui_guidelines.md diff --git a/doc/ui_guidelines.md b/doc/ui_guidelines.md new file mode 100644 index 00000000..9b05ce64 --- /dev/null +++ b/doc/ui_guidelines.md @@ -0,0 +1,14 @@ +# UI design guidelines + +- Align objects all the way to the edge or corner +- Buttons should generally be at least 50px high +- Buttons should generally be on the bottom edge +- Make interactable objects **big** +- Recommendations for inner padding, aka distance between buttons: + - When aligning 4 objects: 4px, e.g. Settings + - When aligning 3 objects: 6px, e.g. App list + - When aligning 2 objects: 10px, e.g. Quick settings +- When using a page indicator, leave 8px for it on the right side + - It is acceptable to leave 8px on the left side as well to center the content +- Top bar takes at least 20px + padding + - Top bar right icons move 8px to the left when using a page indicator diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index 1d05be8d..da9d04f2 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -38,8 +38,9 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, lv_label_set_text(labelIsValidated, "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); buttonValidate = lv_btn_create(lv_scr_act(), nullptr); - lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); buttonValidate->user_data = this; + lv_obj_set_height(buttonValidate, 50); + lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x009900)); @@ -48,6 +49,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, buttonReset = lv_btn_create(lv_scr_act(), nullptr); buttonReset->user_data = this; + lv_obj_set_height(buttonReset, 50); lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x990000)); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index b4f4d2cf..eb53820b 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -25,42 +25,38 @@ List::List(uint8_t screenID, settingsController.SetSettingsMenu(screenID); if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = 0; + pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = LV_VER_RES; pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; - uint16_t indicatorPos = indicatorSize * screenID; + const uint16_t indicatorSize = LV_VER_RES / numScreens; + const uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = 6 + indicatorPos; - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + pageIndicatorPoints[0].x = LV_HOR_RES - 1; + pageIndicatorPoints[0].y = indicatorPos; + pageIndicatorPoints[1].x = LV_HOR_RES - 1; + pageIndicatorPoints[1].y = indicatorPos + indicatorSize; pageIndicator = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); } lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - // lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); - lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); - lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 4); lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); lv_obj_set_pos(container1, 0, 0); - lv_obj_set_width(container1, LV_HOR_RES - 15); + lv_obj_set_width(container1, LV_HOR_RES - 8); lv_obj_set_height(container1, LV_VER_RES); lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); @@ -73,11 +69,11 @@ List::List(uint8_t screenID, itemApps[i] = lv_btn_create(container1, nullptr); lv_obj_set_style_local_bg_opa(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); - lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 57); lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_width(itemApps[i], LV_HOR_RES - 25); - lv_obj_set_height(itemApps[i], 52); + lv_obj_set_width(itemApps[i], LV_HOR_RES - 8); + lv_obj_set_height(itemApps[i], 57); lv_obj_set_event_cb(itemApps[i], ButtonEventHandler); lv_btn_set_layout(itemApps[i], LV_LAYOUT_ROW_MID); itemApps[i]->user_data = this; diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index c8d5e4b0..99a1518e 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -50,60 +50,55 @@ inline void lv_img_set_src_arr(lv_obj_t* img, const lv_img_dsc_t* src_img) { Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::MusicService& music) : Screen(app), musicService(music) { lv_obj_t* label; + lv_style_init(&btn_style); + lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, 20); + lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, LV_COLOR_AQUA); + lv_style_set_bg_opa(&btn_style, LV_STATE_DEFAULT, LV_OPA_20); + btnVolDown = lv_btn_create(lv_scr_act(), nullptr); btnVolDown->user_data = this; lv_obj_set_event_cb(btnVolDown, event_handler); - lv_obj_set_size(btnVolDown, 65, 75); - lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 15, -10); - lv_obj_set_style_local_radius(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnVolDown, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnVolDown, 76, 76); + lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_add_style(btnVolDown, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnVolDown, nullptr); lv_label_set_text(label, Symbols::volumDown); - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, true); btnVolUp = lv_btn_create(lv_scr_act(), nullptr); btnVolUp->user_data = this; lv_obj_set_event_cb(btnVolUp, event_handler); - lv_obj_set_size(btnVolUp, 65, 75); - lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_style_local_radius(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnVolUp, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnVolUp, 76, 76); + lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_add_style(btnVolUp, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnVolUp, nullptr); lv_label_set_text(label, Symbols::volumUp); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, true); btnPrev = lv_btn_create(lv_scr_act(), nullptr); btnPrev->user_data = this; lv_obj_set_event_cb(btnPrev, event_handler); - lv_obj_set_size(btnPrev, 65, 75); - lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 15, -10); - lv_obj_set_style_local_radius(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnPrev, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnPrev, 76, 76); + lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_add_style(btnPrev, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnPrev, nullptr); lv_label_set_text(label, Symbols::stepBackward); btnNext = lv_btn_create(lv_scr_act(), nullptr); btnNext->user_data = this; lv_obj_set_event_cb(btnNext, event_handler); - lv_obj_set_size(btnNext, 65, 75); - lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); - lv_obj_set_style_local_radius(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnNext, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnNext, 76, 76); + lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_add_style(btnNext, LV_STATE_DEFAULT, &btn_style); label = lv_label_create(btnNext, nullptr); lv_label_set_text(label, Symbols::stepForward); btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; lv_obj_set_event_cb(btnPlayPause, event_handler); - lv_obj_set_size(btnPlayPause, 65, 75); - lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, -10); - lv_obj_set_style_local_radius(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); - lv_obj_set_style_local_bg_opa(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_size(btnPlayPause, 76, 76); + lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_obj_add_style(btnPlayPause, LV_STATE_DEFAULT, &btn_style); txtPlayPause = lv_label_create(btnPlayPause, nullptr); lv_label_set_text(txtPlayPause, Symbols::play); @@ -147,6 +142,7 @@ Music::Music(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Mus } Music::~Music() { + lv_style_reset(&btn_style); lv_obj_clean(lv_scr_act()); } @@ -272,21 +268,19 @@ void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) { bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { case TouchEvents::SwipeUp: { - displayVolumeButtons = true; - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, false); + lv_obj_set_hidden(btnVolUp, false); - lv_obj_set_hidden(btnNext, displayVolumeButtons); - lv_obj_set_hidden(btnPrev, displayVolumeButtons); + lv_obj_set_hidden(btnNext, true); + lv_obj_set_hidden(btnPrev, true); return true; } case TouchEvents::SwipeDown: { - displayVolumeButtons = false; - lv_obj_set_hidden(btnNext, displayVolumeButtons); - lv_obj_set_hidden(btnPrev, displayVolumeButtons); + lv_obj_set_hidden(btnNext, false); + lv_obj_set_hidden(btnPrev, false); - lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); - lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + lv_obj_set_hidden(btnVolDown, true); + lv_obj_set_hidden(btnVolUp, true); return true; } case TouchEvents::SwipeLeft: { diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index ef8f1fec..00d3ad92 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -57,10 +57,11 @@ namespace Pinetime { lv_obj_t* imgDiscAnim; lv_obj_t* txtTrackDuration; + lv_style_t btn_style; + /** For the spinning disc animation */ bool frameB; - bool displayVolumeButtons = false; Pinetime::Controllers::MusicService& musicService; std::string artist; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index d5d6cb80..a64320e6 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -35,37 +35,35 @@ Tile::Tile(uint8_t screenID, label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 15, 6); + lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); // Battery batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); - lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 6); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -8, 0); if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = 0; + pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = LV_VER_RES; pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; - uint16_t indicatorPos = indicatorSize * screenID; + const uint16_t indicatorSize = LV_VER_RES / numScreens; + const uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = 6 + indicatorPos; - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + pageIndicatorPoints[0].x = LV_HOR_RES - 1; + pageIndicatorPoints[0].y = indicatorPos; + pageIndicatorPoints[1].x = LV_HOR_RES - 1; + pageIndicatorPoints[1].y = indicatorPos + indicatorSize; pageIndicator = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); } @@ -85,7 +83,7 @@ Tile::Tile(uint8_t screenID, btnm1 = lv_btnmatrix_create(lv_scr_act(), nullptr); lv_btnmatrix_set_map(btnm1, btnmMap); - lv_obj_set_size(btnm1, LV_HOR_RES - 10, LV_VER_RES - 60); + lv_obj_set_size(btnm1, LV_HOR_RES - 16, LV_VER_RES - 60); lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 10); lv_obj_set_style_local_radius(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, 20); @@ -93,6 +91,8 @@ Tile::Tile(uint8_t screenID, lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_COLOR_AQUA); lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_20); lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111)); + lv_obj_set_style_local_pad_all(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 0); + lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 6); for (uint8_t i = 0; i < 6; i++) { if (applications[i].application == Apps::None) { diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 621929b8..1410fc28 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -67,12 +67,12 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryHalf); - lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -8, -4); + lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0); notificationIcon = lv_label_create(lv_scr_act(), NULL); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 8, -4); + lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); // Date - Day / Week day diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 7a240f1f..2b902b3b 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -35,7 +35,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryFull); - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); batteryPlug = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); @@ -50,7 +50,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, notificationIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); - lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); + lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); label_date = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); @@ -75,7 +75,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatIcon, Symbols::heartBeat); lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); heartbeatValue = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); @@ -85,7 +85,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, stepValue = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); lv_label_set_text(stepValue, "0"); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); stepIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); @@ -110,7 +110,7 @@ bool WatchFaceDigital::Refresh() { if (bleState.IsUpdated()) { lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); } - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); @@ -208,7 +208,7 @@ bool WatchFaceDigital::Refresh() { lv_label_set_text_static(heartbeatValue, ""); } - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); } @@ -216,7 +216,7 @@ bool WatchFaceDigital::Refresh() { motionSensorOk = motionController.IsSensorOk(); if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) { lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + 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); } diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 0421d103..2d76d2dd 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -30,27 +30,29 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, motorController {motorController}, settingsController {settingsController} { + // This is the distance (padding) between all objects on this screen. + const int innerDistance = 10; + // Time label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 15, 4); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0); batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); - lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 4); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); - lv_obj_t* lbl_btn; + lv_style_init(&btn_style); + lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, (LV_VER_RES - 20 - 2 * innerDistance) / 8); + lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, lv_color_hex(0x111111)); btn1 = lv_btn_create(lv_scr_act(), nullptr); btn1->user_data = this; lv_obj_set_event_cb(btn1, ButtonEventHandler); - lv_obj_align(btn1, nullptr, LV_ALIGN_CENTER, -50, -30); - lv_obj_set_style_local_radius(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - - lv_btn_set_fit2(btn1, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn1, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); + lv_obj_align(btn1, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 20 + innerDistance); btn1_lvl = lv_label_create(btn1, nullptr); lv_obj_set_style_local_text_font(btn1_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -59,12 +61,11 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn2 = lv_btn_create(lv_scr_act(), nullptr); btn2->user_data = this; lv_obj_set_event_cb(btn2, ButtonEventHandler); - lv_obj_align(btn2, nullptr, LV_ALIGN_CENTER, 50, -30); - lv_obj_set_style_local_radius(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn2, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn2, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); + lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 20 + innerDistance); + lv_obj_t* lbl_btn; lbl_btn = lv_label_create(btn2, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); lv_label_set_text_static(lbl_btn, Symbols::highlight); @@ -72,14 +73,11 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn3 = lv_btn_create(lv_scr_act(), nullptr); btn3->user_data = this; lv_obj_set_event_cb(btn3, ButtonEventHandler); - lv_obj_align(btn3, nullptr, LV_ALIGN_CENTER, -50, 60); lv_btn_set_checkable(btn3, true); - lv_obj_set_style_local_radius(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + lv_obj_add_style(btn3, LV_BTN_PART_MAIN, &btn_style); lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); - lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn3, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_set_size(btn3, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); + lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); btn3_lvl = lv_label_create(btn3, nullptr); lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -94,11 +92,9 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn4 = lv_btn_create(lv_scr_act(), nullptr); btn4->user_data = this; lv_obj_set_event_cb(btn4, ButtonEventHandler); - lv_obj_align(btn4, nullptr, LV_ALIGN_CENTER, 50, 60); - lv_obj_set_style_local_radius(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); - lv_obj_set_style_local_bg_color(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_obj_set_style_local_bg_grad_dir(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); - lv_btn_set_fit2(btn4, LV_FIT_TIGHT, LV_FIT_TIGHT); + lv_obj_add_style(btn4, LV_BTN_PART_MAIN, &btn_style); + lv_obj_set_size(btn4, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); + lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lbl_btn = lv_label_create(btn4, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -114,6 +110,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, } QuickSettings::~QuickSettings() { + lv_style_reset(&btn_style); lv_task_del(taskUpdate); lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h index e0fc0a87..2eefe1a7 100644 --- a/src/displayapp/screens/settings/QuickSettings.h +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -44,6 +44,8 @@ namespace Pinetime { lv_obj_t* batteryIcon; lv_obj_t* label_time; + lv_style_t btn_style; + lv_obj_t* btn1; lv_obj_t* btn1_lvl; lv_obj_t* btn2; From fc6458a35c2260fe152fe84bcd06174cec6d3b92 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 13 Jun 2021 17:21:03 +0300 Subject: [PATCH 26/31] Add image with example layouts --- doc/ui/example.png | Bin 0 -> 10642 bytes doc/ui_guidelines.md | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 doc/ui/example.png diff --git a/doc/ui/example.png b/doc/ui/example.png new file mode 100644 index 0000000000000000000000000000000000000000..2f6cb789212631bdf4378085a401272b40ab6ca3 GIT binary patch literal 10642 zcmbVyc|4Tu`}QqD3tA;>J&7n(_FW5Q&n~+bL}thsTh=p2ytod+zJH&ht9X<2cUi;U%35EZaG^BM8Exe(}6M zg3$NC&y&oI@ZY&3lu7s>;}y*d=aF^vPeN&GBwX3%a`Cbof`}eL|IvBAQO3i?gE&=F z+&QeX^K}dkId|*2E$;fYLmoG94u>wNYhN-6WIcc&hYL(aJED1uTzcF(rcTYCu2mKpppnlu8 z0Dp$bLnIbh4`zkCmo1Y>+g3 zP#I$EtL!@BNe@5Y#UM&qXa4uH8UMy*r0*O9`dr0p4jN;YUgXAyfJT;zV50gY8Ze|H z_-4d69KDS;rpRN!DZg{*1Uga`_q7&X<#dx=tJGQV+1Xj|pHDADE3E&F)D`CE{~59# zC+XDgFj!9*Gu>E;)4bw8& zXeAb+_&tZFi9LsLOmLHpNZfmQLBR{7?b-7E&PsECUri-id3%%e4GfN|zj^cKOKt5{ zCc4m*o8N!Fk~!Lb5--C|n_Hftb(;*v`dB7X{gUvc*J>(^SeFJCl{9zA*kUZtU-p|7PC^5MgWpEx-qOUvwY!K^}J zV!EB3opn8xWXT-Th;ZjkDfQ-YD*1VQe1i@hGrApB`WzH~DB6BtU^#gDBXcDSJim{f zJ>}&~4i;{iOHo$d={;V9Jp1?Ui=A_d_g`Ba=_w`i*9_bmj$dC9lxLXSk{XSs75kpu zyKNoWc;s4{shA>jNlD3DGTho~MOUw0mAw9C-<#xQc-|V{dA+)SW#u-Hg69*SEuMiJ zsao;jy?F#Hw@kv=*iG8El9uAqmsCv0gWX3Y?7nii4>u2deD8npf!}g>Z$@!(aa*F- z&(BY*X_enFMN-aPAM24n({Pm|2#bkHZ*eg;ZdbS8pPQD}2tm(*FQvM7SdLK1Mf^ev z3KspJ!aKe^KW;utN>U3w&3k~IeWW6ger#tzADWj8akHZxMUGy4N@4@ z_Huv!s*fKz=*o_k`pg^a>qj)LEsf@O?p8VO5{mAxU40PrnL6oS4(FJ<6x+)CUZrbQ z2dr-@gcc%w(r`Asb^QIPfk>y0rQJ3WFOr z($lF6h1cp1D%~!=(Mh2w$nD)suR!~z*Q)jfex9Di>6RuYgKgdrVM*SO_I6=u=_mqS z!8`o6jfgTmdGf@@(ZtZulW3J|RT}b%iIw|F%W$%Ipz#%Bz*eN<2M8Qo}zQxwUOhGaEZ?t6b{jN#9s=5*%UJHc$#$UgJq z8oIj519Aj;kM^H6k^4D09TlP?BaakyQ-6#~Dk)N@iF5^7wireoNp#bnxYl1CN}8^h z-_Ol`LR~{!+vxUfO4-V9OH~XurFk0uXf||^ZN1>sT zyksh7|Ni}N=>u9+HZbhO&p4lPJs9Nk7cWv067~w_%?-C)@LigDT05YxtsNS4=T6Mm zE28Qb!gQ5$atRtFFmL2rK-JC8cdFN~Uneb%WNJso zZ{508NLV<@4uD7)*{@7Nz2VO!Q%_x z<>&jpTiv>Yy|G4x%VsmGL7d@fbd$YZn}~iF3qY^F0rUu>bbj;gA$r(~b*HBrxxTB6 zZXu6x<7<)cTmfuO;s1O27mD=<{*CpG??)7l9Jy1!wM*7T+U6q)+=n=jNn7VrKUhpT zj@TmZIt2RG5^0WA#x6mZe@d5}DPeC#U_Mtdyos+BNpnMZpqTYlbZ-0hpPGn_#2#W@ zIOOopGjNmr?)(j4K{i8&Y^D-|aBfT70dEcn3$1BG1Wf1~cM4pk`%?hB0@j)SzsjnM z-A1-;*_FsO8Q*o~BUj!@wGS{VIi@tUH2YC_R_!(>%)AQM0;f)a4oC?9yw`b`6SG?{vVJf_d z8vm)lo2jRIvWvwu-|pXUK#)I=wqJ|*KeQx>W0oX8CM#~z&Xt>8N=y)i!KJo(H$n!fA$Vtj3G^3VOC7>GH); zwCLWbi8v~J>{w$MkNgmK0uTM4p&?UKQz)if{QU6TvWR)1!}kyOa69{$0?BlLs&nD3 z0gc(QPJ;+Tef`(NEveGvv7S<&ZvOKK&rz2mqtZXDsdZ+!1+Y;-{T7+(Jymsp=+q&a zyX9Ug&@;Kc49Qw(HF4`N-C}Bat;IK{lfz%rUJDi=YWaCPGX>V`uH2$pwhW@Fz zdXpG-So>R+de27iKaYxXs*jbmr)a~be`$dh>wx5RgH*>4ceh38e7#b3v-7kwmGnG; zr691{z3Ii7Zvr*i2k6^>;(biYq+&wrw*aWH=S~j|ISl;zmEkeb6OoKA)!5%}Q!NGy zyD=>gUAqDxvYUzHaIcWL4*-h(7LayiN9*EjhjlIsmsG*9lk)UeabXdW>w<_9YoAum z20K>Sar*RWo#oRkIh%ztAtOUWRaMnWjE|Euqp#1Vs=Au9;ra9D={Y&|4n9hZeZB~m zHY5$aj6?qmnhvATlxg%|&=dsF6fLRw zFKGG)SMmg6_@$|cX=FFea^V&+#2HX|oT2Uscmm6erEEzRD2M9rb< z(f%)Wbw=vy4;>vH4NXi^-@Q9c>n_qA?Z`Fp_Ld{CqPsV64<(q5FDJKb=?n97cs$cM z+p);Gt-U?E9b4CcZlMBfb8~Y6?32}Tk8*>H7e61wPNb*CH4DbyeoY=HX`Z{kQ}5=@ ztPhoy`}gd54YZozGhRXh{z$Z|<1AhL6=S%qzF0uPKhAq3o!$Dlq@)qNL*LJ@OhZ%C z$i&3{_Nix4QK@h--MZXwY#*W$T(@`PG_k;NI&yFLZ3^BgUh|VriyD z*S*`hNa(M>&H_(5VC9);<-h7~WN64SYUwrb+>C@1YHNO9Vv*CrJ1}QxZQVQObi%w) zD_r6C0}^idig($&cltykF=g-yh!Ov_+jTEb-68bb_jr$rpaF=MaeeJQKb{T9u$77F z_=yu*uCA_}r>@+E9bMovj{$AjWQ#Ovgm}X)Xv6R5*(;!R2?B&E{?6DxGwi!OM_exC z2Lx|w^@F+Y+qduMtS+$KhBRzW@sI7m5r-cg&v{a37s>AooH6M_xYBip8#Ms6``Ov; zZoit0Dqm3rn%lyKrP!W`jEqd`#+F;oe{%~Ly4{Ow(FS4n+FLH~!Gj0JZD%SQQnX`2 zoVk^5o7P5&DG$#9dS(h4q;O22n#H5n*95*Pl8P|_l>m39@W|siM(+j(qqsWqtwdb@ zv+nK1fhZEpTic!mBsMIg#Nztsf%1iWRz5VMlx+7l5D4)^&B^-DpBteZy$Pge(vWkd z4P_W*Mk^jtHt%+9%r=)cAZKNbWz98!a&61E*HzbdcPFm>jw(k1RrtgS1)8%CLCy$O zC|%u!&MjG&^P?@-vWt3}H(-{Gr)9tniFkA-Q(>X+4r%3g?NP$QyTLb6R*rMN3cgFY z{>S+vBaTo*G>31{zA+;XSzYz+WPj?y(x>cXM^H==Pt{2vr!<+IK}NknnZr4fPLbNFrFLF{OkQ?8`i9?-YOS*A@t%xv{IJiOx^n_@Cxy}CY#sb3B8{>|5;V930R-W)V2j6(xa));(uzFi%< zRu-aB5ZHZue7eC!`7<*(?O2&62T-Gq&B^Md`5qsmOP3C*3yX@jUkz7G8O<&4nc4bv z>j8@dNRp>I3B9h~_vfzp;Cb#yy z`K@7K<1|d7#l~{OHq{;^c*K$1M^k_qHGQXzB?j}J))DiN;RfQ-*q&{!OBw@K5|SSg ztCRZZ@niS3#le<`e|AlJ9Vk;!VrFlz+*1qXd;{WdsjiSyqRa}nJV&!9`dj%eUbl3u z+Ha3@^tu|?k-ZLlz$!N?D#~7gm4&5Evcuxs(L~iq0qy36ss7M8`3Xu=U5s=*uCt&( zVs^OYlY{?Ur@d8aHM&lAlHuaww-;POIZl0Wz;+jASBbF-(lP`p z%(D%-i#=rHbUInl?-hJsi&#-x!uMA9;g6F2RaI3ldKQbQ_?R27liC@)8~Q|sLj=Rl zeVPP(6b26=q5x8g>iUVNPSmGARGL$qrrGQ>QF?*N>?>eb=tHifH)coLtg<}>++3lE zn5yrxY&0}9d^Yv>cNf#Oi5s_l3Mzxyd`dAO0@JCPCSpB@WZsmx4USNz>&3f7sE=|0 z>#O^J|Gt%NUKFNN@DeC${}cc$g|!C>D14tL-M3D>I5~IPvmr(rpk}_@9YWjI+L~5Y zW@Th#BaA&?cluNq^`K`c($h?BZIJkGw7gVZQp3Qrq zsQFmK?1F+;PX)JMTEL==f?0X=jf|c{EW`Mea}<5%hNvFB1MG%=AE))%8xGde!RiHY z@_R}jKYjYQKhM5>$yBn(=-W@c29AyyKl=Ok^YZ3^m8PnumI0EVH1zs$fzA6ZzU!;= zP}ZhL%P+{CYBF;2WW+YKs0UVqDwmxdr*?bxp1Axjxyl`II`k9Z=150wycD)4tLpKA z(I1b+jA6_Fb>s+Y1(2yZKYw0Bow^t)=Vt5mB@;O++sCS^gW+7Fb;I9E@=<6&rzdyo z=L2rmU`Hn>cc7$TFBt%A4z7(NDhrHqTD091bLNbH7j{d^zrdGj|M+k(@#-hmx;RC1$ORJ% zi&)fo1F|S;Npko*&z3Y8=Yv)sDkK)}FJxC)U_h>HP|<-iM2NAq|0;29Vtq{)Ansi^ z?a_k=jT8RsKBenx%RqIcUclbYjPqaf0&B48>Ch$g$No86;4k1tPCF_#8_U>&f!desD>Se*A=>Yrd`Uz})r-awN>11%^;X zg@uKi!D`BZY=+(2AW^v(E$M^}8gGLbBR}waooq8@ z{-6Gly-XjjxlM*b^=S8`cuZK8{{C{@Dtl12->)Ob(#XId2{a1zR;@_N@@LKFrP)zQ zFb`Y44uY!^E$1#QpFog^J9h=N0$@`M?4+4*ZVf_*51&z2S08Cf4F{g^8ceFpgoFxH zrPHVN!1XaR5*-&&V-THgu}k8q^w#GlR>MW_$;7?M zyD3c(%j0BS@W<4ApbA^%j^gCBC*Jz6j#`UYk$qQZJ2La~8aZtFz|}!v5DXrC_2u>j zIa-b-c?1e6>HB@I8K@Fcm;I)GRCxom6nIVB0gW?_XoZriIQ4NaX|~;b_!2Uyr}Fvp z=LGQpJo7gejwwtfAnH;M4%Ny5Xuf=g8s_@AG58^|9%{C?EErKLrC-c$)c#v#w8 ztre%xIm7!(8XMO!+72|f3)tpw$cRe^K=g89iUWC?SULUQcI?X0WhZg%J8%FMT^X5~ z;&J4k5t>6<$mG;p;Uj%2%WZ7$$t(kdgE3uk^QSSo^7yfnM6$=k_$;Y>Wk5`u2DI`i z4@)GJUGRQ6XaM=qqBRZ=2QTkyYisicAkZE4t)pzGC1quOZG~bHKRc+rUQ#s+m6pC` z{gtBk%t zib~d*(n3+NukHtukt_H&3Xk9w8ym^^C=5PzsI%OwAlMeUGFqzvMJK3;ZFP0R-^9u) z?$M)1xRr$|W9=uu4(exSX3mEDuT)~!azNdG8OCwax-sPJD)(RY1Sifav~%Nmr{da= zj}KEcg*oHbXra%Kn?wtAqPXo?3c~4SS9cNCKDZz<-fyYK^INHpN3QNNw)kV8R*y2g zmjSzD`?hUO(6nexy1>>+!vou{%$&9I{Jyp2=6BfNQ<+WQ-ACJnI;T|}p0El{K{Wg|sTnit-Dg#tHJBp|b^ zBl!(VnZdl?X`Sw{;%|UJzl`&N4Z1pxU7n6#&jM)dSL*TT@k&L364cj?fiKV1o{#`w z(Si0$TuN<82PfnAFO|Ij)KJAeQ(Up=f_Fq5)dUHU{Q2`mMd0vVWRG0@_&2ZS0h27# zM38?;tB~vY;$2N}p9JvStI5kCP}?b9(`bzBI$oW+djCe*!m-8SrAtrj>SNPk;%CL}zMdqU_3E(nxB+N`!V#o*$Y2qMI?_hNMH?6x9EqxR zZ{}+-D8CTK-8ptk447&ptqjN|db6upZk=5Vv?;Ox(p6c5&jE2*0^a2gfDAg)u=(M` z2rI9F{fgjrP-GkL4pJB~Mau;jPFQb*atL&fq+@OVueF&}Wg%tdUR-y2bF;pPMe!3t zQy8G^EVvjPG^O__CW2O+=FLwC{8&Fmg#t@LtU7+ZXEEI}@*=#=@?lseN zK@!_T`Q?8&oc^srU6@bJ(Ws%{wPM(OXUVdyD5(an{Xw9%y{)b0yUQ^UYPPnv+G~o^ z(x~W>Pipz<mc9zLoaue6%HF6A?Kv+kAnC!FI-4YxdAOEXGzK>4cjFWS!L zIAY@qv{D0qywLpcaurvDL=PtzX$h)b=-YFhZ8CeYUf(Jf~u?dq_@>js+mG!EpLI zVZY`#UNVSw!@#i8>h)hQMZE!Y^W%_%sA?ic*t}!VA(o1)6>8z|z6mG6H#P_w}Xi zb}ADaZ|mxOuP)P;fbdiASPHPKE}`>6-$0gP`5dyF|jE+gbXM=XHcUAhbw>_ zHUvfmIs`Ri%!@FyBQHE<$nCk-xj-oE;+3uMFtJI+O#so3><%fRVtl9Tq@$&rqi@~1 zHKc%qG%}6DAp$z|EWo6#4boURi<3LjXTNIbhByZsT>75-t1c!L2xEtaj?RlsoeccY z)wm8;U}j~yp+yhuKE8HY=mZej?_>XI(j#rMfn1a22=7^2JcUrNG~xO8ptFJI%#qd4 z>s*ML+gDZE7M}j;=9u-p8{VZ$9&7BG(gn?3sbO^MEWO`8aUlV$et8w|pn(i1{Iq&E=iUJYZ_`b_o*N%0j<35 zET*aBsQvHK#}>fJu-Uqo>0`2aYnEI{=hUV!KQ-RBHW{p(hW6!&7+>E~Uay}|*`s!_ zv2~y#674#Pit0Rl`gA)ht1)CZu-Oz~`N!nt&4DwH?Lzu0xS5BdXQF)k=w-;vJvPvbT+%wA^5IcX>Js{B(feL?zEgy;Te6&DInxIj^Uur)H`Q{JYS(ySknZ zVI2z$$Zl#;9Ee?F%(^@g;<=X+`iV6-sjkomZQp}c#!Q971TCQcuHMC{1Epv}B{QHp zbaTIW`hk%Ft7A6^MGawQW|&|-!OwsG@Zoj&;Y2tqusJ9YAxWzsjfO#aV(^R5e)I(t zQm!jOf&@~zz9WB*4?lnlTm#bQVBIM*sfDSc}vfnoc zHcp8LJfQ4RThuAPo0d{IINW3Z!L5LtoO~Yk;Z0YbqV8;f-Gj8`Wd8VuVpb&Z{%(mw zc}_1lnX=4BVT4)0ms9ZO1jinri~UoH=YlC#Sg@k1`=317HB0M`BB0-2@f!kadhJ?r zx}~0;YjroY0?5OpDeycxN8KMkdZb0WdzS$Z9v*_!_T#Vcm{y8VIDy6sgR>9r71{v5 za^(t~5)c3Y0+R;1lo!3cyuQ@eW9E2!Q07Lg{qlvf=F1t3Yj}z_oT1NDd5bgLQ}^Xb zbf2FRP;=S^hYa%aPC}0vbsI@D&6>0I@)KzZ2?;e)T=8YF`loXJ;GiF`EoJ6w`x8dKj>g^h~U1w#$2rOJKz8in=AQd}IziD6VEn!pTlm z1B1c(FPrZ_a3ID`1k3$GSI|@X=8+R8LN*o<0yKJS0G0w5LaiV)cVphEAoBL067%G$Zk7ikyml@T{bF-qZ zOthj;p{s}oL~H-vy;m6)s*ilj<{`4OvP$uGw6(oO&qg7pyd9oNM*nr#;MIqc)as7g zMIWb)uWkC@3|QPn;Nnume&~gL`V`J5y=o3eLpr)cA3qi+WLRCktZt7U+BoEy)Gs6= zB1u%lF1z-MO>G1;n`D>r z%H$mj(F5|^5z0sCoDg@QTg$-83N-|d^7E&`7O-NPfI0l1rxH@G7h-#JmX^Ged^@j4 z5sRs={naP}IQZ1ZqDFs^oXr572lBWC-cMJ#e|gh5> zlM*q378)EQ>TzJ>IH>|P^G1F*&qCchj%^tN^Q&OsIlrSqJmH5F#Ct1B=dLr;y8h%H|=2BN?TPAnrEZx)0N zB*VS?_cOrd08R?YV+8u^-Me?Vp~l0xMWvwpfrXhKuy6^yzw_X043z}OE;OWKv_Vxu zXQKs3&NBkRSx%A%aarP<0neVn9$CBB$D*zeRS-^1JSPySzq;{qgswtouB1*Fi!*o6 z;%k=4hOV0-26c4E5W=^BY{^$k_o(2U)rR&~0KE^=DuDcHPv7-|V->0!r8R6@-~ai%6JfYSLt9nROe Date: Sat, 24 Jul 2021 21:46:55 +0300 Subject: [PATCH 27/31] Adjust previously missed scrollbar and firmware validation buttons --- src/displayapp/screens/FirmwareValidation.cpp | 4 ++-- src/displayapp/screens/Label.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index da9d04f2..233ebd5b 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -39,7 +39,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, buttonValidate = lv_btn_create(lv_scr_act(), nullptr); buttonValidate->user_data = this; - lv_obj_set_height(buttonValidate, 50); + lv_obj_set_size(buttonValidate, 115, 50); lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x009900)); @@ -49,7 +49,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, buttonReset = lv_btn_create(lv_scr_act(), nullptr); buttonReset->user_data = this; - lv_obj_set_height(buttonReset, 50); + lv_obj_set_size(buttonReset, 115, 50); lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x990000)); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 0132dbd2..f724fd48 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -6,10 +6,10 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ : Screen(app), labelText {labelText} { if (numScreens > 1) { - pageIndicatorBasePoints[0].x = 240 - 1; - pageIndicatorBasePoints[0].y = 6; - pageIndicatorBasePoints[1].x = 240 - 1; - pageIndicatorBasePoints[1].y = 240 - 6; + pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = 0; + pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = LV_VER_RES; pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); @@ -17,13 +17,13 @@ Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::Displ lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - uint16_t indicatorSize = 228 / numScreens; + uint16_t indicatorSize = LV_VER_RES / numScreens; uint16_t indicatorPos = indicatorSize * screenID; - pageIndicatorPoints[0].x = 240 - 1; - pageIndicatorPoints[0].y = (6 + indicatorPos); - pageIndicatorPoints[1].x = 240 - 1; - pageIndicatorPoints[1].y = (6 + indicatorPos) + indicatorSize; + pageIndicatorPoints[0].x = LV_HOR_RES - 1; + pageIndicatorPoints[0].y = indicatorPos; + pageIndicatorPoints[1].x = LV_HOR_RES - 1; + pageIndicatorPoints[1].y = indicatorPos + indicatorSize; pageIndicator = lv_line_create(lv_scr_act(), NULL); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); From bc829053718f925662ca1dcdc9856426dabef573 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Thu, 29 Jul 2021 21:25:03 +0300 Subject: [PATCH 28/31] Clean up using variables --- .../screens/settings/QuickSettings.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 2d76d2dd..54e2f3e2 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -31,7 +31,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, settingsController {settingsController} { // This is the distance (padding) between all objects on this screen. - const int innerDistance = 10; + static constexpr uint8_t innerDistance = 10; // Time label_time = lv_label_create(lv_scr_act(), nullptr); @@ -43,16 +43,22 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); + static constexpr uint8_t barHeight = 20 + innerDistance; + static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2; + static constexpr uint8_t buttonWidth = (LV_HOR_RES_MAX - innerDistance) / 2; // wide buttons + //static constexpr uint8_t buttonWidth = buttonHeight; // square buttons + static constexpr uint8_t buttonXOffset = (LV_HOR_RES_MAX - buttonWidth * 2 - innerDistance) / 2; + lv_style_init(&btn_style); - lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, (LV_VER_RES - 20 - 2 * innerDistance) / 8); + lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, buttonHeight / 4); lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, lv_color_hex(0x111111)); btn1 = lv_btn_create(lv_scr_act(), nullptr); btn1->user_data = this; lv_obj_set_event_cb(btn1, ButtonEventHandler); lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &btn_style); - lv_obj_set_size(btn1, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); - lv_obj_align(btn1, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 20 + innerDistance); + lv_obj_set_size(btn1, buttonWidth, buttonHeight); + lv_obj_align(btn1, nullptr, LV_ALIGN_IN_TOP_LEFT, buttonXOffset, barHeight); btn1_lvl = lv_label_create(btn1, nullptr); lv_obj_set_style_local_text_font(btn1_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -62,8 +68,8 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn2->user_data = this; lv_obj_set_event_cb(btn2, ButtonEventHandler); lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &btn_style); - lv_obj_set_size(btn2, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); - lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 20 + innerDistance); + lv_obj_set_size(btn2, buttonWidth, buttonHeight); + lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, - buttonXOffset, barHeight); lv_obj_t* lbl_btn; lbl_btn = lv_label_create(btn2, nullptr); @@ -76,8 +82,8 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_btn_set_checkable(btn3, true); lv_obj_add_style(btn3, LV_BTN_PART_MAIN, &btn_style); lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); - lv_obj_set_size(btn3, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); - lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_set_size(btn3, buttonWidth, buttonHeight); + lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, buttonXOffset, 0); btn3_lvl = lv_label_create(btn3, nullptr); lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); @@ -93,8 +99,8 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, btn4->user_data = this; lv_obj_set_event_cb(btn4, ButtonEventHandler); lv_obj_add_style(btn4, LV_BTN_PART_MAIN, &btn_style); - lv_obj_set_size(btn4, (LV_HOR_RES - innerDistance) / 2, (LV_VER_RES - 20 - 2 * innerDistance) / 2); - lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_size(btn4, buttonWidth, buttonHeight); + lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, - buttonXOffset, 0); lbl_btn = lv_label_create(btn4, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); From ee44b6ff4998d6f4d0672c05c1f65c0a9692dc0d Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Thu, 29 Jul 2021 21:49:06 +0300 Subject: [PATCH 29/31] Adjust inner padding in applist --- src/displayapp/screens/Tile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index a64320e6..777b5bb7 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -92,7 +92,7 @@ Tile::Tile(uint8_t screenID, lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_20); lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111)); lv_obj_set_style_local_pad_all(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 0); - lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 6); + lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 10); for (uint8_t i = 0; i < 6; i++) { if (applications[i].application == Apps::None) { From b91100573e474d6bf4aa324b982d190d035dd232 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Wed, 18 Aug 2021 19:20:25 +0300 Subject: [PATCH 30/31] Fix music app buttons --- src/displayapp/screens/Music.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index 99a1518e..257e9aea 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -292,7 +292,7 @@ bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return true; } default: { - return true; + return false; } } } From df8ea7fe523bb9ec0ac3e24f0b1bebe5743d90cc Mon Sep 17 00:00:00 2001 From: hubmartin Date: Mon, 16 Aug 2021 16:42:42 +0200 Subject: [PATCH 31/31] Add memory print usage --- src/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40e1f2a5..f72f50c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -839,7 +839,7 @@ target_compile_options(${EXECUTABLE_NAME} PUBLIC set_target_properties(${EXECUTABLE_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_NAME} @@ -869,7 +869,7 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME} @@ -906,7 +906,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME} @@ -936,7 +936,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME} @@ -977,7 +977,7 @@ add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME} @@ -1010,7 +1010,7 @@ add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES SUFFIX ".out" - LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map" + LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map" ) add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}