Files
esp-gui-lib/src/menudisplay.cpp
T

211 lines
4.6 KiB
C++

#include "menudisplay.h"
// local includes
#include "tftinstance.h"
namespace espgui {
void MenuDisplay::start()
{
Base::start();
// m_selectedIndex = 0;
// m_scrollOffset = 0;
m_rotateOffset = 0;
m_pressed = false;
}
void MenuDisplay::initScreen()
{
Base::initScreen();
for (auto &label : m_labels)
label.start();
runForEveryMenuItem([](MenuItem &item){
item.start();
});
m_icons.fill(nullptr);
m_highlightedIndex = -1;
}
void MenuDisplay::update()
{
Base::update();
if (!m_pressed)
{
const auto offset = m_rotateOffset;
m_rotateOffset = 0;
const auto itemCount = menuItemCount();
if (itemCount)
{
if (m_selectedIndex == -1)
m_selectedIndex = 0;
m_selectedIndex = m_selectedIndex + offset;
if (m_selectedIndex < 0)
m_selectedIndex += itemCount;
if (m_selectedIndex >= itemCount)
m_selectedIndex -= itemCount;
if (m_selectedIndex < m_scrollOffset)
m_scrollOffset = m_selectedIndex;
if (m_selectedIndex >= m_scrollOffset + m_labels.size())
m_scrollOffset = m_selectedIndex - m_labels.size() + 1;
}
else
{
m_selectedIndex = -1;
m_scrollOffset = 0;
}
runForEveryMenuItem([&](MenuItem &item){
item.update();
});
if (m_selectedIndex >= 0 && getMenuItem(m_selectedIndex).skipScroll())
{
if (offset > 0)
{
m_rotateOffset++;
}
else if (offset < 0)
{
m_rotateOffset--;
}
}
}
else
{
m_pressed = false;
if (m_selectedIndex >= 0)
getMenuItem(m_selectedIndex).triggered();
}
}
void MenuDisplay::redraw()
{
Base::redraw();
tft.setTextFont(4);
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
int i{0};
auto labelsIter = std::begin(m_labels);
auto iconsIter = std::begin(m_icons);
int newHighlightedIndex{-1};
const auto drawItemRect = [](const auto &label, const auto color){
tft.drawRect(5,
label.y()-1,
tft.width() - 10,
lineHeight+1,
color);
};
runForEveryMenuItem([&](MenuItem &item){
const auto index = i++;
if (!item.visible())
{
return;
}
if (index < m_scrollOffset)
return;
if (labelsIter == std::end(m_labels))
return;
const auto relativeIndex = index - m_scrollOffset;
const auto selected = index == m_selectedIndex;
if (selected)
newHighlightedIndex = relativeIndex;
else if (relativeIndex == m_highlightedIndex)
drawItemRect(*labelsIter, TFT_BLACK);
tft.setTextFont(item.font());
tft.setTextColor(item.color(), TFT_BLACK);
labelsIter->redraw(item.text());
if (item.icon() != *iconsIter)
{
tft.fillRect(6, labelsIter->y()+1, 24, 24, TFT_BLACK);
auto icon = item.icon();
if (icon)
{
tft.setSwapBytes(true);
tft.pushImage(6, labelsIter->y()+1, icon->WIDTH, icon->HEIGHT, icon->buffer);
tft.setSwapBytes(false);
}
*iconsIter = icon;
}
if (selected && (relativeIndex != m_highlightedIndex))
{
drawItemRect(*labelsIter, TFT_WHITE);
}
labelsIter++;
iconsIter++;
});
for (; labelsIter != std::end(m_labels); labelsIter++, iconsIter++)
{
const auto relativeIndex = std::distance(std::begin(m_labels), labelsIter);
if (relativeIndex == m_highlightedIndex)
drawItemRect(*labelsIter, TFT_BLACK);
labelsIter->clear();
if (*iconsIter)
{
tft.fillRect(5, labelsIter->y()+1, 24, 24, TFT_BLACK);
*iconsIter = nullptr;
}
}
m_highlightedIndex = newHighlightedIndex;
}
void MenuDisplay::stop()
{
Base::stop();
runForEveryMenuItem([](MenuItem &item){
item.stop();
});
}
void MenuDisplay::buttonPressed(Button button)
{
//Base::buttonPressed(button);
switch (button)
{
case Button::Left: this->back(); break;
case Button::Right: m_pressed = true; break;
case Button::Up: m_rotateOffset--; break;
case Button::Down: m_rotateOffset++; break;
}
}
void MenuDisplay::buttonReleased(Button button)
{
//Base::buttonPressed(button);
// TODO stop auto scroll
}
} // namespace espgui