feat(ui): Improved Button/touch handling for throttle / switch alert screen (#3061)

* Button and touch handling for throttle / switch alert screen.

* Restore original touch behaviour for confirmation dialog.

* Add buttons for 'actions' at bottom of screen.

* Fix infinite loop that can happen in some instances.

* Remove the option for a long press on the touch screen to close the dialog. On screen buttons must be used to close.

Co-authored-by: Phil Mitchell <phil.a.mitchell@gmail.com>
This commit is contained in:
philmoz
2023-01-25 10:44:12 +10:00
committed by GitHub
co-authored by Phil Mitchell
parent 3d700f42f0
commit 475ad1fb6f
4 changed files with 103 additions and 93 deletions
+82 -79
View File
@@ -43,26 +43,70 @@ FullScreenDialog::FullScreenDialog(
confirmHandler(confirmHandler)
{
Layer::push(this);
// // TODO: if 'confirmHandler':
// // -> add a confirm / cancel button
// //
// #if defined(HARDWARE_TOUCH) && 0
// new FabButton(this, LCD_W - (FAB_BUTTON_SIZE + PAGE_PADDING),
// LCD_H - (FAB_BUTTON_SIZE + PAGE_PADDING), ICON_NEXT,
// [=]() -> uint8_t {
// deleteLater();
// if (confirmHandler) confirmHandler();
// return 0;
// });
// #endif
bringToTop();
lv_obj_add_event_cb(lvobj, FullScreenDialog::long_pressed, LV_EVENT_LONG_PRESSED, nullptr);
}
void FullScreenDialog::init()
{
if (!loaded) {
loaded = true;
std::string t;
if (type == WARNING_TYPE_ALERT) {
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || defined(TRANSLATIONS_CZ)
t = STR_WARNING + "\n" + title;
#else
t = title + "\n" + STR_WARNING;
#endif
} else if (!title.empty()) {
t = title;
}
new StaticText(this,
rect_t{ALERT_TITLE_LEFT, ALERT_TITLE_TOP, LCD_W - ALERT_TITLE_LEFT - PAGE_PADDING, LCD_H - ALERT_TITLE_TOP - PAGE_PADDING},
t.c_str(), 0, COLOR_THEME_WARNING | FONT(XL));
messageLabel = new StaticText(this,
rect_t{ALERT_MESSAGE_LEFT, ALERT_MESSAGE_TOP, LCD_W - ALERT_MESSAGE_LEFT - PAGE_PADDING, LCD_H - ALERT_MESSAGE_TOP - PAGE_PADDING},
message.c_str(), 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
if (!action.empty()) {
auto btn = new TextButton(this, { (LCD_W - 280) / 2, LCD_H - 48, 280, 40 }, action.c_str(),
[=]() {
closeDialog();
return 0;
}, COLOR_THEME_PRIMARY1 | FONT(BOLD));
lv_obj_set_style_bg_color(btn->getLvObj(), makeLvColor(COLOR_THEME_SECONDARY3), 0);
lv_obj_set_style_bg_opa(btn->getLvObj(), LV_OPA_COVER, 0);
lv_obj_set_style_text_color(btn->getLvObj(), makeLvColor(COLOR_THEME_PRIMARY1), 0);
} else {
if (type == WARNING_TYPE_CONFIRM) {
auto btn = new TextButton(this, { LCD_W / 3 - 50, LCD_H - 48, 100, 40 }, STR_EXIT,
[=]() {
deleteLater();
return 0;
}, COLOR_THEME_PRIMARY1 | FONT(BOLD));
lv_obj_set_style_bg_color(btn->getLvObj(), makeLvColor(COLOR_THEME_SECONDARY3), 0);
lv_obj_set_style_bg_opa(btn->getLvObj(), LV_OPA_COVER, 0);
lv_obj_set_style_text_color(btn->getLvObj(), makeLvColor(COLOR_THEME_PRIMARY1), 0);
btn = new TextButton(this, { LCD_W * 2 / 3 - 50, LCD_H - 48, 100, 40 }, STR_OK,
[=]() {
closeDialog();
return 0;
}, COLOR_THEME_PRIMARY1 | FONT(BOLD));
lv_obj_set_style_bg_color(btn->getLvObj(), makeLvColor(COLOR_THEME_SECONDARY3), 0);
lv_obj_set_style_bg_opa(btn->getLvObj(), LV_OPA_COVER, 0);
lv_obj_set_style_text_color(btn->getLvObj(), makeLvColor(COLOR_THEME_PRIMARY1), 0);
}
}
}
}
void FullScreenDialog::paint(BitmapBuffer * dc)
{
init();
OpenTxTheme::instance()->drawBackground(dc);
dc->drawFilledRect(0, ALERT_FRAME_TOP, LCD_W, ALERT_FRAME_HEIGHT, SOLID,
@@ -78,44 +122,13 @@ void FullScreenDialog::paint(BitmapBuffer * dc)
dc->drawMask(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP,
OpenTxTheme::instance()->error, COLOR_THEME_WARNING);
}
}
if (type == WARNING_TYPE_ALERT) {
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || \
defined(TRANSLATIONS_CZ)
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, STR_WARNING,
COLOR_THEME_WARNING | FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT,
title.c_str(), COLOR_THEME_WARNING | FONT(XL));
#else
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(),
COLOR_THEME_WARNING | FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT,
STR_WARNING, COLOR_THEME_WARNING | FONT(XL));
#endif
} else if (!title.empty()) {
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(),
COLOR_THEME_WARNING | FONT(XL));
}
if (!message.empty()) {
dc->drawText(ALERT_MESSAGE_LEFT, ALERT_MESSAGE_TOP, message.c_str(),
FONT(BOLD));
}
if (!action.empty()) {
dc->drawText(LCD_W / 2, ALERT_ACTION_TOP, action.c_str(),
CENTERED | FONT(BOLD));
} else if (type == WARNING_TYPE_CONFIRM) {
LcdFlags flags = FONT(BOLD);
int w = getTextWidth(STR_OK, 0, flags);
dc->drawText(ALERT_MESSAGE_LEFT, ALERT_ACTION_TOP,
STR_OK, flags);
dc->drawText(ALERT_MESSAGE_LEFT + w + 20, ALERT_ACTION_TOP,
STR_EXIT, flags);
}
void FullScreenDialog::closeDialog()
{
if (confirmHandler)
confirmHandler();
deleteLater();
}
void FullScreenDialog::long_pressed(lv_event_t* e)
@@ -124,15 +137,18 @@ void FullScreenDialog::long_pressed(lv_event_t* e)
auto fs = (FullScreenDialog*)lv_obj_get_user_data(obj);
if (fs) {
fs->onClicked();
fs->closeDialog();
lv_indev_wait_release(lv_indev_get_act());
}
}
void FullScreenDialog::onClicked()
void FullScreenDialog::onEvent(event_t event)
{
if (confirmHandler) confirmHandler();
deleteLater();
// Buttons other than RTN or ENTER
if (type == WARNING_TYPE_ALERT) {
closeDialog();
killEvents(event);
}
}
void FullScreenDialog::onCancel()
@@ -169,7 +185,7 @@ static void run_ui_manually()
MainWindow::instance()->run(false);
}
void FullScreenDialog::runForever()
void FullScreenDialog::runForever(bool checkPwr)
{
running = true;
@@ -180,29 +196,20 @@ void FullScreenDialog::runForever()
while (running) {
resetBacklightTimeout();
auto check = pwrCheck();
if (check == e_power_off) {
boardOff();
if (checkPwr) {
auto check = pwrCheck();
if (check == e_power_off) {
boardOff();
#if defined(SIMU)
return;
return;
#endif
} else if (check == e_power_press) {
WDG_RESET();
RTOS_WAIT_MS(1);
continue;
}
}
else if (check == e_power_press) {
WDG_RESET();
RTOS_WAIT_MS(1);
continue;
}
run_ui_manually();
}
deleteLater();
}
void FullScreenDialog::runForeverNoPwrCheck()
{
running = true;
while (running) {
resetBacklightTimeout();
run_ui_manually();
}
@@ -239,11 +246,7 @@ bool confirmationDialog(const char* title, const char* msg, bool checkPwr,
});
}
if (checkPwr) {
dialog->runForever();
} else {
dialog->runForeverNoPwrCheck();
}
dialog->runForever(checkPwr);
return confirmed;
}
+10 -3
View File
@@ -32,6 +32,8 @@ enum DialogType {
WARNING_TYPE_INFO
};
class StaticText;
class FullScreenDialog : public Window
{
public:
@@ -54,7 +56,7 @@ class FullScreenDialog : public Window
void paint(BitmapBuffer * dc) override;
void onClicked() override;
void onEvent(event_t event) override;
void onCancel() override;
void deleteLater(bool detach = true, bool trash = true) override;
@@ -66,8 +68,9 @@ class FullScreenDialog : public Window
closeCondition = std::move(handler);
}
void runForever();
void runForeverNoPwrCheck();
void runForever(bool checkPwr = true);
void closeDialog();
protected:
uint8_t type;
@@ -77,6 +80,10 @@ class FullScreenDialog : public Window
bool running = false;
std::function<bool(void)> closeCondition;
std::function<void(void)> confirmHandler;
bool loaded = false;
StaticText* messageLabel;
virtual void init();
static void long_pressed(lv_event_t* e);
};
+9 -11
View File
@@ -23,22 +23,20 @@
#include "switches.h"
SwitchWarnDialog::SwitchWarnDialog() :
FullScreenDialog(WARNING_TYPE_ALERT, STR_SWITCHWARN)
FullScreenDialog(WARNING_TYPE_ALERT, STR_SWITCHWARN, "", STR_PRESS_ANY_KEY_TO_SKIP)
{
last_bad_switches = 0xff;
bad_pots = 0;
last_bad_pots = 0x0;
setCloseCondition(std::bind(&SwitchWarnDialog::warningInactive, this));
}
warn_label = new StaticText(this, rect_t{}, "", 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
lv_obj_t* obj = warn_label->getLvObj();
lv_label_set_long_mode(obj, LV_LABEL_LONG_DOT);
warn_label->setLeft(ALERT_MESSAGE_LEFT);
warn_label->setWidth(LCD_W - ALERT_MESSAGE_LEFT - PAGE_PADDING);
warn_label->setTop(ALERT_MESSAGE_TOP);
warn_label->setHeight(LCD_H - ALERT_MESSAGE_TOP - PAGE_PADDING);
void SwitchWarnDialog::init()
{
if (!loaded) {
FullScreenDialog::init();
lv_label_set_long_mode(messageLabel->getLvObj(), LV_LABEL_LONG_DOT);
}
}
bool SwitchWarnDialog::warningInactive()
@@ -98,5 +96,5 @@ void SwitchWarnDialog::checkEvents()
}
}
warn_label->setText(warn_txt);
messageLabel->setText(warn_txt);
}
@@ -46,6 +46,8 @@ class SwitchWarnDialog : public FullScreenDialog
StaticText* warn_label;
bool warningInactive();
void init() override;
};
#endif