diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 871ff3b6cf..d4bab4ad12 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -5,6 +5,7 @@ #include "components/brightness/BrightnessController.h" #include "components/fs/FS.h" #include "drivers/Cst816s.h" +#include "displayapp/Apps.h" namespace Pinetime { namespace Controllers { @@ -31,6 +32,17 @@ namespace Pinetime { void Init(); void SaveSettings(); + void SetFavoriteApp(Applications::Apps app){ + if (app != settings.favoriteApp) { + settingsChanged = true; + } + settings.favoriteApp = app; + } + + Applications::Apps GetFavoriteApp(){ + return settings.favoriteApp; + } + void SetClockFace(uint8_t face) { if (face != settings.clockFace) { settingsChanged = true; @@ -179,6 +191,8 @@ namespace Pinetime { std::bitset<3> wakeUpMode {0}; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; + + Applications::Apps favoriteApp = Applications::Apps::None; }; SettingsData settings; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 837082ddd9..fff0518210 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -218,7 +218,13 @@ void DisplayApp::Refresh() { if (currentApp == Apps::Clock) { switch (gesture) { case TouchEvents::SwipeUp: - LoadApp(Apps::Launcher, DisplayApp::FullRefreshDirections::Up); + if (favoriteAppActive) { + favoriteAppActive = false; + LoadApp(Apps::Launcher, DisplayApp::FullRefreshDirections::Up); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); + } else { + LoadApp(Apps::Launcher, DisplayApp::FullRefreshDirections::Up); + } break; case TouchEvents::SwipeDown: LoadApp(Apps::Notifications, DisplayApp::FullRefreshDirections::Down); @@ -226,6 +232,19 @@ void DisplayApp::Refresh() { case TouchEvents::SwipeRight: LoadApp(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim); break; + case TouchEvents::SwipeLeft: + favoriteApp = settingsController.GetFavoriteApp(); + favoriteAppActive = true; + if (favoriteApp == Apps::None) { + if (previousApp != Apps::None) { + LoadApp(previousApp, DisplayApp::FullRefreshDirections::LeftAnim); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); + } + } else { + LoadApp(favoriteApp, DisplayApp::FullRefreshDirections::LeftAnim); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown); + } + break; case TouchEvents::DoubleTap: PushMessageToSystemTask(System::Messages::GoToSleep); break; @@ -246,7 +265,12 @@ void DisplayApp::Refresh() { PushMessageToSystemTask(System::Messages::GoToSleep); } else { if (!currentScreen->OnButtonPushed()) { - LoadApp(returnToApp, returnDirection); + if (favoriteAppActive) { + favoriteAppActive = false; + LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::RightAnim); + } else { + LoadApp(returnToApp, returnDirection); + } brightnessController.Set(settingsController.GetBrightness()); brightnessController.Backup(); } @@ -414,6 +438,10 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, motionController, settingsController); break; } + Apps* NotBlacklistedReturnApp = std::find(std::begin(blackListReturnApps), std::end(blackListReturnApps), currentApp); + if (NotBlacklistedReturnApp == std::end(blackListReturnApps)) { + previousApp = currentApp; + } currentApp = app; } diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 63e898f02a..a67d19cf51 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -102,7 +102,11 @@ namespace Pinetime { std::unique_ptr currentScreen; Apps currentApp = Apps::None; + Apps previousApp = Apps::None; Apps returnToApp = Apps::None; + Apps favoriteApp = Apps::None; + bool favoriteAppActive = false; + FullRefreshDirections returnDirection = FullRefreshDirections::None; TouchEvents returnTouchEvent = TouchEvents::None; @@ -115,6 +119,13 @@ namespace Pinetime { void PushMessageToSystemTask(Pinetime::System::Messages message); Apps nextApp = Apps::None; + Apps blackListReturnApps[7] = {Apps::Clock, + Apps::Launcher, + Apps::QuickSettings, + Apps::Notifications, + Apps::NotificationsPreview, + Apps::Settings, + Apps::QuickSettings}; DisplayApp::FullRefreshDirections nextDirection; }; } diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp index 064b47a6c1..2608be6a43 100644 --- a/src/displayapp/screens/List.cpp +++ b/src/displayapp/screens/List.cpp @@ -17,7 +17,7 @@ List::List(uint8_t screenID, DisplayApp* app, Controllers::Settings& settingsController, std::array& applications) - : Screen(app), settingsController {settingsController} { + : Screen(app), settingsController {settingsController}, motorController {motorController} { // Set the background to Black lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0)); @@ -84,6 +84,9 @@ List::List(uint8_t screenID, labelBt = lv_label_create(itemApps[i], nullptr); lv_label_set_text_fmt(labelBt, " %s", applications[i].name); + if (applications[i].application == settingsController.GetFavoriteApp()) { + lv_btn_set_state(itemApps[i], LV_BTN_STATE_CHECKED_PRESSED); + } } } @@ -99,13 +102,35 @@ List::~List() { } void List::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_CLICKED) { - for (int i = 0; i < MAXLISTITEMS; i++) { - if (apps[i] != Apps::None && object == itemApps[i]) { - app->StartApp(apps[i], DisplayApp::FullRefreshDirections::Up); - running = false; - return; - } + if (event == LV_EVENT_SHORT_CLICKED or event == LV_EVENT_LONG_PRESSED) { + switch (event) { + case LV_EVENT_SHORT_CLICKED: { + for (int i = 0; i < MAXLISTITEMS; i++) { + if (apps[i] != Apps::None && object == itemApps[i]) { + app->StartApp(apps[i], DisplayApp::FullRefreshDirections::Up); + running = false; + return; + } + } + } break; + case LV_EVENT_LONG_PRESSED: { + for (int i = 0; i < MAXLISTITEMS; i++) { + if (apps[i] != Apps::None) { + lv_btn_set_state(itemApps[i], LV_BTN_STATE_RELEASED); + } + if (apps[i] != Apps::None && object == itemApps[i]) { + if (settingsController.GetFavoriteApp() == apps[i]) { + settingsController.SetFavoriteApp(Apps::None); + } else { + settingsController.SetFavoriteApp(apps[i]); + lv_btn_set_state(itemApps[i], LV_BTN_STATE_CHECKED_PRESSED); + } + } + } + motorController.RunForDuration(35); + } break; + default: + break; } } } diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h index d9f61f2910..74b13f9370 100644 --- a/src/displayapp/screens/List.h +++ b/src/displayapp/screens/List.h @@ -6,6 +6,7 @@ #include "Screen.h" #include "../Apps.h" #include "components/settings/Settings.h" +#include "components/motor/MotorController.h" #define MAXLISTITEMS 4 @@ -32,6 +33,7 @@ namespace Pinetime { private: Controllers::Settings& settingsController; Pinetime::Applications::Apps apps[MAXLISTITEMS]; + Controllers::MotorController& motorController; lv_obj_t* itemApps[MAXLISTITEMS]; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 1d4f0d0ef7..bd1dc0ef17 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -1,6 +1,7 @@ #include "Tile.h" #include "../DisplayApp.h" #include "BatteryIcon.h" +#include "Symbols.h" using namespace Pinetime::Applications::Screens; @@ -11,12 +12,8 @@ namespace { } static void event_handler(lv_obj_t* obj, lv_event_t event) { - if (event != LV_EVENT_VALUE_CHANGED) return; - Tile* screen = static_cast(obj->user_data); - auto* eventDataPtr = (uint32_t*) lv_event_get_data(); - uint32_t eventData = *eventDataPtr; - screen->OnValueChangedEvent(obj, eventData); + screen->OnValueChangedEvent(obj, event); } } @@ -27,7 +24,11 @@ Tile::Tile(uint8_t screenID, Pinetime::Controllers::Battery& batteryController, Controllers::DateTime& dateTimeController, std::array& applications) - : Screen(app), batteryController {batteryController}, dateTimeController {dateTimeController} { + : Screen(app), + batteryController {batteryController}, + dateTimeController {dateTimeController}, + settingsController {settingsController}, + motorController {motorController} { settingsController.SetAppMenu(screenID); @@ -98,6 +99,8 @@ Tile::Tile(uint8_t screenID, lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_CLICK_TRIG); if (applications[i].application == Apps::None) { lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_DISABLED); + } else if (applications[i].application == settingsController.GetFavoriteApp()) { + lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_CHECK_STATE); } } @@ -123,9 +126,26 @@ void Tile::UpdateScreen() { lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); } -void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { - if(obj != btnm1) return; - - app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Up); - running = false; +void Tile::OnValueChangedEvent(lv_obj_t* obj, lv_event_t event) { + if (obj != btnm1) + return; + uint8_t lastPressedButton = lv_btnmatrix_get_active_btn(obj); + switch (event) { + case LV_EVENT_SHORT_CLICKED: { + app->StartApp(apps[lastPressedButton], DisplayApp::FullRefreshDirections::Up); + running = false; + break; + } + case LV_EVENT_LONG_PRESSED: { + lv_btnmatrix_clear_btn_ctrl_all(btnm1, LV_BTNMATRIX_CTRL_CHECK_STATE); + if (settingsController.GetFavoriteApp() == apps[lastPressedButton]) { + settingsController.SetFavoriteApp(Apps::None); + } else { + settingsController.SetFavoriteApp(apps[lastPressedButton]); + lv_btnmatrix_set_btn_ctrl(btnm1, lastPressedButton, LV_BTNMATRIX_CTRL_CHECK_STATE); + } + motorController.RunForDuration(35); + break; + } + } } diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 83d3fdf5fa..25b7fc14fd 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -9,6 +9,7 @@ #include "components/settings/Settings.h" #include "components/datetime/DateTimeController.h" #include "components/battery/BatteryController.h" +#include "components/motor/MotorController.h" namespace Pinetime { namespace Applications { @@ -31,11 +32,13 @@ namespace Pinetime { ~Tile() override; void UpdateScreen(); - void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId); + void OnValueChangedEvent(lv_obj_t* obj, lv_event_t event); private: Pinetime::Controllers::Battery& batteryController; Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + Controllers::MotorController& motorController; lv_task_t* taskUpdate;