Skip to content

Dialogs ​

Dialogs ask the user for something and reply later. Barton shows native file dialogs, and any window can act as a dialog that returns a result.

File dialogs ​

An event handler that takes a FileDialog can show one. The dialog doesn't block the app, and the user's choice arrives in the callback passed to then:

cpp
MenuItem {
    "Open...",
    on_activate = [](FileDialog dialog) {
        dialog.show(OpenFile {}.with_filter("Images", "png;jpg"))
            .then([](const FileDialogEvent& event, State& state) {
                if (const auto* path = event.path())
                    state.image = *path;
            });
    },
}

The callback follows the same rules as any handler, so it can take state, windows or any other parameter.

There are three kinds of file dialog:

KindAsks for
OpenFileOne or more existing files, with with_many() for several
SaveFileA path to save to
OpenFolderOne or more folders

Each can set a title, a starting location and the button labels, and the file dialogs can filter by type:

cpp
SaveFile {}
    .with_title("Export Level")
    .with_location(state.project_dir)
    .with_accept("Export")
    .with_filter("Level", "json")

Responses ​

A file dialog ends in one of three ways: the user picks something, cancels, or the dialog fails to open.

cpp
.then([](const FileDialogEvent& event, State& state) {
    if (const auto* accepted = event.accepted())
        state.files = accepted->paths;
    else if (event.cancelled())
        state.status = "Nothing chosen";
    else if (const auto* error = event.error())
        state.status = error->message();
})

When only one path matters, path() returns the first one picked, or nothing.

Custom dialogs ​

A window becomes a dialog by declaring the type of result it returns. Opening it then gives a pending reply, and the window answers by closing with a value:

cpp
class ConfirmDelete : public Window {
public:
    using Result = bool;

    View render() const {
        return Row {
            gap = 8_px,
            Container {
                on_click = [](CurrentWindow window) { window.close_with(true); },
                Text { "Delete" },
            },
            Container {
                on_click = [](CurrentWindow window) { window.close_with(false); },
                Text { "Cancel" },
            },
        };
    }
};
cpp
on_activate = [](Windows& windows) {
    windows.open<ConfirmDelete>({ .title = "Delete layer?", .width = 320, .height = 140 })
        .then([](bool confirmed, State& state) {
            if (confirmed)
                state.layers.pop_back();
        });
}

If the window is closed without a result, such as from its title bar, a second callback receives Dismissed:

cpp
.then(
    [](bool confirmed, State& state) { ... },
    [](Dismissed, State& state) { state.status = "Kept the layer"; }
)

Barton is in early development.