Introduced new screen stack to keep selected menu item when going back

This commit is contained in:
2022-03-02 04:10:53 +01:00
parent 6e051cc04f
commit 0f1371d49f
8 changed files with 163 additions and 7 deletions

View File

@ -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

View File

@ -0,0 +1,18 @@
#pragma once
// system includes
#include <utility>
// local includes
#include "actioninterface.h"
#include "screenmanager.h"
namespace espgui {
class PopScreenAction : public virtual ActionInterface
{
public:
void triggered() override { popScreen(); }
};
} // namespace espgui

View File

@ -0,0 +1,59 @@
#pragma once
// system includes
#include <utility>
// local includes
#include "actioninterface.h"
#include "screenmanager.h"
namespace espgui {
template<typename Tscreen>
class PushScreenAction : public virtual ActionInterface
{
public:
void triggered() override { pushScreen<Tscreen>(); }
};
template<typename Tscreen, typename ...Targs>
class PushScreenActionArgs;
template<typename Tscreen, typename T1>
class PushScreenActionArgs<Tscreen, T1> : public virtual ActionInterface
{
public:
PushScreenActionArgs(T1 &&arg1) :
m_arg1{std::move<T1>(arg1)}
{}
PushScreenActionArgs(const T1 &arg1) :
m_arg1{arg1}
{}
void triggered() override { pushScreen<Tscreen>(std::move(m_arg1)); }
private:
T1 m_arg1;
};
template<typename Tscreen, typename T1, typename T2>
class PushScreenActionArgs<Tscreen, T1, T2> : public virtual ActionInterface
{
public:
PushScreenActionArgs(T1 &&arg1, T2 &&arg2) :
m_arg1{std::move<T1>(arg1)},
m_arg2{std::move<T2>(arg2)}
{}
PushScreenActionArgs(const T1 &arg1, const T2 &arg2) :
m_arg1{arg1},
m_arg2{arg2}
{}
void triggered() override { pushScreen<Tscreen>(std::move(m_arg1), std::move(m_arg2)); }
private:
T1 m_arg1;
T2 m_arg2;
};
} // namespace espgui

View File

@ -8,6 +8,7 @@
#include "screenmanager.h"
namespace espgui {
template<typename Tscreen>
class SwitchScreenAction : public virtual ActionInterface
{
@ -15,7 +16,6 @@ public:
void triggered() override { switchScreen<Tscreen>(); }
};
template<typename Tscreen, typename ...Targs>
class SwitchScreenActionArgs;
@ -55,4 +55,5 @@ private:
T1 m_arg1;
T2 m_arg2;
};
} // namespace espgui

View File

@ -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;

View File

@ -138,8 +138,8 @@ private:
std::array<const Icon<24, 24> *, rowCount> m_icons;
int m_selectedIndex;
int m_scrollOffset;
int m_selectedIndex{};
int m_scrollOffset{};
int m_highlightedIndex;
int m_rotateOffset;

View File

@ -3,6 +3,8 @@
namespace espgui {
std::unique_ptr<Display> currentDisplay;
std::stack<std::unique_ptr<Display>> displayStack;
std::function<void()> 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

View File

@ -4,6 +4,7 @@
#include <memory>
#include <functional>
#include <utility>
#include <stack>
// local includes
#include "display.h"
@ -12,8 +13,16 @@ namespace espgui {
extern std::unique_ptr<Display> currentDisplay;
extern std::stack<std::unique_ptr<Display>> displayStack;
extern std::function<void()> changeScreenCallback;
void deconstructScreen();
void pushScreenInternal();
void popScreen();
template<typename T, typename... Args>
void switchScreenImpl(Args... args)
{
@ -38,8 +47,6 @@ void switchScreenRefImpl(Args&&... args)
currentDisplay->redraw();
}
extern std::function<void()> changeScreenCallback;
template<typename T, typename... Args>
void switchScreen(Args... args)
{
@ -58,4 +65,46 @@ void switchScreenRef(Args&&... args)
switchScreenRefImpl<T>(std::forward<Args>(args)...);
}
template<typename T, typename... Args>
void pushScreenImpl(Args... args)
{
pushScreenInternal();
currentDisplay = std::make_unique<T>(args...);
currentDisplay->start();
currentDisplay->initScreen();
currentDisplay->update();
currentDisplay->redraw();
}
template<typename T, typename... Args>
void pushScreenRefImpl(Args&&... args)
{
pushScreenInternal();
currentDisplay = std::make_unique<T>(std::forward<Args>(args)...);
currentDisplay->start();
currentDisplay->initScreen();
currentDisplay->update();
currentDisplay->redraw();
}
template<typename T, typename... Args>
void pushScreen(Args... args)
{
if (currentDisplay)
changeScreenCallback = [args...](){ pushScreenImpl<T>(args...); };
else
pushScreenImpl<T>(args...);
}
template<typename T, typename... Args>
void pushScreenRef(Args&&... args)
{
if (currentDisplay)
changeScreenCallback = [args...](){ pushScreenRefImpl<T>(std::forward<Args>(args)...); };
else
pushScreenRefImpl<T>(std::forward<Args>(args)...);
}
} // namespace espgui