diff --git a/CMakeLists.txt b/CMakeLists.txt index d462d06..fa3451a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ set(headers src/tftcolors.h src/titleinterface.h src/visibleinterface.h + src/widgets/centeredlabel.h src/widgets/graph.h src/widgets/label.h src/widgets/progressbar.h @@ -84,6 +85,7 @@ set(sources src/icons/back_grey.cpp src/icons/checked_grey.cpp src/icons/unchecked_grey.cpp + src/widgets/centeredlabel.cpp src/widgets/label.cpp src/widgets/progressbar.cpp src/widgets/reverseprogressbar.cpp diff --git a/src/widgets/centeredlabel.cpp b/src/widgets/centeredlabel.cpp new file mode 100644 index 0000000..b11b792 --- /dev/null +++ b/src/widgets/centeredlabel.cpp @@ -0,0 +1,83 @@ +#include "centeredlabel.h" + +// 3rdparty lib includes +#include + +// local includes +#include "tftinterface.h" +#include "richtextrenderer.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_y, m_lastWidth, m_lastHeight, bgcolor); + + start(tft); +} +} diff --git a/src/widgets/centeredlabel.h b/src/widgets/centeredlabel.h new file mode 100644 index 0000000..93ee7bf --- /dev/null +++ b/src/widgets/centeredlabel.h @@ -0,0 +1,37 @@ +#pragma once + +// system includes +#include + +// 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