diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 25ea2b4..ea1983f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -136,6 +136,7 @@ set(headers displays/menus/enablemenu.h displays/menus/espnowmenu.h displays/menus/espnowsettingsmenu.h + displays/menus/extrabuttoncalibratemenu.h displays/menus/feedbackdebugmenu.h displays/menus/gametrakmodesettingsmenu.h displays/menus/garagenmenu.h @@ -360,6 +361,7 @@ set(sources displays/menus/enablemenu.cpp displays/menus/espnowmenu.cpp displays/menus/espnowsettingsmenu.cpp + displays/menus/extrabuttoncalibratemenu.cpp displays/menus/feedbackdebugmenu.cpp displays/menus/gametrakmodesettingsmenu.cpp displays/menus/garagenmenu.cpp diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 736ea58..19cfde2 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -238,3 +238,19 @@ struct ESPNowSyncTimeEnabledAccessor : public RefAccessorSaveSettings { bo struct ESPNowSyncTimeWithOthersEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.espnow.syncTimeWithOthers; } }; struct ESPNowSyncBlinkEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.espnow.syncBlink; } }; #endif + +// Button Mapping accessors +struct ButtonLeftAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingLeft; } }; +struct ButtonRightAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingRight; } }; +struct ButtonUpAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingUp; } }; +struct ButtonDownAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingDown; } }; + +struct ButtonLeft2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingLeft2; } }; +struct ButtonRight2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingRight2; } }; +struct ButtonUp2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingUp2; } }; +struct ButtonDown2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingDown2; } }; + +struct ButtonProfile0Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingProfile0; } }; +struct ButtonProfile1Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingProfile1; } }; +struct ButtonProfile2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingProfile2; } }; +struct ButtonProfile3Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.dpadMappingProfile3; } }; diff --git a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp index 0ae86cb..b8b38fd 100644 --- a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp +++ b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp @@ -18,10 +18,12 @@ #include "displays/menus/timersmenu.h" #include "displays/menus/settingsmenu.h" #include "displays/buttoncalibratedisplay.h" +#include "displays/menus/extrabuttoncalibratemenu.h" namespace { constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings"; constexpr char TEXT_BUTTONCALIBRATE[] = "Button Calibrate"; +constexpr char TEXT_EXTRABUTTONCALIBRATE[] = "Cal other Buttons"; constexpr char TEXT_LOCKSCREENSETTINGS[] = "Lockscreen Settings"; constexpr char TEXT_POTISCALIBRATE[] = "Potis Calibrate"; constexpr char TEXT_SAMPLECOUNT[] = "sampleCount"; @@ -174,6 +176,7 @@ BoardcomputerHardwareSettingsMenu::BoardcomputerHardwareSettingsMenu() { constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::lock>>>(); constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); constructMenuItem, DummyAction>>(); constructMenuItem, DummyAction>>(); constructMenuItem, SwitchScreenAction>>(); diff --git a/main/displays/menus/extrabuttoncalibratemenu.cpp b/main/displays/menus/extrabuttoncalibratemenu.cpp new file mode 100644 index 0000000..92bc6a2 --- /dev/null +++ b/main/displays/menus/extrabuttoncalibratemenu.cpp @@ -0,0 +1,246 @@ +#include "extrabuttoncalibratemenu.h" + +// 3rd party includes +#include +#include +#include +#include + +// local includes +#include "esp_log.h" +#include "accessors/settingsaccessors.h" +#include "actions/switchscreenaction.h" +#include "bobbyerrorhandler.h" +#include "displays/menus/boardcomputerhardwaresettingsmenu.h" +#include "globals.h" + +using namespace espgui; + +namespace { +Status currentStatus; + +constexpr const char TAG[] = "BUTTON"; + +constexpr char TEXT_EXTRABUTTONCALIBRATEMENU[] = "Calibrate Buttons"; +constexpr char TEXT_BUTTON_LEFT2[] = "Left2"; +constexpr char TEXT_BUTTON_RIGHT2[] = "Right2"; +constexpr char TEXT_BUTTON_UP2[] = "Up2"; +constexpr char TEXT_BUTTON_DOWN2[] = "Down2"; + +constexpr char TEXT_BUTTON_PROFILE0[] = "Profile0"; +constexpr char TEXT_BUTTON_PROFILE1[] = "Profile1"; +constexpr char TEXT_BUTTON_PROFILE2[] = "Profile2"; +constexpr char TEXT_BUTTON_PROFILE3[] = "Profile3"; + +constexpr char TEXT_BACK[] = "Back"; + +template +class ButtonCalibrateMenuItem : + public MenuItem, + public TextWithValueHelper +{ + using StandardText = TextWithValueHelper; +public: + void triggered() override + { + ESP_LOGI(TAG, "Pressed menu item for %s", Tprefix); + currentStatus = status; + } + + int color() const override + { + return (status == currentStatus || currentStatus == Idle) ? TFT_WHITE : TFT_DARKGREY; + } + + std::string text() const override + { + if (status == currentStatus) + { + return fmt::format("Press {}", Tprefix); + } + else + { + return StandardText::text(); + } + } +}; + +} // namespace + +ExtraButtonCalibrateMenu::ExtraButtonCalibrateMenu() +{ + constructMenuItem>(); + constructMenuItem>(); + constructMenuItem>(); + constructMenuItem>(); + + constructMenuItem>(); + constructMenuItem>(); + constructMenuItem>(); + constructMenuItem>(); + + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void ExtraButtonCalibrateMenu::start() +{ + Base::start(); + m_oldMode = currentMode; + currentMode = &m_mode; + currentStatus = Idle; +} + +void ExtraButtonCalibrateMenu::update() +{ + Base::update(); +} + +void ExtraButtonCalibrateMenu::stop() +{ + Base::stop(); + + if (currentMode == &m_mode) + { + m_mode.stop(); + lastMode = nullptr; + currentMode = m_oldMode; + } +} + +void ExtraButtonCalibrateMenu::rawButtonPressed(uint8_t button) +{ + if (currentStatus == Idle) + { + Base::rawButtonPressed(button); + } + else + { + if (validateNewButton(button)) + { + ESP_LOGI(TAG, "Valid new button: %i", button); + switch(currentStatus) + { + case WaitingUp2: + if (auto result = configs.write_config(configs.dpadMappingUp2, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingDown2: + if (auto result = configs.write_config(configs.dpadMappingDown2, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingLeft2: + if (auto result = configs.write_config(configs.dpadMappingLeft2, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingRight2: + if (auto result = configs.write_config(configs.dpadMappingRight2, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingProfile0: + if (auto result = configs.write_config(configs.dpadMappingProfile0, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingProfile1: + if (auto result = configs.write_config(configs.dpadMappingProfile1, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingProfile2: + if (auto result = configs.write_config(configs.dpadMappingProfile2, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + case WaitingProfile3: + if (auto result = configs.write_config(configs.dpadMappingProfile3, button); !result) + { + BobbyErrorHandler{}.errorOccured(std::move(result).error()); + break; + } + break; + default: + break; + } + currentStatus = Idle; + } + else + { + ESP_LOGE(TAG, "Invalid new button: %i", button); + currentStatus = Idle; + } + } +} + +void ExtraButtonCalibrateMenu::rawButtonReleased(uint8_t button) +{ +// if (currentStatus == Idle) +// { +// Base::rawButtonReleased(button); +// } +} + +void ExtraButtonCalibrateMenu::buttonPressed(espgui::Button button) +{ + if (currentStatus == Idle) + { + Base::buttonPressed(button); + } + else + { + switch (button) + { + case Left: + ESP_LOGI(TAG, "Canceling procedure"); + currentStatus = Idle; + break; + default: + break; + } + } +} + +void ExtraButtonCalibrateMenu::buttonReleased(espgui::Button button) +{ +// if (currentStatus == Idle) +// { +// Base::buttonReleased(button); +// } +} + +std::string ExtraButtonCalibrateMenu::text() const +{ + return TEXT_EXTRABUTTONCALIBRATEMENU; +} + +void ExtraButtonCalibrateMenu::back() +{ + switchScreen(); +} + +bool ExtraButtonCalibrateMenu::validateNewButton(uint8_t button) +{ + return ( + button != configs.dpadMappingDown.value && + button != configs.dpadMappingUp.value && + button != configs.dpadMappingLeft.value && + button != configs.dpadMappingRight.value + ); +} diff --git a/main/displays/menus/extrabuttoncalibratemenu.h b/main/displays/menus/extrabuttoncalibratemenu.h new file mode 100644 index 0000000..d336fd8 --- /dev/null +++ b/main/displays/menus/extrabuttoncalibratemenu.h @@ -0,0 +1,45 @@ +#pragma once + +// local includes +#include "displays/bobbymenudisplay.h" +#include "modeinterface.h" +#include "modes/ignoreinputmode.h" + +namespace { +enum Status : uint8_t +{ + Idle, + WaitingLeft2, + WaitingRight2, + WaitingUp2, + WaitingDown2, + WaitingProfile0, + WaitingProfile1, + WaitingProfile2, + WaitingProfile3 +}; +} // namespace + +class ExtraButtonCalibrateMenu : + public BobbyMenuDisplay +{ + using Base = BobbyMenuDisplay; +public: + ExtraButtonCalibrateMenu(); + std::string text() const override; + void back() override; + + void start() override; + void update() override; + void stop() override; + + void rawButtonPressed(uint8_t button) override; + void rawButtonReleased(uint8_t button) override; + void buttonPressed(espgui::Button button) override; + void buttonReleased(espgui::Button button) override; + +private: + ModeInterface *m_oldMode; + IgnoreInputMode m_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque}; + bool validateNewButton(uint8_t button); +};