Accessors now report result of setter, added error handler interface
This commit is contained in:
@ -14,12 +14,14 @@ set(headers
|
||||
src/confirminterface.h
|
||||
src/display.h
|
||||
src/displaywithtitle.h
|
||||
src/errorhandlerinterface.h
|
||||
src/fontinterface.h
|
||||
src/graphdisplay.h
|
||||
src/icon.h
|
||||
src/iconinterface.h
|
||||
src/menudisplay.h
|
||||
src/menuitem.h
|
||||
src/popupdisplay.h
|
||||
src/richtextrenderer.h
|
||||
src/screenmanager.h
|
||||
src/splitgraphdisplay.h
|
||||
@ -56,6 +58,7 @@ set(sources
|
||||
src/menudisplay.cpp
|
||||
src/screenmanager.cpp
|
||||
src/splitgraphdisplay.cpp
|
||||
src/popupdisplay.cpp
|
||||
src/richtextrenderer.cpp
|
||||
src/tftinstance.cpp
|
||||
src/icons/back.cpp
|
||||
|
@ -1,11 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
namespace espgui {
|
||||
template<typename T>
|
||||
struct AccessorInterface
|
||||
{
|
||||
using setter_result_t = tl::expected<void, std::string>;
|
||||
|
||||
virtual T getValue() const = 0;
|
||||
virtual void setValue(T value) = 0;
|
||||
virtual setter_result_t setValue(T value) = 0;
|
||||
};
|
||||
|
||||
//! A special type of AccessorInterface that allows for simple variable read/write operations
|
||||
@ -16,6 +21,6 @@ struct RefAccessor : public virtual AccessorInterface<T>
|
||||
virtual T& getRef() const = 0;
|
||||
|
||||
T getValue() const override { return getRef(); };
|
||||
void setValue(T value) override { getRef() = value; };
|
||||
tl::expected<void, std::string> setValue(T value) override { getRef() = value; return {}; };
|
||||
};
|
||||
} // namespace espgui
|
||||
|
@ -3,17 +3,20 @@
|
||||
// local includes
|
||||
#include "displaywithtitle.h"
|
||||
#include "textinterface.h"
|
||||
#include "actioninterface.h"
|
||||
#include "confirminterface.h"
|
||||
#include "backinterface.h"
|
||||
#include "errorhandlerinterface.h"
|
||||
#include "accessorinterface.h"
|
||||
#include "widgets/label.h"
|
||||
#include "tftinstance.h"
|
||||
#include "backinterface.h"
|
||||
|
||||
namespace espgui {
|
||||
|
||||
class ChangeValueDisplayInterface :
|
||||
public DisplayWithTitle,
|
||||
public virtual ActionInterface
|
||||
public virtual ConfirmInterface,
|
||||
public virtual BackInterface,
|
||||
public virtual ErrorHandlerInterface
|
||||
{
|
||||
using Base = DisplayWithTitle;
|
||||
|
||||
@ -48,8 +51,7 @@ template<typename Tvalue>
|
||||
class ChangeValueDisplay :
|
||||
public ChangeValueDisplayInterface,
|
||||
public virtual AccessorInterface<Tvalue>,
|
||||
public virtual ChangeValueDisplaySettingsInterface<Tvalue>,
|
||||
public virtual BackInterface
|
||||
public virtual ChangeValueDisplaySettingsInterface<Tvalue>
|
||||
{
|
||||
using Base = ChangeValueDisplayInterface;
|
||||
|
||||
@ -95,8 +97,11 @@ void ChangeValueDisplay<Tvalue>::update()
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<AccessorInterface<Tvalue>*>(this)->setValue(m_value);
|
||||
triggered();
|
||||
m_pressed = false;
|
||||
if (auto result = static_cast<AccessorInterface<Tvalue>*>(this)->setValue(m_value); result)
|
||||
confirm();
|
||||
else
|
||||
errorOccured(std::move(result).error());
|
||||
}
|
||||
}
|
||||
|
||||
|
20
src/errorhandlerinterface.h
Normal file
20
src/errorhandlerinterface.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <string>
|
||||
|
||||
namespace espgui {
|
||||
|
||||
class ErrorHandlerInterface
|
||||
{
|
||||
public:
|
||||
virtual void errorOccured(std::string &&error) = 0;
|
||||
};
|
||||
|
||||
class DummyErrorHandler : public virtual ErrorHandlerInterface
|
||||
{
|
||||
public:
|
||||
void errorOccured(std::string &&error) override {}
|
||||
};
|
||||
|
||||
} // namespace espgui
|
111
src/popupdisplay.cpp
Normal file
111
src/popupdisplay.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "popupdisplay.h"
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <tftinstance.h>
|
||||
#include <screenmanager.h>
|
||||
#include <cppmacros.h>
|
||||
|
||||
namespace espgui {
|
||||
|
||||
PopupDisplay::PopupDisplay(std::string &&message, std::unique_ptr<Display> &&lastDisplay) :
|
||||
m_message{std::move(message)}, m_lastDisplay{std::move(lastDisplay)}
|
||||
{
|
||||
}
|
||||
|
||||
void PopupDisplay::initScreen()
|
||||
{
|
||||
Base::initScreen();
|
||||
|
||||
m_lastDisplay->initScreen();
|
||||
|
||||
initOverlay();
|
||||
}
|
||||
|
||||
void PopupDisplay::buttonPressed(espgui::Button button)
|
||||
{
|
||||
//Base::buttonPressed(button);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
using espgui::Button;
|
||||
case Button::Left:
|
||||
case Button::Right:
|
||||
closeOverlay();
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void PopupDisplay::initOverlay()
|
||||
{
|
||||
constexpr auto leftMargin = 20;
|
||||
constexpr auto rightMargin = leftMargin;
|
||||
constexpr auto topMargin = 50;
|
||||
constexpr auto bottomMargin = topMargin;
|
||||
|
||||
const auto width = espgui::tft.width() - leftMargin - rightMargin;
|
||||
const auto height = espgui::tft.height() - topMargin - bottomMargin;
|
||||
const auto right = espgui::tft.width() - rightMargin;
|
||||
const auto bottom = espgui::tft.height() - bottomMargin;
|
||||
|
||||
CPP_UNUSED(right)
|
||||
|
||||
espgui::tft.drawSunkenRect(leftMargin, topMargin, width, height,
|
||||
color565(240, 240, 240),
|
||||
color565(100, 100, 100),
|
||||
color565(30, 30, 30));
|
||||
|
||||
espgui::tft.setTextColor(TFT_WHITE, color565(30, 30, 30));
|
||||
|
||||
int x = leftMargin + 5;
|
||||
int y = topMargin + 5;
|
||||
for (char c : m_message)
|
||||
{
|
||||
if (c == '\n' || x > espgui::tft.width() - rightMargin - 10)
|
||||
{
|
||||
x = leftMargin + 5;
|
||||
y += espgui::tft.fontHeight(4);
|
||||
}
|
||||
|
||||
if (c != '\n')
|
||||
{
|
||||
const auto addedWidth = espgui::tft.drawChar(espgui::tft.decodeUTF8(c), x, y, 4);
|
||||
x += addedWidth;
|
||||
}
|
||||
|
||||
if (y >= espgui::tft.height() - bottomMargin)
|
||||
break;
|
||||
}
|
||||
|
||||
espgui::tft.setTextColor(TFT_BLACK, color565(170, 170, 170));
|
||||
|
||||
if constexpr (false)
|
||||
{
|
||||
espgui::tft.drawSunkenRect(leftMargin + 15, bottom - 40,
|
||||
(width - 15 - 10 - 15) / 2,
|
||||
30,
|
||||
color565(240, 240, 240),
|
||||
color565(100, 100, 100),
|
||||
color565(170, 170, 170));
|
||||
|
||||
espgui::tft.drawString("Retry", leftMargin + 18, bottom - 37);
|
||||
}
|
||||
|
||||
espgui::tft.drawSunkenRect(leftMargin + 15 + ((width - 15 - 30 - 15) / 2) + 15, bottom - 40,
|
||||
(width - 15 - 10 - 15) / 2,
|
||||
30,
|
||||
color565(240, 240, 240),
|
||||
color565(100, 100, 100),
|
||||
color565(170, 170, 170));
|
||||
|
||||
espgui::tft.drawString("Ok", leftMargin + 18 + ((width - 15 - 30 - 15) / 2) + 15 + 1, bottom - 37);
|
||||
}
|
||||
|
||||
void PopupDisplay::closeOverlay()
|
||||
{
|
||||
auto guard = std::move(espgui::currentDisplay);
|
||||
espgui::currentDisplay = std::move(m_lastDisplay);
|
||||
espgui::currentDisplay->initScreen();
|
||||
}
|
||||
|
||||
} // namespace espgui
|
34
src/popupdisplay.h
Normal file
34
src/popupdisplay.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <memory>
|
||||
|
||||
// local includes
|
||||
#include "display.h"
|
||||
|
||||
namespace espgui {
|
||||
|
||||
class PopupDisplay : public Display
|
||||
{
|
||||
using Base = Display;
|
||||
|
||||
public:
|
||||
PopupDisplay(std::string &&message, std::unique_ptr<Display> &&lastDisplay);
|
||||
|
||||
//void start() override;
|
||||
void initScreen() override;
|
||||
//void update() override;
|
||||
//void redraw() override;
|
||||
//void stop() override;
|
||||
|
||||
void buttonPressed(espgui::Button button) override;
|
||||
|
||||
virtual void initOverlay();
|
||||
virtual void closeOverlay();
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
std::unique_ptr<Display> m_lastDisplay;
|
||||
};
|
||||
|
||||
} // namespace espgui
|
Reference in New Issue
Block a user