Multiple selection in Menu

This commit is contained in:
Bertrand Songis
2020-08-25 09:27:03 +02:00
parent f6e730a94d
commit 8632c038f8
2 changed files with 64 additions and 25 deletions
+38 -12
View File
@@ -36,21 +36,25 @@ void MenuBody::onEvent(event_t event)
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
if (event == EVT_ROTARY_RIGHT) {
if (lines.size() > 0)
if (!lines.empty())
select(int((selectedIndex + 1) % lines.size()));
}
else if (event == EVT_ROTARY_LEFT) {
if (lines.size() > 0)
if (!lines.empty())
select(int(selectedIndex == 0 ? lines.size() - 1 : selectedIndex - 1));
}
else if (event == EVT_KEY_BREAK(KEY_ENTER)) {
if (lines.size() > 0) {
if (!lines.empty()) {
if (selectedIndex < 0) {
select(0);
}
else {
Window::onEvent(event); // the window above will be closed on event
lines[selectedIndex].onPress();
Menu * menu = getParentMenu();
if (menu->multiple) {
menu->invalidate();
}
}
}
}
@@ -68,11 +72,23 @@ void MenuBody::onEvent(event_t event)
#if defined(HARDWARE_TOUCH)
bool MenuBody::onTouchEnd(coord_t /*x*/, coord_t y)
{
Menu * menu = getParentMenu();
int index = y / MENUS_LINE_HEIGHT;
if (index < (int)lines.size()) {
lines[index].onPress();
if (menu->multiple) {
if (selectedIndex == index)
lines[index].onPress();
else
select(index);
menu->invalidate();
}
else {
lines[index].onPress();
}
}
if (!menu->multiple) {
menu->deleteLater();
}
getParent()->getParent()->deleteLater();
return true;
}
#endif
@@ -95,6 +111,12 @@ void MenuBody::paint(BitmapBuffer * dc)
const char * text = line.text.data();
dc->drawText(10, i * MENUS_LINE_HEIGHT + (MENUS_LINE_HEIGHT - 20) / 2, text[0] == '\0' ? "---" : text, flags);
}
Menu * menu = getParentMenu();
if (menu->multiple && line.isChecked && line.isChecked()) {
theme->drawCheckBox(dc, 1, width() - 35, i * MENUS_LINE_HEIGHT + (MENUS_LINE_HEIGHT - 20) / 2, 0);
}
if (i > 0) {
dc->drawSolidHorizontalLine(0, i * MENUS_LINE_HEIGHT - 1, MENUS_WIDTH, MENU_LINE_COLOR);
}
@@ -120,9 +142,10 @@ void MenuWindowContent::paint(BitmapBuffer * dc)
}
}
Menu::Menu(Window * parent):
Menu::Menu(Window * parent, bool multiple):
ModalWindow(parent),
content(createMenuWindow(this))
content(createMenuWindow(this)),
multiple(multiple)
{
}
@@ -146,15 +169,15 @@ void Menu::setTitle(std::string text)
updatePosition();
}
void Menu::addLine(const std::string & text, std::function<void()> onPress)
void Menu::addLine(const std::string & text, std::function<void()> onPress, std::function<bool()> isChecked)
{
content->body.addLine(text, std::move(onPress));
content->body.addLine(text, std::move(onPress), std::move(isChecked));
updatePosition();
}
void Menu::addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress)
void Menu::addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress, std::function<bool()> isChecked)
{
content->body.addCustomLine(std::move(drawLine), std::move(onPress));
content->body.addCustomLine(std::move(drawLine), std::move(onPress), std::move(isChecked));
updatePosition();
}
@@ -170,7 +193,10 @@ void Menu::onEvent(event_t event)
if (toolbar && (event == EVT_KEY_BREAK(KEY_PGDN) || event == EVT_KEY_LONG(KEY_PGDN))) {
toolbar->onEvent(event);
}
else if (event == EVT_KEY_BREAK(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_ENTER)) {
else if (event == EVT_KEY_BREAK(KEY_EXIT)) {
deleteLater();
}
else if (event == EVT_KEY_BREAK(KEY_ENTER) && !multiple) {
deleteLater();
}
}
+26 -13
View File
@@ -28,7 +28,7 @@
class Menu;
class MenuWindowContent;
class MenuBody: public Window {
class MenuBody : public Window {
friend class MenuWindowContent;
friend class Menu;
@@ -36,15 +36,17 @@ class MenuBody: public Window {
friend class MenuBody;
public:
MenuLine(std::string text, std::function<void()> onPress):
MenuLine(std::string text, std::function<void()> onPress, std::function<bool()> isChecked):
text(std::move(text)),
onPress(std::move(onPress))
onPress(std::move(onPress)),
isChecked(std::move(isChecked))
{
}
MenuLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress):
MenuLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress, std::function<bool()> isChecked):
drawLine(std::move(drawLine)),
onPress(std::move(onPress))
onPress(std::move(onPress)),
isChecked(std::move(isChecked))
{
}
@@ -56,6 +58,7 @@ class MenuBody: public Window {
std::string text;
std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine;
std::function<void()> onPress;
std::function<bool()> isChecked;
};
public:
@@ -92,15 +95,15 @@ class MenuBody: public Window {
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
void addLine(const std::string & text, std::function<void()> onPress)
void addLine(const std::string & text, std::function<void()> onPress, std::function<bool()> isChecked)
{
lines.emplace_back(text, onPress);
lines.emplace_back(text, onPress, isChecked);
invalidate();
}
void addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress)
void addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress, std::function<bool()> isChecked)
{
lines.emplace_back(drawLine, onPress);
lines.emplace_back(drawLine, onPress, isChecked);
invalidate();
}
@@ -125,6 +128,8 @@ class MenuBody: public Window {
int selectedIndex = 0;
#endif
std::function<void()> onCancel;
inline Menu * getParentMenu();
};
class MenuWindowContent: public ModalWindowContent {
@@ -152,12 +157,14 @@ class MenuWindowContent: public ModalWindowContent {
};
class Menu: public ModalWindow {
friend class MenuBody;
public:
explicit Menu(Window * parent);
explicit Menu(Window * parent, bool multiple = false);
void setCancelHandler(std::function<void()> handler)
{
content->body.setCancelHandler(handler);
content->body.setCancelHandler(std::move(handler));
}
void setWaitHandler(std::function<void()> handler)
@@ -175,9 +182,9 @@ class Menu: public ModalWindow {
void setTitle(std::string text);
void addLine(const std::string & text, std::function<void()> onPress);
void addLine(const std::string & text, std::function<void()> onPress, std::function<bool()> isChecked = nullptr);
void addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress);
void addCustomLine(std::function<void(BitmapBuffer * dc, coord_t x, coord_t y, LcdFlags flags)> drawLine, std::function<void()> onPress, std::function<bool()> isChecked = nullptr);
void removeLines();
@@ -205,9 +212,15 @@ class Menu: public ModalWindow {
protected:
MenuWindowContent * content;
bool multiple;
Window * toolbar = nullptr;
std::function<void()> waitHandler;
void updatePosition();
};
Menu * MenuBody::getParentMenu()
{
return static_cast<Menu *>(getParent()->getParent());
}
#endif // _MENU_H_