1 Commits

Author SHA1 Message Date
203bdadca9 initial commit 2023-03-03 17:47:49 +01:00
7 changed files with 211 additions and 17 deletions

View File

@ -57,6 +57,7 @@ set(headers
src/widgets/label.h
src/widgets/progressbar.h
src/widgets/reverseprogressbar.h
src/widgets/scrolllabel.h
src/widgets/slider.h
src/widgets/variablerangeprogressbar.h
src/widgets/variablerangereverseprogressbar.h
@ -93,6 +94,7 @@ set(sources
src/widgets/label.cpp
src/widgets/progressbar.cpp
src/widgets/reverseprogressbar.cpp
src/widgets/scrolllabel.cpp
src/widgets/slider.cpp
src/widgets/variablerangeprogressbar.cpp
src/widgets/variablerangereverseprogressbar.cpp

View File

@ -10,7 +10,11 @@ void DisplayWithTitle::initScreen(TftInterface &tft)
{
Base::initScreen(tft);
m_titleLabel.start(tft);
// m_titleLabel.construct(5, 5); // 230, 25
if (!m_titleLabel)
m_titleLabel.construct(5, 5, tft.width() - SCROLLMARGIN, 500);
m_titleLabel->start(tft);
// tft.fillRect(0, 0, tft.width(), 35, TFT_GREY);
@ -21,7 +25,8 @@ void DisplayWithTitle::redraw(TftInterface &tft)
{
Base::redraw(tft);
m_titleLabel.redraw(tft, title(), TFT_GREY, TFT_BLACK, 4);
if (m_titleLabel)
m_titleLabel->redraw(tft, title(), TFT_GREY, TFT_BLACK, 4);
}
} // namespace espgui

View File

@ -1,9 +1,12 @@
#pragma once
// 3rdparty lib includes
#include <delayedconstruction.h>
// local includes
#include "display.h"
#include "titleinterface.h"
#include "widgets/label.h"
#include "widgets/scrolllabel.h"
namespace espgui {
@ -21,7 +24,9 @@ public:
void redraw(TftInterface &tft) override;
private:
Label m_titleLabel{5, 5}; // 230, 25
static constexpr const auto SCROLLMARGIN = 40;
cpputils::DelayedConstruction<ScrollLabel> m_titleLabel;
};
} // namespace espgui

View File

@ -26,7 +26,7 @@ void MenuDisplay::initScreen(TftInterface &tft)
Base::initScreen(tft);
for (auto &label : m_labels)
label.start(tft);
label.start(tft, tft.width() - SCROLLMARGIN);
runForEveryMenuItem([](MenuItem &item){
item.start();

View File

@ -16,7 +16,7 @@
// local includes
#include "displaywithtitle.h"
#include "textinterface.h"
#include "widgets/label.h"
#include "widgets/scrolllabel.h"
#include "menuitem.h"
#include "backinterface.h"
@ -110,37 +110,39 @@ private:
static constexpr auto topMargin = 39;
static constexpr auto lineHeight = 27;
static constexpr auto verticalSpacing = 2;
static constexpr auto SCROLLMARGIN = 90;
std::array<Label, rowCount> m_labels {{
using LabelClass = ScrollLabel;
std::array<LabelClass, rowCount> m_labels {{
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 1
Label{horizontalSpacing + iconWidth, topMargin+(0*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(0*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 2
Label{horizontalSpacing + iconWidth, topMargin+(1*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(1*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 3
Label{horizontalSpacing + iconWidth, topMargin+(2*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(2*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 4
Label{horizontalSpacing + iconWidth, topMargin+(3*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(3*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 5
Label{horizontalSpacing + iconWidth, topMargin+(4*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(4*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 6
Label{horizontalSpacing + iconWidth, topMargin+(5*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(5*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 7
Label{horizontalSpacing + iconWidth, topMargin+(6*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(6*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 8
Label{horizontalSpacing + iconWidth, topMargin+(7*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(7*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 9
Label{horizontalSpacing + iconWidth, topMargin+(8*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(8*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
#if CONFIG_ESPGUI_MENUDISPLAY_ROWS >= 10
Label{horizontalSpacing + iconWidth, topMargin+(9*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
LabelClass{horizontalSpacing + iconWidth, topMargin+(9*(lineHeight+verticalSpacing))}, // 240-(horizontalSpacing*2)-iconWidth, lineHeight
#endif
}};

129
src/widgets/scrolllabel.cpp Normal file
View File

@ -0,0 +1,129 @@
#include "scrolllabel.h"
// system includes
#include <string_view>
// 3rdparty lib includes
#include <fontrenderer.h>
#include <tftcolors.h>
// local includes
#include "tftinterface.h"
#include "richtextrenderer.h"
using namespace std::chrono_literals;
namespace espgui {
ScrollLabel::ScrollLabel(int x, int y, int width, int scrollSpeed) :
m_x{x},
m_y{y},
m_width{width},
m_scrollSpeed{scrollSpeed},
m_lastScrollTime{espchrono::millis_clock::now()},
m_scrollOffset{0}
{}
ScrollLabel::ScrollLabel(int x, int y) :
m_x{x},
m_y{y},
m_width{std::nullopt},
m_scrollSpeed{500},
m_lastScrollTime{espchrono::millis_clock::now()},
m_scrollOffset{0}
{}
void ScrollLabel::start(TftInterface &tft)
{
m_lastStr.clear();
m_lastFont = -1;
m_lastColor = -1;
m_lastWidth = 0;
m_lastHeight = 0;
//m_lastScrollTime = espchrono::millis_clock::now();
//m_scrollOffset = 0;
}
void ScrollLabel::start(TftInterface &tft, int width)
{
m_width = width;
start(tft);
}
void ScrollLabel::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 ScrollLabel::redraw(TftInterface &tft, FontRenderer &fontRenderer, std::string_view str, uint16_t color, uint16_t bgcolor, uint8_t font, bool forceRedraw)
{
const auto char_width = fontRenderer.textWidth(str, font) / std::max(1U, str.length());
const auto max_chars = m_width ? (*m_width / std::max(1U, char_width)) : 0;
bool scroll = (str.length() > max_chars && m_width);
// ESP_LOGI("ScrollLabel", "str: %s, scrolling: %s, strlen: %d, maxchars: %d", str.data(), str.length() > max_chars ? "true" : "false", str.length(), max_chars);
if (m_lastStr == str &&
m_lastColor == color &&
m_lastFont == font &&
!forceRedraw &&
(str.length() <= max_chars || !m_width))
return;
if (str.contains("&"))
scroll = false;
if (scroll)
{
const auto now = espchrono::millis_clock::now();
const auto elapsed = espchrono::ago(m_lastScrollTime);
if (elapsed > (m_scrollSpeed * (m_scrollOffset == 0 ? 3ms : 1ms)))
{
m_lastScrollTime = now;
m_scrollOffset++;
if (m_scrollOffset > str.length() - max_chars)
m_scrollOffset = 0;
}
str = str.substr(m_scrollOffset, max_chars);
}
else
m_scrollOffset = 0;
if (m_lastColor == color &&
m_lastFont == font &&
m_lastStrScroll == str)
return;
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,
m_lastWidth - renderedWidth, m_lastHeight,
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;
m_lastStrScroll = str;
}
void ScrollLabel::clear(TftInterface &tft, uint16_t bgcolor)
{
if (m_lastWidth || m_lastHeight)
tft.fillRect(m_x, m_y, m_lastWidth, m_lastHeight, bgcolor);
start(tft);
}
} // namespace espgui

51
src/widgets/scrolllabel.h Normal file
View File

@ -0,0 +1,51 @@
#pragma once
// system includes
#include <string>
#include <optional>
// 3rdparty lib includes
#include <espchrono.h>
// forward declares
namespace espgui {
class TftInterface;
class FontRenderer;
} // namespace espgui
namespace espgui {
class ScrollLabel
{
public:
ScrollLabel(int x, int y, int width, int scrollSpeed);
ScrollLabel(int x, int y);
int x() const { return m_x; }
int y() const { return m_y; }
const std::optional<int>& width() { return m_width; }
int scrollSpeed() const { return m_scrollSpeed; }
void start(TftInterface &tft);
void start(TftInterface &tft, int width);
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::optional<int> m_width;
const int m_scrollSpeed;
std::string m_lastStr;
std::string m_lastStrScroll;
uint16_t m_lastColor;
uint8_t m_lastFont;
int m_lastWidth;
int m_lastHeight;
espchrono::millis_clock::time_point m_lastScrollTime;
int m_scrollOffset;
};
} // namespace espgui