Added confirmation dialog and use it to confirm shutdown on receiver still connected

This commit is contained in:
Raphael Coeffic
2021-05-24 16:23:06 +02:00
committed by Raphael Coeffic
parent 51e6c48bbe
commit cb8a23cb5e
5 changed files with 177 additions and 64 deletions
+35 -11
View File
@@ -88,31 +88,54 @@ void drawSleepBitmap()
lcdRefresh();
}
//
// TODO: move shutdown animation to Theme
//
#define SHUTDOWN_CIRCLE_DIAMETER 150
void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration, const char * message)
{
if (totalDuration == 0)
return;
static const BitmapBuffer * shutdown = BitmapBuffer::loadBitmap(OpenTxTheme::instance()->getFilePath("shutdown.bmp"));
static const BitmapBuffer* shutdown = nullptr;
if (!shutdown) {
shutdown = BitmapBuffer::loadBitmap(
OpenTxTheme::instance()->getFilePath("shutdown.bmp"));
}
lcd->reset();
if (shutdown) {
OpenTxTheme::instance()->drawBackground(lcd);
lcd->drawBitmap((LCD_W - shutdown->width()) / 2, (LCD_H - shutdown->height()) / 2, shutdown);
lcd->drawBitmap((LCD_W - shutdown->width()) / 2,
(LCD_H - shutdown->height()) / 2, shutdown);
int quarter = duration / (totalDuration / 5);
if (quarter >= 1) lcd->drawBitmapPattern(LCD_W/2, (LCD_H-SHUTDOWN_CIRCLE_DIAMETER)/2, LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR, 0, SHUTDOWN_CIRCLE_DIAMETER/2);
if (quarter >= 2) lcd->drawBitmapPattern(LCD_W/2, LCD_H/2, LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR, SHUTDOWN_CIRCLE_DIAMETER/2, SHUTDOWN_CIRCLE_DIAMETER/2);
if (quarter >= 3) lcd->drawBitmapPattern((LCD_W-SHUTDOWN_CIRCLE_DIAMETER)/2, LCD_H/2, LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR, SHUTDOWN_CIRCLE_DIAMETER, SHUTDOWN_CIRCLE_DIAMETER/2);
if (quarter >= 4) lcd->drawBitmapPattern((LCD_W-SHUTDOWN_CIRCLE_DIAMETER)/2, (LCD_H-SHUTDOWN_CIRCLE_DIAMETER)/2, LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR, SHUTDOWN_CIRCLE_DIAMETER*3/2, SHUTDOWN_CIRCLE_DIAMETER/2);
}
else {
if (quarter >= 1)
lcd->drawBitmapPattern(LCD_W / 2, (LCD_H - SHUTDOWN_CIRCLE_DIAMETER) / 2,
LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR, 0,
SHUTDOWN_CIRCLE_DIAMETER / 2);
if (quarter >= 2)
lcd->drawBitmapPattern(LCD_W / 2, LCD_H / 2, LBM_SHUTDOWN_CIRCLE,
DEFAULT_COLOR, SHUTDOWN_CIRCLE_DIAMETER / 2,
SHUTDOWN_CIRCLE_DIAMETER / 2);
if (quarter >= 3)
lcd->drawBitmapPattern((LCD_W - SHUTDOWN_CIRCLE_DIAMETER) / 2, LCD_H / 2,
LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR,
SHUTDOWN_CIRCLE_DIAMETER,
SHUTDOWN_CIRCLE_DIAMETER / 2);
if (quarter >= 4)
lcd->drawBitmapPattern((LCD_W - SHUTDOWN_CIRCLE_DIAMETER) / 2,
(LCD_H - SHUTDOWN_CIRCLE_DIAMETER) / 2,
LBM_SHUTDOWN_CIRCLE, DEFAULT_COLOR,
SHUTDOWN_CIRCLE_DIAMETER * 3 / 2,
SHUTDOWN_CIRCLE_DIAMETER / 2);
} else {
lcd->clear();
int quarter = duration / (totalDuration / 5);
for (int i = 1; i <= 4; i++) {
if (quarter >= i) {
lcd->drawSolidFilledRect(LCD_W / 2 - 70 + 24 * i, LCD_H / 2 - 10, 20, 20, DEFAULT_BGCOLOR);
lcd->drawSolidFilledRect(LCD_W / 2 - 70 + 24 * i, LCD_H / 2 - 10, 20,
20, DEFAULT_BGCOLOR);
}
}
}
@@ -123,8 +146,9 @@ void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration, const char
void drawFatalErrorScreen(const char * message)
{
lcd->clear();
lcd->drawText(LCD_W/2, LCD_H/2-20, message, FONT(XL)|CENTERED|ALARM_COLOR);
lcd->reset();
lcd->clear(COLOR2FLAGS(BLACK));
lcd->drawText(LCD_W/2, LCD_H/2-20, message, FONT(XL)|CENTERED|COLOR2FLAGS(WHITE));
WDG_RESET();
lcdRefresh();
+87 -31
View File
@@ -23,23 +23,23 @@
#include "opentx.h"
#include "libopenui.h"
FullScreenDialog::FullScreenDialog(uint8_t type, std::string title, std::string message, std::string action, const std::function<void(void)> & confirmHandler):
FormGroup(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE),
type(type),
title(std::move(title)),
message(std::move(message)),
action(std::move(action)),
confirmHandler(confirmHandler)
FullScreenDialog::FullScreenDialog(
uint8_t type, std::string title, std::string message, std::string action,
const std::function<void(void)>& confirmHandler) :
FormGroup(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE),
type(type),
title(std::move(title)),
message(std::move(message)),
action(std::move(action)),
confirmHandler(confirmHandler)
{
Layer::push(this);
#if defined(HARDWARE_TOUCH)
new FabButton(this, LCD_W - 50, LCD_H - 50, ICON_NEXT,
[=]() -> uint8_t {
if (confirmHandler)
confirmHandler();
return 0;
});
new FabButton(this, LCD_W - 50, LCD_H - 50, ICON_NEXT, [=]() -> uint8_t {
if (confirmHandler) confirmHandler();
return 0;
});
#endif
bringToTop();
@@ -50,34 +50,58 @@ void FullScreenDialog::paint(BitmapBuffer * dc)
{
OpenTxTheme::instance()->drawBackground(dc);
dc->drawFilledRect(0, ALERT_FRAME_TOP, LCD_W, ALERT_FRAME_HEIGHT, SOLID, FOCUS_COLOR, OPACITY(8));
dc->drawFilledRect(0, ALERT_FRAME_TOP, LCD_W, ALERT_FRAME_HEIGHT, SOLID,
FOCUS_COLOR, OPACITY(8));
if (type == WARNING_TYPE_ALERT || type == WARNING_TYPE_ASTERISK)
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP, OpenTxTheme::instance()->asterisk);
else if (type == WARNING_TYPE_INFO)
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP, OpenTxTheme::instance()->busy);
else // confirmation
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP, OpenTxTheme::instance()->question);
if (type == WARNING_TYPE_ALERT || type == WARNING_TYPE_ASTERISK) {
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP,
OpenTxTheme::instance()->asterisk);
}
else if (type == WARNING_TYPE_INFO) {
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP,
OpenTxTheme::instance()->busy);
}
else { // confirmation
dc->drawBitmap(ALERT_BITMAP_LEFT, ALERT_BITMAP_TOP,
OpenTxTheme::instance()->question);
}
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, ALARM_COLOR|FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT, title.c_str(), ALARM_COLOR|FONT(XL));
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || \
defined(TRANSLATIONS_CZ)
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, STR_WARNING,
ALARM_COLOR | FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT,
title.c_str(), ALARM_COLOR | FONT(XL));
#else
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(), ALARM_COLOR|FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT, STR_WARNING, ALARM_COLOR|FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(),
ALARM_COLOR | FONT(XL));
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP + ALERT_TITLE_LINE_HEIGHT,
STR_WARNING, ALARM_COLOR | FONT(XL));
#endif
}
else if (!title.empty()) {
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(), ALARM_COLOR|FONT(XL));
} else if (!title.empty()) {
dc->drawText(ALERT_TITLE_LEFT, ALERT_TITLE_TOP, title.c_str(),
ALARM_COLOR | FONT(XL));
}
if (!message.empty()) {
dc->drawText(ALERT_MESSAGE_LEFT, ALERT_MESSAGE_TOP, message.c_str(), FONT(BOLD));
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));
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, 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);
}
}
@@ -152,9 +176,41 @@ void FullScreenDialog::runForever()
deleteLater();
}
void FullScreenDialog::runForeverNoPwrCheck()
{
running = true;
while (running) {
checkBacklight();
WDG_RESET();
RTOS_WAIT_MS(1);
MainWindow::instance()->run(false);
}
deleteLater();
}
void raiseAlert(const char * title, const char * msg, const char * action, uint8_t sound)
{
AUDIO_ERROR_MESSAGE(sound);
auto dialog = new FullScreenDialog(WARNING_TYPE_ALERT, title ? title : "", msg ? msg : "", action ? action : "");
auto dialog = new FullScreenDialog(WARNING_TYPE_ALERT, title ? title : "",
msg ? msg : "", action ? action : "");
dialog->runForever();
}
// POPUP_CONFIRMATION
bool confirmationDialog(const char* title, const char* msg, bool checkPwr)
{
bool confirmed = false;
auto dialog = new FullScreenDialog(WARNING_TYPE_CONFIRM, title ? title : "",
msg ? msg : "", "",
[&confirmed]() { confirmed = true; });
if (checkPwr) {
dialog->runForever();
} else {
dialog->runForeverNoPwrCheck();
}
return confirmed;
}
+4 -1
View File
@@ -34,7 +34,9 @@ enum DialogType {
class FullScreenDialog : public FormGroup
{
public:
FullScreenDialog(uint8_t type, std::string title, std::string message = "", std::string action = "", const std::function<void(void)> & confirmHandler = nullptr);
FullScreenDialog(uint8_t type, std::string title, std::string message = "",
std::string action = "",
const std::function<void(void)>& confirmHandler = nullptr);
#if defined(DEBUG_WINDOWS)
std::string getName() const override
@@ -69,6 +71,7 @@ class FullScreenDialog : public FormGroup
}
void runForever();
void runForeverNoPwrCheck();
protected:
uint8_t type;
+19 -1
View File
@@ -2058,9 +2058,12 @@ uint32_t pwrCheck()
{
#if !defined(COLORLCD)
lcdRefreshWait();
lcdClear();
POPUP_CONFIRMATION(STR_MODEL_SHUTDOWN, nullptr);
#if defined(SHUTDOWN_CONFIRMATION)
if (TELEMETRY_STREAMING() && !g_eeGeneral.disableRssiPoweroffAlarm) {
SET_WARNING_INFO(STR_MODEL_STILL_POWERED, sizeof(TR_MODEL_STILL_POWERED), 0);
@@ -2068,6 +2071,7 @@ uint32_t pwrCheck()
#else
SET_WARNING_INFO(STR_MODEL_STILL_POWERED, sizeof(TR_MODEL_STILL_POWERED), 0);
#endif
event_t evt = getEvent(false);
DISPLAY_WARNING(evt);
LED_ERROR_BEGIN();
@@ -2085,8 +2089,22 @@ uint32_t pwrCheck()
LED_ERROR_END();
return e_power_on;
}
#endif
#else // COLORLCD
// TODO: abort dialog condition (here, RSSI lost)
if (confirmationDialog(STR_MODEL_SHUTDOWN, STR_MODEL_STILL_POWERED, false)) {
pwr_check_state = PWR_CHECK_OFF;
return e_power_off;
} else {
// shutdown has been cancelled
pwr_check_state = PWR_CHECK_PAUSED;
LED_ERROR_END();
return e_power_on;
}
#endif // COLORLCD
}
haptic.play(15, 3, PLAY_NOW);
pwr_check_state = PWR_CHECK_OFF;
return e_power_off;
+32 -20
View File
@@ -460,29 +460,41 @@ uint16_t evalChkSum();
void alert(const char * title, const char * msg, uint8_t sound);
#if !defined(GUI)
#define RAISE_ALERT(...)
#define ALERT(...)
#elif defined(COLORLCD)
void raiseAlert(const char * title, const char * msg, const char * info, uint8_t sound);
inline void RAISE_ALERT(const char * title, const char * msg, const char * info, uint8_t sound)
{
raiseAlert(title, msg, info, sound);
}
inline void ALERT(const char * title, const char * msg, uint8_t sound)
{
raiseAlert(title, msg, "", sound);
}
#else
inline void RAISE_ALERT(const char * title, const char * msg, const char * info, uint8_t sound)
{
showAlertBox(title, msg, info, sound);
}
inline void ALERT(const char * title, const char * msg, uint8_t sound)
{
alert(title, msg, sound);
}
#endif
#elif defined(COLORLCD)
bool confirmationDialog(const char *title, const char *msg, bool checkPwr = true);
void raiseAlert(const char *title, const char *msg, const char *info,
uint8_t sound);
inline void RAISE_ALERT(const char *title, const char *msg, const char *info,
uint8_t sound)
{
raiseAlert(title, msg, info, sound);
}
inline void ALERT(const char *title, const char *msg, uint8_t sound)
{
raiseAlert(title, msg, "", sound);
}
#else // !COLORLCD && GUI
inline void RAISE_ALERT(const char *title, const char *msg, const char *info,
uint8_t sound)
{
showAlertBox(title, msg, info, sound);
}
inline void ALERT(const char *title, const char *msg, uint8_t sound)
{
alert(title, msg, sound);
}
#endif // !COLORLCD && GUI
enum PerOutMode {
e_perout_mode_normal = 0,