summaryrefslogtreecommitdiff
path: root/imfiledialog/ImFileDialog.h
diff options
context:
space:
mode:
Diffstat (limited to 'imfiledialog/ImFileDialog.h')
-rw-r--r--imfiledialog/ImFileDialog.h136
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();
+ };
+}