From fea19c69af3e27bd0ee73889fcd30a043f1ce677 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 17 Aug 2021 23:19:10 +0300 Subject: [PATCH] GUI: Support multiple alt buttons in MessageDialog --- gui/message.cpp | 57 ++++++++++++++++++++++++++++++------------------- gui/message.h | 7 +++++- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/gui/message.cpp b/gui/message.cpp index 656c271bbcc..eb4abaabf3c 100644 --- a/gui/message.cpp +++ b/gui/message.cpp @@ -41,7 +41,7 @@ enum { void MessageDialog::init(const Common::U32String &message, const Common::U32String &defaultButton, - const Common::U32String &altButton, + const Common::U32StringArray &altButtons, Graphics::TextAlign alignment, const char *url) { _url = url; @@ -57,19 +57,19 @@ void MessageDialog::init(const Common::U32String &message, // Using this, and accounting for the space the button(s) need, we can set // the real size of the dialog Common::Array lines; - int lineCount, okButtonPos, cancelButtonPos; + int lineCount; int maxlineWidth = g_gui.getFont().wordWrapText(message, screenW - 2 * 20, lines); + const int buttonCount = altButtons.size() + 1; + const int buttonSpacing = 10; + const int buttonsTotalWidth = buttonCount * buttonWidth + (buttonCount - 1) * buttonSpacing; // Calculate the desired dialog size (maxing out at 300*180 for now) - if (!altButton.empty()) - _w = MAX(maxlineWidth, (2 * buttonWidth) + 10) + 20; - else - _w = MAX(maxlineWidth, buttonWidth) + 20; + _w = MAX(maxlineWidth, buttonsTotalWidth + 20); lineCount = lines.size(); _h = 16; - if (!defaultButton.empty() || !altButton.empty()) + if (!defaultButton.empty() || !altButtons.empty()) _h += buttonHeight + 8; // Limit the number of lines so that the dialog still fits on the screen. @@ -87,21 +87,20 @@ void MessageDialog::init(const Common::U32String &message, new StaticTextWidget(this, 10, 10 + i * kLineHeight, maxlineWidth, kLineHeight, lines[i], alignment); } - if (!defaultButton.empty() && !altButton.empty()) { - okButtonPos = (_w - (buttonWidth * 2)) / 2; - cancelButtonPos = ((_w - (buttonWidth * 2)) / 2) + buttonWidth + 10; - } else { - okButtonPos = cancelButtonPos = (_w - buttonWidth) / 2; - } + // Assume defaultButton is always given + int buttonPos = (_w - buttonsTotalWidth) / 2; if (!defaultButton.empty()) { // Confirm dialog - new ButtonWidget(this, okButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, defaultButton, Common::U32String(), kDefaultCmd, Common::ASCII_RETURN); + new ButtonWidget(this, buttonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, defaultButton, Common::U32String(), kDefaultCmd, Common::ASCII_RETURN); + buttonPos += buttonWidth + buttonSpacing; } - if (!altButton.empty()) { - // Cancel dialog - new ButtonWidget(this, cancelButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, altButton, Common::U32String(), kAltCmd, Common::ASCII_ESCAPE); + int buttonHotKey = altButtons.size() == 1 ? Common::ASCII_ESCAPE : 0; + for (size_t i = 0, total = altButtons.size(); i < total; ++i) { + new ButtonWidget(this, buttonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, altButtons[i], Common::U32String(), kAltCmd + i, buttonHotKey); + buttonHotKey = 0; + buttonPos += buttonWidth + buttonSpacing; } } @@ -112,7 +111,9 @@ MessageDialog::MessageDialog(const Common::U32String &message, const char *url) : Dialog(30, 20, 260, 124) { - init(message, defaultButton, altButton, alignment, url); + init(message, defaultButton, + altButton.empty() ? Common::U32StringArray() : Common::U32StringArray(1, altButton), + alignment, url); } MessageDialog::MessageDialog(const Common::String &message, @@ -122,22 +123,34 @@ MessageDialog::MessageDialog(const Common::String &message, const char *url) : Dialog(30, 20, 260, 124) { - init(Common::U32String(message), Common::U32String(defaultButton), Common::U32String(altButton), alignment, url); + init(Common::U32String(message), Common::U32String(defaultButton), + altButton.empty() ? Common::U32StringArray() : Common::U32StringArray(1, Common::U32String(altButton)), + alignment, url); +} + +MessageDialog::MessageDialog(const Common::U32String &message, + const Common::U32String &defaultButton, + const Common::U32StringArray &altButtons, + Graphics::TextAlign alignment) + : Dialog(30, 20, 260, 124) { + + init(message, defaultButton, altButtons, alignment, nullptr); } void MessageDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - // FIXME: It's a really bad thing that we use two arbitrary constants if (cmd == kDefaultCmd) { setResult(kMessageOK); close(); - } else if (cmd == kAltCmd) { + return; + } + if (cmd >= kAltCmd) { if (_url) { if (g_system->hasFeature(OSystem::kFeatureOpenUrl)) g_system->openUrl(_url); setResult(kMessageOK); } else { - setResult(kMessageAlt); + setResult(kMessageAlt + cmd - kAltCmd); } close(); } else { diff --git a/gui/message.h b/gui/message.h index 87c22cd0ddc..db5e1b1b29f 100644 --- a/gui/message.h +++ b/gui/message.h @@ -25,6 +25,7 @@ #include "gui/dialog.h" #include "common/str.h" +#include "common/str-array.h" namespace GUI { @@ -51,13 +52,17 @@ public: const Common::String &altButton = Common::String(), Graphics::TextAlign alignment = Graphics::kTextAlignCenter, const char *url = nullptr); + MessageDialog(const Common::U32String &message, + const Common::U32String &defaultButton, + const Common::U32StringArray &altButtons, + Graphics::TextAlign alignment = Graphics::kTextAlignCenter); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override; private: const char *_url; void init(const Common::U32String &message, const Common::U32String &defaultButton, - const Common::U32String &altButton, + const Common::U32StringArray &altButtons, Graphics::TextAlign alignment, const char *url); };