diff --git a/CMakeLists.txt b/CMakeLists.txt index 2147539..17c2210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,8 @@ set(headers src/actions/backproxyaction.h src/actions/dummyaction.h src/actions/multiaction.h + src/actions/pushscreenaction.h + src/actions/popscreenaction.h src/actions/setvalueaction.h src/actions/switchscreenaction.h src/actions/toggleboolaction.h diff --git a/src/actions/popscreenaction.h b/src/actions/popscreenaction.h new file mode 100644 index 0000000..e09f03b --- /dev/null +++ b/src/actions/popscreenaction.h @@ -0,0 +1,18 @@ +#pragma once + +// system includes +#include + +// local includes +#include "actioninterface.h" +#include "screenmanager.h" + +namespace espgui { + +class PopScreenAction : public virtual ActionInterface +{ +public: + void triggered() override { popScreen(); } +}; + +} // namespace espgui diff --git a/src/actions/pushscreenaction.h b/src/actions/pushscreenaction.h new file mode 100644 index 0000000..661a5e2 --- /dev/null +++ b/src/actions/pushscreenaction.h @@ -0,0 +1,59 @@ +#pragma once + +// system includes +#include + +// local includes +#include "actioninterface.h" +#include "screenmanager.h" + +namespace espgui { + +template +class PushScreenAction : public virtual ActionInterface +{ +public: + void triggered() override { pushScreen(); } +}; + +template +class PushScreenActionArgs; + +template +class PushScreenActionArgs : public virtual ActionInterface +{ +public: + PushScreenActionArgs(T1 &&arg1) : + m_arg1{std::move(arg1)} + {} + PushScreenActionArgs(const T1 &arg1) : + m_arg1{arg1} + {} + + void triggered() override { pushScreen(std::move(m_arg1)); } + +private: + T1 m_arg1; +}; + +template +class PushScreenActionArgs : public virtual ActionInterface +{ +public: + PushScreenActionArgs(T1 &&arg1, T2 &&arg2) : + m_arg1{std::move(arg1)}, + m_arg2{std::move(arg2)} + {} + PushScreenActionArgs(const T1 &arg1, const T2 &arg2) : + m_arg1{arg1}, + m_arg2{arg2} + {} + + void triggered() override { pushScreen(std::move(m_arg1), std::move(m_arg2)); } + +private: + T1 m_arg1; + T2 m_arg2; +}; + +} // namespace espgui diff --git a/src/actions/switchscreenaction.h b/src/actions/switchscreenaction.h index 1075944..bd773de 100644 --- a/src/actions/switchscreenaction.h +++ b/src/actions/switchscreenaction.h @@ -8,6 +8,7 @@ #include "screenmanager.h" namespace espgui { + template class SwitchScreenAction : public virtual ActionInterface { @@ -15,7 +16,6 @@ public: void triggered() override { switchScreen(); } }; - template class SwitchScreenActionArgs; @@ -55,4 +55,5 @@ private: T1 m_arg1; T2 m_arg2; }; + } // namespace espgui diff --git a/src/menudisplay.cpp b/src/menudisplay.cpp index 5c66d2b..6f6afb0 100644 --- a/src/menudisplay.cpp +++ b/src/menudisplay.cpp @@ -8,8 +8,8 @@ void MenuDisplay::start() { Base::start(); - m_selectedIndex = 0; - m_scrollOffset = 0; +// m_selectedIndex = 0; +// m_scrollOffset = 0; m_rotateOffset = 0; m_pressed = false; diff --git a/src/menudisplay.h b/src/menudisplay.h index e85f50c..102841a 100644 --- a/src/menudisplay.h +++ b/src/menudisplay.h @@ -138,8 +138,8 @@ private: std::array *, rowCount> m_icons; - int m_selectedIndex; - int m_scrollOffset; + int m_selectedIndex{}; + int m_scrollOffset{}; int m_highlightedIndex; int m_rotateOffset; diff --git a/src/screenmanager.cpp b/src/screenmanager.cpp index f609ce9..876fe92 100644 --- a/src/screenmanager.cpp +++ b/src/screenmanager.cpp @@ -3,6 +3,8 @@ namespace espgui { std::unique_ptr currentDisplay; +std::stack> displayStack; + std::function changeScreenCallback; void deconstructScreen() @@ -14,4 +16,29 @@ void deconstructScreen() } } +void pushScreenInternal() +{ + if (currentDisplay) + { + currentDisplay->stop(); + displayStack.push(std::move(currentDisplay)); + assert(!currentDisplay); + } +} + +void popScreen() +{ + deconstructScreen(); + + if (displayStack.empty()) + return; + + currentDisplay = std::move(displayStack.top()); + displayStack.pop(); + currentDisplay->start(); + currentDisplay->initScreen(); + currentDisplay->update(); + currentDisplay->redraw(); +} + } // namespace espgui diff --git a/src/screenmanager.h b/src/screenmanager.h index 944e149..3994af9 100644 --- a/src/screenmanager.h +++ b/src/screenmanager.h @@ -4,6 +4,7 @@ #include #include #include +#include // local includes #include "display.h" @@ -12,8 +13,16 @@ namespace espgui { extern std::unique_ptr currentDisplay; +extern std::stack> displayStack; + +extern std::function changeScreenCallback; + void deconstructScreen(); +void pushScreenInternal(); + +void popScreen(); + template void switchScreenImpl(Args... args) { @@ -38,8 +47,6 @@ void switchScreenRefImpl(Args&&... args) currentDisplay->redraw(); } -extern std::function changeScreenCallback; - template void switchScreen(Args... args) { @@ -58,4 +65,46 @@ void switchScreenRef(Args&&... args) switchScreenRefImpl(std::forward(args)...); } +template +void pushScreenImpl(Args... args) +{ + pushScreenInternal(); + + currentDisplay = std::make_unique(args...); + currentDisplay->start(); + currentDisplay->initScreen(); + currentDisplay->update(); + currentDisplay->redraw(); +} + +template +void pushScreenRefImpl(Args&&... args) +{ + pushScreenInternal(); + + currentDisplay = std::make_unique(std::forward(args)...); + currentDisplay->start(); + currentDisplay->initScreen(); + currentDisplay->update(); + currentDisplay->redraw(); +} + +template +void pushScreen(Args... args) +{ + if (currentDisplay) + changeScreenCallback = [args...](){ pushScreenImpl(args...); }; + else + pushScreenImpl(args...); +} + +template +void pushScreenRef(Args&&... args) +{ + if (currentDisplay) + changeScreenCallback = [args...](){ pushScreenRefImpl(std::forward(args)...); }; + else + pushScreenRefImpl(std::forward(args)...); +} + } // namespace espgui