Compare commits
1 Commits
main
...
scrolllabe
Author | SHA1 | Date | |
---|---|---|---|
203bdadca9 |
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
129
src/widgets/scrolllabel.cpp
Normal 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
51
src/widgets/scrolllabel.h
Normal 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
|
Reference in New Issue
Block a user