Glusoft

Use File Dialogs with the Dialog API

The List of function we will see in this tutorial are :

Open file dialog with SDL_ShowOpenFileDialog

The definition for the function is SDL_ShowOpenFileDialog :

void SDL_ShowOpenFileDialog(
    SDL_DialogFileCallback callback, // A function pointer to be invoked when the user selects a file and accepts, 
                                     // or cancels the dialog, or an error occurs.
    void *userdata, // An optional pointer to pass extra data to the callback when it will be invoked.
    SDL_Window *window, // The window that the dialog should be modal for, may be NULL. 
    const SDL_DialogFileFilter *filters, // A list of filters, may be NULL. Not all platforms support this option, 
                                         // and platforms that do support it may allow the user to ignore the filters. 
                                         // If non-NULL, it must remain valid at least until the callback is invoked.
    int nfilters, // The number of filters. Ignored if filters is NULL.
    const char *default_location, // The default folder or file to start the dialog at, may be NULL.
    bool allow_many // If non-zero, the user will be allowed to select multiple entries.
);

In this example we will open a file dialog when pressing a key. The file dialog should filter the images in the folder.
Before doing the example we need a CMakelist file :

cmake_minimum_required(VERSION 3.16)
project(SDL3_DialogAPI)

# Set C++ standard
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find SDL3
find_package(SDL3 REQUIRED)

# Add executable
add_executable(SDL3_DialogAPI main.cpp)

# Link SDL3
target_link_libraries(SDL3_DialogAPI PRIVATE SDL3::SDL3)

Before calling the file dialog function we need to set the callback function:

static const SDL_DialogFileFilter filters[] = {
    { "PNG images",  "png" },
    { "JPEG images", "jpg;jpeg" },
    { "All images",  "png;jpg;jpeg" },
    { "All files",   "*" }
};

static void SDLCALL callback(void* userdata, const char* const* filelist, int filter)
{
    if (!filelist) {
        SDL_Log("An error occured: %s", SDL_GetError());
        return;
    } else if (!*filelist) {
        SDL_Log("The user did not select any file.");
        SDL_Log("Most likely, the dialog was canceled.");
        return;
    }

    while (*filelist) {
        SDL_Log("Full path to selected file: '%s'", *filelist);
        filelist++;
    }

    if (filter < 0) {
        SDL_Log("The current platform does not support fetching "
                "the selected filter, or the user did not select"
                " any filter.");
        return;
    } else if (filter < SDL_arraysize(filters)) {
        SDL_Log("The filter selected by the user is '%s' (%s).",
                filters[filter].pattern, filters[filter].name);
        return;
    }
}

After that we can call the file dialog function SDL_ShowOpenFileDialog in the event loop :

  SDL_Event e;
    bool quit = false;

    while (!quit) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_EVENT_QUIT) {
                quit = true;
            }
            if(e.type == SDL_EVENT_KEY_DOWN) {
                SDL_ShowOpenFileDialog(callback, NULL, win, filters, SDL_arraysize(filters), "/Users/vulcain/Documents/", true);
            }
        }

        SDL_RenderClear(ren);
        SDL_RenderPresent(ren);
    }

File Dialog with SDL3 Dialog API

Save file dialog with SDL_ShowSaveFileDialog

In this example the goal is to save a file and for that we need to use the function SDL_ShowSaveFileDialog :

void SDL_ShowSaveFileDialog(
    SDL_DialogFileCallback callback, // A function pointer to be invoked when the user selects a file and accepts, 
                                     // or cancels the dialog, or an error occurs. 
    void *userdata, // An optional pointer to pass extra data to the callback when it will be invoked.
    SDL_Window *window, // The window that the dialog should be modal for, may be NULL.
    const SDL_DialogFileFilter *filters, // A list of filters, may be NULL. Not all platforms support this option, 
                                         // and platforms that do support it may allow the user to ignore the filters. 
                                         // If non-NULL, it must remain valid at least until the callback is invoked.
    int nfilters, // The number of filters. Ignored if filters is NULL.
    const char *default_location // The default folder or file to start the dialog at, may be NULL. 
);

For example you can call this function when pressing the s key :

if(e.type == SDL_EVENT_KEY_DOWN) {
    if(e.key.scancode == SDL_SCANCODE_S) {
        SDL_ShowSaveFileDialog(callback, NULL, win, filters, SDL_arraysize(filters), "/Users/vulcain/Documents/");
    }
}

Save File Dialog with SDL3 Dialog API

Open folder file dialog with SDL_ShowOpenFolderDialog

void SDL_ShowOpenFolderDialog(
    SDL_DialogFileCallback callback, // A function pointer to be invoked when the user selects a file and accepts, 
                                     // or cancels the dialog, or an error occurs.
    void *userdata, // An optional pointer to pass extra data to the callback when it will be invoked.
    SDL_Window *window, // The window that the dialog should be modal for, may be NULL.
    const char *default_location, // The default folder or file to start the dialog at, may be NULL. 
    bool allow_many // If non-zero, the user will be allowed to select multiple entries. 
);

You can put the open folder file dialog on the f key:

if(e.key.scancode == SDL_SCANCODE_F) {
    SDL_ShowOpenFolderDialog(callback, NULL, win, "/Users/vulcain/Documents/",true);
}

Folder File Dialog with SDL3 Dialog API

Download the full project : Use file dialog with the Dialog API

Need another OS ? => Windows, Mac, Linux