From 34f5b833d86ea1dad98d683723cf05a17684237b Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Thu, 7 Mar 2024 20:49:22 +0100 Subject: add ImFileDialog with minor changes --- imfiledialog/ImFileDialog.h | 136 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 imfiledialog/ImFileDialog.h (limited to 'imfiledialog/ImFileDialog.h') 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 +#include +#include +#include +#include +#include +#include +#include +#include // 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& GetResults() { return m_result; } + + void Close(); + + inline void SetZoom(float z) { + m_zoom = std::min(25.0f, std::max(1.0f, z)); + m_refreshIconPreview(); + } + inline float GetZoom() { return m_zoom; } + + std::function CreateTexture; // char -> fmt -> { 0 = BGRA, 1 = RGBA } + std::function 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 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 m_backHistory, m_forwardHistory; + float m_zoom; + + std::vector m_selections; + int m_selectedFileItem; + void m_select(const std::filesystem::path& path, bool isCtrlDown = false); + + std::vector m_result; + bool m_finalize(const std::string& filename = ""); + + std::string m_filter; + std::vector> m_filterExtensions; + size_t m_filterSelection; + void m_parseFilter(const std::string& filter); + + std::vector m_iconIndices; + std::vector m_iconFilepaths; // m_iconIndices[x] <-> m_iconFilepaths[x] + std::unordered_map 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 m_treeCache; + void m_clearTree(FileTreeNode* node); + void m_renderTree(FileTreeNode* node); + + unsigned int m_sortColumn; + unsigned int m_sortDirection; + std::vector 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(); + }; +} -- cgit v1.2.3-70-g09d2