namespace Terminal.Gui.Views; /// /// Displays a modal message box with a title, message, and buttons. Returns the index of the selected button, /// or if the user cancels with . /// /// /// /// MessageBox provides static methods for displaying modal dialogs with customizable buttons and messages. /// All methods return where the value is the 0-based index of the button pressed, /// or if the user pressed (typically Esc). /// /// /// uses the default Dialog color scheme. /// uses the Error color scheme. /// /// /// Important: All MessageBox methods require an instance to be passed. /// This enables proper modal dialog management and respects the application's lifecycle. Pass your /// application instance (from ) or use the legacy /// if using the static Application pattern. /// /// /// Example using instance-based pattern: /// /// IApplication app = Application.Create(); /// app.Init(); /// /// int? result = MessageBox.Query(app, "Quit Demo", "Are you sure you want to quit?", "Yes", "No"); /// if (result == 0) // User clicked "Yes" /// app.RequestStop(); /// else if (result == null) // User pressed Esc /// // Handle cancellation /// /// app.Shutdown(); /// /// /// /// Example using legacy static pattern: /// /// Application.Init(); /// /// int? result = MessageBox.Query(ApplicationImpl.Instance, "Quit Demo", "Are you sure?", "Yes", "No"); /// if (result == 0) // User clicked "Yes" /// Application.RequestStop(); /// /// Application.Shutdown(); /// /// /// /// The property provides a global variable alternative for web-based consoles /// without SynchronizationContext. However, using the return value is preferred as it's more thread-safe /// and follows modern async patterns. /// /// public static class MessageBox { private static LineStyle _defaultBorderStyle = LineStyle.Heavy; // Resources/config.json overrides private static Alignment _defaultButtonAlignment = Alignment.Center; // Resources/config.json overrides private static int _defaultMinimumWidth = 0; // Resources/config.json overrides private static int _defaultMinimumHeight = 0; // Resources/config.json overrides /// /// Defines the default border styling for . Can be configured via /// . /// [ConfigurationProperty (Scope = typeof (ThemeScope))] public static LineStyle DefaultBorderStyle { get => _defaultBorderStyle; set => _defaultBorderStyle = value; } /// The default for . /// This property can be set in a Theme. [ConfigurationProperty (Scope = typeof (ThemeScope))] public static Alignment DefaultButtonAlignment { get => _defaultButtonAlignment; set => _defaultButtonAlignment = value; } /// /// Defines the default minimum MessageBox width, as a percentage of the screen width. Can be configured via /// . /// [ConfigurationProperty (Scope = typeof (ThemeScope))] public static int DefaultMinimumWidth { get => _defaultMinimumWidth; set => _defaultMinimumWidth = value; } /// /// Defines the default minimum Dialog height, as a percentage of the screen width. Can be configured via /// . /// [ConfigurationProperty (Scope = typeof (ThemeScope))] public static int DefaultMinimumHeight { get => _defaultMinimumHeight; set => _defaultMinimumHeight = value; } /// /// The index of the selected button, or if the user pressed . /// /// /// This global variable is useful for web-based consoles without a SynchronizationContext or TaskScheduler. /// Warning: Not thread-safe. /// public static int? Clicked { get; private set; } /// /// Displays an error with fixed dimensions. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically sizes the /// MessageBox. /// public static int? ErrorQuery ( IApplication? app, int width, int height, string title, string message, params string [] buttons ) { return QueryFull ( app, true, width, height, title, message, 0, true, buttons); } /// /// Displays an auto-sized error . /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? ErrorQuery (IApplication? app, string title, string message, params string [] buttons) { return QueryFull ( app, true, 0, 0, title, message, 0, true, buttons); } /// /// Displays an error with fixed dimensions and a default button. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Index of the default button (0-based). /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically sizes the /// MessageBox. /// public static int? ErrorQuery ( IApplication? app, int width, int height, string title, string message, int defaultButton = 0, params string [] buttons ) { return QueryFull ( app, true, width, height, title, message, defaultButton, true, buttons); } /// /// Displays an auto-sized error with a default button. /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Index of the default button (0-based). /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? ErrorQuery (IApplication? app, string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull ( app, true, 0, 0, title, message, defaultButton, true, buttons); } /// /// Displays an error with fixed dimensions, a default button, and word-wrap control. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines. /// Index of the default button (0-based). /// /// If , word-wraps the message; otherwise displays as-is with multi-line /// support. /// /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically /// sizes the MessageBox. /// public static int? ErrorQuery ( IApplication? app, int width, int height, string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons ) { return QueryFull ( app, true, width, height, title, message, defaultButton, wrapMessage, buttons); } /// /// Displays an auto-sized error with a default button and word-wrap control. /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines. /// Index of the default button (0-based). /// /// If , word-wraps the message; otherwise displays as-is with multi-line /// support. /// /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? ErrorQuery ( IApplication? app, string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons ) { return QueryFull ( app, true, 0, 0, title, message, defaultButton, wrapMessage, buttons); } /// /// Displays a with fixed dimensions. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically sizes the /// MessageBox. /// public static int? Query (IApplication? app, int width, int height, string title, string message, params string [] buttons) { return QueryFull ( app, false, width, height, title, message, 0, true, buttons); } /// /// Displays an auto-sized . /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? Query (IApplication? app, string title, string message, params string [] buttons) { return QueryFull ( app, false, 0, 0, title, message, 0, true, buttons); } /// /// Displays a with fixed dimensions and a default button. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Index of the default button (0-based). /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically sizes the /// MessageBox. /// public static int? Query ( IApplication? app, int width, int height, string title, string message, int defaultButton = 0, params string [] buttons ) { return QueryFull ( app, false, width, height, title, message, defaultButton, true, buttons); } /// /// Displays an auto-sized with a default button. /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines and will be word-wrapped. /// Index of the default button (0-based). /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? Query (IApplication? app, string title, string message, int defaultButton = 0, params string [] buttons) { return QueryFull ( app, false, 0, 0, title, message, defaultButton, true, buttons); } /// /// Displays a with fixed dimensions, a default button, and word-wrap control. /// /// The application instance. If , uses . /// Width for the MessageBox. /// Height for the MessageBox. /// Title for the MessageBox. /// Message to display. May contain multiple lines. /// Index of the default button (0-based). /// /// If , word-wraps the message; otherwise displays as-is with multi-line /// support. /// /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// Consider using which automatically sizes /// the MessageBox. /// public static int? Query ( IApplication? app, int width, int height, string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons ) { return QueryFull ( app, false, width, height, title, message, defaultButton, wrapMessage, buttons); } /// /// Displays an auto-sized with a default button and word-wrap control. /// /// The application instance. If , uses . /// Title for the MessageBox. /// Message to display. May contain multiple lines. /// Index of the default button (0-based). /// /// If , word-wraps the message; otherwise displays as-is with multi-line /// support. /// /// Array of button labels. /// /// The index of the selected button, or if the user pressed /// . /// /// Thrown if is . /// /// The MessageBox is centered and auto-sized based on title, message, and buttons. /// public static int? Query ( IApplication? app, string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons ) { return QueryFull ( app, false, 0, 0, title, message, defaultButton, wrapMessage, buttons); } private static int? QueryFull ( IApplication? app, bool useErrorColors, int width, int height, string title, string message, int defaultButton = 0, bool wrapMessage = true, params string [] buttons ) { ArgumentNullException.ThrowIfNull (app); // Create button array for Dialog var count = 0; List