Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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})
Expand All @@ -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()
endif()
50 changes: 34 additions & 16 deletions ImFileDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
#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

namespace ifd {
static const char* GetDefaultFolderIcon();
static const char* GetDefaultFileIcon();

/* UI CONTROLS */
bool FolderNode(const char* label, ImTextureID icon, bool& clicked)
{
Expand Down Expand Up @@ -75,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));

Expand Down Expand Up @@ -136,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<int>(i));
if (!isFirstElement) {
ImGui::ArrowButtonEx("##dir_dropdown", ImGuiDir_Right, ImVec2(GUI_ELEMENT_SIZE, GUI_ELEMENT_SIZE));
anyOtherHC |= ImGui::IsItemHovered() | ImGui::IsItemClicked();
Expand All @@ -155,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)
Expand Down Expand Up @@ -466,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<float(bool)> cb)
{
if (!m_currentKey.empty())
return false;
Expand All @@ -481,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())
Expand Down Expand Up @@ -541,7 +545,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;
Expand Down Expand Up @@ -657,9 +661,9 @@ namespace ifd {

std::vector<std::string> 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;
Expand Down Expand Up @@ -873,7 +877,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)
Expand Down Expand Up @@ -1007,7 +1011,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;
Expand Down Expand Up @@ -1215,7 +1219,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<int>(m_content.size()) || m_content.size() == 0)
ImGui::CloseCurrentPopup();
else {
const FileData& data = m_content[m_selectedFileItem];
Expand Down Expand Up @@ -1327,7 +1331,9 @@ 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 (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);
Expand Down Expand Up @@ -1366,25 +1372,37 @@ 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<int>(m_filterSelection);
if (ImGui::Combo("##ext_combo", &sel, m_filter.c_str())) {
m_filterSelection = static_cast<size_t>(sel);
m_setDirectory(m_currentDirectory, false); // refresh
}
}

// user's additional widgets
if (m_cb)
m_cb(false);

// 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)
success = m_finalize(filename);
#ifdef _WIN32
if (!success)
MessageBeep(MB_ICONERROR);
#else
(void)success;
#endif
}
ImGui::SameLine();
Expand Down
12 changes: 7 additions & 5 deletions ImFileDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<float(bool)> cb = nullptr);

bool IsDone(const std::string& key);

Expand Down Expand Up @@ -108,7 +108,7 @@ namespace ifd {

std::string m_filter;
std::vector<std::vector<std::string>> m_filterExtensions;
int m_filterSelection;
size_t m_filterSelection;
void m_parseFilter(const std::string& filter);

std::vector<int> m_iconIndices;
Expand Down Expand Up @@ -137,8 +137,10 @@ namespace ifd {

void m_renderPopups();
void m_renderFileDialog();
};

static const char* GetDefaultFolderIcon();
static const char* GetDefaultFileIcon();
// 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<float(bool)> m_cb;
};
}
34 changes: 28 additions & 6 deletions example.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <SDL2/SDL.h>
#include <imgui/imgui.h>
#include <imgui/examples/imgui_impl_sdl.h>
#include <imgui/examples/imgui_impl_opengl3.h>
#include <imgui.h>
#include <backends/imgui_impl_sdl.h>
#include <backends/imgui_impl_opengl3.h>
#include <time.h>

#ifdef _WIN32
Expand Down Expand Up @@ -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)) {
Expand All @@ -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();
Expand All @@ -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();
}
Expand Down Expand Up @@ -166,4 +188,4 @@ int main(int argc, char* argv[])
SDL_Quit();

return 0;
}
}