1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "SDL_internal.h" |
22 | |
23 | #include "SDL_dialog.h" |
24 | #include "SDL_dialog_utils.h" |
25 | |
26 | void SDL_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props) |
27 | { |
28 | if (!callback) { |
29 | return; |
30 | } |
31 | #ifdef SDL_DIALOG_DISABLED |
32 | SDL_SetError("SDL not built with dialog support" ); |
33 | callback(userdata, NULL, -1); |
34 | #else |
35 | SDL_DialogFileFilter *filters = SDL_GetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, NULL); |
36 | int nfilters = (int) SDL_GetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, -1); |
37 | |
38 | if (filters && nfilters == -1) { |
39 | SDL_SetError("Set filter pointers, but didn't set number of filters (SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER)" ); |
40 | callback(userdata, NULL, -1); |
41 | return; |
42 | } |
43 | |
44 | const char *msg = validate_filters(filters, nfilters); |
45 | |
46 | if (msg) { |
47 | SDL_SetError("Invalid dialog file filters: %s" , msg); |
48 | callback(userdata, NULL, -1); |
49 | return; |
50 | } |
51 | |
52 | switch (type) { |
53 | case SDL_FILEDIALOG_OPENFILE: |
54 | case SDL_FILEDIALOG_SAVEFILE: |
55 | case SDL_FILEDIALOG_OPENFOLDER: |
56 | SDL_SYS_ShowFileDialogWithProperties(type, callback, userdata, props); |
57 | break; |
58 | |
59 | default: |
60 | SDL_SetError("Unsupported file dialog type: %d" , (int) type); |
61 | callback(userdata, NULL, -1); |
62 | break; |
63 | }; |
64 | #endif |
65 | } |
66 | |
67 | void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, bool allow_many) |
68 | { |
69 | #ifdef SDL_DIALOG_DISABLED |
70 | if (!callback) { |
71 | return; |
72 | } |
73 | SDL_SetError("SDL not built with dialog support" ); |
74 | callback(userdata, NULL, -1); |
75 | #else |
76 | SDL_PropertiesID props = SDL_CreateProperties(); |
77 | |
78 | SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, (void *) filters); |
79 | SDL_SetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, nfilters); |
80 | SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, window); |
81 | SDL_SetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, default_location); |
82 | SDL_SetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, allow_many); |
83 | |
84 | SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFILE, callback, userdata, props); |
85 | |
86 | SDL_DestroyProperties(props); |
87 | #endif |
88 | } |
89 | |
90 | void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location) |
91 | { |
92 | #ifdef SDL_DIALOG_DISABLED |
93 | if (!callback) { |
94 | return; |
95 | } |
96 | SDL_SetError("SDL not built with dialog support" ); |
97 | callback(userdata, NULL, -1); |
98 | #else |
99 | SDL_PropertiesID props = SDL_CreateProperties(); |
100 | |
101 | SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, (void *) filters); |
102 | SDL_SetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, nfilters); |
103 | SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, window); |
104 | SDL_SetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, default_location); |
105 | |
106 | SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_SAVEFILE, callback, userdata, props); |
107 | |
108 | SDL_DestroyProperties(props); |
109 | #endif |
110 | } |
111 | |
112 | void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char *default_location, bool allow_many) |
113 | { |
114 | #ifdef SDL_DIALOG_DISABLED |
115 | if (!callback) { |
116 | return; |
117 | } |
118 | SDL_SetError("SDL not built with dialog support" ); |
119 | callback(userdata, NULL, -1); |
120 | #else |
121 | SDL_PropertiesID props = SDL_CreateProperties(); |
122 | |
123 | SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, window); |
124 | SDL_SetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, default_location); |
125 | SDL_SetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, allow_many); |
126 | |
127 | SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFOLDER, callback, userdata, props); |
128 | |
129 | SDL_DestroyProperties(props); |
130 | #endif |
131 | } |
132 | |