git.s-ol.nu forks/DiligentCore / 3477cd7
Reworked Open/SaveFileDialog to allow specifying dialog flags assiduous 2 years ago
2 changed file(s) with 99 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
2929 #include <memory>
3030 #include "../../Basic/interface/BasicFileSystem.hpp"
3131 #include "../../Basic/interface/StandardFile.hpp"
32 #include "../../../Primitives/interface/FlagEnum.h"
3233
3334 class WindowsFile : public StandardFile
3435 {
3637 WindowsFile(const FileOpenAttribs& OpenAttribs);
3738 };
3839
40 enum FILE_DIALOG_FLAGS : Diligent::Uint32
41 {
42 FILE_DIALOG_FLAG_NONE = 0x000,
43
44 /// Prevents the system from adding a link to the selected file in the file system
45 /// directory that contains the user's most recently used documents.
46 FILE_DIALOG_FLAG_DONT_ADD_TO_RECENT = 0x001,
47
48 /// Only existing files can be opened
49 FILE_DIALOG_FLAG_FILE_MUST_EXIST = 0x002,
50
51 /// Restores the current directory to its original value if the user changed the
52 /// directory while searching for files.
53 FILE_DIALOG_FLAG_NO_CHANGE_DIR = 0x004,
54
55 /// Causes the Save As dialog box to show a message box if the selected file already exists.
56 FILE_DIALOG_FLAG_OVERWRITE_PROMPT = 0x008
57 };
58 DEFINE_FLAG_ENUM_OPERATORS(FILE_DIALOG_FLAGS);
59
60 enum FILE_DIALOG_TYPE : Diligent::Uint32
61 {
62 FILE_DIALOG_TYPE_OPEN,
63 FILE_DIALOG_TYPE_SAVE
64 };
65
66 struct FileDialogAttribs
67 {
68 FILE_DIALOG_TYPE Type = FILE_DIALOG_TYPE_OPEN;
69 FILE_DIALOG_FLAGS Flags = FILE_DIALOG_FLAG_NONE;
70
71 const char* Title = nullptr;
72 const char* Filter = nullptr;
73
74 FileDialogAttribs() noexcept {}
75
76 explicit FileDialogAttribs(FILE_DIALOG_TYPE _Type) noexcept :
77 Type{_Type}
78 {
79 switch (Type)
80 {
81 case FILE_DIALOG_TYPE_OPEN:
82 Flags = FILE_DIALOG_FLAG_DONT_ADD_TO_RECENT | FILE_DIALOG_FLAG_FILE_MUST_EXIST | FILE_DIALOG_FLAG_NO_CHANGE_DIR;
83 break;
84
85 case FILE_DIALOG_TYPE_SAVE:
86 Flags = FILE_DIALOG_FLAG_DONT_ADD_TO_RECENT | FILE_DIALOG_FLAG_OVERWRITE_PROMPT | FILE_DIALOG_FLAG_NO_CHANGE_DIR;
87 break;
88 }
89 }
90 };
3991
4092 struct WindowsFileSystem : public BasicFileSystem
4193 {
55107
56108 static std::vector<std::unique_ptr<FindFileData>> Search(const Diligent::Char* SearchPattern);
57109
58 static std::string OpenFileDialog(const char* Title, const char* Filter);
59
60 static std::string SaveFileDialog(const char* Title, const char* Filter);
110 static std::string FileDialog(const FileDialogAttribs& DialogAttribs);
61111
62112 static std::string GetCurrentDirectory();
63113
277277 return SearchRes;
278278 }
279279
280 std::string WindowsFileSystem::OpenFileDialog(const char* Title, const char* Filter)
281 {
282 std::string FileName;
283 char buffer[1024] = {};
284 OPENFILENAMEA ofn = {};
285 ofn.lStructSize = sizeof(ofn);
286 ofn.lpstrFilter = Filter;
287 ofn.lpstrFile = buffer;
288 ofn.nMaxFile = _countof(buffer);
289 ofn.lpstrTitle = Title;
290 ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
291 if (GetOpenFileNameA(&ofn))
280 static DWORD FileDialogFlagsToOFNFlags(FILE_DIALOG_FLAGS FileDialogFlags)
281 {
282 DWORD OFNFlags = 0;
283 while (FileDialogFlags != FILE_DIALOG_FLAG_NONE)
284 {
285 auto Flag = FileDialogFlags & ~static_cast<FILE_DIALOG_FLAGS>(static_cast<Uint32>(FileDialogFlags) - 1);
286 switch (Flag)
287 {
288 case FILE_DIALOG_FLAG_DONT_ADD_TO_RECENT:
289 OFNFlags |= OFN_DONTADDTORECENT;
290 break;
291
292 case FILE_DIALOG_FLAG_FILE_MUST_EXIST:
293 OFNFlags |= OFN_FILEMUSTEXIST;
294 break;
295
296 case FILE_DIALOG_FLAG_NO_CHANGE_DIR:
297 OFNFlags |= OFN_NOCHANGEDIR;
298 break;
299
300 case FILE_DIALOG_FLAG_OVERWRITE_PROMPT:
301 OFNFlags |= OFN_OVERWRITEPROMPT;
302 break;
303
304 default:
305 UNEXPECTED("Unknown file dialog flag (", Flag, ")");
306 }
307 FileDialogFlags &= ~Flag;
308 }
309 return OFNFlags;
310 }
311
312 std::string WindowsFileSystem::FileDialog(const FileDialogAttribs& DialogAttribs)
313 {
314 OPENFILENAMEA ofn = {};
315
316 char buffer[1024] = {};
317 ofn.lStructSize = sizeof(ofn);
318 ofn.lpstrFilter = DialogAttribs.Filter;
319 ofn.lpstrFile = buffer;
320 ofn.nMaxFile = _countof(buffer);
321 ofn.lpstrTitle = DialogAttribs.Title;
322 ofn.Flags = FileDialogFlagsToOFNFlags(DialogAttribs.Flags);
323
324 std::string FileName;
325 if (DialogAttribs.Type == FILE_DIALOG_TYPE_OPEN ? GetOpenFileNameA(&ofn) : GetSaveFileNameA(&ofn))
292326 {
293327 FileName = buffer;
294328 }
295329 return FileName;
296330 }
297
298 std::string WindowsFileSystem::SaveFileDialog(const char* Title, const char* Filter)
299 {
300 std::string FileName;
301 char buffer[1024] = {};
302 OPENFILENAMEA ofn = {};
303 ofn.lStructSize = sizeof(ofn);
304 ofn.lpstrFilter = Filter;
305 ofn.lpstrFile = buffer;
306 ofn.nMaxFile = _countof(buffer);
307 ofn.lpstrTitle = Title;
308 ofn.Flags = OFN_DONTADDTORECENT | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR;
309 if (GetSaveFileNameA(&ofn))
310 {
311 FileName = buffer;
312 }
313 return FileName;
314 }
315
316331
317332 bool WindowsFileSystem::IsDirectory(const Diligent::Char* strPath)
318333 {