diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40e1f2a554..75483de95a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -418,6 +418,7 @@ list(APPEND SOURCE_FILES displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp + displayapp/screens/CheckBoxes.cpp ## Settings displayapp/screens/settings/QuickSettings.cpp diff --git a/src/displayapp/screens/CheckBoxes.cpp b/src/displayapp/screens/CheckBoxes.cpp new file mode 100644 index 0000000000..0c99f336a6 --- /dev/null +++ b/src/displayapp/screens/CheckBoxes.cpp @@ -0,0 +1,112 @@ +#include "CheckBoxes.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t* obj, lv_event_t event) { + CheckBoxes* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +CheckBoxes::CheckBoxes(const char* symbol, const char* titleText, Options* options, DisplayApp* app, bool (*UpdateArray)(Options*, uint8_t)) + : Screen(app), options {options}, UpdateArray {UpdateArray} { + + 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, 0); + 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, 40); + lv_obj_set_width(container1, LV_HOR_RES); + lv_obj_set_height(container1, LV_VER_RES - 40); + lv_cont_set_layout(container1, LV_LAYOUT_GRID); + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(title, titleText); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 5); + + 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(icon, symbol); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + for (optionsTotal = 0; optionsTotal < 6; optionsTotal++) { + if (strcmp(options[optionsTotal].title, "") == 0) { + break; + } + } + + lv_style_init(&buttonStyle); + lv_style_set_bg_color(&buttonStyle, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_style_set_bg_opa(&buttonStyle, LV_STATE_CHECKED, LV_OPA_30); + lv_style_set_bg_color(&buttonStyle, LV_STATE_CHECKED, LV_COLOR_AQUA); + if (optionsTotal <= 4) { + lv_style_set_radius(&buttonStyle, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + } + + for (uint8_t i = 0; i < optionsTotal; i++) { + buttons[i] = lv_btn_create(container1, nullptr); + lv_obj_set_style_local_value_str(buttons[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, options[i].title); + lv_obj_add_style(buttons[i], LV_BTN_PART_MAIN, &buttonStyle); + if (optionsTotal <= 4) { + lv_obj_set_size(buttons[i], LV_HOR_RES, 47); + } else { + lv_obj_set_size(buttons[i], 117, 64); + } + if (options[i].state == true) { + lv_obj_add_state(buttons[i], LV_STATE_CHECKED); + } + buttons[i]->user_data = this; + lv_obj_set_event_cb(buttons[i], event_handler); + } +} + +CheckBoxes::~CheckBoxes() { + lv_obj_clean(lv_scr_act()); +} + +bool CheckBoxes::Refresh() { + return running; +} + +void CheckBoxes::UpdateSelected(lv_obj_t* object, lv_event_t event) { + if (event != LV_EVENT_CLICKED) { + return; + } + + uint8_t clicked; + for (clicked = 0; clicked < optionsTotal; clicked++) { + if (object == buttons[clicked]) { + break; + } + } + + if (UpdateArray(options, clicked)) { + for (uint8_t i = 0; i < optionsTotal; i++) { + if (options[i].state) { + lv_obj_add_state(buttons[i], LV_STATE_CHECKED); + } else { + lv_obj_clear_state(buttons[i], LV_STATE_CHECKED); + } + } + } else { + for (uint8_t i = 0; i < optionsTotal; i++) { + if (object == buttons[i]) { + lv_obj_add_state(buttons[i], LV_STATE_CHECKED); + options[i].state = true; + } else { + lv_obj_clear_state(buttons[i], LV_STATE_CHECKED); + options[i].state = false; + } + } + } +} diff --git a/src/displayapp/screens/CheckBoxes.h b/src/displayapp/screens/CheckBoxes.h new file mode 100644 index 0000000000..4781e3f318 --- /dev/null +++ b/src/displayapp/screens/CheckBoxes.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class CheckBoxes : public Screen { + public: + struct Options { + bool state; + const char* title; + }; + CheckBoxes(const char* symbol, const char* titleText, Options *options, DisplayApp* app, bool (*UpdateArray)(Options*, uint8_t)); + ~CheckBoxes() override; + + bool Refresh() override; + void UpdateSelected(lv_obj_t* object, lv_event_t event); + + private: + struct Options* options; + bool (*UpdateArray)(Options* options, uint8_t clicked); + + uint8_t optionsTotal; + lv_obj_t* buttons[6]; + lv_style_t buttonStyle; + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index 4954185df3..389dad9929 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -7,107 +7,53 @@ using namespace Pinetime::Applications::Screens; -namespace { - static void event_handler(lv_obj_t* obj, lv_event_t event) { - SettingDisplay* screen = static_cast(obj->user_data); - screen->UpdateSelected(obj, event); - } -} - SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); - lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); - lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - - lv_obj_set_pos(container1, 10, 60); - lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Display timeout"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); + : Screen(app), settingsController {settingsController}, screen {[this, &settingsController]() { + return CreateScreen(); + }()} { +} - 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::sun); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); +bool SettingDisplay::UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked) { + return false; +} - optionsTotal = 0; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 5 seconds"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetScreenTimeOut() == 5000) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 15 seconds"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetScreenTimeOut() == 15000) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 20 seconds"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetScreenTimeOut() == 20000) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); +std::unique_ptr SettingDisplay::CreateScreen() { + switch (settingsController.GetScreenTimeOut()) { + case 5000: + options[0].state = true; + break; + case 10000: + options[1].state = true; + break; + case 15000: + options[2].state = true; + break; + case 20000: + options[3].state = true; + break; + case 25000: + options[4].state = true; + break; + case 30000: + options[5].state = true; + break; } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 30 seconds"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetScreenTimeOut() == 30000) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; + + return std::make_unique(Symbols::sun, "Display timeout", options, app, UpdateArray); } SettingDisplay::~SettingDisplay() { + for (uint8_t i = 0; i < 6; i++) { + if (options[i].state == true) { + settingsController.SetScreenTimeOut((i + 1) * 5000); + break; + } + } + app->PushMessage(Applications::Display::Messages::UpdateTimeOut); lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); } bool SettingDisplay::Refresh() { - return running; + return screen->Refresh(); } - -void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (int i = 0; i < optionsTotal; i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - - if (i == 0) { - settingsController.SetScreenTimeOut(5000); - }; - if (i == 1) { - settingsController.SetScreenTimeOut(15000); - }; - if (i == 2) { - settingsController.SetScreenTimeOut(20000); - }; - if (i == 3) { - settingsController.SetScreenTimeOut(30000); - }; - - app->PushMessage(Applications::Display::Messages::UpdateTimeOut); - - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } -} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h index b8ed87ec60..4088a2acc3 100644 --- a/src/displayapp/screens/settings/SettingDisplay.h +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -2,26 +2,36 @@ #include #include +#include #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckBoxes.h" namespace Pinetime { - namespace Applications { namespace Screens { - class SettingDisplay : public Screen { public: SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingDisplay() override; bool Refresh() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); + + static bool UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked); private: + CheckBoxes::Options options[6] = { + {false, "5s"}, + {false, "10s"}, + {false, "15s"}, + {false, "20s"}, + {false, "25s"}, + {false, "30s"}, + }; + Controllers::Settings& settingsController; - uint8_t optionsTotal; - lv_obj_t* cbOption[4]; + std::unique_ptr screen; + std::unique_ptr CreateScreen(); }; } } diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp index 031a2a72a3..1b39497f9d 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.cpp +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -6,84 +6,36 @@ using namespace Pinetime::Applications::Screens; -namespace { - static void event_handler(lv_obj_t* obj, lv_event_t event) { - SettingTimeFormat* screen = static_cast(obj->user_data); - screen->UpdateSelected(obj, event); - } -} - SettingTimeFormat::SettingTimeFormat(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); - lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); - lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - - lv_obj_set_pos(container1, 10, 60); - lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Time format"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + : Screen(app), settingsController {settingsController}, screen {[this, &settingsController]() { + return CreateScreen(); + }()} { +} - lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - lv_label_set_text_static(icon, Symbols::clock); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); +bool UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked) { + return false; +} - optionsTotal = 0; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 12-hour"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); +std::unique_ptr SettingTimeFormat::CreateScreen() { if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); + options[0].state = true; + } else { + options[1].state = true; } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " 24-hour"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; + return std::make_unique(Symbols::clock, "Time format", options, app, UpdateArray); } SettingTimeFormat::~SettingTimeFormat() { + if (options[0].state == true) { + settingsController.SetClockType(Controllers::Settings::ClockType::H12); + } else { + settingsController.SetClockType(Controllers::Settings::ClockType::H24); + } lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); } bool SettingTimeFormat::Refresh() { - return running; + return screen->Refresh(); } - -void SettingTimeFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (int i = 0; i < optionsTotal; i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - - if (i == 0) { - settingsController.SetClockType(Controllers::Settings::ClockType::H12); - }; - if (i == 1) { - settingsController.SetClockType(Controllers::Settings::ClockType::H24); - }; - - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } -} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h index 9203b45be8..898c0c60b2 100644 --- a/src/displayapp/screens/settings/SettingTimeFormat.h +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -2,26 +2,31 @@ #include #include +#include #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckBoxes.h" namespace Pinetime { - namespace Applications { namespace Screens { - class SettingTimeFormat : public Screen { public: SettingTimeFormat(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingTimeFormat() override; bool Refresh() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); private: + CheckBoxes::Options options[3] = { + {false, "12-hour"}, + {false, "24-hour"}, + {false, ""}, + }; + Controllers::Settings& settingsController; - uint8_t optionsTotal; - lv_obj_t* cbOption[2]; + std::unique_ptr screen; + std::unique_ptr CreateScreen(); }; } } diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index cce9a60d8d..22c342b29a 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -7,101 +7,49 @@ using namespace Pinetime::Applications::Screens; -namespace { - static void event_handler(lv_obj_t* obj, lv_event_t event) { - SettingWakeUp* screen = static_cast(obj->user_data); - screen->UpdateSelected(obj, event); +bool SettingWakeUp::UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked) { + options[clicked].state = !options[clicked].state; + if (clicked == 0) { + if (options[0].state) { + options[1].state = false; + } + } else if (clicked == 1) { + if (options[1].state) { + options[0].state = false; + } } + return true; } SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - ignoringEvents = false; - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); - lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); - lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); - lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - - lv_obj_set_pos(container1, 10, 60); - lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Wake Up"); - 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::eye); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + : Screen(app), settingsController {settingsController}, screen {[this, &settingsController]() { + return CreateScreen(); + }()} { +} - optionsTotal = 0; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); +std::unique_ptr SettingWakeUp::CreateScreen() { if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); + options[0].state = true; } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); + options[1].state = true; } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); + options[2].state = true; } - optionsTotal++; + + return std::make_unique(Symbols::eye, "Wake Up", options, app, UpdateArray); } SettingWakeUp::~SettingWakeUp() { + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::SingleTap, options[0].state); + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap, options[1].state); + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist, options[2].state); + lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); } bool SettingWakeUp::Refresh() { - return running; -} - -void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) { - using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode; - if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) { - ignoringEvents = true; - - // Find the index of the checkbox that triggered the event - int index = 0; - for (; index < optionsTotal; ++index) { - if (cbOption[index] == object) { - break; - } - } - - // Toggle needed wakeup mode - auto mode = static_cast(index); - auto currentState = settingsController.isWakeUpModeOn(mode); - settingsController.setWakeUpMode(mode, !currentState); - - // Update checkbox according to current wakeup modes. - // This is needed because we can have extra logic when setting or unsetting wakeup modes, - // for example, when setting SingleTap, DoubleTap is unset and vice versa. - auto modes = settingsController.getWakeUpModes(); - for (int i = 0; i < optionsTotal; ++i) { - lv_checkbox_set_checked(cbOption[i], modes[i]); - } - - ignoringEvents = false; - } + return screen->Refresh(); } diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 248dd9acfd..8e31660c0a 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -2,31 +2,34 @@ #include #include +#include #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckBoxes.h" namespace Pinetime { - namespace Applications { namespace Screens { - class SettingWakeUp : public Screen { public: SettingWakeUp(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWakeUp() override; bool Refresh() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); + + static bool UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked); private: + CheckBoxes::Options options[4] = { + {false, "Single Tap"}, + {false, "Double Tap"}, + {false, "Raise Wrist"}, + {false, ""}, + }; + Controllers::Settings& settingsController; - uint8_t optionsTotal; - lv_obj_t* cbOption[4]; - // When UpdateSelected is called, it uses lv_checkbox_set_checked, - // which can cause extra events to be fired, - // which might trigger UpdateSelected again, causing a loop. - // This variable is used as a mutex to prevent that. - bool ignoringEvents; + std::unique_ptr screen; + std::unique_ptr CreateScreen(); }; } } diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index 02b9081608..80d424a272 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -6,88 +6,34 @@ using namespace Pinetime::Applications::Screens; -namespace { - static void event_handler(lv_obj_t* obj, lv_event_t event) { - SettingWatchFace* screen = static_cast(obj->user_data); - screen->UpdateSelected(obj, event); - } -} - SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : Screen(app), settingsController {settingsController} { - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - // lv_obj_set_style_local_bg_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_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - - lv_obj_set_pos(container1, 10, 60); - lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, "Watch face"); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); - - lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - lv_label_set_text_static(icon, Symbols::home); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); - - optionsTotal = 0; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Digital face"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetClockFace() == 0) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } + : Screen(app), settingsController {settingsController}, screen {[this, &settingsController]() { + return CreateScreen(); + }()} { +} - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " Analog face"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetClockFace() == 1) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } +bool SettingWatchFace::UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked) { + return false; +} - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " PineTimeStyle"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.GetClockFace() == 2) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } +std::unique_ptr SettingWatchFace::CreateScreen() { + options[settingsController.GetClockFace()].state = true; - optionsTotal++; + return std::make_unique(Symbols::home, "Watch face", options, app, UpdateArray); } SettingWatchFace::~SettingWatchFace() { + for (uint8_t i = 0; i < 3; i++) { + if (options[i].state == true) { + settingsController.SetClockFace(i); + break; + } + } + lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); } bool SettingWatchFace::Refresh() { - return running; -} - -void SettingWatchFace::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (uint8_t i = 0; i < optionsTotal; i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - settingsController.SetClockFace(i); - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } + return screen->Refresh(); } diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 1930a22853..a3201d313b 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -2,26 +2,34 @@ #include #include +#include #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" +#include "displayapp/screens/CheckBoxes.h" namespace Pinetime { - namespace Applications { namespace Screens { - class SettingWatchFace : public Screen { public: SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); ~SettingWatchFace() override; bool Refresh() override; - void UpdateSelected(lv_obj_t* object, lv_event_t event); + + static bool UpdateArray(Pinetime::Applications::Screens::CheckBoxes::Options* options, uint8_t clicked); private: + CheckBoxes::Options options[4] = { + {false, "Digital face"}, + {false, "Analog face"}, + {false, "PineTimeStyle"}, + {false, ""}, + }; + Controllers::Settings& settingsController; - uint8_t optionsTotal; - lv_obj_t* cbOption[2]; + std::unique_ptr screen; + std::unique_ptr CreateScreen(); }; } }