2023-05-29 18:25:28 +03:00
|
|
|
#include "config.h"
|
|
|
|
#include "Menu.h"
|
|
|
|
#include <Fonts/FreeSans9pt7b.h>
|
|
|
|
#include <Fonts/FreeSansBold9pt7b.h>
|
|
|
|
|
|
|
|
RTC_DATA_ATTR WatchyDisplay * Menu::m_display = nullptr;
|
|
|
|
RTC_DATA_ATTR std::function<void()> Menu::m_exitCallback = nullptr;
|
2023-05-29 20:00:46 +03:00
|
|
|
RTC_DATA_ATTR uint8_t Menu::m_numPages = 0;
|
|
|
|
RTC_DATA_ATTR uint8_t Menu::m_currentPage = 0;
|
|
|
|
RTC_DATA_ATTR uint8_t Menu::m_numMenuItemsinCurrentPage = 0;
|
|
|
|
RTC_DATA_ATTR uint8_t Menu::m_currentMenuItem = 0;
|
2023-05-29 18:25:28 +03:00
|
|
|
|
|
|
|
Menu::Menu()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Menu::~Menu()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::Init(WatchyDisplay & display)
|
|
|
|
{
|
|
|
|
m_display = &display;
|
|
|
|
m_pages.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::HandleButtonPress(uint64_t buttonMask)
|
|
|
|
{
|
|
|
|
if (m_currentPage == 0) {
|
|
|
|
if (buttonMask & BACK_BTN_MASK) {
|
|
|
|
if (m_exitCallback) {
|
|
|
|
m_exitCallback();
|
2023-05-29 20:00:46 +03:00
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_pages.size() == 0) {
|
|
|
|
if (m_exitCallback) {
|
|
|
|
m_exitCallback();
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buttonMask & UP_BTN_MASK) {
|
|
|
|
if (m_currentMenuItem > 0) {
|
|
|
|
m_currentMenuItem--;
|
|
|
|
}
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
Redraw(true);
|
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (buttonMask & DOWN_BTN_MASK) {
|
2023-05-29 20:00:46 +03:00
|
|
|
if (m_currentMenuItem < m_numMenuItemsinCurrentPage - 1) {
|
2023-05-29 18:25:28 +03:00
|
|
|
m_currentMenuItem++;
|
|
|
|
}
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
Redraw(true);
|
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (buttonMask & MENU_BTN_MASK) {
|
2023-05-29 20:00:46 +03:00
|
|
|
if (m_pages[m_currentPage].menuItems[m_currentMenuItem].callback != nullptr) {
|
2023-05-29 18:25:28 +03:00
|
|
|
m_pages[m_currentPage].menuItems[m_currentMenuItem].callback();
|
2023-05-29 20:00:46 +03:00
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
|
2023-05-29 20:00:46 +03:00
|
|
|
if (m_pages[m_currentPage].menuItems[m_currentMenuItem].pageNum == 0 && m_currentPage == 0 && m_exitCallback) {
|
|
|
|
m_exitCallback();
|
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
m_currentPage = m_pages[m_currentPage].menuItems[m_currentMenuItem].pageNum;
|
|
|
|
m_currentMenuItem = 0;
|
2023-05-29 22:07:52 +03:00
|
|
|
m_numMenuItemsinCurrentPage = m_pages[m_currentPage].menuItems.size();
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
Redraw(false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buttonMask & BACK_BTN_MASK) {
|
|
|
|
m_currentPage = m_pages[m_currentPage].backPageNum;
|
|
|
|
m_currentMenuItem = 0;
|
2023-05-29 22:07:52 +03:00
|
|
|
m_numMenuItemsinCurrentPage = m_pages[m_currentPage].menuItems.size();
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
Redraw(false);
|
|
|
|
return;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::SetPages(const std::vector<MenuPage> & pages)
|
|
|
|
{
|
|
|
|
m_pages = pages;
|
2023-05-29 20:00:46 +03:00
|
|
|
m_numPages = pages.size();
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::SetExitCallback(std::function<void()> callback)
|
|
|
|
{
|
|
|
|
m_exitCallback = callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::Redraw(bool partialRefresh)
|
|
|
|
{
|
|
|
|
if (m_display == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!partialRefresh) {
|
|
|
|
m_display->clearScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_display->setFullWindow();
|
|
|
|
m_display->fillScreen(GxEPD_WHITE);
|
|
|
|
|
|
|
|
if (m_pages.size() > 0) {
|
|
|
|
bool hasTitle = false;
|
2023-05-29 20:00:46 +03:00
|
|
|
bool hasBody = false;
|
|
|
|
|
|
|
|
uint16_t top = 5;
|
|
|
|
|
2023-05-29 18:25:28 +03:00
|
|
|
if (m_pages[m_currentPage].title.length() > 0) {
|
|
|
|
hasTitle = true;
|
|
|
|
|
|
|
|
m_display->setFont(&FreeSansBold9pt7b);
|
|
|
|
m_display->setTextColor(GxEPD_BLACK);
|
|
|
|
int16_t x, y;
|
|
|
|
uint16_t w, h;
|
|
|
|
|
2023-05-29 20:00:46 +03:00
|
|
|
m_display->setTextWrap(false);
|
2023-05-29 18:25:28 +03:00
|
|
|
m_display->getTextBounds(m_pages[m_currentPage].title.c_str(), 0, 0, &x, &y, &w, &h);
|
|
|
|
|
|
|
|
if (m_pages[m_currentPage].titleAlignment == ALIGNMENT_LEFT) { // Left
|
|
|
|
x = 5;
|
|
|
|
} else if (m_pages[m_currentPage].titleAlignment == ALIGNMENT_CENTER) { // Center
|
|
|
|
x = (m_display->width() - w) / 2;
|
|
|
|
} else if (m_pages[m_currentPage].titleAlignment == ALIGNMENT_RIGHT) { // Right
|
|
|
|
x = m_display->width() - w - 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_display->setCursor(x, 15);
|
|
|
|
m_display->print(m_pages[m_currentPage].title.c_str());
|
2023-05-29 20:00:46 +03:00
|
|
|
m_display->drawLine(5, 20, m_display->width() - 10, 20, GxEPD_BLACK);
|
|
|
|
|
|
|
|
top += 35;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_pages[m_currentPage].body.length() > 0) {
|
|
|
|
m_display->setFont(&FreeSans9pt7b);
|
|
|
|
m_display->setTextColor(GxEPD_BLACK);
|
|
|
|
|
|
|
|
int16_t x, y;
|
|
|
|
uint16_t w, h;
|
|
|
|
m_display->setTextWrap(false);
|
|
|
|
m_display->getTextBounds(m_pages[m_currentPage].body.c_str(), 0, 0, &x, &y, &w, &h);
|
|
|
|
m_display->setCursor(5, top);
|
|
|
|
m_display->print(m_pages[m_currentPage].body.c_str());
|
|
|
|
top += h - 5;
|
|
|
|
m_display->drawLine(5, top, m_display->width() - 10, top, GxEPD_BLACK);
|
|
|
|
top += 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < m_numMenuItemsinCurrentPage; i++) {
|
|
|
|
int16_t x, y;
|
|
|
|
uint16_t w, h;
|
2023-05-29 22:07:52 +03:00
|
|
|
m_display->getTextBounds(m_pages[m_currentPage].menuItems[i].title.c_str(), 5, top, &x, &y, &w, &h);
|
2023-05-29 20:00:46 +03:00
|
|
|
|
|
|
|
if (i == m_currentMenuItem) {
|
|
|
|
m_display->fillRect(5, top, m_display->width() - 15, h + 6, GxEPD_BLACK);
|
|
|
|
m_display->setTextColor(GxEPD_WHITE);
|
|
|
|
} else {
|
|
|
|
m_display->setTextColor(GxEPD_BLACK);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_display->setFont(&FreeSans9pt7b);
|
|
|
|
m_display->setCursor(x, top + 15);
|
|
|
|
m_display->print(m_pages[m_currentPage].menuItems[i].title.c_str());
|
|
|
|
|
|
|
|
top += h + 5;
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_display->display(partialRefresh);
|
2023-05-29 20:00:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::Reset()
|
|
|
|
{
|
|
|
|
m_currentPage = 0;
|
|
|
|
m_currentMenuItem = 0;
|
|
|
|
m_numPages = m_pages.size();
|
|
|
|
|
|
|
|
if (m_numPages) {
|
|
|
|
m_numMenuItemsinCurrentPage = m_pages[m_currentPage].menuItems.size();
|
|
|
|
}
|
2023-05-29 18:25:28 +03:00
|
|
|
}
|