Added confirmation dialog and use it to confirm shutdown on receiver still connected
This commit is contained in:
committed by
Raphael Coeffic
parent
51e6c48bbe
commit
cb8a23cb5e
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user