You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lunarium_OLD/src/internal_libs/gui/file_browser.cpp

290 lines
8.7 KiB
C++

/******************************************************************************
* File - fileBrowser.cpp
* Author - Joey Pollack
* Date - 2021/11/04 (y/m/d)
* Mod Date - 2021/11/04 (y/m/d)
* Description - File browser dialog window. Can be used for opening
* and saving files.
******************************************************************************/
#include "file_browser.h"
#include <algorithm>
#include <cstring>
#include <core/core.h>
#include <assets/types/image.h>
#include <graphics/igraphics.h>
#include <internal_data/dataManager.h>
#include <utils/stb/stb_image.h>
#include "dearimgui/imgui.h"
namespace lunarium
{
FileBrowser::FileBrowser()
: mIsOpen(false), mSelectionMode(SelectionMode::FILES_ONLY), mWarnOnExisting(false), mpFolderIcon(nullptr), mResult(Result::CANCEL),
mpNewFolderIcon(nullptr), mpUpFolderIcon(nullptr)
{
mPrompt = "Select an item";
memset(mDirNameBuffer, 0, mBufferSize);
memset(mInputBuffer, 0, mBufferSize);
int x,y,n;
// unsigned char* pData = stbi_load("folder16.png", &x, &y, &n, 0);
// mpFolderIcon = new Image(pData, x, y, ImageFormat::RGBA);
// Core::Graphics().RegisterImage(*mpFolderIcon);
// mpFolderIcon->FreeRawData();
mpFolderIcon = DataManager::mFolderIcon;
// unsigned char* pData = stbi_load("new_dir_icon.png", &x, &y, &n, 0);
// mpNewFolderIcon = new Image(pData, x, y, ImageFormat::RGBA);
// Core::Graphics().RegisterImage(*mpNewFolderIcon);
// mpNewFolderIcon->FreeRawData();
mpNewFolderIcon = DataManager::mNewFolderIcon;
// pData = stbi_load("up_arrow_icon.png", &x, &y, &n, 0);
// mpUpFolderIcon = new Image(pData, x, y, ImageFormat::RGBA);
// Core::Graphics().RegisterImage(*mpUpFolderIcon);
// mpUpFolderIcon->FreeRawData();
mpUpFolderIcon = DataManager::mUpArrowIcon;
}
/// If the given path does not exist this will default to the
/// current working directory
bool FileBrowser::OpenInDirectory(std::filesystem::path path)
{
if (mIsOpen)
return false;
if (!std::filesystem::exists(path))
path = std::filesystem::current_path();
if (!std::filesystem::is_directory(path))
return false;
mCurrentDirectory = path;
// Get list of items in the current directory
ReloadItems();
mIsOpen = true;
return true;
}
bool FileBrowser::DoFrame()
{
if (!mIsOpen)
return false;
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Appearing);
if (!ImGui::Begin("File Browser", &mIsOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking))
{
ImGui::End();
return false;
}
ImGui::TextUnformatted(mPrompt.c_str());
ImGui::Separator();
ImVec2 iconSize(mpNewFolderIcon->GetWidth(), mpNewFolderIcon->GetHeight());
if (ImGui::ImageButton((ImTextureID) mpNewFolderIcon->GetGLTextureID64(), iconSize))
{
ImGui::OpenPopup("New Folder Name");
memset(mDirNameBuffer, 0, mBufferSize);
}
if (ImGui::BeginPopup("New Folder Name"))
{
if (ImGui::InputText("Folder Name", mDirNameBuffer, mBufferSize, ImGuiInputTextFlags_EnterReturnsTrue))
{
std::filesystem::create_directory(mDirNameBuffer);
ImGui::CloseCurrentPopup();
ReloadItems();
}
ImGui::EndPopup();
}
ImGui::SameLine();
iconSize = ImVec2(mpUpFolderIcon->GetWidth(), mpUpFolderIcon->GetHeight());
if (ImGui::ImageButton((ImTextureID) mpUpFolderIcon->GetGLTextureID64(), iconSize))
{
mCurrentDirectory = mCurrentDirectory.parent_path();
ReloadItems();
}
ImGui::SameLine();
ImGui::TextUnformatted(mCurrentDirectory.string().c_str());
DoListBox();
ImGui::Separator();
if (ImGui::InputText("selection", mInputBuffer, mBufferSize))
{
mInputSelection = mCurrentDirectory / mInputBuffer;
mpSelectedItem = &mInputSelection;
}
ImGui::Separator();
bool res = DoButtons();
ImGui::End();
return res;
}
void FileBrowser::AddExtensionFilter(std::string ext)
{
mExtensionsFilter.push_back(ext);
}
void FileBrowser::SetSelectionMode(SelectionMode mode)
{
mSelectionMode = mode;
}
void FileBrowser::WarnOnExistingFileSelection(bool warn)
{
mWarnOnExisting = warn;
}
void FileBrowser::SetPrompt(std::string prompt)
{
mPrompt = prompt;
}
/// returns nullptr if the dialog has not been opened yet
const std::filesystem::path* FileBrowser::GetSelectedItem() const
{
return mpSelectedItem;
}
FileBrowser::Result FileBrowser::GetResult() const
{
return mResult;
}
bool FileBrowser::IsOpen() const
{
return mIsOpen;
}
void FileBrowser::ReloadItems()
{
mpSelectedItem = nullptr;
mItemsInDir.clear();
for(auto const& dir_entry: std::filesystem::directory_iterator{mCurrentDirectory})
{
mItemsInDir.push_back(dir_entry.path());
}
// Sort by type and then by name
std::sort(mItemsInDir.begin(), mItemsInDir.end(), [](std::filesystem::path& lhs, std::filesystem::path& rhs)
{
if (std::filesystem::is_directory(lhs) && std::filesystem::is_directory(rhs))
{
return strcmp(lhs.filename().string().c_str(), rhs.filename().string().c_str()) < 0;
}
if (std::filesystem::is_directory(lhs) && !std::filesystem::is_directory(rhs))
{
return true;
}
return false;
});
}
////////////////////////////////////////////////////////////
// RENDER HELPER METHODS
////////////////////////////////////////////////////////////
void FileBrowser::DoListBox()
{
if (ImGui::BeginListBox("", ImVec2(ImGui::GetWindowWidth(), ImGui::GetWindowHeight() * .575f)))
{
for (int i = 0; i < mItemsInDir.size(); i++)
{
if (std::filesystem::is_directory(mItemsInDir[i]))
{
ImVec2 size(mpFolderIcon->GetWidth(), mpFolderIcon->GetHeight());
ImTextureID id = (ImTextureID) mpFolderIcon->GetGLTextureID64();
ImGui::Image(id, size);
ImGui::SameLine();
}
if (ImGui::Selectable(mItemsInDir[i].filename().string().c_str()))
{
if (std::filesystem::is_directory(mItemsInDir[i]))
{
mCurrentDirectory /= mItemsInDir[i];
ReloadItems();
if (mSelectionMode == SelectionMode::DIRECTORIES_ONLY || mSelectionMode == SelectionMode::ANY)
{
mpSelectedItem = &mCurrentDirectory;
}
}
else
{
if (mSelectionMode == SelectionMode::FILES_ONLY || mSelectionMode == SelectionMode::ANY)
{
mpSelectedItem = &mItemsInDir[i];
}
}
}
}
ImGui::EndListBox();
}
}
bool FileBrowser::DoButtons()
{
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 100.0f);
if (ImGui::Button("OK"))
{
if (std::filesystem::exists(*mpSelectedItem) && mWarnOnExisting)
{
ImGui::OpenPopup("Warn");
}
else
{
mResult = Result::OK;
mIsOpen = false;
return false;
}
}
if (ImGui::BeginPopup("Warn"))
{
ImGui::Text("This file already exists. Are you sure you want to overwrite it?");
if (ImGui::Button("Yes"))
{
mResult = Result::OK;
mIsOpen = false;
ImGui::EndPopup();
return false;
}
ImGui::SameLine();
if (ImGui::Button("No"))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel"))
{
mResult = Result::CANCEL;
mIsOpen = false;
return false;
}
return true;
}
}