From 9b8f381a3a75d550992fa8fbf0ca49339af119b3 Mon Sep 17 00:00:00 2001 From: Marc Peter Date: Thu, 18 Nov 2021 18:35:55 +0100 Subject: [PATCH 1/5] fix build to work with a current version of ImGui Master and docking branch both work. --- CMakeLists.txt | 9 +++++---- example.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e16c52..e66494c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,9 @@ set(SOURCES libs/imgui/imgui.cpp libs/imgui/imgui_widgets.cpp libs/imgui/imgui_draw.cpp - libs/imgui/examples/imgui_impl_opengl3.cpp - libs/imgui/examples/imgui_impl_sdl.cpp + libs/imgui/imgui_tables.cpp + libs/imgui/backends/imgui_impl_opengl3.cpp + libs/imgui/backends/imgui_impl_sdl.cpp ) # cmake toolchain @@ -50,7 +51,7 @@ set_target_properties(ImFileDialogExample PROPERTIES # include directories target_include_directories(ImFileDialogExample PRIVATE ${SDL2_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS}) -target_include_directories(ImFileDialogExample PRIVATE libs/) +target_include_directories(ImFileDialogExample PRIVATE libs libs/imgui) # link libraries target_link_libraries(ImFileDialogExample ${OPENGL_LIBRARIES}) @@ -64,4 +65,4 @@ elseif(UNIX AND NOT APPLE) target_link_libraries(ImFileDialogExample ${GLEW_LIBRARIES} ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} stdc++fs pthread) elseif(APPLE) target_link_libraries(ImFileDialogExample GLEW::GLEW ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS}) -endif() \ No newline at end of file +endif() diff --git a/example.cpp b/example.cpp index 677a6ba..f42d5bb 100644 --- a/example.cpp +++ b/example.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include #include #ifdef _WIN32 @@ -166,4 +166,4 @@ int main(int argc, char* argv[]) SDL_Quit(); return 0; -} \ No newline at end of file +} From d336fae29f5f94259b10442be57313fd4a6f2257 Mon Sep 17 00:00:00 2001 From: Marc Peter Date: Thu, 18 Nov 2021 18:52:11 +0100 Subject: [PATCH 2/5] make declarations of GetDefaultXxxxIcon() private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the compiler complains that they have been "declared ‘static’ but never defined" in user code. --- ImFileDialog.cpp | 3 +++ ImFileDialog.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ImFileDialog.cpp b/ImFileDialog.cpp index 54cdc45..236db73 100644 --- a/ImFileDialog.cpp +++ b/ImFileDialog.cpp @@ -29,6 +29,9 @@ #define PI 3.141592f namespace ifd { + static const char* GetDefaultFolderIcon(); + static const char* GetDefaultFileIcon(); + /* UI CONTROLS */ bool FolderNode(const char* label, ImTextureID icon, bool& clicked) { diff --git a/ImFileDialog.h b/ImFileDialog.h index 1046a77..442a53c 100644 --- a/ImFileDialog.h +++ b/ImFileDialog.h @@ -138,7 +138,4 @@ namespace ifd { void m_renderPopups(); void m_renderFileDialog(); }; - - static const char* GetDefaultFolderIcon(); - static const char* GetDefaultFileIcon(); } From e34c5ca64b79559fa6f500ded9a054a34577d144 Mon Sep 17 00:00:00 2001 From: Marc Peter Date: Thu, 18 Nov 2021 17:05:00 +0100 Subject: [PATCH 3/5] fix compiler warnings for -Wall and MSVC Mostly int/size_t mismatches. --- ImFileDialog.cpp | 29 ++++++++++++++++++----------- ImFileDialog.h | 2 +- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/ImFileDialog.cpp b/ImFileDialog.cpp index 236db73..0969843 100644 --- a/ImFileDialog.cpp +++ b/ImFileDialog.cpp @@ -78,7 +78,7 @@ namespace ifd { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImU32 id = window->GetID(label); + //ImU32 id = window->GetID(label); ImVec2 pos = window->DC.CursorPos; bool ret = ImGui::InvisibleButton(label, ImVec2(-FLT_MIN, g.FontSize + g.Style.FramePadding.y * 2)); @@ -139,14 +139,14 @@ namespace ifd { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); bool isFirstElement = true; - for (int i = 0; i < btnList.size(); i++) { + for (size_t i = 0; i < btnList.size(); i++) { if (totalWidth > size.x - 30 && i != btnList.size() - 1) { // trim some buttons if there's not enough space float elSize = ImGui::CalcTextSize(btnList[i].c_str()).x + style.FramePadding.x * 2.0f + GUI_ELEMENT_SIZE; totalWidth -= elSize; continue; } - ImGui::PushID(i); + ImGui::PushID(static_cast(i)); if (!isFirstElement) { ImGui::ArrowButtonEx("##dir_dropdown", ImGuiDir_Right, ImVec2(GUI_ELEMENT_SIZE, GUI_ELEMENT_SIZE)); anyOtherHC |= ImGui::IsItemHovered() | ImGui::IsItemClicked(); @@ -158,7 +158,7 @@ namespace ifd { #else std::string newPath = "/"; #endif - for (int j = 0; j <= i; j++) { + for (size_t j = 0; j <= i; j++) { newPath += btnList[j]; #ifdef _WIN32 if (j != i) @@ -544,7 +544,7 @@ namespace ifd { // remove from sidebar for (auto& p : m_treeCache) if (p->Path == "Quick Access") { - for (int i = 0; i < p->Children.size(); i++) + for (size_t i = 0; i < p->Children.size(); i++) if (p->Children[i]->Path == path) { p->Children.erase(p->Children.begin() + i); break; @@ -660,9 +660,9 @@ namespace ifd { std::vector exts; - int lastSplit = 0, lastExt = 0; + size_t lastSplit = 0, lastExt = 0; bool inExtList = false; - for (int i = 0; i < filter.size(); i++) { + for (size_t i = 0; i < filter.size(); i++) { if (filter[i] == ',') { if (!inExtList) lastSplit = i + 1; @@ -876,7 +876,7 @@ namespace ifd { } void FileDialog::m_loadPreview() { - for (int i = 0; m_previewLoaderRunning && i < m_content.size(); i++) { + for (size_t i = 0; m_previewLoaderRunning && i < m_content.size(); i++) { auto& data = m_content[i]; if (data.HasIconPreview) @@ -1010,7 +1010,7 @@ namespace ifd { if (m_content.size() > 0) { // find where the file list starts - int fileIndex = 0; + size_t fileIndex = 0; for (; fileIndex < m_content.size(); fileIndex++) if (!m_content[fileIndex].IsDirectory) break; @@ -1218,7 +1218,7 @@ namespace ifd { if (openNewDirectoryDlg) ImGui::OpenPopup("Enter directory name##newdir"); if (ImGui::BeginPopupModal("Are you sure?##delete")) { - if (m_selectedFileItem >= m_content.size() || m_content.size() == 0) + if (m_selectedFileItem >= static_cast(m_content.size()) || m_content.size() == 0) ImGui::CloseCurrentPopup(); else { const FileData& data = m_content[m_selectedFileItem]; @@ -1369,13 +1369,18 @@ namespace ifd { #ifdef _WIN32 if (!success) MessageBeep(MB_ICONERROR); +#else + (void)success; #endif } if (m_type != IFD_DIALOG_DIRECTORY) { ImGui::SameLine(); ImGui::SetNextItemWidth(-FLT_MIN); - if (ImGui::Combo("##ext_combo", &m_filterSelection, m_filter.c_str())) + int sel = static_cast(m_filterSelection); + if (ImGui::Combo("##ext_combo", &sel, m_filter.c_str())) { + m_filterSelection = static_cast(sel); m_setDirectory(m_currentDirectory, false); // refresh + } } // buttons @@ -1388,6 +1393,8 @@ namespace ifd { #ifdef _WIN32 if (!success) MessageBeep(MB_ICONERROR); +#else + (void)success; #endif } ImGui::SameLine(); diff --git a/ImFileDialog.h b/ImFileDialog.h index 442a53c..bbb638a 100644 --- a/ImFileDialog.h +++ b/ImFileDialog.h @@ -108,7 +108,7 @@ namespace ifd { std::string m_filter; std::vector> m_filterExtensions; - int m_filterSelection; + size_t m_filterSelection; void m_parseFilter(const std::string& filter); std::vector m_iconIndices; From 49079b69122273a5ec9362c6ddd4d2752ed580e9 Mon Sep 17 00:00:00 2001 From: Marc Peter Date: Thu, 18 Nov 2021 18:43:03 +0100 Subject: [PATCH 4/5] tweak size computations - top bar isn't cut off anymore if a larger font is used (i.e, 48 points for high-dpi displays) - button sizes for Open/Save and Cancel in the bottom bar now also depend on the font size - the frame inset at the bottom frame border now has the same size as for the other borders (it was slightly too big before) --- ImFileDialog.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ImFileDialog.cpp b/ImFileDialog.cpp index 0969843..0b2a2e1 100644 --- a/ImFileDialog.cpp +++ b/ImFileDialog.cpp @@ -24,7 +24,7 @@ #endif #define ICON_SIZE ImGui::GetFont()->FontSize + 3 -#define GUI_ELEMENT_SIZE 24 +#define GUI_ELEMENT_SIZE std::max(GImGui->FontSize + 10.f, 24.f) #define DEFAULT_ICON_SIZE 32 #define PI 3.141592f @@ -1330,7 +1330,7 @@ namespace ifd { /***** CONTENT *****/ - float bottomBarHeight = (GImGui->FontSize + ImGui::GetStyle().FramePadding.y * 2.0f + ImGui::GetStyle().ItemSpacing.y * 2.0f) * 2; + float bottomBarHeight = (GImGui->FontSize + ImGui::GetStyle().FramePadding.y + ImGui::GetStyle().ItemSpacing.y * 2.0f) * 2; if (ImGui::BeginTable("##table", 2, ImGuiTableFlags_Resizable, ImVec2(0, -bottomBarHeight))) { ImGui::TableSetupColumn("##tree", ImGuiTableColumnFlags_WidthFixed, 125.0f); ImGui::TableSetupColumn("##content", ImGuiTableColumnFlags_WidthStretch); @@ -1384,8 +1384,9 @@ namespace ifd { } // buttons - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 250); - if (ImGui::Button(m_type == IFD_DIALOG_SAVE ? "Save" : "Open", ImVec2(250 / 2 - ImGui::GetStyle().ItemSpacing.x, 0.0f))) { + float ok_cancel_width = GUI_ELEMENT_SIZE * 7; + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ok_cancel_width); + if (ImGui::Button(m_type == IFD_DIALOG_SAVE ? "Save" : "Open", ImVec2(ok_cancel_width / 2 - ImGui::GetStyle().ItemSpacing.x, 0.0f))) { std::string filename(m_inputTextbox); bool success = false; if (!filename.empty() || m_type == IFD_DIALOG_DIRECTORY) From b8cf74e5eb3fb326ee8754e0dfe84ba4015f119a Mon Sep 17 00:00:00 2001 From: Marc Peter Date: Thu, 18 Nov 2021 18:55:02 +0100 Subject: [PATCH 5/5] add optional callback to ImFileDialog::Open() to place custom widgets between filename text box and Open/Save/Cancel buttons --- ImFileDialog.cpp | 9 ++++++++- ImFileDialog.h | 7 ++++++- example.cpp | 26 ++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ImFileDialog.cpp b/ImFileDialog.cpp index 0b2a2e1..dfcab25 100644 --- a/ImFileDialog.cpp +++ b/ImFileDialog.cpp @@ -469,7 +469,7 @@ namespace ifd { return true; } - bool FileDialog::Open(const std::string& key, const std::string& title, const std::string& filter, bool isMultiselect, const std::string& startingDir) + bool FileDialog::Open(const std::string& key, const std::string& title, const std::string& filter, bool isMultiselect, const std::string& startingDir, std::function cb) { if (!m_currentKey.empty()) return false; @@ -484,6 +484,7 @@ namespace ifd { m_selectedFileItem = -1; m_isMultiselect = isMultiselect; m_type = filter.empty() ? IFD_DIALOG_DIRECTORY : IFD_DIALOG_FILE; + m_cb = std::move(cb); m_parseFilter(filter); if (!startingDir.empty()) @@ -1331,6 +1332,8 @@ namespace ifd { /***** CONTENT *****/ float bottomBarHeight = (GImGui->FontSize + ImGui::GetStyle().FramePadding.y + ImGui::GetStyle().ItemSpacing.y * 2.0f) * 2; + if (m_cb) + bottomBarHeight += m_cb(true); // query additional height due to user customizations if (ImGui::BeginTable("##table", 2, ImGuiTableFlags_Resizable, ImVec2(0, -bottomBarHeight))) { ImGui::TableSetupColumn("##tree", ImGuiTableColumnFlags_WidthFixed, 125.0f); ImGui::TableSetupColumn("##content", ImGuiTableColumnFlags_WidthStretch); @@ -1383,6 +1386,10 @@ namespace ifd { } } + // user's additional widgets + if (m_cb) + m_cb(false); + // buttons float ok_cancel_width = GUI_ELEMENT_SIZE * 7; ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ok_cancel_width); diff --git a/ImFileDialog.h b/ImFileDialog.h index bbb638a..def3eb9 100644 --- a/ImFileDialog.h +++ b/ImFileDialog.h @@ -27,7 +27,7 @@ namespace ifd { 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 Open(const std::string& key, const std::string& title, const std::string& filter, bool isMultiselect = false, const std::string& startingDir = "", std::function cb = nullptr); bool IsDone(const std::string& key); @@ -137,5 +137,10 @@ namespace ifd { void m_renderPopups(); void m_renderFileDialog(); + + // customize dialog with user-provided widgets (between filename text box and Open/Save/Cancel buttons) + // param: true -> just return the additional required height + // false -> submit user widgets (return value ignored) + std::function m_cb; }; } diff --git a/example.cpp b/example.cpp index f42d5bb..339d1ee 100644 --- a/example.cpp +++ b/example.cpp @@ -84,6 +84,7 @@ int main(int argc, char* argv[]) glDeleteTextures(1, &texID); }; + int record_type = 0; // 0 = images, 1 = video SDL_Event event; while (run) { while (SDL_PollEvent(&event)) { @@ -107,12 +108,33 @@ int main(int argc, char* argv[]) ImGui_ImplSDL2_NewFrame(wnd); ImGui::NewFrame(); + // define a callback to extend ImFileDialog with radio button + // options to choose between capturing still images and videos + auto cb = [&record_type](bool get_size) + { + static bool sameline = true; + if (get_size) + { + auto &st = ImGui::GetStyle(); + return sameline ? 0.f : (ImGui::GetFontSize() + st.FramePadding.y + st.ItemSpacing.y * 2.f); + } + + ImGui::Checkbox("Same line", &sameline); + ImGui::SameLine(); + ImGui::RadioButton("Images", &record_type, 0); + ImGui::SameLine(); + ImGui::RadioButton("Video", &record_type, 1); + if (sameline) + ImGui::SameLine(); // same line as OK/Cancel buttons + return 0.f; + }; + // Simple window ImGui::Begin("Control Panel"); if (ImGui::Button("Open file")) ifd::FileDialog::Instance().Open("ShaderOpenDialog", "Open a shader", "Image file (*.png;*.jpg;*.jpeg;*.bmp;*.tga){.png,.jpg,.jpeg,.bmp,.tga},.*", true); if (ImGui::Button("Open directory")) - ifd::FileDialog::Instance().Open("DirectoryOpenDialog", "Open a directory", ""); + ifd::FileDialog::Instance().Open("DirectoryOpenDialog", "Open a directory", "", false, "", cb); if (ImGui::Button("Save file")) ifd::FileDialog::Instance().Save("ShaderSaveDialog", "Save a shader", "*.sprj {.sprj}"); ImGui::End(); @@ -129,7 +151,7 @@ int main(int argc, char* argv[]) if (ifd::FileDialog::Instance().IsDone("DirectoryOpenDialog")) { if (ifd::FileDialog::Instance().HasResult()) { std::string res = ifd::FileDialog::Instance().GetResult().u8string(); - printf("DIRECTORY[%s]\n", res.c_str()); + printf("DIRECTORY[%s] (for %s)\n", res.c_str(), record_type ? "video" : "images"); } ifd::FileDialog::Instance().Close(); }