diff --git a/main/actions/qraction.cpp b/main/actions/qraction.cpp index cc0e67a..81195db 100644 --- a/main/actions/qraction.cpp +++ b/main/actions/qraction.cpp @@ -1,39 +1 @@ #include "qraction.h" - -#include -#include -#include -#include "displays/qrdisplay.h" -#include "displays/qrimportdisplay.h" - -using namespace espgui; - -SwitchQrDisplayAction::SwitchQrDisplayAction(const qraction::QrMenu &qrmenu) : - m_msg{qrmenu.message} -{ -} - -SwitchQrDisplayAction::SwitchQrDisplayAction(qraction::QrMenu &&qrmenu) : - m_msg{std::move(qrmenu.message)} -{ -} - -void SwitchQrDisplayAction::triggered() -{ - switchScreen(m_msg); -} - -SwitchQrImportDisplayAction::SwitchQrImportDisplayAction(const std::string &nvskey) : - m_nvskey{nvskey} -{ -} - -SwitchQrImportDisplayAction::SwitchQrImportDisplayAction(std::string &&nvskey) : - m_nvskey{std::move(nvskey)} -{ -} - -void SwitchQrImportDisplayAction::triggered() -{ - switchScreen(std::move(m_nvskey)); -} diff --git a/main/actions/qraction.h b/main/actions/qraction.h index 0813a9b..64b72c7 100644 --- a/main/actions/qraction.h +++ b/main/actions/qraction.h @@ -1,9 +1,15 @@ #pragma once -#include +// system includes #include +// 3rdparty lib includes +#include + +// local includes #include "actions/qraction.h" +#include "displays/qrdisplay.h" +#include "displays/qrimportdisplay.h" namespace qraction { struct QrMenu { @@ -12,24 +18,32 @@ struct QrMenu { }; } // namespace +template class SwitchQrDisplayAction : public virtual espgui::ActionInterface { public: - explicit SwitchQrDisplayAction(const qraction::QrMenu &qrmenu); - explicit SwitchQrDisplayAction(qraction::QrMenu &&qrmenu); + explicit SwitchQrDisplayAction(const qraction::QrMenu &qrmenu) : m_msg{qrmenu.message} {} + explicit SwitchQrDisplayAction(qraction::QrMenu &&qrmenu) : m_msg{std::move(qrmenu.message)} {} - void triggered() override; + void triggered() override + { + espgui::switchScreen>(m_msg); + } private: std::string m_msg; }; +template class SwitchQrImportDisplayAction : public virtual espgui::ActionInterface { public: - explicit SwitchQrImportDisplayAction(const std::string &nvskey); - explicit SwitchQrImportDisplayAction(std::string &&nvskey); + explicit SwitchQrImportDisplayAction(const std::string &nvskey) : m_nvskey{nvskey} {} + explicit SwitchQrImportDisplayAction(std::string &&nvskey) : m_nvskey{std::move(nvskey)} {} - void triggered() override; + void triggered() override + { + espgui::switchScreen>(std::move(m_nvskey)); + } private: std::string m_nvskey; }; diff --git a/main/displays/menus/greenpassmenu.cpp b/main/displays/menus/greenpassmenu.cpp index 55c6294..fe56317 100644 --- a/main/displays/menus/greenpassmenu.cpp +++ b/main/displays/menus/greenpassmenu.cpp @@ -53,7 +53,7 @@ public: } else { - espgui::switchScreen(m_qrmenu.message); + espgui::switchScreen>(m_qrmenu.message); } } private: @@ -84,7 +84,7 @@ GreenPassMenu::GreenPassMenu() } else { - constructMenuItem>>(std::move(nvs_key)); + constructMenuItem, StaticText>>(std::move(nvs_key)); } } constructMenuItem, BobbyCheckbox, DeleteModeAccessor>>(); diff --git a/main/displays/qrdisplay.cpp b/main/displays/qrdisplay.cpp index 461182d..c7f8cc3 100644 --- a/main/displays/qrdisplay.cpp +++ b/main/displays/qrdisplay.cpp @@ -1,19 +1,5 @@ #include "qrdisplay.h" -// 3rd party libs -#include -#include - -// local includes -#include "displays/menus/greenpassmenu.h" - -using namespace espgui; - -QrDisplay::QrDisplay(std::string_view msg) : - m_msg{msg} -{ -} - uint16_t get_qrver_from_strlen(std::string_view str) { // alpha numeric, ECC Level M @@ -100,42 +86,3 @@ uint16_t get_qrver_from_strlen(std::string_view str) else return 40; } - -void QrDisplay::initScreen() -{ - QRCode qrcode; - const auto ver = get_qrver_from_strlen(m_msg); - uint8_t qrcodeBytes[qrcode_getBufferSize(ver)]; - qrcode_initText(&qrcode, qrcodeBytes, ver, ECC_MEDIUM, m_msg.data()); - - const uint8_t multiplier = (tft.width() - 9) / qrcode.size; - const uint8_t x_offset = (tft.width() - qrcode.size * multiplier) / 2; - const uint8_t y_offset = (tft.height() - qrcode.size * multiplier) / 2; - - tft.fillScreen(TFT_WHITE); - - for (uint8_t y = 0; y < qrcode.size; y++) { - for (uint8_t x = 0; x < qrcode.size; x++) { - if (qrcode_getModule(&qrcode, x, y)) - { - tft.fillRect(x*multiplier+x_offset,y*multiplier+y_offset, multiplier, multiplier, TFT_BLACK); - } else { - tft.fillRect(x*multiplier+x_offset,y*multiplier+y_offset, multiplier, multiplier, TFT_WHITE); - } - } - } -} - -void QrDisplay::buttonPressed(espgui::Button button) -{ - Base::buttonPressed(button); - - switch (button) - { - case espgui::Button::Left: - case espgui::Button::Right: - switchScreen(); - break; - default:; - } -} diff --git a/main/displays/qrdisplay.h b/main/displays/qrdisplay.h index 353a816..61de52f 100644 --- a/main/displays/qrdisplay.h +++ b/main/displays/qrdisplay.h @@ -1,23 +1,63 @@ #pragma once // 3rd party includes +#include #include // local includes #include "bobbydisplay.h" +#include "screenmanager.h" uint16_t get_qrver_from_strlen(std::string_view str); +template class QrDisplay : public BobbyDisplay { using Base = BobbyDisplay; public: - explicit QrDisplay(std::string_view msg); + explicit QrDisplay(std::string_view msg) : m_msg{msg} {} - void initScreen() override; + void initScreen() override + { + using namespace espgui; + QRCode qrcode; + const auto ver = get_qrver_from_strlen(m_msg); + uint8_t qrcodeBytes[qrcode_getBufferSize(ver)]; + qrcode_initText(&qrcode, qrcodeBytes, ver, ECC_MEDIUM, m_msg.data()); - void buttonPressed(espgui::Button button) override; + const uint8_t multiplier = (tft.width() - 9) / qrcode.size; + const uint8_t x_offset = (tft.width() - qrcode.size * multiplier) / 2; + const uint8_t y_offset = (tft.height() - qrcode.size * multiplier) / 2; + + tft.fillScreen(TFT_WHITE); + + for (uint8_t y = 0; y < qrcode.size; y++) { + for (uint8_t x = 0; x < qrcode.size; x++) { + if (qrcode_getModule(&qrcode, x, y)) + { + tft.fillRect(x*multiplier+x_offset,y*multiplier+y_offset, multiplier, multiplier, TFT_BLACK); + } else { + tft.fillRect(x*multiplier+x_offset,y*multiplier+y_offset, multiplier, multiplier, TFT_WHITE); + } + } + } + } + + void buttonPressed(espgui::Button button) override + { + using namespace espgui; + Base::buttonPressed(button); + + switch (button) + { + case espgui::Button::Left: + case espgui::Button::Right: + switchScreen(); + break; + default:; + } + } private: std::string_view m_msg; diff --git a/main/displays/qrimportdisplay.cpp b/main/displays/qrimportdisplay.cpp index 6eeb53c..e69de29 100644 --- a/main/displays/qrimportdisplay.cpp +++ b/main/displays/qrimportdisplay.cpp @@ -1,109 +0,0 @@ -constexpr const char * const TAG = "qrimport"; -#include "qrimportdisplay.h" - -// 3rd party includes -#include -#include -#include - -// displays/menus includes -#include "displays/menus/greenpassmenu.h" -#include "bobbyerrorhandler.h" - -// local includes -#include "qrimport.h" - -using namespace espgui; - -QrImportDisplay::QrImportDisplay(const std::string &nvs_key) : - m_nvs_key{nvs_key} -{ -} - -QrImportDisplay::QrImportDisplay(std::string &&nvs_key) : - m_nvs_key{std::move(nvs_key)} -{ -} - -void QrImportDisplay::start() -{ - Base::start(); - - m_statuslabel.start(); - - qrimport::setup_request(); - - if (const auto result = qrimport::start_qr_request(); result) - { - ESP_LOGI(TAG, "started request, waiting for result"); - m_waitingForResult = true; - } - else - { - ESP_LOGE(TAG, "could not start request: %.*s", result.error().size(), result.error().data()); - m_result = tl::make_unexpected(std::move(result).error()); - } -} - -void QrImportDisplay::update() -{ - Base::update(); - - if (!m_waitingForResult) - return; - - if (qrimport::get_request_running()) - return; - - m_waitingForResult = false; - - m_result = qrimport::check_request(); - if (m_result) - { - ESP_LOGI(TAG, "%.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result->size(), m_result->data()); - if (const auto result = qrimport::set_qr_code(m_nvs_key, *m_result); !result) - m_result = tl::make_unexpected(fmt::format("saving qr failed: {}", esp_err_to_name(result.error()))); - } - else - ESP_LOGW(TAG, "failed %.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result.error().size(), m_result.error().data()); -} - -void QrImportDisplay::redraw() -{ - Base::redraw(); - - if (m_waitingForResult) - { - tft.setTextColor(TFT_YELLOW, TFT_BLACK); - m_statuslabel.redraw("In progress"); - } - else if (!m_result && !m_result.error().empty()) - { - tft.setTextColor(TFT_RED, TFT_BLACK); - BobbyErrorHandler{}.errorOccured(fmt::format("Error: {}", m_result.error())); - m_result.error().clear(); - } - else - { - tft.setTextColor(TFT_GREEN, TFT_BLACK); - m_statuslabel.redraw("OK"); - switchScreen(); - } -} - -void QrImportDisplay::buttonPressed(espgui::Button button) -{ - Base::buttonPressed(button); - - switch (button) - { - using espgui::Button; - case Button::Left: - if (!m_waitingForResult) - switchScreen(); - else - ESP_LOGW(TAG, "tried to leave while waiting for result"); - break; - default:; - } -} diff --git a/main/displays/qrimportdisplay.h b/main/displays/qrimportdisplay.h index d1b6ead..74c8ca2 100644 --- a/main/displays/qrimportdisplay.h +++ b/main/displays/qrimportdisplay.h @@ -1,26 +1,114 @@ #pragma once +constexpr const char * const TAG = "qrimport"; // 3rd party includes +#include #include #include #include +#include // local includes #include "bobbydisplay.h" +#include "bobbyerrorhandler.h" +#include "qrimport.h" +#include "screenmanager.h" +template class QrImportDisplay : public BobbyDisplay { using Base = BobbyDisplay; public: - explicit QrImportDisplay(const std::string &nvs_key); - explicit QrImportDisplay(std::string &&nvs_key); + explicit QrImportDisplay(const std::string &nvs_key) : m_nvs_key{nvs_key} {} + explicit QrImportDisplay(std::string &&nvs_key) : m_nvs_key{std::move(nvs_key)} {} - void start() override; - void update() override; - void redraw() override; + void start() override + { + using namespace espgui; + Base::start(); - void buttonPressed(espgui::Button button) override; + m_statuslabel.start(); + + qrimport::setup_request(); + + if (const auto result = qrimport::start_qr_request(); result) + { + ESP_LOGI(TAG, "started request, waiting for result"); + m_waitingForResult = true; + } + else + { + ESP_LOGE(TAG, "could not start request: %.*s", result.error().size(), result.error().data()); + m_result = tl::make_unexpected(std::move(result).error()); + } + } + + void update() override + { + using namespace espgui; + Base::update(); + + if (!m_waitingForResult) + return; + + if (qrimport::get_request_running()) + return; + + m_waitingForResult = false; + + m_result = qrimport::check_request(); + if (m_result) + { + ESP_LOGI(TAG, "%.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result->size(), m_result->data()); + if (const auto result = qrimport::set_qr_code(m_nvs_key, *m_result); !result) + m_result = tl::make_unexpected(fmt::format("saving qr failed: {}", esp_err_to_name(result.error()))); + } + else + ESP_LOGW(TAG, "failed %.*s => %.*s", m_nvs_key.size(), m_nvs_key.data(), m_result.error().size(), m_result.error().data()); + } + + void redraw() override + { + using namespace espgui; + Base::redraw(); + + if (m_waitingForResult) + { + tft.setTextColor(TFT_YELLOW, TFT_BLACK); + m_statuslabel.redraw("In progress"); + } + else if (!m_result && !m_result.error().empty()) + { + tft.setTextColor(TFT_RED, TFT_BLACK); + BobbyErrorHandler{}.errorOccured(fmt::format("Error: {}", m_result.error())); + m_result.error().clear(); + } + else + { + tft.setTextColor(TFT_GREEN, TFT_BLACK); + m_statuslabel.redraw("OK"); + switchScreen(); + } + } + + void buttonPressed(espgui::Button button) override + { + using namespace espgui; + Base::buttonPressed(button); + + switch (button) + { + using espgui::Button; + case Button::Left: + if (!m_waitingForResult) + switchScreen(); + else + ESP_LOGW(TAG, "tried to leave while waiting for result"); + break; + default:; + } + } private: bool m_waitingForResult{false};