47 Commits

Author SHA1 Message Date
ab7319edde Merge pull request #32 from CommanderRedYT/bicycle 2025-04-10 12:19:44 +02:00
6074189811 Configure background color via kconfig 2025-04-09 23:29:55 +02:00
3438b20b58 Improve handling for initial cursor position 2025-02-25 15:12:01 +01:00
20e359a1b9 Add ability to change the color 2025-02-25 14:49:01 +01:00
5f889d4d73 Fix scrolling / skipScroll 2025-02-25 14:48:40 +01:00
beab503d28 Add option to adjust height when switching fonts to smaller 2025-02-21 15:48:55 +01:00
068ef657e8 Expose title dimensions as variables 2025-02-20 16:11:05 +01:00
13dd0481fb Add custom background 2025-02-07 16:46:24 +01:00
1f80ca10f9 Merge pull request #31 from 0xFEEDC0DE64/add-build-script
Add build script
2024-10-03 11:17:32 +02:00
950d9dadbb Add build script 2024-10-03 10:07:14 +02:00
89f1253298 Replace fmt::format with std::format 2024-09-18 16:42:48 +02:00
7e17dcf7d8 Move rich text escape methods to helper .h .cpp files 2023-04-27 17:07:08 +02:00
76041027df C++23 enable in CMakeLists.txt 2023-04-27 14:27:30 +02:00
51bae4e7f3 Removed again lots of arduino bullshit 2023-03-29 16:01:03 +02:00
cac01b252a Updated to new esp-idf 2023-02-27 17:26:53 +01:00
56b0fc30bb Added warning 2023-02-18 15:09:55 +01:00
de5ac4c8c2 Fix crash for empty string 2023-02-18 13:20:30 +01:00
ed892388f6 Merge pull request #30 from 0xFEEDC0DE64/changes
Changes
2023-02-15 17:29:23 +01:00
9c5a4cccb3 Added empty line and namespace label 2023-02-15 17:21:37 +01:00
942a1e45b4 Added icon widget 2023-02-15 17:19:59 +01:00
ddd276e681 Fixed clear 2023-02-15 17:19:54 +01:00
7a6dd2afac Added changeable icons 2023-02-15 17:19:33 +01:00
6d3002c87b Added variable-range types for progress bars 2023-01-29 19:57:28 +01:00
ea4915e750 Changed text() to title() 2023-01-29 17:32:06 +01:00
7cfa4b85e1 Fixed closing of popups 2023-01-23 20:31:06 +01:00
ec7ddb8dea Add CenteredLabel 2023-01-23 17:02:26 +01:00
f3e667e59d New design for menu headers 2023-01-23 13:28:38 +01:00
086e5f6f86 Fix crash with skipScroll in MenuDisplay 2023-01-23 10:43:08 +01:00
e429650c99 Implemented button holding for chrono changevalue displays 2023-01-18 20:20:01 +01:00
9b8b50c88d Add tutorial for compiling iconconvert 2023-01-18 17:05:43 +01:00
f3622e678e Menu items now have a second icon for when selected 2023-01-18 14:04:10 +01:00
6a1199e391 Merge pull request #29 from 0xFEEDC0DE64/rotary
Added rotary interface
2023-01-17 19:59:01 +01:00
d3e438c0ed Added rotary interface 2023-01-16 22:20:54 +01:00
7f2ff4542e Fixed iconconvert alpha handling 2023-01-16 21:43:26 +01:00
9c535eedb4 icon.h was moved to esptftlib 2023-01-16 16:12:58 +01:00
f673391ed3 Fixed BigValueDisplay 2023-01-12 23:41:52 +01:00
c7bba7daa1 Use new fontrenderer 2023-01-12 23:21:21 +01:00
98fb5746c6 Remove ultra-retarded swapBytes 2023-01-12 18:23:07 +01:00
60e7544266 Reduce tft interface 2023-01-12 17:50:16 +01:00
b4b30c863a New design for displays with title (grey bar) 2023-01-11 14:41:24 +01:00
26c0be33b1 Add TitleInterface 2023-01-10 17:41:03 +01:00
f80f8427da Add string include 2023-01-05 20:39:08 +01:00
9ced47e96c Remove debug logging 2023-01-02 18:17:03 +01:00
346ff33fc5 Made some logic changes, fixed rendering 2023-01-02 18:13:54 +01:00
b4724ded46 Added toString function 2023-01-02 18:13:28 +01:00
89305d3c15 Merge pull request #26 from 0xFEEDC0DE64/fix-keyboard 2022-12-26 23:10:40 +01:00
a8a6791af7 Fixed and improved keyboard 2022-12-26 23:09:48 +01:00
67 changed files with 1489 additions and 596 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/build-*
build-*
build/

View File

@ -28,12 +28,14 @@ set(headers
src/errorhandlerinterface.h
src/fontinterface.h
src/graphdisplay.h
src/icon.h
src/iconinterface.h
src/keyboardhelper.h
src/icons/back.h
src/icons/checked.h
src/icons/unchecked.h
src/icons/back_grey.h
src/icons/checked_grey.h
src/icons/unchecked_grey.h
src/marginmenuitem.h
src/menudisplay.h
src/menuitem.h
@ -47,14 +49,17 @@ set(headers
src/textinterface.h
src/textwithvaluehelper.h
src/tftcolors.h
src/tftespiimpl.h
src/tftinterface.h
src/titleinterface.h
src/visibleinterface.h
src/widgets/centeredlabel.h
src/widgets/graph.h
src/widgets/iconwidget.h
src/widgets/label.h
src/widgets/progressbar.h
src/widgets/reverseprogressbar.h
src/widgets/slider.h
src/widgets/variablerangeprogressbar.h
src/widgets/variablerangereverseprogressbar.h
src/widgets/verticalmeter.h
src/widgets/vumeter.h
)
@ -76,14 +81,22 @@ set(sources
src/screenmanager.cpp
src/splitgraphdisplay.cpp
src/popupdisplay.cpp
src/richtexthelper.cpp
src/richtextrenderer.cpp
src/icons/back.cpp
src/icons/checked.cpp
src/icons/unchecked.cpp
src/icons/back_grey.cpp
src/icons/checked_grey.cpp
src/icons/unchecked_grey.cpp
src/widgets/centeredlabel.cpp
src/widgets/iconwidget.cpp
src/widgets/label.cpp
src/widgets/progressbar.cpp
src/widgets/reverseprogressbar.cpp
src/widgets/slider.cpp
src/widgets/variablerangeprogressbar.cpp
src/widgets/variablerangereverseprogressbar.cpp
src/widgets/verticalmeter.cpp
src/widgets/vumeter.cpp
)
@ -93,10 +106,10 @@ set(dependencies
cxx-ring-buffer
espchrono
espcpputils
expected
espwifistack
fmt
TFT_eSPI
esptftlib
espfontlib
)
idf_component_register(
@ -109,6 +122,8 @@ idf_component_register(
${dependencies}
)
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 23)
target_compile_options(${COMPONENT_TARGET}
PRIVATE
-fstack-reuse=all

View File

@ -4,8 +4,8 @@ config ESPGUI_MENUDISPLAY_ROWS
int "Number of rows for MenuDisplays"
default 10
config ESPGUI_ICONS_SWAPBYTES
bool "Swap bytes in icons"
default n
config ESPGUI_MENUITEM_BACKGROUND_COLOR
hex "MenuItem background color"
default 0x5AEB
endmenu

View File

@ -1,2 +1,10 @@
# esp-gui-lib
ESP32 gui library
## How to compile the iconconverter for dummies
```
mkdir build-iconconvert-Desktop_Qt_6_4_1-Debug
cd build-iconconvert-Desktop_Qt_6_4_1-Debug
qmake ../iconconvert
make
```

View File

@ -2,5 +2,15 @@
for i in icons/*
do
build-iconconvert-Desktop_Qt_6_4_0-Debug/iconconvert $i src/icons/ icon_templ.h.tmpl icon_templ.cpp.tmpl
build-iconconvert-Desktop_Qt_6_4_1-Debug/iconconvert $i src/icons/ icon_templ.h.tmpl icon_templ.cpp.tmpl
ICON_NAME="$(basename "$i" .png)"
case "$ICON_NAME" in
icons_to_exclude)
echo no grey version needed
;;
*)
build-iconconvert-Desktop_Qt_6_4_1-Debug/iconconvert "$i" src/icons/ icon_templ.h.tmpl icon_templ.cpp.tmpl --background-color "#5c5c5c" --name-override "${ICON_NAME}_grey"
;;
esac
done

25
iconconvert/build.sh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/bash
if [[ $PWD != *"esp-gui-lib/iconconvert"* ]] || [[ $0 != *"build.sh"* ]]; then
echo "This script must be run from the iconconvert directory"
exit 1
fi
# check if qmake is installed
if ! command -v qmake; then
echo "Qmake is not installed"
exit 1
fi
# check if make is installed
if ! command -v make; then
echo "Make is not installed"
exit 1
fi
mkdir -p build
cd build || exit 1
qmake ..
make
cd ..

View File

@ -7,19 +7,25 @@
#include <QDebug>
namespace {
QColor backgroundColor;
constexpr uint16_t color565(uint8_t red, uint8_t green, uint8_t blue) noexcept
{
return __builtin_bswap16(((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3));
}
uint16_t color565(const QColor &color) noexcept
{
return color565(color.red(), color.green(), color.blue());
return color565(
color.red() * color.alphaF() + ((1-color.alphaF())*backgroundColor.red()),
color.green() * color.alphaF() + ((1-color.alphaF())*backgroundColor.green()),
color.blue() * color.alphaF() + ((1-color.alphaF())*backgroundColor.blue())
);
}
} // namespace
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QCoreApplication app{argc, argv};
QCoreApplication::setApplicationName("iconconvert");
QCoreApplication::setApplicationVersion("1.0");
@ -27,13 +33,32 @@ int main(int argc, char *argv[])
parser.setApplicationDescription("Converts icons to .h/.cpp sources");
parser.addHelpOption();
parser.addVersionOption();
parser.addPositionalArgument("icon", QCoreApplication::translate("main", "Icon file."));
parser.addPositionalArgument("destination", QCoreApplication::translate("main", "Destination directory."));
parser.addPositionalArgument("icon-file", QCoreApplication::translate("main", "Icon file."));
parser.addPositionalArgument("destination-dir", QCoreApplication::translate("main", "Destination directory."));
parser.addPositionalArgument("header-templ", QCoreApplication::translate("main", "Header template"));
parser.addPositionalArgument("footer-templ", QCoreApplication::translate("main", "Footer template"));
QCommandLineOption backgroundColorOption{
{"b", "background-color"},
QCoreApplication::translate("main", "Background color for transparent icons"),
"name", "#000000"
};
parser.addOption(backgroundColorOption);
QCommandLineOption nameOverrideOption{
{"n", "name-override"},
QCoreApplication::translate("main", "Override name for generated .h .cpp files"),
"name"
};
parser.addOption(nameOverrideOption);
parser.process(app);
backgroundColor = QColor{parser.value(backgroundColorOption)};
if (!backgroundColor.isValid())
{
qWarning() << "invalid background color, falling back to #000000";
backgroundColor = QColor{0, 0, 0};
}
const QStringList args = parser.positionalArguments();
if (args.size() < 1)
{
@ -91,7 +116,7 @@ int main(int argc, char *argv[])
else
bytes += ", ";
bytes += QStringLiteral("0x%0").arg(color565(image.pixel(x, y)), 4, 16, QLatin1Char('0'));
bytes += QStringLiteral("0x%0").arg(color565(image.pixelColor(x, y)), 4, 16, QLatin1Char('0'));
if (++i == 16)
{
@ -111,6 +136,9 @@ int main(int argc, char *argv[])
}
}
const auto &nameOverrideValue = parser.value(nameOverrideOption);
const auto &basename = nameOverrideValue.isEmpty() ? fileInfo.baseName() : nameOverrideValue;
{
QString templ;
@ -126,7 +154,7 @@ int main(int argc, char *argv[])
}
{
QFile file{dir.absoluteFilePath(QStringLiteral("%0.h").arg(fileInfo.baseName()))};
QFile file{dir.absoluteFilePath(QStringLiteral("%0.h").arg(basename))};
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
{
qCritical("could not open .h file for writing %s", qPrintable(file.errorString()));
@ -134,7 +162,7 @@ int main(int argc, char *argv[])
}
const auto content = templ
.replace("${name}", fileInfo.baseName())
.replace("${name}", basename)
.replace("${width}", QString::number(image.width()))
.replace("${height}", QString::number(image.height()))
.toUtf8();
@ -162,7 +190,7 @@ int main(int argc, char *argv[])
}
{
QFile file{dir.absoluteFilePath(QStringLiteral("%0.cpp").arg(fileInfo.baseName()))};
QFile file{dir.absoluteFilePath(QStringLiteral("%0.cpp").arg(basename))};
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
{
qCritical("could not open .cpp file for writing %s", qPrintable(file.errorString()));
@ -170,7 +198,7 @@ int main(int argc, char *argv[])
}
const auto content = templ
.replace("${name}", fileInfo.baseName())
.replace("${name}", basename)
.replace("${width}", QString::number(image.width()))
.replace("${height}", QString::number(image.height()))
.replace("${bytes}", bytes)
@ -184,7 +212,7 @@ int main(int argc, char *argv[])
}
}
qDebug() << fileInfo.baseName() << image.width() << image.height();
qDebug() << basename << image.width() << image.height();
return 0;
}

View File

@ -2,15 +2,13 @@
// system includes
#include <string>
// 3rdparty lib includes
#include <tl/expected.hpp>
#include <expected>
namespace espgui {
template<typename T>
struct AccessorInterface
{
using setter_result_t = tl::expected<void, std::string>;
using setter_result_t = std::expected<void, std::string>;
virtual T getValue() const = 0;
virtual setter_result_t setValue(T value) = 0;
@ -24,6 +22,6 @@ struct RefAccessor : public virtual AccessorInterface<T>
virtual T& getRef() const = 0;
T getValue() const override { return getRef(); };
tl::expected<void, std::string> setValue(T value) override { getRef() = value; return {}; };
std::expected<void, std::string> setValue(T value) override { getRef() = value; return {}; };
};
} // namespace espgui

View File

@ -2,6 +2,7 @@
//system includes
#include <cstdint>
#include <string>
namespace espgui {
@ -14,6 +15,18 @@ enum Button
ButtonMax = Down
};
inline std::string toString(Button button)
{
switch (button)
{
case Button::Left: return "Left";
case Button::Right: return "Right";
case Button::Up: return "Up";
case Button::Down: return "Down";
default: return "Unknown";
}
}
class ButtonsInterface
{
public:

View File

@ -1,7 +1,10 @@
#include "changevaluedisplay.h"
// system includes
#include <format>
// 3rdparty lib includes
#include <fmt/core.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -12,21 +15,23 @@ void ChangeValueDisplayInterface::initScreen(TftInterface &tft)
{
Base::initScreen(tft);
FontRenderer fontRenderer{tft};
tft.drawRoundRect(35, 65, 190, 65, 8, TFT_WHITE);
m_valueLabel.start(tft);
if (espgui::isLandscape(tft))
{
tft.drawString("Change value and press", 10, 152, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("button to confirm and", 10, 177, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("go back", 10, 202, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("Change value and press", 10, 152, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("button to confirm and", 10, 177, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("go back", 10, 202, TFT_WHITE, TFT_BLACK, 4);
}
else
{
tft.drawString("Change value and", 10, 160, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("press button to", 10, 185, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("confirm and go", 10, 210, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("back.", 10, 235, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("Change value and", 10, 160, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("press button to", 10, 185, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("confirm and go", 10, 210, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("back.", 10, 235, TFT_WHITE, TFT_BLACK, 4);
}
}
@ -35,6 +40,6 @@ void ChangeValueDisplay<float>::redraw(TftInterface &tft)
{
Base::redraw(tft);
m_valueLabel.redraw(tft, fmt::format("{:.02f}", m_value), TFT_WHITE, TFT_BLACK, 7);
m_valueLabel.redraw(tft, std::format("{:.02f}", m_value), TFT_WHITE, TFT_BLACK, 7);
}
} // namespace espgui

View File

@ -45,7 +45,7 @@ template<typename Tvalue>
class ChangeValueDisplaySettingsInterface
{
public:
virtual Tvalue step() const { return 1; };
virtual Tvalue step() const { return Tvalue{1}; }
};
template<typename Tvalue, typename Tratio>

View File

@ -4,6 +4,7 @@
#include "actions/setvalueaction.h"
#include "actions/backproxyaction.h"
#include "icons/back.h"
#include "icons/back_grey.h"
namespace espgui {
namespace {
@ -16,7 +17,7 @@ ChangeValueDisplay<bool>::ChangeValueDisplay()
{
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<bool>, StaticText<TEXT_TRUE>>>(true, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<bool>, StaticText<TEXT_FALSE>>>(false, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back>>>(*this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back, &icons::back_grey>>>(*this);
}
void ChangeValueDisplay<bool>::start()

View File

@ -5,6 +5,7 @@
// 3rdparty lib includes
#include <espchrono.h>
#include <fontrenderer.h>
// local includes
#include "changevaluedisplay.h"
@ -25,7 +26,8 @@ class ChangeValueDisplayChrono :
public virtual AccessorInterface<T>,
public virtual ConfirmInterface,
public virtual BackInterface,
public virtual ErrorHandlerInterface
public virtual ErrorHandlerInterface,
public virtual ChangeValueDisplaySettingsInterface<T>
{
using Base = DisplayWithTitle;
@ -40,9 +42,20 @@ public:
private:
T m_value;
int m_rotateOffset;
bool m_pressed{};
Label m_valueLabel{36, 71}; // 188, 53
struct ButtonHeldInfo
{
espchrono::millis_clock::time_point nextTimestamp;
int counter{};
};
std::optional<ButtonHeldInfo> m_upHeld;
std::optional<ButtonHeldInfo> m_downHeld;
};
template<typename T>
@ -60,21 +73,23 @@ void ChangeValueDisplayChrono<T>::initScreen(TftInterface &tft)
{
Base::initScreen(tft);
FontRenderer fontRenderer{tft};
tft.drawRoundRect(32, 65, 190, 34, 8, TFT_WHITE);
m_valueLabel.start(tft);
if (espgui::isLandscape(tft))
{
tft.drawString("Change value and press", 10, 152, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("button to confirm and", 10, 177, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("go back", 10, 202, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("Change value and press", 10, 152, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("button to confirm and", 10, 177, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("go back", 10, 202, TFT_WHITE, TFT_BLACK, 4);
}
else
{
tft.drawString("Change value and", 10, 160, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("press button to", 10, 185, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("confirm and go", 10, 210, TFT_WHITE, TFT_BLACK, 4);
tft.drawString("back.", 10, 235, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("Change value and", 10, 160, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("press button to", 10, 185, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("confirm and go", 10, 210, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString("back.", 10, 235, TFT_WHITE, TFT_BLACK, 4);
}
}
@ -83,6 +98,29 @@ void ChangeValueDisplayChrono<T>::update()
{
Base::update();
const auto now = espchrono::millis_clock::now();
if (m_upHeld && now >= m_upHeld->nextTimestamp)
{
using namespace std::chrono_literals;
m_upHeld->nextTimestamp += m_upHeld->counter > 10 ? 50ms : (m_upHeld->counter > 3 ? 100ms : 200ms);
m_upHeld->counter++;
m_rotateOffset--;
}
if (m_downHeld && now >= m_downHeld->nextTimestamp)
{
using namespace std::chrono_literals;
m_downHeld->nextTimestamp += m_downHeld->counter > 10 ? 50ms : (m_downHeld->counter > 3 ? 100ms : 200ms);
m_downHeld->counter++;
m_rotateOffset++;
}
{
const auto rotateOffset = m_rotateOffset;
m_rotateOffset = 0;
m_value -= rotateOffset * this->step();
}
if (m_pressed)
{
m_pressed = false;
@ -110,8 +148,15 @@ void ChangeValueDisplayChrono<T>::buttonPressed(Button button)
{
case Button::Left: this->back(); break;
case Button::Right: m_pressed = true; break;
case Button::Up: m_value += T{1}; break;
case Button::Down: m_value -= T{1}; break;
using namespace std::chrono_literals;
case Button::Up:
m_rotateOffset--;
m_upHeld = ButtonHeldInfo { .nextTimestamp = espchrono::millis_clock::now() + 300ms };
break;
case Button::Down:
m_rotateOffset++;
m_downHeld = ButtonHeldInfo { .nextTimestamp = espchrono::millis_clock::now() + 300ms };
break;
default:;
}
}
@ -121,7 +166,16 @@ void ChangeValueDisplayChrono<T>::buttonReleased(Button button)
{
//Base::buttonPressed(button);
// TODO stop auto scroll
switch (button)
{
case Button::Up:
m_upHeld = std::nullopt;
break;
case Button::Down:
m_downHeld = std::nullopt;
break;
default:;
}
}
} // namespace detail

View File

@ -7,6 +7,7 @@
#include "actions/setvalueaction.h"
#include "actions/backproxyaction.h"
#include "icons/back.h"
#include "icons/back_grey.h"
namespace espgui {
namespace {
@ -23,7 +24,7 @@ ChangeValueDisplay<espchrono::DayLightSavingMode>::ChangeValueDisplay()
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<espchrono::DayLightSavingMode>, StaticText<TEXT_NONE>>>(espchrono::DayLightSavingMode::None, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<espchrono::DayLightSavingMode>, StaticText<TEXT_EUROPEANSUMMERTIME>>>(espchrono::DayLightSavingMode::EuropeanSummerTime, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<espchrono::DayLightSavingMode>, StaticText<TEXT_USDAYLIGHTTIME>>>(espchrono::DayLightSavingMode::UsDaylightTime, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back>>>(*this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back, &icons::back_grey>>>(*this);
}
void ChangeValueDisplay<espchrono::DayLightSavingMode>::start()

View File

@ -1,5 +1,8 @@
#include "changevaluedisplay_ip_address_t.h"
// 3rdparty lib includes
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
#include "tftcolors.h"
@ -19,7 +22,9 @@ void ChangeValueDisplay<wifi_stack::ip_address_t>::initScreen(TftInterface &tft)
{
Base::initScreen(tft);
tft.drawString("Change IP Address", 0, 50, TFT_WHITE, TFT_BLACK, 4);
FontRenderer fontRenderer{tft};
fontRenderer.drawString("Change IP Address", 0, 50, TFT_WHITE, TFT_BLACK, 4);
for(int i = 0; i <= 3; i++)
{
@ -30,9 +35,9 @@ void ChangeValueDisplay<wifi_stack::ip_address_t>::initScreen(TftInterface &tft)
for (auto &label : m_labels)
label.start(tft);
tft.drawString(".", spacing+boxWidth+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
tft.drawString(".", spacing*2+boxWidth*2+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
tft.drawString(".", spacing*3+boxWidth*3+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString(".", spacing+boxWidth+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString(".", spacing*2+boxWidth*2+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
fontRenderer.drawString(".", spacing*3+boxWidth*3+spacing/4, y, TFT_WHITE, TFT_BLACK, 4);
drawRect(tft, m_currentIndex, 1, TFT_YELLOW);
drawRect(tft, m_currentIndex, 2, TFT_YELLOW);

View File

@ -7,6 +7,7 @@
#include "actions/setvalueaction.h"
#include "actions/backproxyaction.h"
#include "icons/back.h"
#include "icons/back_grey.h"
namespace espgui {
namespace {
@ -21,7 +22,7 @@ ChangeValueDisplay<sntp_sync_mode_t>::ChangeValueDisplay()
{
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<sntp_sync_mode_t>, StaticText<TEXT_IMMED>>>(SNTP_SYNC_MODE_IMMED, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<sntp_sync_mode_t>, StaticText<TEXT_SMOOTH>>>(SNTP_SYNC_MODE_SMOOTH, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back>>>(*this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back, &icons::back_grey>>>(*this);
}
void ChangeValueDisplay<sntp_sync_mode_t>::start()

View File

@ -2,11 +2,14 @@
// 3rdparty lib includes
#include <espchrono.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
#include "tftcolors.h"
using namespace std::chrono_literals;
void espgui::ChangeValueDisplay<std::string>::start()
{
Base::start();
@ -24,29 +27,53 @@ void espgui::ChangeValueDisplay<std::string>::initScreen(TftInterface &tft)
m_keyboard.start(tft);
m_needsClear = std::nullopt;
m_locked = false;
}
void espgui::ChangeValueDisplay<std::string>::update()
{
Base::update();
m_keyboard.update();
}
void espgui::ChangeValueDisplay<std::string>::redraw(TftInterface &tft)
{
const auto now = espchrono::millis_clock::now().time_since_epoch().count() / 1000;
Base::redraw(tft);
FontRenderer fontRenderer{tft};
const auto now_ts = espchrono::millis_clock::now().time_since_epoch();
const uint16_t char_width = fontRenderer.textWidth(m_value, 4) / ((!m_value.empty()) ? m_value.size() : 1);
const int16_t maxChars = char_width > 0 ? ((tft.width() - 40) / char_width) : 0;
const auto substr_from = std::max(0, m_value.size() < maxChars ? 0 : static_cast<int>(m_value.size()) - maxChars);
const auto string = m_value.substr(substr_from);
if (m_needsClear)
{
tft.drawRect(m_valueLabel.x() + tft.textWidth(*m_needsClear, 4) + 3, m_valueLabel.y(), 2, tft.fontHeight(4), TFT_BLACK);
tft.drawRect(m_valueLabel.x() + fontRenderer.textWidth(*m_needsClear, 4) + 3, m_valueLabel.y(), 2, fontRenderer.fontHeight(4), TFT_BLACK);
m_needsClear = std::nullopt;
}
m_valueLabel.redraw(tft, m_value, TFT_WHITE, TFT_BLACK, 4);
m_valueLabel.redraw(tft, string, TFT_WHITE, TFT_BLACK, 4);
tft.drawRect(m_valueLabel.x() + tft.textWidth(m_value, 4) + 3, m_valueLabel.y(), 2, tft.fontHeight(4), (now % 1000 < 500) ? TFT_WHITE : TFT_BLACK);
tft.drawRect(m_valueLabel.x() + fontRenderer.textWidth(string, 4) + 3, m_valueLabel.y(), 2, fontRenderer.fontHeight(4), (now_ts % 1000ms < 500ms) ? TFT_WHITE : TFT_BLACK);
m_keyboard.redraw(tft);
m_locked = false;
}
void espgui::ChangeValueDisplay<std::string>::setShownValue(std::string &&value)
{
if (m_locked)
{
return;
}
m_locked = true;
m_needsClear = std::move(m_value);
m_value = std::move(value);
}
@ -61,7 +88,6 @@ void espgui::ChangeValueDisplay<std::string>::buttonReleased(Button button)
{
//Base::buttonReleased(button);
m_keyboard.buttonReleased(button);
// TODO stop auto scroll
}
void espgui::ChangeValueDisplay<std::string>::confirmValue()
@ -74,6 +100,11 @@ void espgui::ChangeValueDisplay<std::string>::confirmValue()
void espgui::ChangeValueDisplay<std::string>::removeLastCharFromShownValue()
{
if (m_locked)
{
return;
}
if (auto val = this->shownValue(); !val.empty())
{
val.pop_back();

View File

@ -31,6 +31,7 @@ public:
void start() override;
void initScreen(TftInterface &tft) override;
void update() override;
void redraw(TftInterface &tft) override;
void buttonPressed(Button button) override;
@ -45,6 +46,8 @@ public:
void removeLastCharFromShownValue();
private:
bool m_locked{false};
std::string m_value;
Label m_valueLabel{12, 55}; // 188, 53

View File

@ -7,6 +7,7 @@
#include "actions/setvalueaction.h"
#include "actions/backproxyaction.h"
#include "icons/back.h"
#include "icons/back_grey.h"
namespace espgui {
namespace {
@ -35,7 +36,7 @@ ChangeValueDisplay<wifi_auth_mode_t>::ChangeValueDisplay()
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_auth_mode_t>, StaticText<TEXT_WPA3_PSK>>>(WIFI_AUTH_WPA3_PSK, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_auth_mode_t>, StaticText<TEXT_WPA2_WPA3_PSK>>>(WIFI_AUTH_WPA2_WPA3_PSK, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_auth_mode_t>, StaticText<TEXT_WAPI_PSK>>>(WIFI_AUTH_WAPI_PSK, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&espgui::icons::back>>>(*this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back, &icons::back_grey>>>(*this);
}
void ChangeValueDisplay<wifi_auth_mode_t>::start()

View File

@ -7,6 +7,7 @@
#include "actions/setvalueaction.h"
#include "actions/backproxyaction.h"
#include "icons/back.h"
#include "icons/back_grey.h"
namespace espgui {
namespace {
@ -25,7 +26,7 @@ ChangeValueDisplay<wifi_mode_t>::ChangeValueDisplay()
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_mode_t>, StaticText<TEXT_STA>>>(WIFI_MODE_STA, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_mode_t>, StaticText<TEXT_AP>>>(WIFI_MODE_AP, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, SetValueAction<wifi_mode_t>, StaticText<TEXT_APSTA>>>(WIFI_MODE_APSTA, *this, *this, *this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&espgui::icons::back>>>(*this);
constructMenuItem<makeComponentArgs<MenuItem, BackProxyAction, StaticText<TEXT_BACK>, StaticMenuItemIcon<&icons::back, &icons::back_grey>>>(*this);
}
void ChangeValueDisplay<wifi_mode_t>::start()

View File

@ -4,15 +4,17 @@
#include "menuitem.h"
#include "accessorinterface.h"
#include "icons/checked.h"
#include "icons/checked_grey.h"
#include "icons/unchecked.h"
#include "icons/unchecked_grey.h"
namespace espgui {
class CheckboxIcon : public virtual MenuItemIconInterface, public virtual AccessorInterface<bool>
{
public:
const MenuItemIcon *icon() const override
const MenuItemIcon *icon(bool selected) const override
{
return getValue() ? &icons::checked : &icons::unchecked;
return getValue() ? (selected ? &icons::checked_grey : &icons::checked) : (selected ? &icons::unchecked_grey : &icons::unchecked);
}
};
} // namespace espgui

View File

@ -11,6 +11,7 @@
namespace espgui {
class TftInterface;
class TextInterface;
class TitleInterface;
class MenuDisplay;
class ChangeValueDisplayInterface;
template<typename Tvalue> class ChangeValueDisplay;
@ -60,6 +61,18 @@ public:
}
};
template <typename T1, typename T2, typename T3, typename ...T4>
class makeComponentArgs12 : public T1, public T2, public T3, public T4...
{
public:
template<typename Targ1, typename Targ2, typename Targ3>
makeComponentArgs12(Targ1&& arg1, Targ2&& arg2, Targ3&& arg3) :
T2{std::forward<Targ1>(arg1)},
T3{std::forward<Targ2>(arg2), std::forward<Targ3>(arg3)}
{
}
};
class Display : public virtual ButtonsInterface
{
public:
@ -83,6 +96,9 @@ public:
virtual TextInterface *asTextInterface() { return nullptr; }
virtual const TextInterface *asTextInterface() const { return nullptr; }
virtual TitleInterface *asTitleInterface() { return nullptr; }
virtual const TitleInterface *asTitleInterface() const { return nullptr; }
virtual MenuDisplay *asMenuDisplay() { return nullptr; }
virtual const MenuDisplay *asMenuDisplay() const { return nullptr; }

View File

@ -11,14 +11,17 @@ void DisplayWithTitle::initScreen(TftInterface &tft)
Base::initScreen(tft);
m_titleLabel.start(tft);
tft.fillRect(0, 33, tft.width(), 3, TFT_WHITE);
// tft.fillRect(0, 0, tft.width(), 35, TFT_GREY);
tft.fillRect(0, TITLE_HEIGHT, tft.width(), TITLE_BORDER, TFT_GREY);
}
void DisplayWithTitle::redraw(TftInterface &tft)
{
Base::redraw(tft);
m_titleLabel.redraw(tft, text(), TFT_YELLOW, TFT_BLACK, 4);
m_titleLabel.redraw(tft, title(), TFT_GREY, TFT_BLACK, 4);
}
} // namespace espgui

View File

@ -2,20 +2,23 @@
// local includes
#include "display.h"
#include "textinterface.h"
#include "titleinterface.h"
#include "widgets/label.h"
namespace espgui {
class DisplayWithTitle :
public Display,
public virtual TextInterface
public virtual TitleInterface
{
using Base = Display;
public:
TextInterface *asTextInterface() override { return this; }
const TextInterface *asTextInterface() const override { return this; }
constexpr static int TITLE_HEIGHT = 34;
constexpr static int TITLE_BORDER = 2;
TitleInterface *asTitleInterface() override { return this; }
const TitleInterface *asTitleInterface() const override { return this; }
void initScreen(TftInterface &tft) override;
void redraw(TftInterface &tft) override;

View File

@ -1,17 +0,0 @@
#pragma once
// system includes
#include <cstdint>
namespace espgui {
template<uint16_t width, uint16_t height>
struct Icon
{
static constexpr auto WIDTH=width;
static constexpr auto HEIGHT=height;
const unsigned short buffer[width*height];
const char * const name{};
};
} // namespace espgui

View File

@ -12,25 +12,11 @@ public:
virtual const Icon<width, height> *icon() const { return nullptr; }
};
template<uint16_t width, uint16_t height>
class SelectedIconInterface
{
public:
virtual const Icon<width, height> *selectedIcon() const { return nullptr; }
};
template<uint16_t width, uint16_t height, const Icon<width, height> *T>
class StaticIcon : public virtual IconInterface<width, height>
{
public:
virtual const Icon<width, height> *icon() const { return T; }
};
template<uint16_t width, uint16_t height, const Icon<width, height> *T>
class StaticSelectedIcon : public virtual SelectedIconInterface<width, height>
{
public:
virtual const Icon<width, height> *selectedIcon() const { return T; }
virtual const Icon<width, height> *icon() const override { return T; }
};
} // namespace espgui

View File

@ -3,42 +3,42 @@
namespace espgui {
namespace icons {
const Icon<24, 24> back {{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c01, 0x4b01, 0x0b01, 0xac01, 0x8c01, 0x8c01, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b01, 0x0900, 0x0000,
0xd02a, 0x3133, 0xcb00, 0xcd09, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x2b01, 0x0700, 0x0000, 0x6f1a, 0xd75c, 0x965c, 0x0300, 0xed09, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b01, 0x0600, 0xffff, 0x2f02, 0x1865,
0xfb75, 0x965c, 0x0000, 0xb01a, 0x1223, 0xf122, 0xb01a, 0x6f1a, 0x0e0a, 0x6c01, 0x4800, 0xea00, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0a01, 0x2900, 0x0000, 0x2f02, 0x3865, 0x1b76, 0x1b76, 0xd75c, 0x4f02, 0xd022, 0xd022, 0xb01a, 0x6f1a, 0x4f12,
0xcd01, 0x2a00, 0x0000, 0x8c01, 0x0700, 0x4b01, 0x0000, 0x0000, 0x0200, 0x0300, 0x2e0a, 0x0000, 0x901a, 0x1865, 0x3c7e, 0x1c76,
0x1c76, 0x1c6e, 0xbb65, 0x9a5d, 0x7a5d, 0x3955, 0xf854, 0xb74c, 0x764c, 0xd43b, 0x112b, 0x6f1a, 0x6c01, 0xf543, 0x2b01, 0xa600,
0x0600, 0x4f02, 0x0000, 0xf122, 0x1865, 0x3c7e, 0x5c7e, 0x5c76, 0x5c76, 0x3c6e, 0x1c66, 0xfc65, 0xbb5d, 0x9a55, 0x5a4d, 0xf944,
0xd844, 0x973c, 0x5644, 0xd43b, 0xf12a, 0xcd09, 0x7c5d, 0xaa00, 0x2f02, 0x0000, 0xf12a, 0x1865, 0x3c86, 0x3c7e, 0x3c6e, 0x3c66,
0x3d66, 0x3d5e, 0x1c5e, 0xfc5d, 0xdb55, 0x9b55, 0x5a4d, 0x1945, 0xb83c, 0x7734, 0x3634, 0xf533, 0xd43b, 0xf12a, 0x8c01, 0x0000,
0x4b01, 0xb022, 0xb754, 0x9a5d, 0x7a4d, 0x7b3d, 0x7b35, 0x9c2d, 0xdc2d, 0xdc2d, 0xbc2d, 0x7b2d, 0x5a35, 0x5a3d, 0x3a45, 0x1945,
0xd83c, 0x7734, 0x3634, 0xd52b, 0xb52b, 0x9433, 0x6f1a, 0x4c01, 0x6b01, 0x901a, 0x3634, 0xd924, 0xd914, 0x1a1d, 0x5b1d, 0x9c1d,
0xdd25, 0xdd25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0xb81c, 0xb82c, 0xb83c, 0x7734, 0x362c, 0xd52b, 0x9423, 0xd533, 0xf122, 0xcc11,
0x2f02, 0x0400, 0xd01a, 0x572c, 0xf924, 0x1a1d, 0x5b1d, 0x7c1d, 0xbc1d, 0xbc25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0x981c, 0x5714,
0x371c, 0x362c, 0x162c, 0xd523, 0x9423, 0xb523, 0x322b, 0xcd11, 0x0000, 0x0e0a, 0x0000, 0xf122, 0x772c, 0x1a25, 0x3a1d, 0x5b1d,
0x7b1d, 0x7b1d, 0x5b1d, 0x3a1d, 0xfa1c, 0xb91c, 0x781c, 0x5714, 0x1614, 0xd513, 0xd523, 0xb523, 0x941b, 0x941b, 0x522b, 0xed11,
0x2300, 0x0000, 0x4f0a, 0x0000, 0xf122, 0x9734, 0x1a25, 0x1a1d, 0x3a1d, 0x5b2d, 0x3a2d, 0x1a2d, 0xf924, 0xd924, 0x7814, 0x3714,
0xf613, 0xb513, 0x9413, 0x741b, 0x741b, 0x941b, 0x522b, 0xed11, 0x0000, 0x8700, 0x0000, 0x4f12, 0x0000, 0xb01a, 0x9734, 0x1a1d,
0xfa1c, 0x9734, 0x321b, 0x7323, 0x9323, 0xd42b, 0x1534, 0x572c, 0xf613, 0x9513, 0x7413, 0x5313, 0x5413, 0x9423, 0x322b, 0xed11,
0x0000, 0x0000, 0x0000, 0xea00, 0xea00, 0x0000, 0x6f12, 0x9734, 0xd924, 0x3534, 0x0000, 0x7012, 0x0000, 0x2900, 0xac01, 0xf122,
0xf533, 0x9513, 0x5413, 0x3313, 0x330b, 0x9423, 0xf122, 0xb022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b01, 0x0800, 0x0000, 0x6f1a,
0x7734, 0x3534, 0x0600, 0xed09, 0x2700, 0xea00, 0xac01, 0x0000, 0xb022, 0xb42b, 0x330b, 0x3313, 0x340b, 0x732b, 0xb022, 0xad09,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2b01, 0x0900, 0x0000, 0x901a, 0x5233, 0x4a00, 0xcd09, 0x0000, 0x0000, 0x0a01, 0x2b01,
0xcd09, 0x532b, 0x5413, 0x330b, 0x541b, 0x322b, 0x8f22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b01, 0x0b01,
0x0700, 0x8d01, 0xac01, 0xac01, 0x0000, 0x0000, 0x0000, 0x4b01, 0xcd09, 0x322b, 0x7413, 0x330b, 0x5323, 0xf12a, 0xea08, 0x0d1a,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xad01, 0xed09, 0xca00, 0x8c01, 0x8c01, 0x0000, 0x0000, 0x0000, 0x8c01,
0xed09, 0x532b, 0x5413, 0x531b, 0x322b, 0x4e22, 0x112b, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa800, 0xed09, 0x2e12, 0x732b, 0x541b, 0x532b, 0xd032, 0xd443, 0x0400, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4900, 0x1b45,
0xb01a, 0xb42b, 0x532b, 0xf032, 0x3a5d, 0x0800, 0xc900, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8c01, 0x0b01, 0x3233, 0x9333, 0xd02a, 0x3f87, 0x2b01, 0xed11, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0901, 0xad01, 0x8c01,
0xb022, 0xf032, 0x1e76, 0x6c01, 0x2e1a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b01, 0x8c01, 0x8c01, 0xcd09, 0x774c, 0x2b01, 0x0e1a, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4200, 0x2100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0611, 0xae2a, 0x2200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0609, 0x965c, 0x1454, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0701, 0xb65c,
0xfb75, 0x144c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0701, 0xf764, 0x1b76, 0x1b76, 0x965c, 0x6901, 0x8911, 0xa911, 0x8911, 0x4809, 0x0709,
0x8400, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2709, 0xd75c, 0x3c7e, 0x1c76,
0x1c76, 0x1c6e, 0xbb65, 0x9a5d, 0x7a5d, 0x3955, 0xf854, 0xb74c, 0x764c, 0xb33b, 0x4d22, 0xc508, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x6811, 0xd75c, 0x3c7e, 0x5c7e, 0x5c76, 0x5c76, 0x3c6e, 0x1c66, 0xfc65, 0xbb5d, 0x9a55, 0x5a4d, 0xf944,
0xd844, 0x973c, 0x5644, 0xb43b, 0xeb19, 0x4100, 0x0000, 0x0000, 0x0000, 0x0000, 0x6811, 0xd764, 0x3c86, 0x3c7e, 0x3c6e, 0x3c66,
0x3d66, 0x3d5e, 0x1c5e, 0xfc5d, 0xdb55, 0x9b55, 0x5a4d, 0x1945, 0xb83c, 0x7734, 0x3634, 0xf533, 0xd43b, 0x0b1a, 0x2100, 0x0000,
0x0000, 0x6811, 0x974c, 0x9a5d, 0x7a4d, 0x7b3d, 0x7b35, 0x9c2d, 0xdc2d, 0xdc2d, 0xbc2d, 0x7b2d, 0x5a35, 0x5a3d, 0x3a45, 0x1945,
0xd83c, 0x7734, 0x3634, 0xd52b, 0xb52b, 0x9433, 0x0609, 0x0000, 0x0000, 0x6809, 0x3634, 0xd924, 0xd914, 0x1a1d, 0x5b1d, 0x9c1d,
0xdd25, 0xdd25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0xb81c, 0xb82c, 0xb83c, 0x7734, 0x362c, 0xd52b, 0x9423, 0xd533, 0x2d1a, 0x0000,
0x0000, 0x0000, 0x8911, 0x562c, 0xf924, 0x1a1d, 0x5b1d, 0x7c1d, 0xbc1d, 0xbc25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0x981c, 0x5714,
0x371c, 0x362c, 0x162c, 0xd523, 0x9423, 0xb523, 0xf122, 0x2100, 0x0000, 0x0000, 0x0000, 0xa911, 0x562c, 0x1a25, 0x3a1d, 0x5b1d,
0x7b1d, 0x7b1d, 0x5b1d, 0x3a1d, 0xfa1c, 0xb91c, 0x781c, 0x5714, 0x1614, 0xd513, 0xd523, 0xb523, 0x941b, 0x941b, 0x322b, 0x4200,
0x0000, 0x0000, 0x0000, 0x0000, 0xa911, 0x772c, 0x1a25, 0x1a1d, 0x3a1d, 0x5b2d, 0x3a2d, 0x1a2d, 0xf924, 0xd924, 0x7814, 0x3714,
0xf613, 0xb513, 0x9413, 0x741b, 0x741b, 0x941b, 0x112b, 0x4200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8909, 0x7734, 0x1a1d,
0xfa1c, 0x7634, 0x6e12, 0xae1a, 0xf022, 0x932b, 0x1534, 0x572c, 0xf613, 0x9513, 0x7413, 0x5313, 0x5413, 0x9423, 0xaf22, 0x2100,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6909, 0x9734, 0xd924, 0xb32b, 0x0000, 0x0000, 0x0000, 0x0000, 0x6300, 0x0c1a,
0xd52b, 0x9513, 0x5413, 0x3313, 0x330b, 0x9423, 0xeb19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6909,
0x7634, 0xb333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xaa11, 0xb42b, 0x330b, 0x3313, 0x340b, 0x732b, 0x0609, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6811, 0xf02a, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x6300, 0x522b, 0x5413, 0x330b, 0x541b, 0x8e22, 0x4100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x8400, 0x2100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4200, 0x1123, 0x7413, 0x330b, 0x5323, 0x2711, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x6300, 0x322b, 0x5413, 0x531b, 0x2c1a, 0x2100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe600, 0x732b, 0x541b, 0xd022, 0xa308, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xcb11, 0xb42b, 0xf022, 0xe510, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2100, 0x112b, 0x102b, 0xe508, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa500,
0xeb19, 0x8308, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
}};
} // namespace icons

45
src/icons/back_grey.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "back_grey.h"
namespace espgui {
namespace icons {
const Icon<24, 24> back_grey {{
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xab4a, 0xcb52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a,
0xcd4a, 0x103b, 0x6b4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xad3a, 0xb65c, 0x755c, 0x6a4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x8d2a, 0xf764,
0xfb75, 0x755c, 0x8a52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0x8d2a, 0x1765, 0x1b76, 0x1b76, 0xd75c, 0x6e22, 0xce3a, 0xce3a, 0xce3a, 0xad3a, 0x8d3a,
0x6c3a, 0x6b4a, 0xcb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xad3a, 0xf764, 0x3c7e, 0x1c76,
0x1c76, 0x1c6e, 0xbb65, 0x9a5d, 0x7a5d, 0x3955, 0xf854, 0xb74c, 0x764c, 0xd43b, 0x103b, 0xac42, 0xcb52, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xaa52, 0xee42, 0xf764, 0x3c7e, 0x5c7e, 0x5c76, 0x5c76, 0x3c6e, 0x1c66, 0xfc65, 0xbb5d, 0x9a55, 0x5a4d, 0xf944,
0xd844, 0x973c, 0x5644, 0xb43b, 0xef3a, 0xab4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xee42, 0xf764, 0x3c86, 0x3c7e, 0x3c6e, 0x3c66,
0x3d66, 0x3d5e, 0x1c5e, 0xfc5d, 0xdb55, 0x9b55, 0x5a4d, 0x1945, 0xb83c, 0x7734, 0x3634, 0xf533, 0xd43b, 0xef3a, 0xcb52, 0xeb5a,
0xcb5a, 0xce3a, 0xb754, 0x9a5d, 0x7a4d, 0x7b3d, 0x7b35, 0x9c2d, 0xdc2d, 0xdc2d, 0xbc2d, 0x7b2d, 0x5a35, 0x5a3d, 0x3a45, 0x1945,
0xd83c, 0x7734, 0x3634, 0xd52b, 0xb52b, 0x9433, 0xad42, 0xcb5a, 0xcb5a, 0xad3a, 0x3634, 0xd924, 0xd914, 0x1a1d, 0x5b1d, 0x9c1d,
0xdd25, 0xdd25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0xb81c, 0xb82c, 0xb83c, 0x7734, 0x362c, 0xd52b, 0x9423, 0xd533, 0xef32, 0xcb5a,
0xeb5a, 0xcb5a, 0xce3a, 0x562c, 0xf924, 0x1a1d, 0x5b1d, 0x7c1d, 0xbc1d, 0xbc25, 0x9c1d, 0x5b1d, 0x1a1d, 0xd91c, 0x981c, 0x5714,
0x371c, 0x362c, 0x162c, 0xd523, 0x9423, 0xb523, 0x322b, 0xab52, 0xeb5a, 0xeb5a, 0xaa52, 0xee3a, 0x7734, 0x1a25, 0x3a1d, 0x5b1d,
0x7b1d, 0x7b1d, 0x5b1d, 0x3a1d, 0xfa1c, 0xb91c, 0x781c, 0x5714, 0x1614, 0xd513, 0xd523, 0xb523, 0x941b, 0x941b, 0x522b, 0xab4a,
0xeb5a, 0xeb5a, 0xeb5a, 0xaa52, 0xee3a, 0x7734, 0x1a25, 0x1a1d, 0x3a1d, 0x5b2d, 0x3a2d, 0x1a2d, 0xf924, 0xd924, 0x7814, 0x3714,
0xf613, 0xb513, 0x9413, 0x741b, 0x741b, 0x941b, 0x322b, 0xab4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xaa52, 0xce3a, 0x9734, 0x1a1d,
0xfa1c, 0x973c, 0x302b, 0x5133, 0x7233, 0xb42b, 0x1534, 0x572c, 0xf613, 0x9513, 0x7413, 0x5313, 0x5413, 0x9423, 0x1133, 0xcb52,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0x8d32, 0x9734, 0xd924, 0xf433, 0x694a, 0xeb5a, 0xcb5a, 0x8b52, 0x8b42, 0xef32,
0xd533, 0x9513, 0x5413, 0x3313, 0x330b, 0x9423, 0xef3a, 0xcb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0x8d32,
0x7634, 0xf43b, 0x6a4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xae32, 0xb42b, 0x330b, 0x3313, 0x340b, 0x732b, 0xcd42, 0xcb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xae3a, 0x5133, 0x6b4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0x8b4a, 0x532b, 0x5413, 0x330b, 0x541b, 0x3133, 0xcb52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xab52, 0x6c3a, 0xab52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xab4a, 0x322b, 0x7413, 0x330b, 0x5323, 0xed42, 0xcb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xcb5a, 0xcb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xab4a, 0x522b, 0x5413, 0x531b, 0x103b, 0xcb52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x8c3a, 0x732b, 0x541b, 0x3133, 0xcc52, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xae32, 0xb42b, 0x522b, 0xed4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x8b4a, 0x3133, 0x723b, 0xcd4a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x4c32,
0xae32, 0xec52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xab52, 0xcb52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
}};
} // namespace icons
} // namespace espgui

10
src/icons/back_grey.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
// local
#include "icon.h"
namespace espgui {
namespace icons {
extern const Icon<24, 24> back_grey;
} // namespace icons
} // namespace espgui

View File

@ -12,24 +12,24 @@ const Icon<24, 24> checked {{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x9503, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x0000, 0x0000, 0x0000, 0x0000, 0x9603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xddbe, 0xbfef, 0xffff, 0xddbe, 0x3a5d, 0x7603, 0x5603, 0x0000,
0x0000, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb7d, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb7d, 0x7603, 0x9503, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x9944, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x0000, 0x0000, 0x2100, 0xab01, 0x9102, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0xd202, 0x4801, 0x0000, 0x0000, 0x0000, 0x0000, 0x6200, 0x1403, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xddbe, 0xbfef, 0xffff, 0xddbe, 0x3a5d, 0x1403, 0x6200, 0x0000,
0x0000, 0x1403, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb7d, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb7d, 0x1403, 0x2100, 0x4801, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x9944, 0xab01,
0xd202, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0x9102, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbfef, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbfef, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0x7703,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3a5d, 0x7603, 0x9503, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb85, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb85, 0x7603, 0x0000,
0x0000, 0x9603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65,
0xddbe, 0xffff, 0xbfef, 0xddbe, 0x9944, 0x7603, 0x5603, 0x0000, 0x0000, 0x0000, 0x0000, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9503, 0x0000, 0x0000,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7603, 0x9102, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0xd202,
0xab01, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3a5d, 0x4801, 0x2100, 0x1403, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb85, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb85, 0x1403, 0x0000,
0x0000, 0x6200, 0x1403, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65,
0xddbe, 0xffff, 0xbfef, 0xddbe, 0x9944, 0x1403, 0x6200, 0x0000, 0x0000, 0x0000, 0x0000, 0x4801, 0xd202, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9102, 0xab01, 0x2100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,

View File

@ -0,0 +1,45 @@
#include "checked_grey.h"
namespace espgui {
namespace icons {
const Icon<24, 24> checked_grey {{
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xec52, 0x312b, 0x5413, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x5413, 0x0f3b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xec52, 0x550b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xddbe, 0xbfef, 0xffff, 0xddbe, 0x3a5d, 0x550b, 0xec52, 0xeb5a,
0xeb5a, 0x550b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb7d, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb7d, 0x550b, 0xec52, 0x0f3b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x9944, 0x312b,
0x5413, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0x5413, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbfef, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbfef, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x7603, 0x5413, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xddbe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xddbe, 0x5413,
0x312b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x9944, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3a5d, 0x0f3b, 0xec52, 0x550b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0xbb85, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xbb85, 0x550b, 0xeb5a,
0xeb5a, 0xec52, 0x550b, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x3a65,
0xddbe, 0xffff, 0xbfef, 0xddbe, 0x9944, 0x550b, 0xec52, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x0f3b, 0x5413, 0x7603, 0x7603, 0x7603,
0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x7603, 0x5413, 0x312b, 0xec52, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
}};
} // namespace icons
} // namespace espgui

10
src/icons/checked_grey.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
// local
#include "icon.h"
namespace espgui {
namespace icons {
extern const Icon<24, 24> checked_grey;
} // namespace icons
} // namespace espgui

View File

@ -12,24 +12,24 @@ const Icon<24, 24> unchecked {{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x1074, 0xf073, 0xf073, 0xd073, 0x1074, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd073, 0xf073, 0xf073, 0x1074, 0x0000,
0x0000, 0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073, 0x9073, 0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073,
0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd073, 0xf073, 0xf073, 0x0000, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1074, 0xf073,
0xf073, 0x9073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xd073, 0xf073,
0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0x1074, 0xf073, 0xf073, 0xf073, 0xf073,
0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073, 0x0000,
0x0000, 0x1074, 0xf073, 0xf073, 0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x1074, 0x1074, 0xf073, 0xf073, 0x1074, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x1074, 0x0000, 0x0000,
0x0000, 0x0000, 0x4100, 0xe839, 0xec52, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0x2d5b, 0x6629, 0x0000, 0x0000, 0x0000, 0x0000, 0x8208, 0x6e63, 0xec52, 0xe418, 0x4100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe418, 0x6a4a, 0x6e63, 0x8208, 0x0000,
0x0000, 0x6e63, 0xe839, 0x8208, 0xec52, 0xaf6b, 0xf073, 0xab52, 0x8208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe839, 0x6e63, 0x2100, 0x6629, 0x6a4a, 0x8208, 0xaf6b, 0xf073, 0xf073, 0xf073, 0xf073,
0xaf6b, 0x8208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xec52, 0xe839,
0x2d5b, 0x0419, 0xab52, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xec52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe418, 0xec52, 0xf073, 0x0000, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xaf6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4100, 0xf073,
0xf073, 0x2100, 0xaf6b, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf073, 0xec52, 0x0419, 0xec52, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xab52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe418, 0x2d5b,
0xe839, 0xec52, 0x8208, 0xaf6b, 0xf073, 0xf073, 0xf073, 0xf073, 0xaf6b, 0x8208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a4a, 0x6629, 0x4100, 0x6e63, 0xe839, 0x8208, 0xab52, 0xf073, 0xaf6b, 0xec52,
0x8208, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe839, 0x6e63, 0x0000,
0x0000, 0x8208, 0x6e63, 0x6a4a, 0x0419, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x4100, 0x0419, 0xec52, 0x6e63, 0x8208, 0x0000, 0x0000, 0x0000, 0x0000, 0x6629, 0x2d5b, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xec52, 0xe839, 0x4100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,

View File

@ -0,0 +1,45 @@
#include "unchecked_grey.h"
namespace espgui {
namespace icons {
const Icon<24, 24> unchecked_grey {{
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0x6e6b, 0xaf6b, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0xaf73, 0x4d63, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x0c5b, 0xcf73, 0xaf6b, 0x0c63, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x0c63, 0x8e6b, 0xcf73, 0x0c5b, 0xeb5a,
0xeb5a, 0xcf73, 0x6d6b, 0x0c5b, 0xaf6b, 0xd073, 0xf073, 0x8f6b, 0x0c5b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x6d6b, 0xcf73, 0xeb5a, 0x4d63, 0x8e6b, 0x0c5b, 0xd073, 0xf073, 0xf073, 0xf073, 0xf073,
0xd073, 0x0c5b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xaf6b, 0x6d6b,
0xaf73, 0x2c63, 0x8e6b, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xaf6b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x0c63, 0xaf6b, 0xf073, 0xeb5a, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0xd073, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xf073,
0xf073, 0xeb5a, 0xd073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xf073, 0xaf6b, 0x2c63, 0xaf6b, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073,
0xf073, 0x8f6b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x0c63, 0xaf73,
0x6d6b, 0xaf6b, 0x0c5b, 0xd073, 0xf073, 0xf073, 0xf073, 0xf073, 0xd073, 0x0c5b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x8e6b, 0x4d63, 0xeb5a, 0xcf73, 0x6e6b, 0x0c5b, 0xae6b, 0xf073, 0xd073, 0xaf6b,
0x0c5b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x6e6b, 0xcf73, 0xeb5a,
0xeb5a, 0x0c5b, 0xcf73, 0x8e6b, 0x2c63, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0x2c63, 0xaf6b, 0xcf73, 0x0c5b, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0x4d63, 0xaf73, 0xf073, 0xf073, 0xf073,
0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xf073, 0xaf6b, 0x6d6b, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a, 0xeb5a,
}};
} // namespace icons
} // namespace espgui

View File

@ -0,0 +1,10 @@
#pragma once
// local
#include "icon.h"
namespace espgui {
namespace icons {
extern const Icon<24, 24> unchecked_grey;
} // namespace icons
} // namespace espgui

View File

@ -4,8 +4,8 @@
#include <esp_log.h>
// 3rdparty lib includes
#include <fmt/core.h>
#include <strutils.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -33,7 +33,7 @@ public:
explicit Keyboard(TDisplay &display) : m_display(display) {}
void start(TftInterface &tft);
void update();
void redraw(TftInterface &tft);
void buttonPressed(Button button);
@ -71,6 +71,18 @@ private:
bool m_needsStart{};
bool m_needsRedraw{};
std::optional<espchrono::millis_clock::time_point> m_back_pressed_time{};
std::optional<espchrono::millis_clock::time_point> m_confirm_pressed_time{};
struct ButtonHeldInfo
{
espchrono::millis_clock::time_point nextTimestamp;
int counter{};
};
std::optional<ButtonHeldInfo> m_upHeld;
std::optional<ButtonHeldInfo> m_downHeld;
};
template<typename TDisplay>
@ -96,16 +108,24 @@ void Keyboard<TDisplay>::moveSelectorDown()
template<typename TDisplay>
void Keyboard<TDisplay>::nextScreen()
{
m_current_screen = static_cast<Screen>(static_cast<uint8_t>(m_current_screen) + uint8_t{1});
if (m_current_screen >= Screen::SCREEN_MAX)
m_current_screen = Screen::SCREEN_1;
updateCharLength();
m_needsStart = true;
m_needsRedraw = true;
}
template<typename TDisplay>
void Keyboard<TDisplay>::drawKeyboard(TftInterface &tft, bool dont_draw_string)
{
FontRenderer fontRenderer{tft};
constexpr const int FONT = 4;
size_t char_index{0};
std::string keyboard_screen{m_keyboard};
@ -120,15 +140,9 @@ void Keyboard<TDisplay>::drawKeyboard(TftInterface &tft, bool dont_draw_string)
keyboard_lines.push_back(line);
}
#if 0
const auto datum = tft.getTextDatum();
tft.setTextDatum(MC_DATUM);
for (size_t i = 0; i < keyboard_lines.size(); i++)
{
tft.setTextColor(TFT_GREY);
const int32_t y = m_keyboard_start_y + (i * tft.fontHeight() + 9);
const int32_t y = m_keyboard_start_y + (i * fontRenderer.fontHeight(FONT) + 9);
std::string line = keyboard_lines[i];
const int16_t x = tft.width() / (line.size() + 1);
for (size_t j = 0; j < line.size(); j++)
@ -137,120 +151,73 @@ void Keyboard<TDisplay>::drawKeyboard(TftInterface &tft, bool dont_draw_string)
const int32_t x_pos = x * (j + 1);
const int32_t y_pos = y;
const auto width = tft.textWidth(_char) + 2;
const auto height = tft.fontHeight() + 4;
if (char_index == m_char_index)
tft.drawRoundRect(x_pos-width/2-1, y_pos-height/2, width+2, height-4, 3, TFT_DARKGREY);
const auto width = fontRenderer.textWidth(_char, FONT) + 2;
const auto height = fontRenderer.fontHeight(FONT) + 4;
if (char_index == m_last_char_index)
{
tft.drawRoundRect(x_pos-width/2-1, y_pos-height/2, width+2, height-4, 3, TFT_BLACK);
}
tft.drawRoundRect(x_pos-width/2-1, y_pos-height/2, width+2, height-4, 3, espgui::TFT_BLACK);
if (char_index == m_char_index)
tft.drawRoundRect(x_pos-width/2-1, y_pos-height/2, width+2, height-4, 3, espgui::TFT_DARKGREY);
if (!dont_draw_string || char_index == m_char_index || char_index == m_last_char_index)
{
if (char_index == m_char_index || char_index == m_last_char_index)
tft.setTextColor(char_index == m_last_char_index ? TFT_GREY : TFT_WHITE);
tft.drawString(_char, x_pos, y_pos);
if (char_index == m_char_index)
tft.setTextColor(TFT_GREY);
fontRenderer.drawString(_char, x_pos, y_pos, (char_index == m_char_index ? espgui::TFT_WHITE : espgui::TFT_GREY), espgui::TFT_BLACK, FONT, 4); // 4 = center
}
char_index++;
}
}
tft.setTextDatum(datum);
// draw 3 extra buttons, back, space and enter (x=10, x=tft.width()/2, x=tft.width()-10)
const int32_t y = m_keyboard_start_y + (keyboard_lines.size() * tft.fontHeight(4));
const int32_t y = m_keyboard_start_y + (keyboard_lines.size() * fontRenderer.fontHeight(FONT));
if (isLandscape(tft))
{
// align left (SHIFT, SPACE)
tft.drawRoundRect(15 - 2, y - 1, tft.textWidth(SHIFT) + 4, tft.fontHeight(4) + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(30 + tft.textWidth(SHIFT, 4) - 2, y - 1, tft.textWidth(SPACE, 4) + 4, tft.fontHeight() + 2, 3,
TFT_DARKGREY);
tft.drawRoundRect(15 - 2, y - 1, fontRenderer.textWidth(SHIFT, FONT) + 4, fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
tft.drawRoundRect(30 + fontRenderer.textWidth(SHIFT, FONT) - 2, y - 1, fontRenderer.textWidth(SPACE, FONT) + 4, fontRenderer.fontHeight(FONT) + 2, 3,
espgui::TFT_DARKGREY);
// align right (BACKSPACE, ENTER); align from tft.width()
tft.drawRoundRect(tft.width() - 30 - tft.textWidth(ENTER) - tft.textWidth(BACKSPACE) - 2, y - 1,
tft.textWidth(BACKSPACE) + 4, tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 15 - tft.textWidth(ENTER) - 2, y - 1, tft.textWidth(ENTER) + 4,
tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 30 - fontRenderer.textWidth(ENTER, FONT) - fontRenderer.textWidth(BACKSPACE, FONT) - 2, y - 1,
fontRenderer.textWidth(BACKSPACE, FONT) + 4, fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 15 - fontRenderer.textWidth(ENTER, FONT) - 2, y - 1, fontRenderer.textWidth(ENTER, FONT) + 4,
fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
// if (!dont_draw_string)
{
// align left (SHIFT, SPACE)
if (m_char_index == m_char_length)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(SHIFT, 15, y);
if (m_char_index == m_char_length + 1)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(SPACE, 30 + tft.textWidth(SHIFT), y);
fontRenderer.drawString(SHIFT, 15, y, (m_char_index == m_char_length ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
fontRenderer.drawString(SPACE, 30 + fontRenderer.textWidth(SHIFT, FONT), y, (m_char_index == m_char_length + 1 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length +1 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
// align right (BACKSPACE, ENTER); align from tft.width()
if (m_char_index == m_char_length + 2)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(BACKSPACE, tft.width() - 30 - tft.textWidth(ENTER) - tft.textWidth(BACKSPACE), y);
if (m_char_index == m_char_length + 3)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(ENTER, tft.width() - 15 - tft.textWidth(ENTER), y);
fontRenderer.drawString(BACKSPACE, tft.width() - 30 - fontRenderer.textWidth(ENTER, FONT) - fontRenderer.textWidth(BACKSPACE, FONT), y, (m_char_index == m_char_length + 2 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length + 2 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
fontRenderer.drawString(ENTER, tft.width() - 15 - fontRenderer.textWidth(ENTER, FONT), y, (m_char_index == m_char_length + 3 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length + 3 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
}
}
else
{
const int32_t y_2 = y + tft.fontHeight() + 4;
const int32_t y_2 = y + fontRenderer.fontHeight(FONT) + 4;
// align left (SHIFT, SPACE)
tft.drawRoundRect(15 - 2, y - 1, tft.textWidth(SHIFT) + 4, tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(15 - 2, y_2 - 1, tft.textWidth(SPACE) + 4, tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(15 - 2, y - 1, fontRenderer.textWidth(SHIFT, FONT) + 4, fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
tft.drawRoundRect(15 - 2, y_2 - 1, fontRenderer.textWidth(SPACE, FONT) + 4, fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
// align right (BACKSPACE, ENTER); align from tft.width()
tft.drawRoundRect(tft.width() - 15 - tft.textWidth(ENTER) - 2, y - 1, tft.textWidth(ENTER) + 4,
tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 15 - tft.textWidth(BACKSPACE) - 2, y_2 - 1, tft.textWidth(BACKSPACE) + 4,
tft.fontHeight() + 2, 3, TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 15 - fontRenderer.textWidth(ENTER, FONT) - 2, y - 1, fontRenderer.textWidth(ENTER, FONT) + 4,
fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
tft.drawRoundRect(tft.width() - 15 - fontRenderer.textWidth(BACKSPACE, FONT) - 2, y_2 - 1, fontRenderer.textWidth(BACKSPACE, FONT) + 4,
fontRenderer.fontHeight(FONT) + 2, 3, espgui::TFT_DARKGREY);
// if (!dont_draw_string)
{
// align left (SHIFT, SPACE)
if (m_char_index == m_char_length)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(SHIFT, 15, y);
if (m_char_index == m_char_length + 1)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(SPACE, 15, y_2);
fontRenderer.drawString(SHIFT, 15, y, (m_char_index == m_char_length ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
fontRenderer.drawString(SPACE, 15, y_2, (m_char_index == m_char_length + 1 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length + 1 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
// align right (BACKSPACE, ENTER); align from tft.width()
if (m_char_index == m_char_length + 2)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(BACKSPACE, tft.width() - 15 - tft.textWidth(BACKSPACE), y_2);
if (m_char_index == m_char_length + 3)
tft.setTextColor(TFT_BLACK, TFT_WHITE);
else
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(ENTER, tft.width() - 15 - tft.textWidth(ENTER), y);
fontRenderer.drawString(BACKSPACE, tft.width() - 15 - fontRenderer.textWidth(BACKSPACE, FONT), y_2, (m_char_index == m_char_length + 2 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length + 2 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
fontRenderer.drawString(ENTER, tft.width() - 15 - fontRenderer.textWidth(ENTER, FONT), y, (m_char_index == m_char_length + 3 ? espgui::TFT_BLACK : espgui::TFT_WHITE), (m_char_index == m_char_length + 3 ? espgui::TFT_WHITE : espgui::TFT_BLACK), FONT);
}
}
#endif
}
template<typename TDisplay>
@ -313,66 +280,150 @@ void Keyboard<TDisplay>::start(TftInterface &tft)
updateCharLength();
drawKeyboard(tft);
m_upHeld = std::nullopt;
m_downHeld = std::nullopt;
}
template<typename TDisplay>
void Keyboard<TDisplay>::redraw(TftInterface &tft)
{
const auto isLandscape = espgui::isLandscape(tft);
if (m_needsStart)
{
m_needsStart = false;
drawKeyboard(tft, true);
tft.fillRect(1, m_keyboard_start_y - 10, tft.width()-1, tft.height() - m_keyboard_start_y - (isLandscape ? 0 : 30), TFT_BLACK);
tft.drawSunkenRect(1, m_keyboard_start_y - 10, tft.width()-1, tft.height() - m_keyboard_start_y - (isLandscape ? 0 : 30), TFT_WHITE, TFT_GREY, TFT_BLACK);
updateCharLength();
}
if (m_needsRedraw)
{
m_needsRedraw = false;
drawKeyboard(tft, true);
drawKeyboard(tft);
}
}
template<typename TDisplay>
void Keyboard<TDisplay>::buttonPressed(Button button)
{
using namespace std::chrono_literals;
switch (button)
{
case Right:
{
if (m_char_index < m_char_length)
m_display.setShownValue(m_display.shownValue() + m_keyset[m_char_index]);
else if (m_char_index == m_char_length) // shift
{
nextScreen();
}
else if (m_char_index == m_char_length + 1) // space
{
m_display.setShownValue(m_display.shownValue() + " ");
}
else if (m_char_index == m_char_length + 2) // backspace
{
m_display.removeLastCharFromShownValue();
}
else if (m_char_index == m_char_length + 3) // enter
{
m_display.confirmValue();
}
m_confirm_pressed_time = espchrono::millis_clock::now();
break;
}
case Left:
popScreen();
return;
m_back_pressed_time = espchrono::millis_clock::now();
break;
case Up:
moveSelectorLeft();
m_needsRedraw = true;
m_upHeld = ButtonHeldInfo { .nextTimestamp = espchrono::millis_clock::now() + 300ms };
break;
case Down:
moveSelectorRight();
m_needsRedraw = true;
m_downHeld = ButtonHeldInfo { .nextTimestamp = espchrono::millis_clock::now() + 300ms };
break;
default:;
}
}
template<typename TDisplay>
void Keyboard<TDisplay>::buttonReleased(espgui::Button button) {}
void Keyboard<TDisplay>::buttonReleased(espgui::Button button)
{
using namespace std::chrono_literals;
switch (button)
{
case Left:
if (!m_back_pressed_time)
return;
if (espchrono::ago(*m_back_pressed_time) < 350ms)
m_display.removeLastCharFromShownValue();
m_back_pressed_time = std::nullopt;
break;
case Right:
if (!m_confirm_pressed_time)
return;
if (espchrono::ago(*m_confirm_pressed_time) < 350ms)
{
if (m_char_index < m_char_length)
m_display.setShownValue(m_display.shownValue() + m_keyset[m_char_index]);
else if (m_char_index == m_char_length) // shift
{
nextScreen();
}
else if (m_char_index == m_char_length + 1) // space
{
m_display.setShownValue(m_display.shownValue() + " ");
}
else if (m_char_index == m_char_length + 2) // backspace
{
m_display.removeLastCharFromShownValue();
}
else if (m_char_index == m_char_length + 3) // enter
{
m_display.confirmValue();
}
}
m_confirm_pressed_time = std::nullopt;
break;
case Up:
m_upHeld = std::nullopt;
break;
case Down:
m_downHeld = std::nullopt;
break;
default:;
}
}
template<typename TDisplay>
void Keyboard<TDisplay>::update()
{
using namespace std::chrono_literals;
const auto now = espchrono::millis_clock::now();
if (m_back_pressed_time)
{
if (espchrono::ago(*m_back_pressed_time) > 350ms)
{
m_back_pressed_time = std::nullopt;
popScreen();
}
}
if (m_confirm_pressed_time)
{
if (espchrono::ago(*m_confirm_pressed_time) > 350ms)
{
m_confirm_pressed_time = std::nullopt;
nextScreen();
}
}
if (m_upHeld && now >= m_upHeld->nextTimestamp)
{
m_upHeld->nextTimestamp += m_upHeld->counter > 3 ? 100ms : 200ms;
m_upHeld->counter++;
moveSelectorLeft();
m_needsRedraw = true;
}
if (m_downHeld && now >= m_downHeld->nextTimestamp)
{
m_downHeld->nextTimestamp += m_downHeld->counter > 3 ? 100ms : 200ms;
m_downHeld->counter++;
moveSelectorRight();
m_needsRedraw = true;
}
}
} // namespace espgui

View File

@ -59,20 +59,25 @@ void MenuDisplay::update()
const auto offset = m_rotateOffset;
m_rotateOffset = 0;
const auto itemCount = menuItemCount();
if (itemCount)
if (const auto itemCount = menuItemCount())
{
if (m_selectedIndex == -1)
m_selectedIndex = 0;
m_selectedIndex = m_selectedIndex + offset;
m_selectedIndex += offset;
if (m_selectedIndex < 0)
m_selectedIndex += itemCount;
if (m_selectedIndex >= itemCount)
m_selectedIndex -= itemCount;
if (getMenuItem(m_selectedIndex).skipScroll())
{
m_selectedIndex = offset >= 0 ?
getNextAccessibleMenuItemIndex(m_selectedIndex) :
getPreviousAccessibleMenuItemIndex(m_selectedIndex);
}
if (m_selectedIndex < m_scrollOffset)
m_scrollOffset = m_selectedIndex;
if (m_selectedIndex >= m_scrollOffset + m_labels.size())
@ -87,24 +92,12 @@ void MenuDisplay::update()
runForEveryMenuItem([&](MenuItem &item){
item.update();
});
if (m_selectedIndex >= 0 && getMenuItem(m_selectedIndex).skipScroll())
{
if (offset > 0)
{
m_rotateOffset++;
}
else if (offset < 0)
{
m_rotateOffset--;
}
}
}
if (m_pressed)
{
m_pressed = false;
if (m_selectedIndex >= 0)
if (m_selectedIndex >= 0 && m_selectedIndex < m_menuItems.size())
getMenuItem(m_selectedIndex).triggered();
}
}
@ -156,20 +149,13 @@ void MenuDisplay::redraw(TftInterface &tft)
if (relativeIndex != m_highlightedIndex)
{
drawItemRect(*labelsIter, TFT_GREY);
drawItemRect(*labelsIter, CONFIG_ESPGUI_MENUITEM_BACKGROUND_COLOR);
*iconsIter = nullptr;
labelsIter->start(tft);
if (auto icon = item.selectedIcon())
{
#ifdef CONFIG_ESPGUI_ICONS_SWAPBYTES
tft.setSwapBytes(true);
#endif
tft.pushImage(tft.width() - 6 - icon->WIDTH, labelsIter->y() + 1, icon->WIDTH, icon->HEIGHT,
icon->buffer);
#ifdef CONFIG_ESPGUI_ICONS_SWAPBYTES
tft.setSwapBytes(false);
#endif
tft.pushImage(tft.width() - 6 - icon->WIDTH, labelsIter->y() + 1, *icon);
}
}
}
@ -178,31 +164,22 @@ void MenuDisplay::redraw(TftInterface &tft)
drawItemRect(*labelsIter, TFT_BLACK);
*iconsIter = nullptr;
labelsIter->start(tft);
}
}
labelsIter->redraw(tft, item.text(), item.color(), selected ? TFT_GREY : TFT_BLACK, item.font());
labelsIter->redraw(tft, item.text(), item.color(), selected ? CONFIG_ESPGUI_MENUITEM_BACKGROUND_COLOR : TFT_BLACK, item.font());
if (item.icon() != *iconsIter)
if (const auto icon = item.icon(selected); icon != *iconsIter)
{
auto icon = item.icon();
if (icon)
{
#ifdef CONFIG_ESPGUI_ICONS_SWAPBYTES
tft.setSwapBytes(true);
#endif
tft.pushImage(6, labelsIter->y() + 1, icon->WIDTH, icon->HEIGHT, icon->buffer);
#ifdef CONFIG_ESPGUI_ICONS_SWAPBYTES
tft.setSwapBytes(false);
#endif
}
tft.pushImage(6, labelsIter->y() + 1, *icon);
else if (*iconsIter)
tft.fillRect(6, labelsIter->y() + 1, 24, 24, selected ? TFT_GREY : TFT_BLACK);
tft.fillRect(6, labelsIter->y() + 1, 24, 24, selected ? CONFIG_ESPGUI_MENUITEM_BACKGROUND_COLOR : TFT_BLACK);
*iconsIter = icon;
}
// if (selected && (relativeIndex != m_highlightedIndex))
// {
// drawItemRect(*labelsIter, TFT_GREY);
// drawItemRect(*labelsIter, CONFIG_ESPGUI_MENUITEM_BACKGROUND_COLOR);
// }
labelsIter++;

View File

@ -42,7 +42,6 @@ public:
int selectedIndex() const { return m_selectedIndex; }
std::size_t menuItemCount() const { return m_menuItems.size(); }
MenuItem& getMenuItem(std::size_t index)
@ -57,6 +56,32 @@ public:
return *m_menuItems[index].get();
}
int getNextAccessibleMenuItemIndex(int index) const
{
for (std::size_t i = index + 1; i < m_menuItems.size(); ++i)
if (!m_menuItems[i]->skipScroll())
return i;
for (std::size_t i = 0; i < index; ++i)
if (!m_menuItems[i]->skipScroll())
return i;
return -1;
}
int getPreviousAccessibleMenuItemIndex(int index) const
{
for (std::size_t i = index - 1; i < m_menuItems.size(); --i)
if (!m_menuItems[i]->skipScroll())
return i;
for (std::size_t i = m_menuItems.size() - 1; i > index; --i)
if (!m_menuItems[i]->skipScroll())
return i;
return -1;
}
void runForEveryMenuItem(std::function<void(MenuItem&)> &&callback)
{
for (const auto &ptr : m_menuItems)
@ -96,6 +121,11 @@ public:
return ptr;
}
void rotate(int offset)
{
m_rotateOffset += offset;
}
protected:
void setSelectedIndex(int selectedIndex) { m_selectedIndex = selectedIndex; }

View File

@ -13,16 +13,80 @@ namespace espgui {
using MenuItemIcon = Icon<24, 24>;
using MenuItemIconInterface = IconInterface<24, 24>;
template<uint16_t width, uint16_t height>
class SelectableIconInterface
{
public:
virtual const Icon<width, height> *icon(bool selected) const { return nullptr; }
};
template<uint16_t width, uint16_t height, const Icon<width, height> *T, const Icon<width, height> *Tselected>
class StaticSelectableIcon : public virtual SelectableIconInterface<width, height>
{
public:
virtual const Icon<width, height> *icon(bool selected) const override { return selected ? Tselected : T; }
};
template<uint16_t width, uint16_t height>
class SelectedIconInterface
{
public:
virtual const Icon<width, height> *selectedIcon() const { return nullptr; }
};
template<uint16_t width, uint16_t height, const Icon<width, height> *T>
class StaticSelectedIcon : public virtual SelectedIconInterface<width, height>
{
public:
virtual const Icon<width, height> *selectedIcon() const override { return T; }
};
template<uint16_t width, uint16_t height>
class ChangeableSelectableIcon : public virtual SelectableIconInterface<width, height>
{
public:
virtual const Icon<width, height> *icon(bool selected) const override { return selected ? m_selectedIcon : m_icon; }
void setIcon(const Icon<width, height> *icon, const Icon<width, height> *selectedIcon)
{
m_icon = icon;
m_selectedIcon = selectedIcon;
}
void setIcon(const Icon<width, height> *icon) { m_icon = icon; }
void setSelectedIcon(const Icon<width, height> *selectedIcon) { m_selectedIcon = selectedIcon; }
private:
const Icon<width, height> *m_icon = nullptr;
const Icon<width, height> *m_selectedIcon = nullptr;
};
template<uint16_t width, uint16_t height>
class ChangeableSelectedIcon : public virtual SelectedIconInterface<width, height>
{
public:
virtual const Icon<width, height> *selectedIcon() const override { return m_selectedIcon; }
void setSelectedIcon(const Icon<width, height> *selectedIcon) { m_selectedIcon = selectedIcon; }
private:
const Icon<width, height> *m_selectedIcon = nullptr;
};
using MenuItemIconInterface = SelectableIconInterface<24, 24>;
using MenuItemSelectedIconInterface = SelectedIconInterface<24, 24>;
template<const MenuItemIcon *T>
using StaticMenuItemIcon = StaticIcon<24, 24, T>;
template<const MenuItemIcon *T, const MenuItemIcon *Tselected>
using StaticMenuItemIcon = StaticSelectableIcon<24, 24, T, Tselected>;
template<const MenuItemIcon *T>
using StaticMenuItemSelectedIcon = StaticSelectedIcon<24, 24, T>;
using ChangeableMenuItemIcon = ChangeableSelectableIcon<24, 24>;
using ChangeableMenuItemSelectedIcon = ChangeableSelectedIcon<24, 24>;
class MenuItem :
public virtual ActionInterface,
public virtual TextInterface,

View File

@ -6,6 +6,7 @@
// 3rdparty lib includes
#include <screenmanager.h>
#include <cppmacros.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -36,6 +37,8 @@ void MessagePopupDisplay::buttonPressed(Button button)
void MessagePopupDisplay::initOverlay(TftInterface &tft)
{
FontRenderer fontRenderer{tft};
const auto leftMargin = 20;
const auto rightMargin = leftMargin;
const auto topMargin = tft.height() > 300 ? 50 : 20;
@ -61,12 +64,12 @@ void MessagePopupDisplay::initOverlay(TftInterface &tft)
if (c == '\n' || x > tft.width() - rightMargin - 10)
{
x = leftMargin + 5;
y += tft.fontHeight(4);
y += fontRenderer.fontHeight(4);
}
if (c != '\n')
{
const auto addedWidth = tft.drawString(std::string_view{&c, 1}, x, y, TFT_WHITE, color565(30, 30, 30), 4);
const auto addedWidth = fontRenderer.drawString(std::string_view{&c, 1}, x, y, TFT_WHITE, color565(30, 30, 30), 4);
x += addedWidth;
}
@ -83,7 +86,7 @@ void MessagePopupDisplay::initOverlay(TftInterface &tft)
color565(100, 100, 100),
color565(170, 170, 170));
tft.drawString("Retry", leftMargin + 18, bottom - 37, TFT_BLACK, color565(170, 170, 170), 4);
fontRenderer.drawString("Retry", leftMargin + 18, bottom - 37, TFT_BLACK, color565(170, 170, 170), 4);
}
tft.drawSunkenRect(leftMargin + 15 + ((width - 15 - 30 - 15) / 2) + 15, bottom - 40,
@ -93,7 +96,7 @@ void MessagePopupDisplay::initOverlay(TftInterface &tft)
color565(100, 100, 100),
color565(170, 170, 170));
tft.drawString("Ok", leftMargin + 18 + ((width - 15 - 30 - 15) / 2) + 15 + 1, bottom - 37, TFT_BLACK, color565(170, 170, 170), 4);
fontRenderer.drawString("Ok", leftMargin + 18 + ((width - 15 - 30 - 15) / 2) + 15 + 1, bottom - 37, TFT_BLACK, color565(170, 170, 170), 4);
}
} // namespace espgui

View File

@ -19,17 +19,11 @@ void PopupDisplay::initScreen(TftInterface &tft)
initOverlay(tft);
}
void PopupDisplay::redraw(TftInterface &tft)
{
if (m_wantsClose)
closeOverlay(tft);
else
Base::redraw(tft);
}
void PopupDisplay::closeOverlay()
{
m_wantsClose = true;
espgui::changeScreenCallback = [this](espgui::TftInterface &tft){
closeOverlay(tft);
};
}
void PopupDisplay::closeOverlay(TftInterface &tft)

View File

@ -17,16 +17,12 @@ public:
void initScreen(TftInterface &tft) override;
void redraw(TftInterface &tft) override;
virtual void initOverlay(TftInterface &tft) = 0;
void closeOverlay();
void closeOverlay(TftInterface &tft);
private:
std::unique_ptr<Display> m_lastDisplay;
bool m_wantsClose{};
};
} // namespace espgui

18
src/richtexthelper.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "richtexthelper.h"
// 3rdparty lib includes
#include <strutils.h>
namespace espgui {
void richTextEscape(std::string &subject)
{
cpputils::stringReplaceAll('&', "&&", subject);
}
std::string richTextEscape(std::string_view subject)
{
return cpputils::stringReplaceAll('&', "&&", subject);
}
} // namespace espgui

View File

@ -1,5 +1,9 @@
#pragma once
// system includes
#include <string>
#include <string_view>
namespace espgui {
namespace colors {
constexpr char RED[] = "&1"; // #ff0000 (TFT_RED)
@ -17,4 +21,8 @@ constexpr char SMALL[] = "&s"; // tft.setTextFont(2)
constexpr char MEDIUM[] = "&m"; // tft.setTextFont(4)
constexpr char RESTORE[] = "&f"; // restore original font
} // namespace fonts
void richTextEscape(std::string &subject);
std::string richTextEscape(std::string_view subject);
} // namespace espgui

View File

@ -4,7 +4,7 @@
#include <string_view>
// 3rdparty lib includes
#include <strutils.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -12,34 +12,30 @@
namespace espgui {
void richTextEscape(std::string &subject)
{
cpputils::stringReplaceAll('&', "&&", subject);
}
std::string richTextEscape(std::string_view subject)
{
return cpputils::stringReplaceAll('&', "&&", subject);
}
int16_t renderRichText(TftInterface &tft, std::string_view str, int32_t poX, int32_t poY, uint16_t color, uint16_t bgcolor, uint8_t font)
{
FontRenderer fontRenderer{tft};
return renderRichText(tft, fontRenderer, str, poX, poY, color, bgcolor, font);
}
int16_t renderRichText(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, int32_t poX, int32_t poY, uint16_t color, uint16_t bgcolor, uint8_t font)
{
if (str.empty())
return 0;
const int16_t fontHeight = tft.fontHeight(font);
const int16_t fontHeight = fontRenderer.fontHeight(font);
const uint16_t oldColor = color;
const uint8_t oldFont = font;
int16_t width{};
const auto drawString = [&tft, &poX, &poY, &color, &bgcolor, &font, &width, &fontHeight, &oldFont](std::string_view str) {
const auto addedWith = tft.drawString(str, poX, poY, color, bgcolor, font);
const auto drawString = [&tft, &fontRenderer, &poX, &poY, &color, &bgcolor, &font, &width, &fontHeight, &oldFont](std::string_view str) {
const auto addedWith = fontRenderer.drawString(str, poX, poY, color, bgcolor, font);
if (font != oldFont)
{
if (const int16_t newFontHeight = tft.fontHeight(font); newFontHeight < fontHeight)
if (const int16_t newFontHeight = fontRenderer.fontHeight(font); newFontHeight < fontHeight)
{
tft.fillRect(poX, poY + newFontHeight,
addedWith, fontHeight - newFontHeight,
@ -103,18 +99,30 @@ again:
}
case 'f':
case 's':
case 'S':
case 'm':
{
font = [&controlChar,&oldFont]() -> uint8_t {
bool changeHeight = false;
font = [&controlChar,&oldFont,&changeHeight]() -> uint8_t {
switch (controlChar)
{
case 'f': return oldFont;
case 's': return 2;
case 'S': {
changeHeight = true;
return 2;
}
case 'm': return 4;
}
__builtin_unreachable();
}();
if (changeHeight)
{
// adjust y rendering position to new font height
poY += fontRenderer.fontHeight(oldFont) - fontRenderer.fontHeight(font);
}
auto newNewIter = newIter + 1;
if (newNewIter != std::end(str))
{

View File

@ -5,13 +5,11 @@
#include <string>
// forward declares
namespace espgui { class TftInterface; }
namespace espgui { class TftInterface; class FontRenderer; }
namespace espgui {
void richTextEscape(std::string &subject);
std::string richTextEscape(std::string_view subject);
int16_t renderRichText(TftInterface &tft, std::string_view str, int32_t poX, int32_t poY, uint16_t color, uint16_t bgcolor, uint8_t font);
int16_t renderRichText(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, int32_t poX, int32_t poY, uint16_t color, uint16_t bgcolor, uint8_t font);
} // namespace espgui

View File

@ -1,9 +1,17 @@
#include "screenmanager.h"
// system includes
#include <cassert>
// esp-idf includes
#include <esp_log.h>
namespace espgui {
namespace {
constexpr const char * const TAG = "SCREENMANAGER";
} // namespace
std::unique_ptr<Display> currentDisplay;
std::stack<std::unique_ptr<Display>> displayStack;
@ -33,7 +41,10 @@ void popScreenImpl(TftInterface &tft)
deconstructScreen();
if (displayStack.empty())
{
ESP_LOGW(TAG, "displayStack is empty");
return;
}
currentDisplay = std::move(displayStack.top());
displayStack.pop();

View File

@ -7,8 +7,11 @@ public:
};
template<bool TScroll>
class StaticScrollBehaviour : public ScrollInterface {
class StaticScrollBehaviour : public virtual ScrollInterface {
public:
bool skipScroll() const override { return TScroll; }
};
using SkipScroll = StaticScrollBehaviour<true>;
} // namespace espgui

View File

@ -4,7 +4,7 @@
#include "display.h"
#include "tftinterface.h"
#include "tftcolors.h"
#include "textinterface.h"
#include "titleinterface.h"
#include "widgets/label.h"
#include "widgets/graph.h"
#include "confirminterface.h"
@ -49,7 +49,7 @@ public:
template<std::size_t COUNT0, std::size_t COUNT1>
class SplitGraphDisplay :
public Display,
public virtual TextInterface,
public virtual TitleInterface,
public virtual TopGraphAccessorInterface<COUNT0>,
public virtual BottomGraphAccessorInterface<COUNT1>,
public virtual ConfirmInterface,
@ -85,7 +85,7 @@ void SplitGraphDisplay<COUNT0, COUNT1>::initScreen(TftInterface &tft)
template<std::size_t COUNT0, std::size_t COUNT1>
void SplitGraphDisplay<COUNT0, COUNT1>::redraw(TftInterface &tft)
{
m_titleLabel.redraw(tft, text(), TFT_YELLOW, TFT_BLACK, 4);
m_titleLabel.redraw(tft, title(), TFT_YELLOW, TFT_BLACK, 4);
m_graph0.redraw(tft, static_cast<const TopGraphAccessorInterface<COUNT0>&>(*this).getTopBuffers());
m_graph1.redraw(tft, static_cast<const BottomGraphAccessorInterface<COUNT1>&>(*this).getBottomBuffers());

View File

@ -1,7 +1,9 @@
#pragma once
// system includes
#include <format>
// 3rdparty lib includes
#include <fmt/core.h>
#include <strutils.h>
#include <espstrutils.h>
#include <espwifiutils.h>
@ -26,7 +28,7 @@ struct TextWithValueHelper : public Taccessor, public virtual TextInterface
using espchrono::toString;
using wifi_stack::toString;
return fmt::format("{} {}", Tprefix, richTextEscape(toString(Taccessor::getValue())));
return std::format("{} {}", Tprefix, richTextEscape(toString(Taccessor::getValue())));
}
};
@ -42,7 +44,7 @@ struct ChangeableTextWithValueHelper : public Taccessor, public virtual TextInte
using espchrono::toString;
using wifi_stack::toString;
return fmt::format("{} {}", m_prefix, richTextEscape(toString(Taccessor::getValue())));
return std::format("{} {}", m_prefix, richTextEscape(toString(Taccessor::getValue())));
}
const std::string &prefix() const { return m_prefix; }
@ -65,7 +67,7 @@ struct TextWithHighlightedValueHelper : public Taccessor, public virtual TextInt
using espchrono::toString;
using wifi_stack::toString;
return fmt::format("{} {}{}", Tprefix, Tguilib_color, richTextEscape(toString(Taccessor::getValue())));
return std::format("{} {}{}", Tprefix, Tguilib_color, richTextEscape(toString(Taccessor::getValue())));
}
};
@ -81,7 +83,7 @@ struct ChangeableTextWithHighlightedValueHelper : public Taccessor, public virtu
using espchrono::toString;
using wifi_stack::toString;
return fmt::format("{} {}{}", m_prefix, Tguilib_color, richTextEscape(toString(Taccessor::getValue())));
return std::format("{} {}{}", m_prefix, Tguilib_color, richTextEscape(toString(Taccessor::getValue())));
}
const std::string &prefix() const { return m_prefix; }

View File

@ -1,93 +0,0 @@
#pragma once
// 3rdparty lib includes
#include "TFT_eSPI.h"
// local includes
#include "tftinterface.h"
namespace espgui {
class TftESpiImpl : public TftInterface
{
public:
void init() { m_tft.init(); }
void drawPixel(int32_t x, int32_t y, uint16_t color) override { m_tft.drawPixel(x, y, color); }
void drawChar(int32_t x, int32_t y, uint16_t c, uint16_t color, uint16_t bg, uint8_t size) override { m_tft.drawChar(x, y, c, color, bg, size); }
void drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint16_t color) override { m_tft.drawLine(xs, ys, xe, ye, color); }
void drawFastVLine(int32_t x, int32_t y, int32_t h, uint16_t color) override { m_tft.drawFastVLine(x, y, h, color); }
void drawFastHLine(int32_t x, int32_t y, int32_t w, uint16_t color) override { m_tft.drawFastHLine(x, y, w, color); }
void fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color) override { m_tft.fillRect(x, y, w, h, color); }
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) override { return m_tft.drawChar(uniCode, x, y, color, bgcolor, font); }
int16_t height() const override { return m_tft.height(); }
int16_t width() const override { return m_tft.width(); }
void setRotation(uint8_t r) override { m_tft.setRotation(r); }
uint8_t getRotation(void) const { return m_tft.getRotation(); }
void setTextSize(uint8_t s) override { m_tft.setTextSize(s); }
// Graphics drawing
void fillScreen(uint32_t color) override { m_tft.fillScreen(color); }
void drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) override { m_tft.drawRect(x, y, w, h, color); }
void drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color) override { m_tft.drawRoundRect(x, y, w, h, radius, color); }
void fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color) override { m_tft.fillRoundRect(x, y, w, h, radius, color); }
void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) override { m_tft.fillRectVGradient(x, y, w, h, color1, color2); }
void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) override { m_tft.fillRectHGradient(x, y, w, h, color1, color2); }
uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF) override { return m_tft.drawPixel(x, y, color, alpha, bg_color); }
void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) override { m_tft.drawSpot(ax, ay, r, fg_color, bg_color); }
void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF) override { m_tft.fillSmoothCircle(x, y, r, color, bg_color); }
void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF) override { m_tft.fillSmoothRoundRect(x, y, w, h, radius, color, bg_color); }
void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) override { m_tft.drawWideLine(ax, ay, bx, by, wd, fg_color, bg_color); }
void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) override { m_tft.drawWedgeLine(ax, ay, bx, by, aw, bw, fg_color, bg_color); }
void drawSunkenRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color0, uint32_t color1, uint32_t color2) override { m_tft.drawSunkenRect(x, y, w, h, color0, color1, color2); }
void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color) override { m_tft.drawCircle(x, y, r, color); }
void drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color) override { m_tft.drawCircleHelper(x, y, r, cornername, color); }
void fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color) override { m_tft.fillCircle(x, y, r, color); }
void fillCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, int32_t delta, uint32_t color) override { m_tft.fillCircleHelper(x, y, r, cornername, delta, color); }
void drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color) override { m_tft.drawEllipse(x, y, rx, ry, color); }
void fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color) override { m_tft.fillEllipse(x, y, rx, ry, color); }
void drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color) override { m_tft.drawTriangle(x1, y1, x2, y2, x3, y3, color); }
void fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color) override { m_tft.fillTriangle(x1, y1, x2, y2, x3, y3, color); }
int16_t textWidth(std::string_view string, uint8_t font) override { return m_tft.textWidth(string, font); }
int16_t fontHeight(int16_t font) override { return m_tft.fontHeight(font); }
int16_t drawString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) override { return m_tft.drawString(string, x, y, color, bgcolor, font); }
int16_t drawCentreString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) override { return m_tft.drawCentreString(string, x, y, color, bgcolor, font); }
int16_t drawRightString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) override { return m_tft.drawRightString(string, x, y, color, bgcolor, font); }
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data) { m_tft.pushImage(x, y, w, h, data); }
void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent) { m_tft.pushImage(x, y, w, h, data, transparent); }
uint16_t decodeUTF8(const uint8_t *buf, uint16_t *index, uint16_t remaining) override { return m_tft.decodeUTF8(buf, index, remaining); }
uint16_t decodeUTF8(uint8_t c) override { return m_tft.decodeUTF8(c); }
void setSwapBytes(bool swap) override { m_tft.setSwapBytes(swap); }
bool getSwapBytes(void) override { return m_tft.getSwapBytes(); }
void startWrite(void) override { m_tft.startWrite(); }
void writeColor(uint16_t color, uint32_t len) override { m_tft.writeColor(color, len); }
void endWrite(void) override { m_tft.endWrite(); }
void pushColor(uint16_t color, uint32_t len) override { m_tft.pushColor(color, len); }
void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h) override { m_tft.setAddrWindow(xs, ys, w, h); }
private:
TFT_eSPI m_tft;
};
} // namespace espgui

View File

@ -1,112 +0,0 @@
#pragma once
// system includes
#include <cstdint>
#include <string_view>
namespace espgui {
class TftInterface
{
public:
explicit TftInterface() = default;
virtual ~TftInterface() = default;
virtual void drawPixel(int32_t x, int32_t y, uint16_t color) = 0;
virtual void drawChar(int32_t x, int32_t y, uint16_t c, uint16_t color, uint16_t bg, uint8_t size) = 0;
virtual void drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint16_t color) = 0;
virtual void drawFastVLine(int32_t x, int32_t y, int32_t h, uint16_t color) = 0;
virtual void drawFastHLine(int32_t x, int32_t y, int32_t w, uint16_t color) = 0;
virtual void fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color) = 0;
virtual int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) = 0;
virtual int16_t height(void) const = 0;
virtual int16_t width(void) const = 0;
virtual void setRotation(uint8_t r) = 0; // Set the display image orientation to 0, 1, 2 or 3
virtual uint8_t getRotation(void) const = 0; // Read the current rotation
virtual void setTextSize(uint8_t size); // Set character size multiplier (this increases pixel size)
// Graphics drawing
virtual void fillScreen(uint32_t color) = 0;
virtual void drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) = 0;
virtual void drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color) = 0;
virtual void fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color) = 0;
virtual void fillRectVGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) = 0;
virtual void fillRectHGradient(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color1, uint32_t color2) = 0;
// Draw a pixel blended with the pixel colour on the TFT or sprite, return blended colour
// If bg_color is not included the background pixel colour will be read from TFT or sprite
virtual uint16_t drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color = 0x00FFFFFF) = 0;
// Draw a small anti-aliased filled circle at ax,ay with radius r (uses drawWideLine)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
virtual void drawSpot(float ax, float ay, float r, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) = 0;
// Draw an anti-aliased filled circle at x, y with radius r
// If bg_color is not included the background pixel colour will be read from TFT or sprite
virtual void fillSmoothCircle(int32_t x, int32_t y, int32_t r, uint32_t color, uint32_t bg_color = 0x00FFFFFF) = 0;
virtual void fillSmoothRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color, uint32_t bg_color = 0x00FFFFFF) = 0;
// Draw an anti-aliased wide line from ax,ay to bx,by width wd with radiused ends (radius is wd/2)
// If bg_color is not included the background pixel colour will be read from TFT or sprite
virtual void drawWideLine(float ax, float ay, float bx, float by, float wd, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) = 0;
// Draw an anti-aliased wide line from ax,ay to bx,by with different width at each end aw, bw and with radiused ends
// If bg_color is not included the background pixel colour will be read from TFT or sprite
virtual void drawWedgeLine(float ax, float ay, float bx, float by, float aw, float bw, uint32_t fg_color, uint32_t bg_color = 0x00FFFFFF) = 0;
virtual void drawSunkenRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color0, uint32_t color1, uint32_t color2) = 0;
virtual void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color) = 0;
virtual void drawCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, uint32_t color) = 0;
virtual void fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color) = 0;
virtual void fillCircleHelper(int32_t x, int32_t y, int32_t r, uint8_t cornername, int32_t delta, uint32_t color) = 0;
virtual void drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color) = 0;
virtual void fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color) = 0;
// Corner 1 Corner 2 Corner 3
virtual void drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color) = 0;
virtual void fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color) = 0;
virtual int16_t textWidth(std::string_view string, uint8_t font); // Returns pixel width of string in specified font
virtual int16_t fontHeight(int16_t font); // Returns pixel height of string in specified font
// Handle char arrays
// Use with setTextDatum() to position string on TFT, and setTextPadding() to blank old displayed strings
virtual int16_t drawString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) = 0; // Draw string using specifed font number
virtual int16_t drawCentreString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) = 0; // Deprecated, use setTextDatum() and drawString()
virtual int16_t drawRightString(std::string_view string, int32_t x, int32_t y, uint16_t color, uint16_t bgcolor, uint8_t font) = 0; // Deprecated, use setTextDatum() and drawString()
// These are used to render images or sprites stored in RAM arrays (used by Sprite class for 16bpp Sprites)
virtual void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data) = 0;
virtual void pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent) = 0;
// Used by library and Smooth font class to extract Unicode point codes from a UTF8 encoded string
virtual uint16_t decodeUTF8(const uint8_t *buf, uint16_t *index, uint16_t remaining) = 0;
virtual uint16_t decodeUTF8(uint8_t c) = 0;
// Swap the byte order for pushImage() and pushPixels() - corrects endianness
virtual void setSwapBytes(bool swap) = 0;
virtual bool getSwapBytes(void) = 0;
// Bare metal functions
virtual void startWrite(void) = 0;
virtual void writeColor(uint16_t color, uint32_t len) = 0;
virtual void endWrite(void) = 0;
// Push (aka write pixel) colours to the set window
virtual void pushColor(uint16_t color, uint32_t len) = 0;
// The TFT_eSprite class inherits the following functions (not all are useful to Sprite class
virtual void setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h) = 0;
};
inline bool isLandscape(const TftInterface &tft)
{
return (tft.getRotation() == 1 || tft.getRotation() == 3);
}
} // namespace espgui

75
src/titleinterface.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
// system includes
#include <string>
#include <utility>
namespace espgui {
class TitleInterface {
public:
virtual std::string title() const = 0;
};
class EmptyTitle : public virtual TitleInterface
{
public:
std::string title() const override { return {}; }
};
template<const char *Ttitle>
class StaticTitle : public virtual TitleInterface
{
public:
static constexpr const char *STATIC_TITLE = Ttitle;
std::string title() const override { return Ttitle; }
};
class ChangeableTitle : public virtual TitleInterface
{
public:
ChangeableTitle() = default;
ChangeableTitle(std::string &&title) : m_title{std::move(title)} {}
ChangeableTitle(std::string_view title) : m_title{title} {}
std::string title() const override { return m_title; }
void setTitle(std::string &&title) { m_title = std::move(title); }
void setTitle(const std::string &title) { m_title = title; }
private:
std::string m_title;
};
template<typename T>
class CachedTitle : public virtual T
{
public:
std::string title() const override
{
if (!m_loaded)
{
m_title = T::title();
m_loaded = true;
}
return m_title;
}
private:
mutable bool m_loaded{};
mutable std::string m_title;
};
template<typename T>
class StaticallyCachedTitle : public virtual T
{
public:
std::string title() const override
{
static const auto title = T::title();
return title;
}
};
} // namespace espgui

View File

@ -0,0 +1,82 @@
#include "centeredlabel.h"
// 3rdparty lib includes
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
namespace espgui {
CenteredLabel::CenteredLabel(int x, int y) :
m_x{x},
m_y{y}
{
}
void CenteredLabel::start(TftInterface &tft)
{
m_lastStr.clear();
m_lastFont = -1;
m_lastColor = -1;
m_lastWidth = 0;
m_lastHeight = 0;
}
void CenteredLabel::redraw(TftInterface &tft, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw)
{
espgui::FontRenderer fontRenderer{tft};
redraw(tft, fontRenderer, str, color, bgcolor, font, forceRedraw);
}
void CenteredLabel::redraw(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw)
{
if (m_lastStr == str &&
m_lastColor == color &&
m_lastFont == font &&
!forceRedraw)
return;
const auto renderedWidth = fontRenderer.drawCentreString(str, m_x, m_y, color, bgcolor, font);
const auto renderedHeight = fontRenderer.fontHeight(font);
if (renderedWidth < m_lastWidth)
{
const auto oldLeftX = m_x - (m_lastWidth / 2);
const auto newLeftX = m_x - (renderedWidth / 2);
tft.fillRect(oldLeftX, m_y,
newLeftX - oldLeftX,
renderedHeight,
bgcolor);
const auto oldRightX = m_x + (m_lastWidth / 2);
const auto newRightX = m_x + (renderedWidth / 2);
tft.fillRect(newRightX, m_y,
oldRightX - newRightX,
renderedHeight,
bgcolor);
}
// if (renderedHeight < m_lastHeight)
// tft.fillRect(m_x, m_y + renderedHeight,
// renderedWidth, m_lastHeight - renderedHeight,
// bgcolor);
m_lastStr = str;
m_lastColor = color;
m_lastFont = font;
m_lastWidth = renderedWidth;
m_lastHeight = renderedHeight;
}
void CenteredLabel::clear(TftInterface &tft, uint16_t bgcolor)
{
if (m_lastWidth || m_lastHeight)
tft.fillRect(m_x - (m_lastWidth / 2), m_y, m_lastWidth, m_lastHeight, bgcolor);
start(tft);
}
}

View File

@ -0,0 +1,37 @@
#pragma once
// system includes
#include <string>
// forward declares
namespace espgui {
class TftInterface;
class FontRenderer;
} // namespace espgui
namespace espgui {
class CenteredLabel
{
public:
CenteredLabel(int x, int y);
int x() const { return m_x; }
int y() const { return m_y; }
void start(TftInterface &tft);
void redraw(TftInterface &tft, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw = false);
void redraw(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw = false);
void clear(TftInterface &tft, uint16_t bgcolor);
private:
const int m_x;
const int m_y;
std::string m_lastStr;
uint16_t m_lastColor;
uint8_t m_lastFont;
int m_lastWidth;
int m_lastHeight;
};
} // namespace espgui

View File

@ -0,0 +1,68 @@
#include "iconwidget.h"
namespace espgui {
void IconWidget::start(TftInterface &tft)
{
m_lastIcon = nullptr;
}
void IconWidget::start(TftInterface &tft, const int32_t iconWidth, const int32_t iconHeight, const uint16_t *icon)
{
if (m_iconWidth != iconWidth || m_iconHeight != iconHeight)
{
ESP_LOGE(TAG, "Icon size mismatch: %dx%d vs %ldx%ld", m_iconWidth, m_iconHeight, iconWidth, iconHeight);
return;
}
m_lastIcon = icon;
if (icon)
tft.pushImage(m_x, m_y, m_iconWidth, m_iconHeight, icon);
}
void IconWidget::redraw(TftInterface &tft, const int32_t iconWidth, const int32_t iconHeight, const uint16_t *icon, uint16_t bgcolor, bool forceRedraw)
{
if (m_iconWidth != iconWidth || m_iconHeight != iconHeight)
{
ESP_LOGE(TAG, "Icon size mismatch: %dx%d vs %ldx%ld", m_iconWidth, m_iconHeight, iconWidth, iconHeight);
return;
}
if (forceRedraw || m_lastIcon != icon)
{
if (icon)
tft.pushImage(m_x, m_y, m_iconWidth, m_iconHeight, icon);
else if (m_lastIcon)
tft.fillRect(m_x, m_y, m_iconWidth, m_iconHeight, bgcolor);
m_lastIcon = icon;
}
}
void IconWidget::redraw(TftInterface &tft, const int32_t iconWidth, const int32_t iconHeight, const uint16_t *icon, bool forceRedraw)
{
redraw(tft, iconWidth, iconHeight, icon, m_bgcolor, forceRedraw);
}
void IconWidget::clear(TftInterface &tft, uint16_t bgcolor)
{
if (m_lastIcon)
tft.fillRect(m_x, m_y, m_iconWidth, m_iconHeight, bgcolor);
m_lastIcon = nullptr;
}
void IconWidget::clear(TftInterface &tft)
{
clear(tft, m_bgcolor);
}
IconWidget::IconWidget(int x, int y, int iconWidth, int iconHeight, uint16_t bgcolor):
m_x{x},
m_y{y},
m_iconWidth{iconWidth},
m_iconHeight{iconHeight},
m_bgcolor{bgcolor},
m_lastIcon{nullptr}
{}
} // namespace espgui

46
src/widgets/iconwidget.h Normal file
View File

@ -0,0 +1,46 @@
#pragma once
// esp-idf includes
#include <esp_log.h>
// local includes
#include "icon.h"
#include "tftcolors.h"
#include "tftinterface.h"
namespace espgui {
class IconWidget
{
static constexpr const char * const TAG = "IconWidget";
public:
IconWidget(int x, int y, int iconWidth, int iconHeight, uint16_t bgcolor = espgui::TFT_BLACK);
void start(TftInterface &tft);
void start(TftInterface &tft, int32_t iconWidth, int32_t iconHeight, const uint16_t *icon);
void redraw(TftInterface &tft, int32_t iconWidth, int32_t iconHeight, const uint16_t *icon, uint16_t bgcolor, bool forceRedraw = false);
void redraw(TftInterface &tft, int32_t iconWidth, int32_t iconHeight, const uint16_t *icon, bool forceRedraw = false);
void clear(espgui::TftInterface &tft, uint16_t bgcolor);
void clear(espgui::TftInterface &tft);
int x() const { return m_x; }
int y() const { return m_y; }
private:
const int m_x;
const int m_y;
const int m_iconWidth;
const int m_iconHeight;
uint16_t m_bgcolor;
const uint16_t *m_lastIcon;
};
} // namespace espgui

View File

@ -1,5 +1,8 @@
#include "label.h"
// 3rdparty lib includes
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
#include "richtextrenderer.h"
@ -22,6 +25,12 @@ void Label::start(TftInterface &tft)
}
void Label::redraw(TftInterface &tft, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw)
{
espgui::FontRenderer fontRenderer{tft};
redraw(tft, fontRenderer, str, color, bgcolor, font, forceRedraw);
}
void Label::redraw(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw)
{
if (m_lastStr == str &&
m_lastColor == color &&
@ -29,8 +38,8 @@ void Label::redraw(TftInterface &tft, std::string_view str, uint16_t color, uint
!forceRedraw)
return;
const auto renderedWidth = renderRichText(tft, str, m_x, m_y, color, bgcolor, font);
const auto renderedHeight = tft.fontHeight(font);
const auto renderedWidth = renderRichText(tft, fontRenderer, str, m_x, m_y, color, bgcolor, font);
const auto renderedHeight = fontRenderer.fontHeight(font);
if (renderedWidth < m_lastWidth)
tft.fillRect(m_x + renderedWidth, m_y,

View File

@ -6,6 +6,7 @@
// forward declares
namespace espgui {
class TftInterface;
class FontRenderer;
} // namespace espgui
namespace espgui {
@ -19,6 +20,7 @@ public:
void start(TftInterface &tft);
void redraw(TftInterface &tft, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw = false);
void redraw(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw = false);
void clear(TftInterface &tft, uint16_t bgcolor);
private:

View File

@ -8,8 +8,8 @@
#include "tftcolors.h"
namespace espgui {
ProgressBar::ProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color) :
m_x{x}, m_y{y}, m_width{width}, m_height{height}, m_min{min}, m_max{max}, m_color{color}
ProgressBar::ProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color, uint32_t backgroundColor) :
m_x{x}, m_y{y}, m_width{width}, m_height{height}, m_min{min}, m_max{max}, m_color{color}, m_backgroundColor{backgroundColor}
{
}
@ -17,6 +17,7 @@ void ProgressBar::start(TftInterface &tft)
{
m_lastValue = m_x+1;
tft.drawRect(m_x, m_y, m_width, m_height, TFT_WHITE);
tft.fillRect(m_x+1, m_y+1, m_width-2, m_height-2, m_backgroundColor);
}
void ProgressBar::redraw(TftInterface &tft, int value)
@ -24,10 +25,28 @@ void ProgressBar::redraw(TftInterface &tft, int value)
value = cpputils::mapValueClamped(value, m_min, m_max, m_x+1, m_x+m_width-1);
if (value < m_lastValue)
tft.fillRect(value, m_y+1, m_lastValue-value, m_height-2, TFT_BLACK);
tft.fillRect(value, m_y+1, m_lastValue-value, m_height-2, m_backgroundColor);
else if (value > m_lastValue)
tft.fillRect(m_lastValue, m_y+1, value-m_lastValue, m_height-2, m_color);
m_lastValue = value;
}
void ProgressBar::changeColor(TftInterface &tft, const uint32_t color, const uint32_t backgroundColor)
{
if (color != m_color)
{
// redraw already drawn area in new color
tft.fillRect(m_x+1, m_y+1, m_lastValue-m_x-1, m_height-2, color);
m_color = color;
}
if (backgroundColor != m_backgroundColor)
{
// redraw background in new color
tft.fillRect(m_x+1, m_y+1, m_width-2, m_height-2, backgroundColor);
m_backgroundColor = backgroundColor;
}
}
} // namespace espgui

View File

@ -16,11 +16,13 @@ namespace espgui {
class ProgressBar
{
public:
ProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color = TFT_YELLOW);
ProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color = TFT_YELLOW, uint32_t backgroundColor = TFT_BLACK);
void start(TftInterface &tft);
void redraw(TftInterface &tft, int value);
void changeColor(TftInterface &tft, const uint32_t color = TFT_YELLOW, const uint32_t backgroundColor = TFT_BLACK);
private:
const int m_x;
const int m_y;
@ -28,7 +30,8 @@ private:
const int m_height;
const int m_min;
const int m_max;
const uint32_t m_color;
uint32_t m_color;
uint32_t m_backgroundColor;
int m_lastValue{};
};

View File

@ -0,0 +1,33 @@
#include "variablerangeprogressbar.h"
// 3rdparty lib includes
#include <cpputils.h>
// local includes
#include "tftinterface.h"
#include "tftcolors.h"
namespace espgui {
VariableRangeProgressBar::VariableRangeProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color) :
m_x{x}, m_y{y}, m_width{width}, m_height{height}, m_min{min}, m_max{max}, m_color{color}
{
}
void VariableRangeProgressBar::start(TftInterface &tft)
{
m_lastValue = m_x+1;
tft.drawRect(m_x, m_y, m_width, m_height, TFT_WHITE);
}
void VariableRangeProgressBar::redraw(TftInterface &tft, int value)
{
value = cpputils::mapValueClamped(value, m_min, m_max, m_x+1, m_x+m_width-1);
if (value < m_lastValue)
tft.fillRect(value, m_y+1, m_lastValue-value, m_height-2, TFT_BLACK);
else if (value > m_lastValue)
tft.fillRect(m_lastValue, m_y+1, value-m_lastValue, m_height-2, m_color);
m_lastValue = value;
}
} // namespace espgui

View File

@ -0,0 +1,42 @@
#pragma once
// system includes
#include <cstdint>
// 3rdparty lib includes
#include <TFT_eSPI.h>
// local includes
#include "tftcolors.h"
// forward declares
namespace espgui { class TftInterface; }
namespace espgui {
class VariableRangeProgressBar
{
public:
VariableRangeProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color = TFT_YELLOW);
void start(TftInterface &tft);
void redraw(TftInterface &tft, int value);
void setMin(int min) { m_min = min; }
void setMax(int max) { m_max = max; }
void setMinMax(int min, int max) { m_min = min; m_max = max; }
int getMin() const { return m_min; }
int getMax() const { return m_max; }
private:
const int m_x;
const int m_y;
const int m_width;
const int m_height;
int m_min;
int m_max;
const uint32_t m_color;
int m_lastValue{};
};
} // namespace espgui

View File

@ -0,0 +1,33 @@
#include "variablerangereverseprogressbar.h"
// 3rdparty lib includes
#include <cpputils.h>
// local includes
#include "tftinterface.h"
#include "tftcolors.h"
namespace espgui {
VariableRangeReverseProgressBar::VariableRangeReverseProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color) :
m_x{x}, m_y{y}, m_width{width}, m_height{height}, m_min{min}, m_max{max}, m_color{color}
{
}
void VariableRangeReverseProgressBar::start(TftInterface &tft)
{
m_lastValue = m_x+m_width-1;
tft.drawRect(m_x, m_y, m_width, m_height, TFT_WHITE);
}
void VariableRangeReverseProgressBar::redraw(TftInterface &tft, int value)
{
value = cpputils::mapValueClamped(value, m_min, m_max, m_x+m_width-1, m_x+1);
if (value < m_lastValue)
tft.fillRect(value, m_y+1, m_lastValue-value, m_height-2, m_color);
else if (value > m_lastValue)
tft.fillRect(m_lastValue, m_y+1, value-m_lastValue, m_height-2, TFT_BLACK);
m_lastValue = value;
}
} // namespace espgui

View File

@ -0,0 +1,42 @@
#pragma once
// system includes
#include <cstdint>
// 3rdparty lib includes
#include <TFT_eSPI.h>
// local includes
#include "tftcolors.h"
// forward declares
namespace espgui { class TftInterface; }
namespace espgui {
class VariableRangeReverseProgressBar
{
public:
VariableRangeReverseProgressBar(int x, int y, int width, int height, int min, int max, uint32_t color=TFT_YELLOW);
void start(TftInterface &tft);
void redraw(TftInterface &tft, int value);
void setMin(int min) { m_min = min; }
void setMax(int max) { m_max = max; }
void setMinMax(int min, int max) { m_min = min; m_max = max; }
int getMin() const { return m_min; }
int getMax() const { return m_max; }
private:
const int m_x;
const int m_y;
const int m_width;
const int m_height;
int m_min;
int m_max;
const uint32_t m_color;
int m_lastValue{};
};
} // namespace espgui

View File

@ -2,6 +2,7 @@
// 3rdparty lib includes
#include <cpputils.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -15,10 +16,12 @@ VerticalMeter::VerticalMeter(const char *text, const char *format, int x, int y)
void VerticalMeter::start(TftInterface &tft)
{
FontRenderer fontRenderer{tft};
int w = 36;
tft.drawRect(m_x, m_y, w, 155, TFT_GREY);
tft.fillRect(m_x + 2, m_y + 19, w - 3, 155 - 38, TFT_WHITE);
tft.drawCentreString(m_text, m_x + w / 2, m_y + 2, TFT_CYAN, TFT_BLACK, 2);
fontRenderer.drawCentreString(m_text, m_x + w / 2, m_y + 2, TFT_CYAN, TFT_BLACK, 2);
for (int i = 0; i < 110; i += 10)
tft.drawFastHLine(m_x + 20, m_y + 27 + i, 6, TFT_BLACK);
@ -29,14 +32,16 @@ void VerticalMeter::start(TftInterface &tft)
tft.fillTriangle(m_x + 3, m_y + 127, m_x + 3 + 16, m_y + 127, m_x + 3, m_y + 127 - 5, TFT_RED);
tft.fillTriangle(m_x + 3, m_y + 127, m_x + 3 + 16, m_y + 127, m_x + 3, m_y + 127 + 5, TFT_RED);
tft.drawCentreString("---", m_x + w / 2, m_y + 155 - 18, TFT_CYAN, TFT_BLACK, 2);
fontRenderer.drawCentreString("---", m_x + w / 2, m_y + 155 - 18, TFT_CYAN, TFT_BLACK, 2);
}
void VerticalMeter::redraw(TftInterface &tft, float value, float min, float max)
{
FontRenderer fontRenderer{tft};
char buf[16];
snprintf(&buf[0], 16, m_format, value);
tft.drawRightString(buf, m_x + 36 - 5, 187 - 27 + 155 - 18, TFT_GREEN, TFT_BLACK, 2);
fontRenderer.drawRightString(buf, m_x + 36 - 5, 187 - 27 + 155 - 18, TFT_GREEN, TFT_BLACK, 2);
const int dx = 3 + m_x;
value = cpputils::mapValueClamped<float>(value, min, max, 0.f, 100.f);

View File

@ -2,10 +2,11 @@
// system includes
#include <cmath>
#include <cstring>
// 3rdparty lib includes
#include <cpputils.h>
#include <stdlib_noniso.h>
#include <fontrenderer.h>
// local includes
#include "tftinterface.h"
@ -14,6 +15,8 @@
namespace espgui {
void VuMeter::start(TftInterface &tft)
{
FontRenderer fontRenderer{tft};
ltx = 0;
osx = 120;
osy = 120;
@ -79,11 +82,11 @@ void VuMeter::start(TftInterface &tft)
x0 = sx * (100 + tl + 10) + 120;
y0 = sy * (100 + tl + 10) + 140;
switch (i / 25) {
case -2: tft.drawCentreString("0", x0, y0 - 12, TFT_BLACK, TFT_BLACK, 2); break;
case -1: tft.drawCentreString("7.5", x0, y0 - 9, TFT_BLACK, TFT_BLACK, 2); break;
case 0: tft.drawCentreString("15", x0, y0 - 6, TFT_BLACK, TFT_BLACK, 2); break;
case 1: tft.drawCentreString("22.5", x0, y0 - 9, TFT_BLACK, TFT_BLACK, 2); break;
case 2: tft.drawCentreString("30", x0, y0 - 12, TFT_BLACK, TFT_BLACK, 2); break;
case -2: fontRenderer.drawCentreString("0", x0, y0 - 12, TFT_BLACK, TFT_BLACK, 2); break;
case -1: fontRenderer.drawCentreString("7.5", x0, y0 - 9, TFT_BLACK, TFT_BLACK, 2); break;
case 0: fontRenderer.drawCentreString("15", x0, y0 - 6, TFT_BLACK, TFT_BLACK, 2); break;
case 1: fontRenderer.drawCentreString("22.5", x0, y0 - 9, TFT_BLACK, TFT_BLACK, 2); break;
case 2: fontRenderer.drawCentreString("30", x0, y0 - 12, TFT_BLACK, TFT_BLACK, 2); break;
}
}
@ -96,15 +99,92 @@ void VuMeter::start(TftInterface &tft)
if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
}
tft.drawString("KM/h", 5 + 230 - 40, 119 - 20, TFT_BLACK, TFT_BLACK, 2); // Units at bottom right
tft.drawCentreString("KM/h", 120, 70, TFT_BLACK, TFT_BLACK, 4); // Comment out to avoid font 4
fontRenderer.drawString("KM/h", 5 + 230 - 40, 119 - 20, TFT_BLACK, TFT_BLACK, 2); // Units at bottom right
fontRenderer.drawCentreString("KM/h", 120, 70, TFT_BLACK, TFT_BLACK, 4); // Comment out to avoid font 4
tft.drawRect(5, 3, 230, 119, TFT_BLACK); // Draw bezel line
}
namespace {
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
bool negative = false;
if (std::isnan(number)) {
std::strcpy(s, "nan");
return s;
}
if (std::isinf(number)) {
std::strcpy(s, "inf");
return s;
}
char* out = s;
int fillme = width; // how many cells to fill for the integer part
if (prec > 0) {
fillme -= (prec+1);
}
// Handle negative numbers
if (number < 0.0) {
negative = true;
fillme--;
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
// I optimized out most of the divisions
double rounding = 2.0;
for (uint8_t i = 0; i < prec; ++i)
rounding *= 10.0;
rounding = 1.0 / rounding;
number += rounding;
// Figure out how big our number really is
double tenpow = 1.0;
int digitcount = 1;
while (number >= 10.0 * tenpow) {
tenpow *= 10.0;
digitcount++;
}
number /= tenpow;
fillme -= digitcount;
// Pad unused cells with spaces
while (fillme-- > 0) {
*out++ = ' ';
}
// Handle negative sign
if (negative) *out++ = '-';
// Print the digits, and if necessary, the decimal point
digitcount += prec;
int8_t digit = 0;
while (digitcount-- > 0) {
digit = (int8_t)number;
if (digit > 9) digit = 9; // insurance
*out++ = (char)('0' | digit);
if ((digitcount == prec) && (prec > 0)) {
*out++ = '.';
}
number -= digit;
number *= 10.0;
}
// make sure the string is terminated
*out = 0;
return s;
}
}
void VuMeter::redraw(TftInterface &tft, float value)
{
FontRenderer fontRenderer{tft};
char buf[8]; dtostrf(value, 4, 0, buf);
tft.drawRightString(buf, 50, 119 - 25, TFT_BLACK, TFT_WHITE, 4);
fontRenderer.drawRightString(buf, 50, 119 - 25, TFT_BLACK, TFT_WHITE, 4);
if (value < -3) value = -3; // Limit value to emulate needle end stops
if (value > 33) value = 33;
@ -123,7 +203,7 @@ void VuMeter::redraw(TftInterface &tft, float value)
tft.drawLine(120 + 20 * ltx + 1, 140 - 20, osx + 1, osy, TFT_WHITE);
// Re-plot text under needle
tft.drawCentreString("KM/h", 120, 70, TFT_BLACK, TFT_BLACK, 4); // // Comment out to avoid font 4
fontRenderer.drawCentreString("KM/h", 120, 70, TFT_BLACK, TFT_BLACK, 4); // // Comment out to avoid font 4
// Store new needle end coords for next erase
ltx = tx;