diff options
Diffstat (limited to 'imfiledialog/ImFileDialog.h')
| -rw-r--r-- | imfiledialog/ImFileDialog.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/imfiledialog/ImFileDialog.h b/imfiledialog/ImFileDialog.h new file mode 100644 index 0000000..76b2123 --- /dev/null +++ b/imfiledialog/ImFileDialog.h @@ -0,0 +1,136 @@ +#pragma once +#include <ctime> +#include <stack> +#include <string> +#include <thread> +#include <vector> +#include <functional> +#include <filesystem> +#include <unordered_map> +#include <algorithm> // std::min, std::max + +#define IFD_DIALOG_FILE 0 +#define IFD_DIALOG_DIRECTORY 1 +#define IFD_DIALOG_SAVE 2 + +namespace ifd { + class FileDialog { + public: + static inline FileDialog& Instance() + { + static FileDialog ret; + return ret; + } + + FileDialog(); + ~FileDialog(); + + bool Save(const std::string& key, const std::string& title, const std::string& filter, const std::string& startingDir = ""); + + bool Open(const std::string& key, const std::string& title, const std::string& filter, bool isMultiselect = false, const std::string& startingDir = ""); + + bool IsDone(const std::string& key, int window_w, int window_h); + + inline bool HasResult() { return m_result.size(); } + inline const std::filesystem::path& GetResult() { return m_result[0]; } + inline const std::vector<std::filesystem::path>& GetResults() { return m_result; } + + void Close(); + + inline void SetZoom(float z) { + m_zoom = std::min<float>(25.0f, std::max<float>(1.0f, z)); + m_refreshIconPreview(); + } + inline float GetZoom() { return m_zoom; } + + std::function<void*(uint8_t*, int, int, char)> CreateTexture; // char -> fmt -> { 0 = BGRA, 1 = RGBA } + std::function<void(void*)> DeleteTexture; + + class FileTreeNode { + public: +#ifdef _WIN32 + FileTreeNode(const std::wstring& path) { + Path = std::filesystem::path(path); + Read = false; + } +#endif + + FileTreeNode(const std::string& path) { + Path = std::filesystem::u8path(path); + Read = false; + } + + std::filesystem::path Path; + bool Read; + std::vector<FileTreeNode*> Children; + }; + class FileData { + public: + FileData(const std::filesystem::path& path); + + std::filesystem::path Path; + bool IsDirectory; + size_t Size; + time_t DateModified; + + bool HasIconPreview; + void* IconPreview; + uint8_t* IconPreviewData; + int IconPreviewWidth, IconPreviewHeight; + }; + + private: + std::string m_currentKey; + std::string m_currentTitle; + std::filesystem::path m_currentDirectory; + bool m_isMultiselect; + bool m_isOpen; + uint8_t m_type; + char m_inputTextbox[1024]; + char m_pathBuffer[1024]; + char m_newEntryBuffer[1024]; + char m_searchBuffer[128]; + bool m_calledOpenPopup; + std::stack<std::filesystem::path> m_backHistory, m_forwardHistory; + float m_zoom; + + std::vector<std::filesystem::path> m_selections; + int m_selectedFileItem; + void m_select(const std::filesystem::path& path, bool isCtrlDown = false); + + std::vector<std::filesystem::path> m_result; + bool m_finalize(const std::string& filename = ""); + + std::string m_filter; + std::vector<std::vector<std::string>> m_filterExtensions; + size_t m_filterSelection; + void m_parseFilter(const std::string& filter); + + std::vector<int> m_iconIndices; + std::vector<std::string> m_iconFilepaths; // m_iconIndices[x] <-> m_iconFilepaths[x] + std::unordered_map<std::string, void*> m_icons; + void* m_getIcon(const std::filesystem::path& path); + void m_clearIcons(); + void m_refreshIconPreview(); + void m_clearIconPreview(); + + std::thread* m_previewLoader; + bool m_previewLoaderRunning; + void m_stopPreviewLoader(); + void m_loadPreview(); + + std::vector<FileTreeNode*> m_treeCache; + void m_clearTree(FileTreeNode* node); + void m_renderTree(FileTreeNode* node); + + unsigned int m_sortColumn; + unsigned int m_sortDirection; + std::vector<FileData> m_content; + void m_setDirectory(const std::filesystem::path& p, bool addHistory = true); + void m_sortContent(unsigned int column, unsigned int sortDirection); + void m_renderContent(); + + void m_renderPopups(); + void m_renderFileDialog(); + }; +} |
