diff --git a/CMakeLists.txt b/CMakeLists.txt index 96fac73..e04ed1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ set(headers src/richtextrenderer.h src/screenmanager.h src/scrollinterface.h + src/selectorscrollinterface.h src/splitgraphdisplay.h src/textinterface.h src/textwithvaluehelper.h diff --git a/src/buttonsinterface.h b/src/buttonsinterface.h index 143bb5f..4b455ba 100644 --- a/src/buttonsinterface.h +++ b/src/buttonsinterface.h @@ -22,6 +22,7 @@ public: virtual void buttonPressed(Button button) = 0; virtual void buttonReleased(Button button) = 0; + virtual void buttonHeld(Button button) {}; }; } // namespace espgui diff --git a/src/menudisplay.cpp b/src/menudisplay.cpp index bfdcb68..6e50e1d 100644 --- a/src/menudisplay.cpp +++ b/src/menudisplay.cpp @@ -3,6 +3,10 @@ // local includes #include "tftinstance.h" +#include "esp_log.h" + +using namespace std::chrono_literals; + namespace espgui { void MenuDisplay::start() { @@ -13,6 +17,18 @@ void MenuDisplay::start() m_rotateOffset = 0; m_pressed = false; + + m_upScrolling = false; + m_upHoldingSince = std::nullopt; + + m_downScrolling = false; + m_downHoldingSince = std::nullopt; + + m_leftScrolling = false; + m_leftHoldingSince = std::nullopt; + + m_rightScrolling = false; + m_rightHoldingSince = std::nullopt; } void MenuDisplay::initScreen() @@ -35,6 +51,84 @@ void MenuDisplay::update() { Base::update(); + { + const auto ago = espchrono::ago(*m_upHoldingSince); + if (m_upHoldingSince && (m_upScrolling || ago > getInitialScrollSpeed())) + { + if (ago > getScrollSpeed()) + { + if (!m_upScrolling) + { + // gets executed one time + buttonHeld(espgui::Up); + } + m_upScrolling = true; + m_upHoldingSince = espchrono::millis_clock::now(); + + // do sth + m_rotateOffset--; + } + } + } + + { + const auto ago = espchrono::ago(*m_downHoldingSince); + if (m_downHoldingSince && (m_downScrolling || ago > getInitialScrollSpeed())) + { + if (ago > getScrollSpeed()) + { + if (!m_downScrolling) + { + // gets executed one time + buttonHeld(espgui::Down); + } + m_downScrolling = true; + m_downHoldingSince = espchrono::millis_clock::now(); + + // do sth + m_rotateOffset++; + } + } + } + + { + const auto ago = espchrono::ago(*m_leftHoldingSince); + if (m_leftHoldingSince && (m_leftScrolling || ago > getInitialScrollSpeed())) + { + if (ago > getScrollSpeed()) + { + if (!m_leftScrolling) + { + // gets executed one time + buttonHeld(espgui::Left); + } + m_leftScrolling = true; + m_leftHoldingSince = espchrono::millis_clock::now(); + + // do sth + } + } + } + + { + const auto ago = espchrono::ago(*m_rightHoldingSince); + if (m_rightHoldingSince && (m_rightScrolling || ago > getInitialScrollSpeed())) + { + if (ago > getScrollSpeed()) + { + if (!m_rightScrolling) + { + // gets executed one time + buttonHeld(espgui::Right); + } + m_rightScrolling = true; + m_rightHoldingSince = espchrono::millis_clock::now(); + + // do sth + } + } + } + if (!m_pressed) { const auto offset = m_rotateOffset; @@ -195,16 +289,29 @@ void MenuDisplay::buttonPressed(Button button) switch (button) { - case Button::Left: this->back(); break; - case Button::Right: m_pressed = true; break; - case Button::Up: m_rotateOffset--; break; - case Button::Down: m_rotateOffset++; break; + case Button::Left: this->back(); m_leftHoldingSince = espchrono::millis_clock::now(); m_leftScrolling = false; break; + case Button::Right: m_pressed = true; m_rightHoldingSince = espchrono::millis_clock::now(); m_rightScrolling = false; break; + case Button::Up: m_rotateOffset--; m_upHoldingSince = espchrono::millis_clock::now(); m_upScrolling = false; break; + case Button::Down: m_rotateOffset++; m_downHoldingSince = espchrono::millis_clock::now(); m_downScrolling = false; break; } } void MenuDisplay::buttonReleased(Button button) { //Base::buttonPressed(button); - // TODO stop auto scroll + + switch (button) + { + case Button::Up: m_upHoldingSince = std::nullopt; break; + case Button::Down: m_downHoldingSince = std::nullopt; break; + case Button::Left: m_leftHoldingSince = std::nullopt; break; + case Button::Right: m_rightHoldingSince = std::nullopt; break; + default:; + } +} + +void MenuDisplay::buttonHeld(Button button) +{ + ESP_LOGI("Menudisplay", "buttonHeld %d", button); } } // namespace espgui diff --git a/src/menudisplay.h b/src/menudisplay.h index 102841a..e8d2295 100644 --- a/src/menudisplay.h +++ b/src/menudisplay.h @@ -8,18 +8,25 @@ #include #include #include +#include + +// 3rdparty lib includes +#include // local includes #include "displaywithtitle.h" +#include "selectorscrollinterface.h" #include "textinterface.h" #include "widgets/label.h" #include "menuitem.h" #include "backinterface.h" namespace espgui { + using namespace std::chrono_literals; class MenuDisplay : public DisplayWithTitle, - public virtual BackInterface + public virtual BackInterface, + public virtual SelectorScrollInterface<> { using Base = DisplayWithTitle; @@ -32,6 +39,7 @@ public: void buttonPressed(Button button) override; void buttonReleased(Button button) override; + void buttonHeld(Button button) override; MenuDisplay *asMenuDisplay() override { return this; } const MenuDisplay *asMenuDisplay() const override { return this; } @@ -146,5 +154,17 @@ private: bool m_pressed; std::vector> m_menuItems; + + bool m_upScrolling; + std::optional m_upHoldingSince; + + bool m_downScrolling; + std::optional m_downHoldingSince; + + bool m_leftScrolling; + std::optional m_leftHoldingSince; + + bool m_rightScrolling; + std::optional m_rightHoldingSince; }; } // namespace espgui diff --git a/src/selectorscrollinterface.h b/src/selectorscrollinterface.h new file mode 100644 index 0000000..91e9908 --- /dev/null +++ b/src/selectorscrollinterface.h @@ -0,0 +1,50 @@ +#pragma once + +// 3rdparty lib includes +#include + +namespace espgui { +namespace { +template +struct is_allowed +{ + static constexpr bool value = false; +}; + +template <> +struct is_allowed +{ + static constexpr bool value = true; +}; +template <> +struct is_allowed +{ + static constexpr bool value = true; +}; +template <> +struct is_allowed +{ + static constexpr bool value = true; +}; +template <> +struct is_allowed +{ + static constexpr bool value = true; +}; +} // namespace + +template +class SelectorScrollInterface { + static_assert(is_allowed::value, "Type not supported"); +public: + TimeType getInitialScrollSpeed() const { return initialScrollDelay; } + TimeType getScrollSpeed() const { return scrollDelay; } + + void setInitialScrollSpeed(TimeType speed) { initialScrollDelay = speed; } + void setScrollSpeed(TimeType speed) { scrollDelay = speed; } + +private: + TimeType initialScrollDelay{initialDelay}; + TimeType scrollDelay{delay}; +}; +} // namespace espgui