File Browser basic functionality working

Gui_Panel_Refactor
Joeyrp 4 years ago
parent 18ce0d4375
commit 9e6a15d08f

@ -36,6 +36,7 @@ set(LUNARIUM_SRC
"src/input/keyboard.cpp" "src/input/keyboard.cpp"
"src/input/inputManager.cpp" "src/input/inputManager.cpp"
"src/gui/gui.cpp" "src/gui/gui.cpp"
"src/gui/fileBrowser.cpp"
"src/gui/logGui.cpp" "src/gui/logGui.cpp"
"src/gui/luaConsole.cpp" "src/gui/luaConsole.cpp"
"src/scripting/scriptManager.cpp" "src/scripting/scriptManager.cpp"

@ -32,6 +32,12 @@ Core:
✔ Add key to show debug log window @done (9/13/2021, 6:47:44 PM) ✔ Add key to show debug log window @done (9/13/2021, 6:47:44 PM)
☐ Add checkboxes to disable log categories and levels ☐ Add checkboxes to disable log categories and levels
✔ Add LUA Console window @done (10/26/2021, 4:43:41 PM) ✔ Add LUA Console window @done (10/26/2021, 4:43:41 PM)
FileBrowser:
✔ Allow opening of listed directories @done (11/8/2021, 3:16:26 PM)
✔ Add indication that an item is directory @done (11/8/2021, 6:19:20 PM)
✔ Sort items by type (Directories should come first) @done (11/8/2021, 6:26:01 PM)
☐ Allow the user to type in a filename
✔ Add a "New Directory" button @done (11/8/2021, 7:15:51 PM)
Input: Input:
✔ Port over the Element2D input system and adjust it to use glfw @done (9/8/2021, 8:20:07 PM) ✔ Port over the Element2D input system and adjust it to use glfw @done (9/8/2021, 8:20:07 PM)
@ -59,6 +65,7 @@ Core:
Utils: Utils:
✔ Make Logger fully static (no need to ever GetInstance) @done (10/26/2021, 4:43:55 PM) ✔ Make Logger fully static (no need to ever GetInstance) @done (10/26/2021, 4:43:55 PM)
✔ Need to add a static initialize method @done (10/26/2021, 4:43:57 PM) ✔ Need to add a static initialize method @done (10/26/2021, 4:43:57 PM)
☐ Add a templated return value to the OK variant of OpRes @low
Assets: Assets:

@ -4,7 +4,7 @@ The root project folder needs to contain a project.xml file that describes the p
Project directory structure (this should be auto-generated by the editor when creating a new project): Project directory structure (this should be auto-generated by the editor when creating a new project):
Project root Project root
├── project.xml ├── project.lproj (this is actually an xml file but the lproj extension allows it to be identified as a project file without opening it)
├── engine/ ├── engine/
│ └── Lunarium_NE.exe (non-editor version of the engine. Used for creating a release build of the project) │ └── Lunarium_NE.exe (non-editor version of the engine. Used for creating a release build of the project)

@ -0,0 +1,273 @@
/******************************************************************************
* 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 "fileBrowser.h"
#include <core/core.h>
#include <assets/types/image.h>
#include <graphics/igraphics.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)
{
int x,y,n;
unsigned char* pData = stbi_load("dir_icon.png", &x, &y, &n, 0);
mpFolderIcon = new Image(pData, x, y, ImageFormat::RGBA);
Core::Graphics().RegisterImage(*mpFolderIcon);
mpFolderIcon->FreeRawData();
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();
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();
}
/// 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;
}
ImVec2 iconSize(mpNewFolderIcon->GetWidth(), mpNewFolderIcon->GetHeight());
if (ImGui::ImageButton((ImTextureID) mpNewFolderIcon->GetGLTextureID(), iconSize))
{
ImGui::OpenPopup("New Folder Name");
memset(mInputBuffer, 0, mBufferSize);
}
if (ImGui::BeginPopup("New Folder Name"))
{
if (ImGui::InputText("Folder Name", mInputBuffer, mBufferSize, ImGuiInputTextFlags_EnterReturnsTrue))
{
std::filesystem::create_directory(mInputBuffer);
ImGui::CloseCurrentPopup();
ReloadItems();
}
ImGui::EndPopup();
}
ImGui::SameLine();
iconSize = ImVec2(mpUpFolderIcon->GetWidth(), mpUpFolderIcon->GetHeight());
if (ImGui::ImageButton((ImTextureID) mpUpFolderIcon->GetGLTextureID(), iconSize))
{
mCurrentDirectory = mCurrentDirectory.parent_path();
ReloadItems();
}
ImGui::SameLine();
ImGui::TextUnformatted(mCurrentDirectory.string().c_str());
DoListBox();
ImGui::Separator();
if (mpSelectedItem)
{
ImGui::Text("Selected: %s", mpSelectedItem->filename().string().c_str());
}
else
{
ImGui::Text("Selected: ");
}
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;
}
/// 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 strcmpi(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() * .65f)))
{
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->GetGLTextureID();
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;
}
}

@ -0,0 +1,81 @@
/******************************************************************************
* File - fileBrowser.h
* 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.
******************************************************************************/
// Some useful links:
// https://en.cppreference.com/w/cpp/filesystem/is_directory
// https://en.cppreference.com/w/cpp/filesystem/path
#ifndef FILE_SELECT_H_
#define FILE_SELECT_H_
#include <utils/opRes.h>
#include <vector>
#include <filesystem>
namespace lunarium
{
class Image;
class FileBrowser
{
public:
enum Result
{
OK,
CANCEL
};
enum SelectionMode
{
FILES_ONLY,
DIRECTORIES_ONLY,
ANY,
};
public:
FileBrowser();
bool OpenInDirectory(std::filesystem::path path);
bool DoFrame();
bool IsOpen() const;
void AddExtensionFilter(std::string ext);
void SetSelectionMode(SelectionMode mode);
void WarnOnExistingFileSelection(bool warn);
// returns nullptr if the dialog has not been opened yet
const std::filesystem::path* GetSelectedItem() const;
Result GetResult() const;
private:
bool mIsOpen;
SelectionMode mSelectionMode;
bool mWarnOnExisting;
Result mResult;
std::filesystem::path mCurrentDirectory;
std::vector<std::filesystem::path> mItemsInDir;
std::vector<std::string> mExtensionsFilter; // Show only these extensions. If empty show all files.
std::filesystem::path* mpSelectedItem;
Image* mpFolderIcon;
Image* mpNewFolderIcon;
Image* mpUpFolderIcon;
static const int mBufferSize = 256;
char mInputBuffer[mBufferSize];
private:
void ReloadItems();
void DoListBox();
bool DoButtons();
};
}
#endif // FILE_SELECT_H_

@ -18,6 +18,21 @@ namespace lunarium
{ {
} }
Image::Image(unsigned char* data, int width, int height, ImageFormat format)
: Asset(AssetType::ASSET_TYPE_IMAGE), mRawData(data), mRawDataSize(width * height), mWidth(width), mHeight(height), mGLTextureID((unsigned)-1)
{
mFormat = format;
if (mFormat == ImageFormat::RGB)
{
mRawDataSize *= 3;
}
else if (mFormat == ImageFormat::RGBA)
{
mRawDataSize *= 4;
}
}
Image::~Image() Image::~Image()
{ {
delete[] mRawData; delete[] mRawData;

@ -19,6 +19,7 @@ namespace lunarium
{ {
public: public:
Image(); Image();
Image(unsigned char* data, int width, int height, ImageFormat format);
~Image(); ~Image();
unsigned int GetGLTextureID() const; unsigned int GetGLTextureID() const;

@ -7,7 +7,9 @@
******************************************************************************/ ******************************************************************************/
#include "helpers.h" #include "helpers.h"
#include "logger.h"
#include <algorithm> #include <algorithm>
#include <filesystem>
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
@ -38,6 +40,28 @@ namespace lunarium
return glsl_version; return glsl_version;
} }
////////////////////////////////////////////////////////////
// FILE SYSTEM FUNCTIONS
////////////////////////////////////////////////////////////
std::vector<std::string> FileSystem::GetFilesInDirectory(std::string path)
{
std::vector<std::string> files;
for (auto &p : std::filesystem::recursive_directory_iterator(path))
{
files.push_back(p.path().filename().string());
}
return files;
}
bool FileSystem::MakeDir(std::string path)
{
if (std::filesystem::exists(path))
return false;
return std::filesystem::create_directory(path);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// MATH FUNCTIONS // MATH FUNCTIONS
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

@ -23,6 +23,13 @@ namespace lunarium
static std::string GetGLSLVersionString(); static std::string GetGLSLVersionString();
}; };
class FileSystem
{
public:
static std::vector<std::string> GetFilesInDirectory(std::string path);
static bool MakeDir(std::string path);
};
class Math class Math
{ {
public: public:

@ -11,6 +11,7 @@
#include "panels/mainPanel.h" #include "panels/mainPanel.h"
#include <core/core.h> #include <core/core.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <gui/fileBrowser.h>
// Panels // Panels
#include "panels/about.h" #include "panels/about.h"
@ -18,7 +19,7 @@
namespace lunarium namespace lunarium
{ {
Editor::Editor() Editor::Editor()
: mLogCat(-1), mpMainPanel(nullptr), mDoNewProject(false), mDoOpenProject(false), : mLogCat(-1), mpMainPanel(nullptr), mpFileBrowser(nullptr), mpPath(nullptr), mDoNewProject(false), mDoOpenProject(false),
mDoSaveProject(false), mDoSaveAs(false) mDoSaveProject(false), mDoSaveAs(false)
{ {
} }
@ -55,6 +56,15 @@ namespace lunarium
iter->second->DoFrame(); iter->second->DoFrame();
} }
} }
if (mpFileBrowser)
{
if (!mpFileBrowser->DoFrame())
{
mpPath = mpFileBrowser->GetSelectedItem();
}
}
} }
uint32_t Editor::GetLogCat() const uint32_t Editor::GetLogCat() const
@ -76,9 +86,41 @@ namespace lunarium
// FILE // FILE
if (mDoNewProject) if (mDoNewProject)
{ {
if (!mpFileBrowser)
{
mpFileBrowser = new FileBrowser;
// mpFileBrowser->WarnOnExistingFileSelection(true);
mpFileBrowser->SetSelectionMode(FileBrowser::SelectionMode::DIRECTORIES_ONLY);
if (!mpFileBrowser->OpenInDirectory(""))
{
delete mpFileBrowser;
mpFileBrowser = nullptr;
Logger::Log(mLogCat, LogLevel::ERROR, "Could not open the File Browser");
}
}
else
{
if (!mpFileBrowser->IsOpen())
{
if (mpFileBrowser->GetResult() == FileBrowser::Result::OK)
{
Logger::Log(mLogCat, LogLevel::INFO, "Generating new project at %s", mpPath->string().c_str());
// TODO: Generate new project at mpPath
}
else
{
Logger::Log(mLogCat, LogLevel::INFO, "New Project operation cancelled");
}
mpPath = nullptr;
delete mpFileBrowser;
mpFileBrowser = nullptr;
mDoNewProject = false; mDoNewProject = false;
} }
}
}
if (mDoOpenProject) if (mDoOpenProject)
{ {

@ -13,10 +13,12 @@
#include <utils/opRes.h> #include <utils/opRes.h>
#include "panels/iPanel.h" #include "panels/iPanel.h"
#include <filesystem>
#include <map> #include <map>
namespace lunarium namespace lunarium
{ {
class FileBrowser;
class MainPanel; class MainPanel;
class Editor : public iRunMode class Editor : public iRunMode
{ {
@ -48,6 +50,9 @@ namespace lunarium
MainPanel* mpMainPanel; MainPanel* mpMainPanel;
std::map<PanelType, Panel*> mPanels; std::map<PanelType, Panel*> mPanels;
FileBrowser* mpFileBrowser;
const std::filesystem::path* mpPath;
// Menu Bar Events // Menu Bar Events
// Don't want to handles these events during rendering // Don't want to handles these events during rendering
bool mDoNewProject; bool mDoNewProject;

@ -15,6 +15,9 @@ namespace lunarium
{ {
PT_MAIN, PT_MAIN,
PT_ABOUT, PT_ABOUT,
PT_SCENE_TREE,
PT_CONTENT_BROWSER,
PT_CONSOLE,
PT_UNKNOWN, PT_UNKNOWN,
}; };

@ -0,0 +1,14 @@
/******************************************************************************
* File - sceneTree.cpp
* Author - Joey Pollack
* Date - 2021/11/04 (y/m/d)
* Mod Date - 2021/11/04 (y/m/d)
* Description - The tree view listing all objects in the scene
******************************************************************************/
#include "sceneTree.h"
namespace lunarium
{
}

@ -0,0 +1,22 @@
/******************************************************************************
* File - sceneTree.h
* Author - Joey Pollack
* Date - 2021/11/04 (y/m/d)
* Mod Date - 2021/11/04 (y/m/d)
* Description - The tree view listing all objects in the scene
******************************************************************************/
#ifndef SCENE_TREE_H_
#define SCENE_TREE_H_
#include "iPanel.h"
namespace lunarium
{
class SceneTree : public Panel
{
};
}
#endif // SCENE_TREE_H_

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
Loading…
Cancel
Save