dialog

Native-only message dialogs for MoonBit on Windows, macOS, and Linux.

dialog
gui
native
message-box
moon add justjavac/dialog@0.1.4
Download zip
Author
Version
0.1.4
License
MIT
Last updated
2 months ago
Downloads
37
README

#justjavac/dialog

coverage linux macos windows

Native-only dialogs and path pickers for MoonBit.

  • Windows uses Win32 message and file dialogs.
  • macOS uses CoreFoundation alerts and AppleScript path pickers.
  • Linux tries zenity, then kdialog, then xmessage for message dialogs.

let dialog = @dialog.MessageDialog::new(
"Build finished successfully.",
title="moonbit-dialog",
level=Info,
)

let confirm = @dialog.ConfirmDialog::new(
"Overwrite the generated files?",
)

let choice = @dialog.ChoiceDialog::new(
"Save changes before closing?",
buttons=YesNoCancel,
level=Question,
)

let relabeled = @dialog.MessageDialog::new(
"Build finished successfully.",
).with_labels(@dialog.DialogLabels::ok("Open report"))

match @dialog.open_file(directory="C:/Projects") {
Ok(outcome) => ignore(outcome)
Err(error) => ignore(error)
}

let filters = [
@dialog.FileFilter::new("Text Files", ["*.txt", "*.md"]),
@dialog.FileFilter::new("All Files", ["*"]),
]

let save_dialog = @dialog.SaveFileDialog::new(file_name="report")
.with_filters(filters)
.with_default_extension("txt")

let open_many = @dialog.OpenFilesDialog::new(directory="C:/Projects")
.with_filters([
@dialog.FileFilter::new("Sources", ["*.mbt", "*.c", "*.h"]),
])

#
ChoiceDialog

pub struct ChoiceDialog {
title : String
message : String
level : DialogLevel
buttons : DialogButtons
labels : DialogLabels
} derive(Eq,
Debug
)

A generic dialog request with one of the standard button combinations.

#
ChoiceDialog::new

fn ChoiceDialog::new(message : StringView, title? : StringView, buttons? : DialogButtons, level? : DialogLevel) -> ChoiceDialog

Create a generic dialog request with a standard button combination.

title defaults to "Dialog", buttons defaults to Ok, and level defaults to Info.

The returned dialog starts with DialogLabels::none() and can be refined with with_labels before it is shown.

This builder is the most general request type in the package and is useful when the button layout itself is part of the caller's configuration.

#
ChoiceDialog::show

fn ChoiceDialog::show(self : ChoiceDialog) -> Result[DialogOutcome, DialogError]

Show a dialog and return the backend plus the selected response.

This method uses the configured button combination and any custom labels, while preserving the backend information for diagnostics or analytics.

The response inside DialogOutcome is interpreted relative to the chosen DialogButtons, letting one typed result model cover all standard layouts.

#
ChoiceDialog::with_labels

fn ChoiceDialog::with_labels(self : ChoiceDialog, labels : DialogLabels) -> ChoiceDialog

Attach custom labels to a generic dialog.

This returns a new dialog value and leaves the original unchanged. Unsupported backends keep their native default captions.

The stored labels are mapped according to the dialog's buttons layout when ChoiceDialog::show runs.

#
ConfirmDialog

pub struct ConfirmDialog {
title : String
message : String
level : DialogLevel
labels : DialogLabels
} derive(Eq,
Debug
)

A yes-or-no confirmation dialog request.

#
ConfirmDialog::new

fn ConfirmDialog::new(message : StringView, title? : StringView, level? : DialogLevel) -> ConfirmDialog

Create a yes-or-no confirmation dialog request.

title defaults to "Confirm" and level defaults to Question.

The dialog starts with DialogLabels::none(), which keeps native button captions until callers explicitly override them with with_labels.

Like the other dialog builders, this only stores request data and does not interact with the operating system until show is invoked.

#
ConfirmDialog::show

Show a confirmation dialog and return both the backend and the response.

The result distinguishes which backend handled the request and whether the user picked the affirmative or negative action.

Successful outcomes normally use Yes or No, while transport and native failures are surfaced separately through Err(DialogError).

#
ConfirmDialog::with_labels

fn ConfirmDialog::with_labels(self : ConfirmDialog, labels : DialogLabels) -> ConfirmDialog

Attach custom labels to a confirmation dialog.

This returns a new dialog value and leaves the original unchanged. Unsupported backends keep their native default captions.

DialogLabels::yes_no is usually the most natural companion for this API, though all label helpers write into the same underlying slots.

#
DialogBackend

pub(all) enum DialogBackend {
WindowsWin32
MacOSCoreFoundation
MacOSAppleScript
LinuxZenity
LinuxKDialog
LinuxXMessage
} derive(Eq,
Debug
)

The concrete backend that displayed a message dialog.

Windows and macOS use direct native APIs, while Linux tries several common desktop helpers without going through a shell.

#
DialogButtons

pub(all) enum DialogButtons {
Ok
OkCancel
YesNo
YesNoCancel
} derive(Eq,
Debug
)

The standard button combinations supported by the generic dialog API.

#
DialogError

pub(all) enum DialogError {
UnsupportedPlatform(Platform)
BackendUnavailable(Platform)
BackendFailed(DialogBackend, Int)
} derive(Eq,
Debug
)

Errors returned when a dialog cannot be shown.

  • UnsupportedPlatform means the current OS is outside the current scope.
  • BackendUnavailable means no supported Linux dialog helper was found.
  • BackendFailed means a chosen backend or native API reported failure.

#
DialogLabels

pub struct DialogLabels {
accept : String
reject : String
cancel : String
} derive(Eq,
Debug
)

Optional custom labels for the standard dialog buttons.

The accept label is used for Ok or Yes, reject is used for No, and cancel is used for Cancel.

#
DialogLabels::none

Create an empty label override set that keeps backend defaults.

This is useful when building dialogs incrementally and wanting to reset any previously configured custom captions.

Passing the returned value to with_labels is equivalent to opting back into native button text for whichever backend eventually shows the dialog.

#
DialogLabels::ok

fn DialogLabels::ok(label : StringView) -> DialogLabels

Create a label override set for one-button dialogs.

The value is stored in the accept slot, which is used for Ok in message dialogs and the affirmative action in other single-button flows.

This helper is primarily intended for MessageDialog or generic dialogs that use the Ok button layout.

#
DialogLabels::ok_cancel

fn DialogLabels::ok_cancel(ok_label : StringView, cancel_label : StringView) -> DialogLabels

Create a label override set for OK-cancel dialogs.

ok_label is mapped to the accept button and cancel_label is mapped to the cancel button, while the reject slot remains unused.

Backends that do not support relabeling ignore these values and keep their native captions, so callers can pair this with supports_custom_labels.

#
DialogLabels::yes_no

fn DialogLabels::yes_no(yes_label : StringView, no_label : StringView) -> DialogLabels

Create a label override set for yes-no dialogs.

yes_label is stored as the accept caption and no_label is stored as the reject caption.

This mapping matches the response model used by ConfirmDialog and generic dialogs with the YesNo layout.

#
DialogLabels::yes_no_cancel

fn DialogLabels::yes_no_cancel(yes_label : StringView, no_label : StringView, cancel_label : StringView) -> DialogLabels

Create a label override set for yes-no-cancel dialogs.

This fills all three standard caption slots so a dialog can fully override its affirmative, negative, and cancel labels where the backend allows it.

It is useful when a flow needs domain-specific wording such as "Save", "Discard", and "Stay" instead of generic yes/no/cancel captions.

#
DialogLevel

pub(all) enum DialogLevel {
Info
Warning
Error
Question
} derive(Eq,
Debug
)

The requested severity or intent of a dialog.

Backends map these levels to the closest native icon or emphasis style they support.

#
DialogOutcome

pub struct DialogOutcome {
backend : DialogBackend
response : DialogResponse
} derive(Eq,
Debug
)

A completed dialog result including the backend and the chosen response.

#
DialogResponse

pub(all) enum DialogResponse {
Ok
Cancel
Yes
No
} derive(Eq,
Debug
)

The user's response to a dialog.

#
FileFilter

pub struct FileFilter {
name : String
patterns : Array[String]
} derive(Eq,
Debug
)

A named set of filename patterns for open/save dialogs.

#
FileFilter::new

fn FileFilter::new(name : StringView, patterns : Array[String]) -> FileFilter

Create a named file filter for open/save dialogs.

patterns is copied defensively so later mutations to the caller-owned array do not affect the dialog request. Backends may ignore filters that do not contain any patterns.

Typical patterns look like "*.txt" or "*.png", and several patterns can be grouped under the same display name.

#
MessageDialog

pub struct MessageDialog {
title : String
message : String
level : DialogLevel
labels : DialogLabels
} derive(Eq,
Debug
)

A message dialog request.

This type keeps the public API explicit and easy to extend later when the module grows beyond a single message box implementation.

#
MessageDialog::new

fn MessageDialog::new(message : StringView, title? : StringView, level? : DialogLevel) -> MessageDialog

Create a message dialog request.

title defaults to "Message" so callers can use the short form when only the message body matters. level defaults to Info.

The returned value starts with DialogLabels::none(), so callers can opt into custom captions later with with_labels when the chosen backend supports them.

This constructor only prepares an immutable request value. No native dialog is shown until MessageDialog::show is called on the returned object.

#
MessageDialog::show

Show a message dialog on the current desktop platform.

Backend selection rules:
  • Windows uses the Win32 MessageBoxW API.
  • macOS uses a CoreFoundation user notification API.
  • Linux tries zenity, then kdialog, then xmessage via direct process spawning without shell command construction.

The function returns the backend that succeeded so callers can log or debug platform-specific behavior when needed.

Failures are reported as Err(DialogError), which keeps unsupported platforms, missing helpers, and backend-specific native errors distinct.

#
MessageDialog::with_labels

fn MessageDialog::with_labels(self : MessageDialog, labels : DialogLabels) -> MessageDialog

Attach custom labels to a message dialog.

This returns a new dialog value and leaves the original unchanged. Unsupported backends keep their native default captions.

The provided labels are interpreted as a one-button caption set when the dialog is eventually shown.

#
MultiPathDialogOutcome

pub struct MultiPathDialogOutcome {
backend : DialogBackend
selection : MultiPathSelection
} derive(Eq,
Debug
)

A completed multi-path dialog result including the backend and the selection.

#
MultiPathSelection

pub(all) enum MultiPathSelection {
Selected(Array[String])
Cancelled
} derive(Eq,
Debug
)

The result of a multi-path dialog.

#
OpenFileDialog

pub struct OpenFileDialog {
title : String
directory : String
filters : Array[FileFilter]
} derive(Eq,
Debug
)

An open-file dialog request.

#
OpenFileDialog::new

fn OpenFileDialog::new(title? : StringView, directory? : StringView) -> OpenFileDialog

Create an open-file dialog request.

title defaults to "Open File" and directory defaults to an empty string, allowing the backend to choose its default starting location. Newly created dialogs start without any filename filters.

Call with_filters on the returned value if you want the picker to focus on a limited set of file types.

#
OpenFileDialog::show

Show an open-file dialog.

The result contains both the backend that handled the request and either the selected path or Cancelled when the user dismisses the dialog.

This keeps cancellation distinct from operational failure so callers do not need to infer meaning from an empty string.

#
OpenFileDialog::with_filters

fn OpenFileDialog::with_filters(self : OpenFileDialog, filters : Array[FileFilter]) -> OpenFileDialog

Attach filename filters to an open-file dialog.

This replaces any existing filters, copies the provided array defensively, and preserves the dialog title and starting directory.

Use this when you want the picker UI to emphasize a narrow set of file types while keeping the original request immutable.

#
OpenFilesDialog

pub struct OpenFilesDialog {
title : String
directory : String
filters : Array[FileFilter]
} derive(Eq,
Debug
)

A multi-file open dialog request.

#
OpenFilesDialog::new

fn OpenFilesDialog::new(title? : StringView, directory? : StringView) -> OpenFilesDialog

Create an open-files dialog request.

title defaults to "Open Files" and directory defaults to an empty string, allowing the backend to choose its default starting location. Newly created dialogs start without any filename filters.

Attach filters later with with_filters if you want to narrow visible file types without rebuilding the request.

#
OpenFilesDialog::show

Show an open-files dialog.

The result contains both the backend that handled the request and either the selected paths or Cancelled when the user dismisses the dialog.

On success the selected paths are returned after decoding the serialized wire format produced by the native backend.

#
OpenFilesDialog::with_filters

fn OpenFilesDialog::with_filters(self : OpenFilesDialog, filters : Array[FileFilter]) -> OpenFilesDialog

Attach filename filters to a multi-file open dialog.

This replaces any existing filters, copies the provided array defensively, and preserves the dialog title and starting directory.

It behaves like OpenFileDialog::with_filters, but targets the multi-select request type instead.

#
PathDialogOutcome

pub struct PathDialogOutcome {
backend : DialogBackend
selection : PathDialogSelection
} derive(Eq,
Debug
)

A completed path dialog result including the backend and the selection.

#
PathDialogSelection

pub(all) enum PathDialogSelection {
Selected(String)
Cancelled
} derive(Eq,
Debug
)

The result of a path-based dialog.

#
Platform

pub(all) enum Platform {
Windows
MacOS
Linux
Unknown
} derive(Eq,
Debug
)

The detected operating system for the current native process.

Unknown is returned when the runtime is not one of the currently supported desktop platforms.

#
SaveFileDialog

pub struct SaveFileDialog {
title : String
directory : String
file_name : String
filters : Array[FileFilter]
default_extension : String
} derive(Eq,
Debug
)

A save-file dialog request.

#
SaveFileDialog::new

fn SaveFileDialog::new(title? : StringView, directory? : StringView, file_name? : StringView) -> SaveFileDialog

Create a save-file dialog request.

title defaults to "Save File", directory defaults to an empty string, and file_name defaults to an empty string. Newly created dialogs start without filters or a default extension.

The returned request can be refined with with_filters and with_default_extension before it is shown.

#
SaveFileDialog::show

Show a save-file dialog.

The result contains both the backend that handled the request and either the chosen save path or Cancelled when the user dismisses the dialog.

When the chosen path has no extension, the native layer may append the configured default extension before returning the final selection.

#
SaveFileDialog::with_default_extension

fn SaveFileDialog::with_default_extension(self : SaveFileDialog, extension : StringView) -> SaveFileDialog

Set a default file extension for a save-file dialog.

This updates only the stored default extension and preserves the current title, directory, file name, and filters.

Callers may pass either "txt" or ".txt"; the native layer normalizes the value before appending it to extensionless paths.

#
SaveFileDialog::with_filters

fn SaveFileDialog::with_filters(self : SaveFileDialog, filters : Array[FileFilter]) -> SaveFileDialog

Attach filename filters to a save-file dialog.

This replaces any existing filters, copies the provided array defensively, and preserves the dialog title, directory, file name, and default extension.

The native backend may apply these filters differently, but the request always keeps the full structured filter list.

#
SelectFolderDialog

pub struct SelectFolderDialog {
title : String
directory : String
} derive(Eq,
Debug
)

A folder-selection dialog request.

#
SelectFolderDialog::new

fn SelectFolderDialog::new(title? : StringView, directory? : StringView) -> SelectFolderDialog

Create a folder-selection dialog request.

title defaults to "Select Folder" and directory defaults to an empty string so the backend can choose its default starting location.

This request type stays minimal because folder pickers do not use file filters or default extensions.

#
SelectFolderDialog::show

Show a folder-selection dialog.

The result contains both the backend that handled the request and either the selected folder path or Cancelled.

Like the file pickers, dismissal is returned as data rather than being treated as an operational error.

#
ask_yes_no

fn ask_yes_no(message : StringView, title? : StringView, level? : DialogLevel) -> Result[DialogOutcome, DialogError]

Ask a yes-or-no question without constructing ConfirmDialog manually.

This convenience function uses the same defaults as ConfirmDialog::new and returns the selected response together with the backend that displayed the dialog.

It is the shortest way to request a typed confirmation while preserving the same backend and error details as ConfirmDialog::show.

#
ask_yes_no_cancel

fn ask_yes_no_cancel(message : StringView, title? : StringView, level? : DialogLevel) -> Result[DialogOutcome, DialogError]

Show a yes-no-cancel dialog.

This is equivalent to show_dialog(message, title~, buttons=YesNoCancel,level~) and defaults to the "Confirm" title with Question severity.

Use this helper when dismissal needs to remain a first-class branch instead of being folded into a negative answer.

#
current_platform

fn current_platform() -> Platform

Return the current native desktop platform.

This reports the compile-time platform targeted by the native backend and is mainly useful for diagnostics, logging, and platform-aware tests.

The value describes the build target seen by this package rather than a runtime probe of which desktop helpers are currently installed.

#
open_file

fn open_file(title? : StringView, directory? : StringView) -> Result[PathDialogOutcome, DialogError]

Open a file without constructing OpenFileDialog manually.

This convenience function uses the same defaults as OpenFileDialog::new and returns the selected path together with the backend that produced it.

Choose this helper for the no-filter case and switch to the builder form when you need more request customization.

#
open_files

fn open_files(title? : StringView, directory? : StringView) -> Result[MultiPathDialogOutcome, DialogError]

Open multiple files without constructing OpenFilesDialog manually.

This convenience function uses the same defaults as OpenFilesDialog::new and returns the selected paths together with the backend that handled the request.

Prefer the builder form when you need filters; otherwise this helper keeps a simple multi-file pick to a single call.

#
save_file

fn save_file(title? : StringView, directory? : StringView, file_name? : StringView) -> Result[PathDialogOutcome, DialogError]

Save a file without constructing SaveFileDialog manually.

This convenience function uses the same defaults as SaveFileDialog::new and returns the resulting path selection together with the backend that handled the request.

Prefer the builder form when you need filters, a reusable initial file name, or save-time extension behavior.

#
select_folder

fn select_folder(title? : StringView, directory? : StringView) -> Result[PathDialogOutcome, DialogError]

Select a folder without constructing SelectFolderDialog manually.

This convenience function uses the same defaults as SelectFolderDialog::new and returns the resulting folder selection together with the backend that handled the request.

It is the shortest entry point when you only need a one-off folder choice.

#
show_dialog

fn show_dialog(message : StringView, title? : StringView, buttons? : DialogButtons, level? : DialogLevel) -> Result[DialogOutcome, DialogError]

Show a dialog without constructing ChoiceDialog manually.

This is the most flexible convenience entry point and mirrors the defaults of ChoiceDialog::new.

Prefer this helper for one-off prompts and switch to the builder form when you need to reuse the request or attach custom labels.

#
show_error

fn show_error(message : StringView, title? : StringView) -> Result[DialogBackend, DialogError]

Show an error dialog using the Error level.

This is equivalent to show_message(message, title~, level=Error) and uses "Error" as the default title.

It is intended for direct failure-reporting paths that still need a typed Result for backend diagnostics.

#
show_info

fn show_info(message : StringView, title? : StringView) -> Result[DialogBackend, DialogError]

Show an informational dialog using the Info level.

This is equivalent to show_message(message, title~, level=Info) and uses "Information" as the default title.

The returned backend identifies which native implementation displayed the dialog on the current platform.

#
show_message

fn show_message(message : StringView, title? : StringView, level? : DialogLevel) -> Result[DialogBackend, DialogError]

Show a simple message dialog without creating MessageDialog manually.

This is the smallest entry point for the library and is intended for the common case where a single title and message are enough.

It uses the same defaults as MessageDialog::new and returns the backend that successfully displayed the dialog.

Result handling matches MessageDialog::show, so callers can start with this helper and later switch to the builder form without changing behavior.

#
show_ok_cancel

fn show_ok_cancel(message : StringView, title? : StringView, level? : DialogLevel) -> Result[DialogOutcome, DialogError]

Show an OK-or-cancel dialog.

This is equivalent to show_dialog(message, title~, buttons=OkCancel,level~) and defaults to the "Confirm" title with Question severity.

Successful results use DialogResponse::Ok for acceptance and DialogResponse::Cancel when the user backs out of the dialog.

#
show_warning

fn show_warning(message : StringView, title? : StringView) -> Result[DialogBackend, DialogError]

Show a warning dialog using the Warning level.

This is equivalent to show_message(message, title~, level=Warning) and uses "Warning" as the default title.

Use this helper when severity is the only customization you need beyond an optional title override.

#
supports_custom_labels

fn supports_custom_labels(backend : DialogBackend) -> Bool

Return whether a backend applies custom button labels directly.

Windows and the current kdialog path fall back to native default labels. Callers can use this to decide whether exposing label customization is worth surfacing for a known backend.

This describes the capability of the integration path used by this library, not a general property of every dialog API on the operating system.

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io