diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a01311b6..68f94328 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -426,6 +426,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingChimes.cpp displayapp/screens/settings/SettingShakeThreshold.cpp displayapp/screens/settings/SettingBluetooth.cpp + displayapp/screens/settings/SettingQuickR.cpp ## Watch faces displayapp/screens/WatchFaceAnalog.cpp diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 81cf4923..a18a1ed8 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -13,6 +13,7 @@ namespace Pinetime { enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; + enum class QuickApp : uint8_t { MusicPlayer = 0, Calculator = 1, Alarm = 2, Timer = 3, HeartRate = 4 }; //, Alarm = 5, Timer = 6, Stopwatch = 7 }; enum class Colors : uint8_t { White, Silver, @@ -241,6 +242,34 @@ namespace Pinetime { return getWakeUpModes()[static_cast(mode)]; } + + + + + // New Settings + void SetQuickRModes(QuickApp App_now, bool enabled) { + if (enabled != isQuickROn(App_now)) { + settingsChanged = true; + } + settings.quickApp.set(static_cast(App_now), enabled); + }; + + std::bitset<5> getQuickRModes() const { + return settings.quickApp; + } + + bool isQuickROn(const QuickApp app_holder) const { + return getQuickRModes()[static_cast(app_holder)]; + } + + + + + + + + + void SetBrightness(Controllers::BrightnessController::Levels level) { if (level != settings.brightLevel) { settingsChanged = true; @@ -279,6 +308,7 @@ namespace Pinetime { struct SettingsData { uint32_t version = settingsVersion; uint32_t stepsGoal = 10000; + uint32_t setquickr = 10000; uint32_t screenTimeOut = 15000; ClockType clockType = ClockType::H24; @@ -292,6 +322,7 @@ namespace Pinetime { WatchFaceInfineat watchFaceInfineat; std::bitset<5> wakeUpMode {0}; + std::bitset<5> quickApp {0}; uint16_t shakeWakeThreshold = 150; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index c8a48228..1e951938 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -38,7 +38,8 @@ namespace Pinetime { SettingShakeThreshold, SettingBluetooth, Error, - Calculator + Calculator, + SettingQuickR }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 1ae59f05..8d4e50d8 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -51,6 +51,7 @@ #include "displayapp/screens/settings/SettingChimes.h" #include "displayapp/screens/settings/SettingShakeThreshold.h" #include "displayapp/screens/settings/SettingBluetooth.h" +#include "displayapp/screens/settings/SettingQuickR.h" #include "libs/lv_conf.h" @@ -292,9 +293,9 @@ void DisplayApp::Refresh() { return TouchEvents::SwipeLeft; } }; - + if (!currentScreen->OnTouchEvent(gesture)) { - if (currentApp == Apps::Clock || currentApp == Apps::Music || currentApp == Apps::Calculator || currentApp == Apps::QuickSettings) { + if (currentApp == Apps::Clock || currentApp == Apps::QuickSettings || (currentApp == Apps::Music && quick_app[0]) || (currentApp == Apps::Calculator && quick_app[1]) || (currentApp == Apps::Alarm && quick_app[2]) || (currentApp == Apps::Timer && quick_app[3]) || (currentApp == Apps::HeartRate && quick_app[4])) { switch (gesture) { case TouchEvents::SwipeUp: if (currentApp == Apps::Clock) { @@ -311,26 +312,10 @@ void DisplayApp::Refresh() { } break; case TouchEvents::SwipeRight: - if (currentApp == Apps::Clock) { - LoadNewScreen(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim); - } else if (currentApp == Apps::QuickSettings) { - LoadNewScreen(Apps::Calculator, DisplayApp::FullRefreshDirections::RightAnim); - } else if (currentApp == Apps::Calculator) { - LoadNewScreen(Apps::Music, DisplayApp::FullRefreshDirections::RightAnim); - } else { - LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::RightAnim); - } + gotoquickapp(-1); break; case TouchEvents::SwipeLeft: - if (currentApp == Apps::Clock) { - LoadNewScreen(Apps::Music, DisplayApp::FullRefreshDirections::LeftAnim); - } else if (currentApp == Apps::Music) { - LoadNewScreen(Apps::Calculator, DisplayApp::FullRefreshDirections::LeftAnim); - } else if (currentApp == Apps::Calculator) { - LoadNewScreen(Apps::QuickSettings, DisplayApp::FullRefreshDirections::LeftAnim); - } else { - LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::LeftAnim); - } + gotoquickapp(1); break; case TouchEvents::DoubleTap: PushMessageToSystemTask(System::Messages::GoToSleep); @@ -349,6 +334,7 @@ void DisplayApp::Refresh() { if (!currentScreen->OnButtonPushed()) { if (currentApp == Apps::Clock) { PushMessageToSystemTask(System::Messages::GoToSleep); + } else { LoadPreviousScreen(); } @@ -453,6 +439,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio // break; case Apps::None: case Apps::Clock: + currentQ_app = 2; currentScreen = std::make_unique(dateTimeController, batteryController, bleController, @@ -594,6 +581,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::Calculator: currentScreen = std::make_unique(); break; + case Apps::SettingQuickR: + currentScreen = std::make_unique(settingsController); + break; } currentApp = app; } @@ -653,3 +643,84 @@ void DisplayApp::ApplyBrightness() { } brightnessController.Set(brightness); } + + void DisplayApp::gotoquickapp(int app_step){ + NRF_LOG_INFO("QuickRing Swiped"); + currentQ_app += app_step; + + quick_app = settingsController.getQuickRModes(); + + while(true) + { + if(currentQ_app > 7) + { + currentQ_app = 1; + } else if(currentQ_app < 1) + { + currentQ_app = 7; + } + + if(currentQ_app != 1 && currentQ_app != 2) + { + if(quick_app[currentQ_app-3]) + { + break; + } + else + { + currentQ_app += (app_step); + } + } + else + { + break; + } + } + + + int quickringtotal = 2; + for(int i = 0; i < 5; i++){ + quickringtotal += (quick_app[i] ? 1 : 0 ); + } + + + + NRF_LOG_INFO("case number current Q: %i", currentQ_app); + Apps app = Apps::Clock; + switch (currentQ_app) { + case 1: + app = Apps::QuickSettings; + break; + case 2: + app = Apps::Clock; + break; + case 3: + app = Apps::Music; + break; + case 4: + app = Apps::Calculator; + break; + case 5: + app = Apps::Alarm; + break; + case 6: + app = Apps::Timer; + break; + case 7: + app = Apps::HeartRate; + break; + default: + break; + } + + + if(app_step < 0){ + LoadNewScreen(app, DisplayApp::FullRefreshDirections::RightAnim); + } + else + { + LoadNewScreen(app, DisplayApp::FullRefreshDirections::LeftAnim); + } + //appStackDirections.Pop(); + //returnAppStack.Pop(); + } \ No newline at end of file diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 2c8a3b64..e87e5f1e 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -118,6 +118,8 @@ namespace Pinetime { void LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction); void LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction); void PushMessageToSystemTask(Pinetime::System::Messages message); + void gotoquickapp(int app_step); + Apps nextApp = Apps::None; DisplayApp::FullRefreshDirections nextDirection; @@ -130,6 +132,8 @@ namespace Pinetime { int time_var; bool isDimmed = false; + int currentQ_app = 2; + std::bitset<5> quick_app; }; } } diff --git a/src/displayapp/screens/settings/SettingQuickR.cpp b/src/displayapp/screens/settings/SettingQuickR.cpp new file mode 100644 index 00000000..63bf13f9 --- /dev/null +++ b/src/displayapp/screens/settings/SettingQuickR.cpp @@ -0,0 +1,77 @@ +#include "displayapp/screens/settings/SettingQuickR.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/InfiniTimeTheme.h" + +using namespace Pinetime::Applications::Screens; + +constexpr std::array SettingQuickR::options; + +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + if (event == LV_EVENT_VALUE_CHANGED) { + screen->UpdateSelected(obj); + } + } +} + +SettingQuickR::SettingQuickR(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} { + lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 35); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 20); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Quick Ring"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + + lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::check); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + for (unsigned int i = 0; i < 5; i++) { + cbOption[i] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text(cbOption[i], options[i].name); + if (settingsController.isQuickROn(static_cast(i))) { + lv_checkbox_set_checked(cbOption[i], true); + } + cbOption[i]->user_data = this; + lv_obj_set_event_cb(cbOption[i], event_handler); + } +} + +SettingQuickR::~SettingQuickR() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingQuickR::UpdateSelected(lv_obj_t* object) { + // Find the index of the checkbox that triggered the event + for (size_t i = 0; i < 5; i++) { + if (cbOption[i] == object) { + bool currentState = settingsController.isQuickROn(options[i].quickApp); + settingsController.SetQuickRModes(options[i].quickApp, !currentState); + break; + } + } + + // Update checkbox according to current wakeup modes. + // This is needed because we can have extra logic when setting or unsetting wakeup modes, + // for example, when setting SingleTap, DoubleTap is unset and vice versa. + auto modes = settingsController.getQuickRModes(); + for (size_t i = 0; i < 5; ++i) { + lv_checkbox_set_checked(cbOption[i], modes[i]); + } +} diff --git a/src/displayapp/screens/settings/SettingQuickR.h b/src/displayapp/screens/settings/SettingQuickR.h new file mode 100644 index 00000000..cf70d19e --- /dev/null +++ b/src/displayapp/screens/settings/SettingQuickR.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingQuickR : public Screen { + public: + SettingQuickR(Pinetime::Controllers::Settings& settingsController); + ~SettingQuickR() override; + void UpdateSelected(lv_obj_t* object); + + private: + struct Option { + Controllers::Settings::QuickApp quickApp; + const char* name; + }; + + static constexpr std::array options = {{ + {Controllers::Settings::QuickApp::MusicPlayer, "Music Player"}, + {Controllers::Settings::QuickApp::Calculator, "Calculator"}, + {Controllers::Settings::QuickApp::Alarm, "Alarms"}, + {Controllers::Settings::QuickApp::Timer, "Timer"}, + {Controllers::Settings::QuickApp::HeartRate, "Heart Rate"}, + }}; + + lv_obj_t* cbOption[5]; + Controllers::Settings& settingsController; + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index 3f809753..c21fa234 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -29,7 +29,7 @@ namespace Pinetime { static constexpr int entriesPerScreen = 4; // Increment this when more space is needed - static constexpr int nScreens = 3; + static constexpr int nScreens = 4; static constexpr std::array entries {{ {Symbols::sun, "Display", Apps::SettingDisplay}, @@ -40,11 +40,14 @@ namespace Pinetime { {Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::clock, "Date&Time", Apps::SettingSetDateTime}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, - {Symbols::clock, "Chimes", Apps::SettingChimes}, + {Symbols::check, "QuickRing", Apps::SettingQuickR}, + + {Symbols::clock, "Chimes", Apps::SettingChimes}, {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, {Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth}, + {Symbols::list, "About", Apps::SysInfo}, // {Symbols::none, "None", Apps::None},