diff options
Diffstat (limited to 'core/src/Utils/Dialog')
-rw-r--r-- | core/src/Utils/Dialog/Dialog.cpp | 18 | ||||
-rw-r--r-- | core/src/Utils/Dialog/Dialog.hpp | 52 | ||||
-rw-r--r-- | core/src/Utils/Dialog/Dialog_linux.cpp | 83 | ||||
-rw-r--r-- | core/src/Utils/Dialog/Dialog_macos.mm | 113 | ||||
-rw-r--r-- | core/src/Utils/Dialog/Dialog_win32.cpp | 64 | ||||
-rw-r--r-- | core/src/Utils/Dialog/fwd.hpp | 1 |
6 files changed, 331 insertions, 0 deletions
diff --git a/core/src/Utils/Dialog/Dialog.cpp b/core/src/Utils/Dialog/Dialog.cpp new file mode 100644 index 0000000..c4459c0 --- /dev/null +++ b/core/src/Utils/Dialog/Dialog.cpp @@ -0,0 +1,18 @@ +// Adapted from https://github.com/aaronmjacobs/Boxer/blob/master/include/boxer/boxer.h
+#include "Dialog.hpp"
+
+namespace Dialog {
+
+Selection Show(const char* message, const char* title, Style style) {
+ return Show(message, title, style, kDefaultButtons);
+}
+
+Selection Show(const char* message, const char* title, Buttons buttons) {
+ return Show(message, title, kDefaultStyle, buttons);
+}
+
+Selection Show(const char* message, const char* title) {
+ return Show(message, title, kDefaultStyle, kDefaultButtons);
+}
+
+} // namespace Dialog
diff --git a/core/src/Utils/Dialog/Dialog.hpp b/core/src/Utils/Dialog/Dialog.hpp new file mode 100644 index 0000000..e8989e3 --- /dev/null +++ b/core/src/Utils/Dialog/Dialog.hpp @@ -0,0 +1,52 @@ +// Adapted from https://github.com/aaronmjacobs/Boxer/blob/master/include/boxer/boxer.h
+#pragma once
+
+namespace Dialog {
+
+/// Options for styles to apply to a message box.
+enum class Style {
+ Info,
+ Warning,
+ Error,
+ Question,
+};
+
+/// Options for buttons to provide on a message box.
+enum class Buttons {
+ OK,
+ OKCancel,
+ YesNo,
+ Quit,
+};
+
+/// Possible responses from a message box. 'None' signifies that no option was chosen, and 'Error' signifies that an
+/// error was encountered while creating the message box.
+enum class Selection {
+ OK,
+ Cancel,
+ Yes,
+ No,
+ Quit,
+ None,
+ Error,
+};
+
+/// The default style to apply to a message box.
+constexpr Style kDefaultStyle = Style::Info;
+
+/// The default buttons to provide on a message box.
+constexpr Buttons kDefaultButtons = Buttons::OK;
+
+/// Blocking call to create a modal message box with the given message, title, style, and buttons.
+Selection Show(const char* message, const char* title, Style style, Buttons buttons);
+
+/// Convenience function to call show() with the default buttons.
+Selection Show(const char* message, const char* title, Style style);
+
+/// Convenience function to call show() with the default style.
+Selection Show(const char* message, const char* title, Buttons buttons);
+
+/// Convenience function to call show() with the default style and buttons.
+Selection Show(const char* message, const char* title);
+
+} // namespace Dialog
diff --git a/core/src/Utils/Dialog/Dialog_linux.cpp b/core/src/Utils/Dialog/Dialog_linux.cpp new file mode 100644 index 0000000..11c3cee --- /dev/null +++ b/core/src/Utils/Dialog/Dialog_linux.cpp @@ -0,0 +1,83 @@ +// Adapted from https://github.com/aaronmjacobs/Boxer/blob/master/src/boxer_linux.cpp
+#include "Dialog.hpp"
+
+#include <gtk/gtk.h>
+
+namespace Dialog {
+namespace {
+
+ GtkMessageType GetMessageType(Style style) {
+ switch (style) {
+ case Style::Info:
+ return GTK_MESSAGE_INFO;
+ case Style::Warning:
+ return GTK_MESSAGE_WARNING;
+ case Style::Error:
+ return GTK_MESSAGE_ERROR;
+ case Style::Question:
+ return GTK_MESSAGE_QUESTION;
+ default:
+ return GTK_MESSAGE_INFO;
+ }
+ }
+
+ GtkButtonsType GetButtonsType(Buttons buttons) {
+ switch (buttons) {
+ case Buttons::OK:
+ return GTK_BUTTONS_OK;
+ case Buttons::OKCancel:
+ return GTK_BUTTONS_OK_CANCEL;
+ case Buttons::YesNo:
+ return GTK_BUTTONS_YES_NO;
+ case Buttons::Quit:
+ return GTK_BUTTONS_CLOSE;
+ default:
+ return GTK_BUTTONS_OK;
+ }
+ }
+
+ Selection getSelection(gint response) {
+ switch (response) {
+ case GTK_RESPONSE_OK:
+ return Selection::OK;
+ case GTK_RESPONSE_CANCEL:
+ return Selection::Cancel;
+ case GTK_RESPONSE_YES:
+ return Selection::Yes;
+ case GTK_RESPONSE_NO:
+ return Selection::No;
+ case GTK_RESPONSE_CLOSE:
+ return Selection::Quit;
+ default:
+ return Selection::None;
+ }
+ }
+
+} // namespace
+
+Selection Show(const char* message, const char* title, Style style, Buttons buttons) {
+ if (!gtk_init_check(0, nullptr)) {
+ return Selection::Error;
+ }
+
+ // Create a parent window to stop gtk_dialog_run from complaining
+ GtkWidget* parent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+ GTK_DIALOG_MODAL,
+ GetMessageType(style),
+ GetButtonsType(buttons),
+ "%s",
+ message);
+ gtk_window_set_title(GTK_WINDOW(dialog), title);
+ Selection selection = getSelection(gtk_dialog_run(GTK_DIALOG(dialog)));
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ gtk_widget_destroy(GTK_WIDGET(parent));
+ while (g_main_context_iteration(nullptr, false)) {
+ // Do nothing
+ }
+
+ return selection;
+}
+} // namespace Dialog
diff --git a/core/src/Utils/Dialog/Dialog_macos.mm b/core/src/Utils/Dialog/Dialog_macos.mm new file mode 100644 index 0000000..c0164a0 --- /dev/null +++ b/core/src/Utils/Dialog/Dialog_macos.mm @@ -0,0 +1,113 @@ +// Adapted from https://github.com/aaronmjacobs/Boxer/blob/master/src/boxer_osx.mm
+#include "Dialog.hpp"
+
+#import <Cocoa/Cocoa.h>
+
+namespace Dialog {
+namespace {
+
+ NSString* const kOkStr = @"OK";
+ NSString* const kCancelStr = @"Cancel";
+ NSString* const kYesStr = @"Yes";
+ NSString* const kNoStr = @"No";
+ NSString* const kQuitStr = @"Quit";
+
+ NSAlertStyle GetAlertStyle(Style style) {
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
+ switch (style) {
+ case Style::Info:
+ return NSAlertStyleInformational;
+ case Style::Warning:
+ return NSAlertStyleWarning;
+ case Style::Error:
+ return NSAlertStyleCritical;
+ case Style::Question:
+ return NSAlertStyleWarning;
+ default:
+ return NSAlertStyleInformational;
+ }
+#else
+ switch (style) {
+ case Style::Info:
+ return NSInformationalAlertStyle;
+ case Style::Warning:
+ return NSWarningAlertStyle;
+ case Style::Error:
+ return NSCriticalAlertStyle;
+ case Style::Question:
+ return NSWarningAlertStyle;
+ default:
+ return NSInformationalAlertStyle;
+ }
+#endif
+ }
+
+ void SetButtons(NSAlert* alert, Buttons buttons) {
+ switch (buttons) {
+ case Buttons::OK:
+ [alert addButtonWithTitle:kOkStr];
+ break;
+ case Buttons::OKCancel:
+ [alert addButtonWithTitle:kOkStr];
+ [alert addButtonWithTitle:kCancelStr];
+ break;
+ case Buttons::YesNo:
+ [alert addButtonWithTitle:kYesStr];
+ [alert addButtonWithTitle:kNoStr];
+ break;
+ case Buttons::Quit:
+ [alert addButtonWithTitle:kQuitStr];
+ break;
+ default:
+ [alert addButtonWithTitle:kOkStr];
+ }
+ }
+
+ Selection GetSelection(int index, Buttons buttons) {
+ switch (buttons) {
+ case Buttons::OK:
+ return index == NSAlertFirstButtonReturn ? Selection::OK : Selection::None;
+ case Buttons::OKCancel:
+ if (index == NSAlertFirstButtonReturn) {
+ return Selection::OK;
+ } else if (index == NSAlertSecondButtonReturn) {
+ return Selection::Cancel;
+ } else {
+ return Selection::None;
+ }
+ case Buttons::YesNo:
+ if (index == NSAlertFirstButtonReturn) {
+ return Selection::Yes;
+ } else if (index == NSAlertSecondButtonReturn) {
+ return Selection::No;
+ } else {
+ return Selection::None;
+ }
+ case Buttons::Quit:
+ return index == NSAlertFirstButtonReturn ? Selection::Quit : Selection::None;
+ default:
+ return Selection::None;
+ }
+ }
+
+} // namespace
+
+Selection show(const char* message, const char* title, Style style, Buttons buttons) {
+ NSAlert* alert = [[NSAlert alloc] init];
+
+ [alert setMessageText:[NSString stringWithCString:title encoding:[NSString defaultCStringEncoding]]];
+ [alert setInformativeText:[NSString stringWithCString:message encoding:[NSString defaultCStringEncoding]]];
+
+ [alert setAlertStyle:GetAlertStyle(style)];
+ SetButtons(alert, buttons);
+
+ // Force the alert to appear on top of any other windows
+ [[alert window] setLevel:NSModalPanelWindowLevel];
+
+ Selection selection = GetSelection([alert runModal], buttons);
+ [alert release];
+
+ return selection;
+}
+
+} // namespace Dialog
diff --git a/core/src/Utils/Dialog/Dialog_win32.cpp b/core/src/Utils/Dialog/Dialog_win32.cpp new file mode 100644 index 0000000..b82f382 --- /dev/null +++ b/core/src/Utils/Dialog/Dialog_win32.cpp @@ -0,0 +1,64 @@ +// Adapted from https://github.com/aaronmjacobs/Boxer/blob/master/src/boxer_win.cpp
+#include "Dialog.hpp"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+namespace Dialog {
+namespace {
+
+ UINT GetIcon(Style style) {
+ switch (style) {
+ case Style::Info:
+ return MB_ICONINFORMATION;
+ case Style::Warning:
+ return MB_ICONWARNING;
+ case Style::Error:
+ return MB_ICONERROR;
+ case Style::Question:
+ return MB_ICONQUESTION;
+ default:
+ return MB_ICONINFORMATION;
+ }
+ }
+
+ UINT GetButtons(Buttons buttons) {
+ switch (buttons) {
+ case Buttons::OK:
+ case Buttons::Quit: // There is no 'Quit' button on Windows :(
+ return MB_OK;
+ case Buttons::OKCancel:
+ return MB_OKCANCEL;
+ case Buttons::YesNo:
+ return MB_YESNO;
+ default:
+ return MB_OK;
+ }
+ }
+
+ Selection GetSelection(int response, Buttons buttons) {
+ switch (response) {
+ case IDOK:
+ return buttons == Buttons::Quit ? Selection::Quit : Selection::OK;
+ case IDCANCEL:
+ return Selection::Cancel;
+ case IDYES:
+ return Selection::Yes;
+ case IDNO:
+ return Selection::No;
+ default:
+ return Selection::None;
+ }
+ }
+
+} // namespace
+
+Selection Show(const char* message, const char* title, Style style, Buttons buttons) {
+ UINT flags = MB_TASKMODAL;
+
+ flags |= GetIcon(style);
+ flags |= GetButtons(buttons);
+
+ return GetSelection(MessageBox(nullptr, message, title, flags), buttons);
+}
+} // namespace Dialog
diff --git a/core/src/Utils/Dialog/fwd.hpp b/core/src/Utils/Dialog/fwd.hpp new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/core/src/Utils/Dialog/fwd.hpp @@ -0,0 +1 @@ +#pragma once
|