1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-02 08:39:46 +02:00

Define BasicUI::ShowMessageBox

This commit is contained in:
Paul Licameli 2021-02-09 12:50:27 -05:00
parent a656c9ce1a
commit 14ad405b04
4 changed files with 150 additions and 3 deletions

View File

@ -8,7 +8,6 @@ Paul Licameli
**********************************************************************/
#include "BasicUI.h"
#include "Internat.h"
#include <mutex>
#include <vector>

View File

@ -13,8 +13,7 @@ Paul Licameli
#include <functional>
#include "Identifier.h"
class TranslatableString;
#include "Internat.h"
namespace BasicUI {
@ -74,6 +73,66 @@ struct ErrorDialogOptions {
//! "Message", suitably translated
BASIC_UI_API TranslatableString DefaultCaption();
enum class Icon {
None,
Warning,
Error,
Question,
Information,
};
enum class Button {
Default, //!< Like Ok, except maybe minor difference of dialog position
Ok, //!< One button
YesNo //!< Two buttons
};
struct MessageBoxOptions {
//! @name Chain-call style initializers
//! @{
MessageBoxOptions &&Parent(WindowPlacement *parent_) &&
{ parent = parent_; return std::move(*this); }
MessageBoxOptions &&Caption(TranslatableString caption_) &&
{ caption = std::move(caption_); return std::move(*this); }
MessageBoxOptions &&IconStyle(Icon style) &&
{ iconStyle = style; return std::move(*this); }
MessageBoxOptions &&ButtonStyle(Button style) &&
{ buttonStyle = style; return std::move(*this); }
//! Override the usual defaulting to Yes; affects only the YesNo case
MessageBoxOptions &&DefaultIsNo() &&
{ yesOrOkDefaultButton = false; return std::move(*this); }
MessageBoxOptions &&CancelButton() &&
{ cancelButton = true; return std::move(*this); }
//! Center the dialog on its parent window, if any
MessageBoxOptions &&Centered() &&
{ centered = true; return std::move(*this); }
//! @}
WindowPlacement *parent{ nullptr };
TranslatableString caption{ DefaultCaption() };
Icon iconStyle{ Icon::None };
Button buttonStyle{ Button::Default };
bool yesOrOkDefaultButton{ true };
bool cancelButton{ false };
bool centered{ false };
};
enum class MessageBoxResult : int {
None, //!< May be returned if no Services are installed
Yes,
No,
Ok,
Cancel,
};
//! @}
//! Abstract class defines a few user interface services, not mentioning particular toolkits
@ -90,6 +149,9 @@ public:
const TranslatableString &message,
const ManualPageID &helpPage,
const ErrorDialogOptions &options) = 0;
virtual MessageBoxResult DoMessageBox(
const TranslatableString& message,
MessageBoxOptions options) = 0;
};
//! Fetch the global instance, or nullptr if none is yet installed
@ -132,6 +194,19 @@ inline void ShowErrorDialog(
p->DoShowErrorDialog(placement, dlogTitle, message, helpPage, options);
}
//! Show a modal message box with either Ok or Yes and No, and optionally Cancel
/*!
@return indicates which button was pressed
*/
inline MessageBoxResult ShowMessageBox( const TranslatableString &message,
MessageBoxOptions options = {})
{
if (auto p = Get())
return p->DoMessageBox(message, std::move(options));
else
return MessageBoxResult::None;
}
//! @}
}

View File

@ -13,6 +13,7 @@ Paul Licameli
#ifdef HAS_SENTRY_REPORTING
#include "widgets/ErrorReportDialog.h"
#endif
#include "widgets/AudacityMessageBox.h"
#include <wx/app.h>
using namespace BasicUI;
@ -88,3 +89,72 @@ void wxWidgetsBasicUI::DoShowErrorDialog(
pDlog.release(); // not a memory leak, because it has a parent
}
}
BasicUI::MessageBoxResult
wxWidgetsBasicUI::DoMessageBox(
const TranslatableString &message,
MessageBoxOptions options)
{
// Compute the style argument to pass to wxWidgets
long style = 0;
switch (options.iconStyle) {
case Icon::Warning :
style = wxICON_WARNING;
break;
case Icon::Error :
style = wxICON_ERROR;
break;
case Icon::Question :
style = wxICON_QUESTION;
break;
case Icon::Information :
style = wxICON_INFORMATION;
break;
default:
break;
}
switch (options.buttonStyle) {
case Button::Ok :
style |= wxOK;
break;
case Button::YesNo :
style |= wxYES_NO;
break;
default:
break;
}
if (!options.yesOrOkDefaultButton && options.buttonStyle == Button::YesNo)
style |= wxNO_DEFAULT;
if (options.cancelButton)
style |= wxCANCEL;
if (options.centered)
style |= wxCENTER;
// Preserving the default style AudacityMessageBox had,
// when none of the above were explicitly specified
if (!style)
style = wxOK | wxCENTRE;
// This calls through to ::wxMessageBox:
auto wxResult =
::AudacityMessageBox(message, options.caption, style,
options.parent ? GetParent(*options.parent) : nullptr);
// This switch exhausts all possibilities for the return from::wxMessageBox.
// see utilscmn.cpp in wxWidgets.
// Remap to our toolkit-neutral enumeration.
switch (wxResult) {
case wxID_YES:
return MessageBoxResult::Yes;
case wxID_NO:
return MessageBoxResult::No;
case wxID_OK:
return MessageBoxResult::Ok;
case wxID_CANCEL:
return MessageBoxResult::Cancel;
case wxID_HELP:
// should not happen, because we don't ever pass wxHELP
default:
wxASSERT(false);
return MessageBoxResult::None;
}
}

View File

@ -41,6 +41,9 @@ protected:
const TranslatableString &message,
const ManualPageID &helpPage,
const BasicUI::ErrorDialogOptions &options) override;
BasicUI::MessageBoxResult DoMessageBox(
const TranslatableString &message,
BasicUI::MessageBoxOptions options) override;
};
#endif