ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
dialog.cpp
Go to the documentation of this file.
2
3#include <SDL3/SDL.h>
4#include <array>
5#include <atomic>
6#include <mutex>
7#include <utility>
8
10#include "./asw/modules/log.h"
11
12namespace {
13// SDL may run the file chooser callback on another thread
14std::mutex file_mutex;
15std::optional<std::string> chosen_file;
16std::atomic<bool> file_pending = false;
17
18// SDL reads the filters until the chooser closes, so they live here
19std::vector<asw::dialog::FileFilter> active_filters;
20std::vector<SDL_DialogFileFilter> active_sdl_filters;
21
22void SDLCALL on_file_chosen(void* /*userdata*/, const char* const* files, int /*filter*/)
23{
24 if (files == nullptr) {
25 asw::log::warn("File chooser failed: {}", SDL_GetError());
26 } else if (files[0] != nullptr) {
27 const std::scoped_lock lock(file_mutex);
28 chosen_file = files[0];
29 }
30
31 file_pending = false;
32}
33
34void show_message(SDL_MessageBoxFlags flags, const std::string& title, const std::string& message)
35{
36 SDL_ShowSimpleMessageBox(flags, title.c_str(), message.c_str(), asw::display::get_window());
37}
38} // namespace
39
40void asw::dialog::info(const std::string& title, const std::string& message)
41{
42 show_message(SDL_MESSAGEBOX_INFORMATION, title, message);
43}
44
45void asw::dialog::warn(const std::string& title, const std::string& message)
46{
47 show_message(SDL_MESSAGEBOX_WARNING, title, message);
48}
49
50void asw::dialog::error(const std::string& title, const std::string& message)
51{
52 show_message(SDL_MESSAGEBOX_ERROR, title, message);
53}
54
55bool asw::dialog::confirm(const std::string& title, const std::string& message)
56{
57 const std::array buttons {
58 SDL_MessageBoxButtonData { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "No" },
59 SDL_MessageBoxButtonData { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" },
60 };
61
62 const SDL_MessageBoxData data {
63 SDL_MESSAGEBOX_WARNING,
65 title.c_str(),
66 message.c_str(),
67 static_cast<int>(buttons.size()),
68 buttons.data(),
69 nullptr,
70 };
71
72 int pressed = 0;
73 return SDL_ShowMessageBox(&data, &pressed) && pressed == 1;
74}
75
77 FileMode mode, const std::string& default_location, const std::vector<FileFilter>& filters)
78{
79 if (file_pending) {
80 return false;
81 }
82
83 {
84 const std::scoped_lock lock(file_mutex);
85 chosen_file.reset();
86 }
87
88 active_filters = filters;
89 active_sdl_filters.clear();
90 for (const auto& filter : active_filters) {
91 active_sdl_filters.push_back({ filter.name.c_str(), filter.pattern.c_str() });
92 }
93
94 const auto* sdl_filters = active_sdl_filters.empty() ? nullptr : active_sdl_filters.data();
95 const auto filter_count = static_cast<int>(active_sdl_filters.size());
96 const char* location = default_location.empty() ? nullptr : default_location.c_str();
97
98 // Set before showing, the callback can run before the call returns
99 file_pending = true;
100
101 if (mode == FileMode::Save) {
102 SDL_ShowSaveFileDialog(on_file_chosen, nullptr, asw::display::get_window(), sdl_filters,
103 filter_count, location);
104 } else {
105 SDL_ShowOpenFileDialog(on_file_chosen, nullptr, asw::display::get_window(), sdl_filters,
106 filter_count, location, false);
107 }
108
109 return true;
110}
111
113{
114 return file_pending;
115}
116
117std::optional<std::string> asw::dialog::take_file()
118{
119 const std::scoped_lock lock(file_mutex);
120 return std::exchange(chosen_file, std::nullopt);
121}
Native message boxes and file choosers.
Display and window routines for the ASW library.
Structured logging system.
std::optional< std::string > chosen_file
Definition dialog.cpp:15
std::vector< asw::dialog::FileFilter > active_filters
Definition dialog.cpp:19
void SDLCALL on_file_chosen(void *, const char *const *files, int)
Definition dialog.cpp:22
std::atomic< bool > file_pending
Definition dialog.cpp:16
void show_message(SDL_MessageBoxFlags flags, const std::string &title, const std::string &message)
Definition dialog.cpp:34
std::vector< SDL_DialogFileFilter > active_sdl_filters
Definition dialog.cpp:20
FileMode
Kind of file chooser.
Definition dialog.h:49
void warn(const std::string &title, const std::string &message)
Show a warning message box. Blocks until it is closed.
Definition dialog.cpp:45
void error(const std::string &title, const std::string &message)
Show an error message box. Blocks until it is closed.
Definition dialog.cpp:50
bool confirm(const std::string &title, const std::string &message)
Ask a yes or no question. Blocks until it is answered.
Definition dialog.cpp:55
std::optional< std::string > take_file()
Take the file the user chose. Returns it once, then empty until the next chooser.
Definition dialog.cpp:117
void info(const std::string &title, const std::string &message)
Show an information message box. Blocks until it is closed.
Definition dialog.cpp:40
bool is_file_pending()
Check if a file chooser is open.
Definition dialog.cpp:112
bool request_file(FileMode mode, const std::string &default_location="", const std::vector< FileFilter > &filters={ })
Open a native file chooser. It does not block, the chosen file arrives later through take_file()....
Definition dialog.cpp:76
asw::Window * get_window()
Get the SDL window.
Definition display.cpp:144
void warn(const std::string &message)
Log a warning message.
Definition log.cpp:191