Menus can now have a title and a Cancel button

This commit is contained in:
Bertrand Songis
2019-11-04 18:31:50 +01:00
parent c744ee226a
commit 3e3d8b95e7
6 changed files with 134 additions and 47 deletions
+17 -6
View File
@@ -108,6 +108,17 @@ class BitmapBufferBase
this->offsetY = offsetY;
}
inline void clearOffset()
{
setOffset(0, 0);
}
inline void reset()
{
clearOffset();
clearClippingRect();
}
coord_t getOffsetX() const
{
return offsetX;
@@ -146,8 +157,8 @@ class BitmapBufferBase
inline const pixel_t * getPixelPtr(coord_t x, coord_t y) const
{
#if defined(PCBX10) && !defined(SIMU)
x = width - x - 1;
y = height - y - 1;
x = _width - x - 1;
y = _height - y - 1;
#endif
return &data[y * _width + x];
}
@@ -284,8 +295,8 @@ class BitmapBuffer: public BitmapBufferBase<uint16_t>
inline const pixel_t * getPixelPtr(coord_t x, coord_t y) const
{
#if defined(PCBX10) && !defined(SIMU)
x = width - x - 1;
y = height - y - 1;
x = _width - x - 1;
y = _height - y - 1;
#endif
return &data[y * _width + x];
}
@@ -293,8 +304,8 @@ class BitmapBuffer: public BitmapBufferBase<uint16_t>
inline pixel_t * getPixelPtr(coord_t x, coord_t y)
{
#if defined(PCBX10) && !defined(SIMU)
x = width - x - 1;
y = height - y - 1;
x = _width - x - 1;
y = _height - y - 1;
#endif
return &data[y * _width + x];
}
+3
View File
@@ -55,6 +55,9 @@ void Choice::onEvent(event_t event)
void Choice::openMenu()
{
auto menu = new Menu();
if (!menuTitle.empty())
menu->setTitle(menuTitle);
auto value = getValue();
int count = 0;
int current = -1;
+6
View File
@@ -80,10 +80,16 @@ class Choice : public ChoiceBase {
textHandler = std::move(handler);
}
void setMenuTitle(const std::string value)
{
menuTitle = std::move(value);
}
protected:
const char * values = nullptr;
int16_t vmin = 0;
int16_t vmax = 0;
std::string menuTitle;
std::function<int16_t()> getValue;
std::function<void(int16_t)> setValue;
std::function<bool(int)> isValueAvailable;
@@ -101,6 +101,9 @@
#define SCROLLBAR_COLOR COLOR(SCROLLBAR_COLOR_INDEX)
#define MENU_COLOR COLOR(MENU_COLOR_INDEX)
#define MENU_BGCOLOR COLOR(MENU_BGCOLOR_INDEX)
#define MENU_LINE_COLOR COLOR(MENU_LINE_COLOR_INDEX)
#define MENU_HIGHLIGHT_COLOR COLOR(MENU_HIGHLIGHT_COLOR_INDEX)
#define MENU_HIGHLIGHT_BGCOLOR COLOR(MENU_HIGHLIGHT_BGCOLOR_INDEX)
#define CUSTOM_COLOR COLOR(CUSTOM_COLOR_INDEX)
#endif
+51 -18
View File
@@ -18,14 +18,16 @@
*/
#include "menu.h"
#include "font.h"
MenuWindow::MenuWindow(Menu * parent):
Window(parent, {LCD_W / 2 - 100, LCD_H / 2, 200, 0}, OPAQUE)
Window(parent, {(LCD_W - MENUS_WIDTH) / 2, (LCD_H - MENUS_WIDTH) / 2, MENUS_WIDTH, 0}, OPAQUE),
body(this, {0, 0, width(), height()}, OPAQUE)
{
setFocus();
body.setFocus();
}
void MenuWindow::select(int index)
void MenuBody::select(int index)
{
selectedIndex = index;
if (innerHeight > height()) {
@@ -35,7 +37,7 @@ void MenuWindow::select(int index)
}
#if defined(HARDWARE_KEYS)
void MenuWindow::onEvent(event_t event)
void MenuBody::onEvent(event_t event)
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
@@ -61,7 +63,7 @@ void MenuWindow::onEvent(event_t event)
#endif
#if defined(HARDWARE_TOUCH)
bool MenuWindow::onTouchEnd(coord_t x, coord_t y)
bool MenuBody::onTouchEnd(coord_t x, coord_t y)
{
int index = y / MENUS_LINE_HEIGHT;
lines[index].onPress();
@@ -69,13 +71,18 @@ bool MenuWindow::onTouchEnd(coord_t x, coord_t y)
}
#endif
void MenuWindow::paint(BitmapBuffer * dc)
void MenuBody::paint(BitmapBuffer * dc)
{
int width = (innerHeight > height() ? 195 : 200);
dc->clear(MENU_BGCOLOR);
for (auto i = 0; i < lines.size(); i++) {
for (auto i = 0; i < (int)lines.size(); i++) {
auto & line = lines[i];
LcdFlags flags = (selectedIndex == (int) i ? HIGHLIGHT_COLOR : MENU_COLOR);
LcdFlags flags = MENU_COLOR;
if (selectedIndex == i) {
flags = MENU_HIGHLIGHT_COLOR;
if (MENU_HIGHLIGHT_BGCOLOR != MENU_BGCOLOR)
dc->drawSolidFilledRect(0, i * MENUS_LINE_HEIGHT, width(), MENUS_LINE_HEIGHT, MENU_HIGHLIGHT_BGCOLOR);
}
if (line.drawLine) {
line.drawLine(dc, 0, i * MENUS_LINE_HEIGHT /*+ (lineHeight - 20) / 2*/, flags);
}
@@ -84,38 +91,64 @@ void MenuWindow::paint(BitmapBuffer * dc)
dc->drawText(10, i * MENUS_LINE_HEIGHT + (MENUS_LINE_HEIGHT - 20) / 2, text[0] == '\0' ? "---" : text, flags);
}
if (i > 0) {
dc->drawSolidHorizontalLine(0, i * MENUS_LINE_HEIGHT - 1, width, DISABLE_COLOR);
dc->drawSolidHorizontalLine(0, i * MENUS_LINE_HEIGHT - 1, MENUS_WIDTH, MENU_LINE_COLOR);
}
}
}
void MenuWindow::paint(BitmapBuffer * dc)
{
// the background
dc->clear(MENU_BGCOLOR);
// the title
if (!title.empty()) {
dc->drawText(MENUS_WIDTH / 2, (MENUS_HEADER_HEIGHT - getFontHeight(FONT(BOLD))) / 2, title.c_str(), CENTERED | FONT(BOLD));
dc->drawSolidHorizontalLine(0, MENUS_HEADER_HEIGHT - 1, MENUS_WIDTH, MENU_LINE_COLOR);
}
// the cancel button
if (MENUS_FOOTER_HEIGHT > 0) {
dc->drawText(MENUS_WIDTH / 2, height() - MENUS_FOOTER_HEIGHT + (MENUS_FOOTER_HEIGHT - getFontHeight(FONT(BOLD))) / 2, "Cancel", CENTERED);
dc->drawSolidHorizontalLine(0, height() - MENUS_FOOTER_HEIGHT, MENUS_WIDTH, MENU_LINE_COLOR);
}
}
void Menu::updatePosition()
{
if (!toolbar) {
// there is no navigation bar at the left, we may center the window on screen
int count = min<int>(MENUS_MAX_LINES, menuWindow.lines.size());
coord_t h = count * MENUS_LINE_HEIGHT - 1;
menuWindow.setTop((LCD_H - h) / 2 + 20);
menuWindow.setHeight(h);
auto headerHeight = menuWindow.title.empty() ? 0 : MENUS_HEADER_HEIGHT;
auto bodyHeight = limit<coord_t>(MENUS_MIN_HEIGHT, menuWindow.body.lines.size() * MENUS_LINE_HEIGHT - 1, MENUS_MAX_HEIGHT);
menuWindow.setTop((LCD_H - headerHeight - bodyHeight - MENUS_FOOTER_HEIGHT) / 2 + MENUS_OFFSET_TOP);
menuWindow.setHeight(headerHeight + bodyHeight + MENUS_FOOTER_HEIGHT);
menuWindow.body.setTop(headerHeight);
menuWindow.body.setHeight(bodyHeight);
}
menuWindow.setInnerHeight(menuWindow.lines.size() * MENUS_LINE_HEIGHT - 1);
menuWindow.body.setInnerHeight(menuWindow.body.lines.size() * MENUS_LINE_HEIGHT - 1);
}
void Menu::setTitle(const std::string text)
{
menuWindow.setTitle(text);
updatePosition();
}
void Menu::addLine(const std::string & text, std::function<void()> onPress)
{
menuWindow.addLine(text, std::move(onPress));
menuWindow.body.addLine(text, std::move(onPress));
updatePosition();
}
void Menu::addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress)
{
menuWindow.addCustomLine(drawLine, std::move(onPress));
menuWindow.body.addCustomLine(drawLine, std::move(onPress));
updatePosition();
}
void Menu::removeLines()
{
menuWindow.removeLines();
menuWindow.body.removeLines();
updatePosition();
}
+54 -23
View File
@@ -26,12 +26,14 @@
#include "mainwindow.h"
class Menu;
class MenuWindow;
class MenuWindow: public Window {
class MenuBody: public Window {
friend class MenuWindow;
friend class Menu;
class MenuLine {
friend class MenuWindow;
friend class MenuBody;
public:
MenuLine(std::string text, std::function<void()> onPress):
@@ -57,19 +59,21 @@ class MenuWindow: public Window {
};
public:
explicit MenuWindow(Menu * parent);
#if defined(DEBUG_WINDOWS)
std::string getName() override
MenuBody(Window * parent, const rect_t & rect, WindowFlags flags):
Window(parent, rect, flags)
{
return "MenuWindow";
setPageHeight(MENUS_LINE_HEIGHT);
}
void select(int index);
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
void setCancelHandler(std::function<void()> handler)
{
onCancel = handler;
}
#if defined(HARDWARE_TOUCH)
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
void addLine(const std::string & text, std::function<void()> onPress)
{
@@ -89,18 +93,13 @@ class MenuWindow: public Window {
invalidate();
}
void select(int index);
void setCancelHandler(std::function<void()> handler)
{
onCancel = handler;
}
void paint(BitmapBuffer * dc) override;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
#if defined(HARDWARE_TOUCH)
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
protected:
std::vector<MenuLine> lines;
#if defined(HARDWARE_TOUCH)
@@ -111,6 +110,36 @@ class MenuWindow: public Window {
std::function<void()> onCancel;
};
class MenuWindow: public Window {
friend class Menu;
public:
explicit MenuWindow(Menu * parent);
~MenuWindow() override
{
body.detach();
}
#if defined(DEBUG_WINDOWS)
std::string getName() override
{
return "MenuWindow";
}
#endif
void setTitle(const std::string text)
{
title = std::move(text);
}
void paint(BitmapBuffer * dc) override;
protected:
MenuBody body;
std::string title;
};
class Menu : public Window {
public:
Menu() :
@@ -129,7 +158,7 @@ class Menu : public Window {
void setCancelHandler(std::function<void()> handler)
{
menuWindow.setCancelHandler(handler);
menuWindow.body.setCancelHandler(handler);
}
void deleteLater()
@@ -157,15 +186,17 @@ class Menu : public Window {
menuWindow.setHeight(toolbar->height());
}
void setTitle(const std::string text);
void addLine(const std::string & text, std::function<void()> onPress);
void addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress);
void removeLines();
void select(int index)
inline void select(int index)
{
menuWindow.select(index);
menuWindow.body.select(index);
}
#if defined(HARDWARE_KEYS)