mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-09 20:08:57 +03:00
1058 lines
37 KiB
C++
1058 lines
37 KiB
C++
|
|
#include "FileSystemUI.h"
|
|
|
|
#include <imgui/imgui.h>
|
|
|
|
#include <imgui/imgui_internal.h>
|
|
#include "Nuake/Resource/FontAwesome5.h"
|
|
#include "Nuake/Scene/Components/ParentComponent.h"
|
|
#include "Nuake/Rendering/Textures/Texture.h"
|
|
#include "Nuake/Rendering/Textures/TextureManager.h"
|
|
#include "EditorInterface.h"
|
|
|
|
#include <Nuake/Rendering/Textures/Material.h>
|
|
#include "../Misc/PopupHelper.h"
|
|
#include <Nuake/FileSystem/FileDialog.h>
|
|
#include <Nuake/FileSystem/Directory.h>
|
|
#include <Nuake/FileSystem/File.h>
|
|
#include "Nuake/Scene/Systems/WadConverter.h"
|
|
#include "../Misc/ThumbnailManager.h"
|
|
|
|
#include <Nuake/Resource/SkyResource.h>
|
|
|
|
namespace Nuake
|
|
{
|
|
Ref<Directory> FileSystemUI::m_CurrentDirectory;
|
|
|
|
void FileSystemUI::Draw()
|
|
{
|
|
|
|
}
|
|
|
|
void FileSystemUI::DrawDirectoryContent()
|
|
{
|
|
}
|
|
|
|
void FileSystemUI::DrawFiletree()
|
|
{
|
|
}
|
|
|
|
|
|
std::string renameTempValue = "";
|
|
|
|
void FileSystemUI::EditorInterfaceDrawFiletree(Ref<Directory> dir)
|
|
{
|
|
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding;
|
|
//if (is_selected)
|
|
|
|
if (m_CurrentDirectory == dir)
|
|
base_flags |= ImGuiTreeNodeFlags_Selected;
|
|
if (dir->Directories.size() <= 0)
|
|
base_flags |= ImGuiTreeNodeFlags_Leaf;
|
|
|
|
std::string icon = ICON_FA_FOLDER;
|
|
bool open = ImGui::TreeNodeEx((icon + " " + dir->Name.c_str()).c_str(), base_flags);
|
|
|
|
if (ImGui::IsItemClicked())
|
|
m_CurrentDirectory = dir;
|
|
|
|
if (open)
|
|
{
|
|
if (dir->Directories.size() > 0)
|
|
for (auto& d : dir->Directories)
|
|
EditorInterfaceDrawFiletree(d);
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
|
|
void FileSystemUI::DrawDirectory(Ref<Directory> directory, uint32_t drawId)
|
|
{
|
|
ImGui::PushFont(FontManager::GetFont(Icons));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
|
const char* icon = ICON_FA_FOLDER;
|
|
const std::string id = std::string("##") + directory->Name;
|
|
|
|
ImVec2 prevCursor = ImGui::GetCursorPos();
|
|
ImVec2 prevScreenPos = ImGui::GetCursorScreenPos();
|
|
const bool selected = ImGui::Selectable(id.c_str(), Editor->Selection.Directory == directory, ImGuiSelectableFlags_AllowOverlap | ImGuiSelectableFlags_AllowDoubleClick, ImVec2(100, 150));
|
|
const std::string hoverMenuId = std::string("item_hover_menu") + std::to_string(drawId);
|
|
if (ImGui::IsItemHovered() && ImGui::IsMouseReleased(1))
|
|
{
|
|
ImGui::OpenPopup(hoverMenuId.c_str());
|
|
m_HasClickedOnFile = true;
|
|
}
|
|
|
|
const std::string renameId = "Rename" + std::string("##") + hoverMenuId;
|
|
bool shouldRename = false;
|
|
|
|
const std::string deleteId = "Delete" + std::string("##") + hoverMenuId;
|
|
bool shouldDelete = false;
|
|
|
|
if (selected)
|
|
{
|
|
if (ImGui::IsMouseDoubleClicked(0))
|
|
{
|
|
m_CurrentDirectory = directory;
|
|
}
|
|
|
|
//Editor->Selection = EditorSelection(directory);
|
|
}
|
|
|
|
if (ImGui::IsItemHovered())
|
|
ImGui::SetTooltip(directory->Name.c_str());
|
|
|
|
|
|
ImGui::SetCursorPos(prevCursor);
|
|
ImGui::Image((ImTextureID)TextureManager::Get()->GetTexture2("Resources/Images/folder_icon.png")->GetImGuiDescriptorSet(), ImVec2(100, 100));
|
|
|
|
auto imguiStyle = ImGui::GetStyle();
|
|
|
|
ImVec2 startOffset = ImVec2(imguiStyle.CellPadding.x / 2.0f, 0);
|
|
ImVec2 offsetEnd = ImVec2(startOffset.x, imguiStyle.CellPadding.y / 2.0f);
|
|
ImU32 rectColor = IM_COL32(255, 255, 255, 16);
|
|
ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 100) - startOffset, prevScreenPos + ImVec2(100, 150) + offsetEnd, rectColor, 1.0f);
|
|
std::string visibleName = directory->Name;
|
|
const uint32_t MAX_CHAR_NAME = 34;
|
|
if (directory->Name.size() > MAX_CHAR_NAME)
|
|
{
|
|
visibleName = std::string(directory->Name.begin(), directory->Name.begin() + MAX_CHAR_NAME - 3) + "...";
|
|
}
|
|
|
|
ImGui::TextWrapped(visibleName.c_str());
|
|
|
|
ImGui::SetCursorPosY(prevCursor.y + 150 - ImGui::GetTextLineHeight());
|
|
ImGui::TextColored({ 1, 1, 1, 0.5f }, "Folder");
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
|
|
if (ImGui::BeginPopup(hoverMenuId.c_str()))
|
|
{
|
|
if (ImGui::MenuItem("Open"))
|
|
{
|
|
m_CurrentDirectory = directory;
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::BeginMenu("Copy"))
|
|
{
|
|
if (ImGui::MenuItem("Full Path"))
|
|
{
|
|
OS::CopyToClipboard(directory->FullPath);
|
|
}
|
|
|
|
if (ImGui::MenuItem("Directory Name"))
|
|
{
|
|
OS::CopyToClipboard(String::Split(directory->Name, '/')[0]);
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
if (ImGui::MenuItem("Delete"))
|
|
{
|
|
shouldDelete = true;
|
|
}
|
|
|
|
if (ImGui::MenuItem("Rename"))
|
|
{
|
|
shouldRename = true;
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::MenuItem("Show in File Explorer"))
|
|
{
|
|
OS::OpenIn(directory->FullPath);
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
// Rename Popup
|
|
|
|
if (shouldRename)
|
|
{
|
|
renameTempValue = directory->Name;
|
|
PopupHelper::OpenPopup(renameId);
|
|
}
|
|
|
|
if (PopupHelper::DefineTextDialog(renameId, renameTempValue))
|
|
{
|
|
if (OS::RenameDirectory(directory, renameTempValue) != 0)
|
|
{
|
|
Logger::Log("Cannot rename directory: " + renameTempValue, "editor", CRITICAL);
|
|
}
|
|
RefreshFileBrowser();
|
|
renameTempValue = "";
|
|
}
|
|
|
|
// Delete Popup
|
|
|
|
if(shouldDelete)
|
|
{
|
|
PopupHelper::OpenPopup(deleteId);
|
|
}
|
|
|
|
if(PopupHelper::DefineConfirmationDialog(deleteId, " Are you sure you want to delete the folder and all its children?\n This action cannot be undone, and all data within the folder \n will be permanently lost."))
|
|
{
|
|
if (FileSystem::DeleteFolder(directory->FullPath) != 0)
|
|
{
|
|
Logger::Log("Failed to remove directory: " + directory->Name, "editor", CRITICAL);
|
|
}
|
|
RefreshFileBrowser();
|
|
}
|
|
|
|
ImGui::PopFont();
|
|
}
|
|
|
|
bool FileSystemUI::EntityContainsItself(Entity source, Entity target)
|
|
{
|
|
ParentComponent& targeParentComponent = target.GetComponent<ParentComponent>();
|
|
if (!targeParentComponent.HasParent)
|
|
return false;
|
|
|
|
Entity currentParent = target.GetComponent<ParentComponent>().Parent;
|
|
while (currentParent != source)
|
|
{
|
|
if (currentParent.GetComponent<ParentComponent>().HasParent)
|
|
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
|
else
|
|
return false;
|
|
|
|
if (currentParent == source)
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void FileSystemUI::DrawFile(Ref<File> file, uint32_t drawId)
|
|
{
|
|
ImGui::PushFont(EditorInterface::bigIconFont);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, {0.f, 0.f});
|
|
std::string fileExtension = file->GetExtension();
|
|
|
|
ImVec2 prevCursor = ImGui::GetCursorPos();
|
|
ImVec2 prevScreenPos = ImGui::GetCursorScreenPos();
|
|
std::string id = std::string("##") + file->GetAbsolutePath();
|
|
const bool selected = ImGui::Selectable(id.c_str(), Editor->Selection.File == file, ImGuiSelectableFlags_AllowOverlap | ImGuiSelectableFlags_AllowDoubleClick, ImVec2(100, 150));
|
|
|
|
const std::string hoverMenuId = std::string("item_hover_menu") + std::to_string(drawId);
|
|
if (ImGui::IsItemHovered() && ImGui::IsMouseReleased(1))
|
|
{
|
|
ImGui::OpenPopup(hoverMenuId.c_str());
|
|
m_HasClickedOnFile = true;
|
|
}
|
|
|
|
bool shouldOpenScene = false;
|
|
if (selected)
|
|
{
|
|
if (ImGui::IsMouseDoubleClicked(0))
|
|
{
|
|
switch (file->GetFileType())
|
|
{
|
|
case FileType::Map:
|
|
OS::OpenTrenchbroomMap(file->GetAbsolutePath());
|
|
break;
|
|
case FileType::NetScript:
|
|
case FileType::UI:
|
|
case FileType::CSS:
|
|
OS::OpenIn(file->GetAbsolutePath());
|
|
break;
|
|
case FileType::Scene:
|
|
//shouldOpenScene = true;
|
|
this->Editor->OpenSceneWindow(file->GetRelativePath());
|
|
break;
|
|
case FileType::Solution:
|
|
OS::OpenIn(file->GetAbsolutePath());
|
|
break;
|
|
case FileType::Prefab:
|
|
this->Editor->OpenPrefabWindow(file->GetRelativePath());
|
|
break;
|
|
}
|
|
}
|
|
|
|
Editor->Selection = EditorSelection(file);
|
|
}
|
|
|
|
if (ImGui::IsItemHovered())
|
|
ImGui::SetTooltip(file->GetName().c_str());
|
|
|
|
if (ImGui::BeginDragDropSource())
|
|
{
|
|
char pathBuffer[256];
|
|
std::strncpy(pathBuffer, file->GetAbsolutePath().c_str(), sizeof(pathBuffer));
|
|
std::string dragType;
|
|
if (fileExtension == ".wren")
|
|
{
|
|
dragType = "_Script";
|
|
}
|
|
else if (fileExtension == ".cs")
|
|
{
|
|
dragType = "_NetScript";
|
|
}
|
|
else if (fileExtension == ".map")
|
|
{
|
|
dragType = "_Map";
|
|
}
|
|
else if (fileExtension == ".material")
|
|
{
|
|
dragType = "_Material";
|
|
}
|
|
else if (fileExtension == ".nkmesh" || fileExtension == ".obj" || fileExtension == ".mdl" || fileExtension == ".gltf" || fileExtension == ".md3" || fileExtension == ".fbx" || fileExtension == ".glb")
|
|
{
|
|
dragType = "_Model";
|
|
}
|
|
else if (fileExtension == ".interface")
|
|
{
|
|
dragType = "_Interface";
|
|
}
|
|
else if (fileExtension == ".prefab")
|
|
{
|
|
dragType = "_Prefab";
|
|
}
|
|
else if (fileExtension == ".png" || fileExtension == ".jpg")
|
|
{
|
|
dragType = "_Image";
|
|
}
|
|
else if (fileExtension == ".wav" || fileExtension == ".ogg")
|
|
{
|
|
dragType = "_AudioFile";
|
|
}
|
|
else if (fileExtension == ".html")
|
|
{
|
|
dragType = "_UIFile";
|
|
}
|
|
else if (fileExtension == ".sky")
|
|
{
|
|
dragType = "_SkyFile";
|
|
}
|
|
else if (fileExtension == ".env")
|
|
{
|
|
dragType = "_EnvFile";
|
|
}
|
|
|
|
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
|
|
ImGui::Text(file->GetName().c_str());
|
|
ImGui::EndDragDropSource();
|
|
}
|
|
|
|
|
|
Ref<VulkanImage> textureImage = TextureManager::Get()->GetTexture2("Resources/Images/file_icon.png");
|
|
|
|
const auto textureMgr = TextureManager::Get();
|
|
const auto fileType = file->GetFileType();
|
|
if (fileType == FileType::Material)
|
|
{
|
|
//auto image = ThumbnailManager::Get().GetThumbnail(file->GetRelativePath());
|
|
//if (image)
|
|
//{
|
|
// textureImage = image;
|
|
//}
|
|
}
|
|
else if (fileType == FileType::Image)
|
|
{
|
|
const std::string path = file->GetAbsolutePath();
|
|
textureImage = textureMgr->GetTexture2(path);
|
|
}
|
|
else if (fileType == FileType::Project)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/project_icon.png");
|
|
}
|
|
else if (fileType == FileType::NetScript)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/csharp_icon.png");
|
|
}
|
|
else if (fileType == FileType::Scene)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/scene_icon.png");
|
|
}
|
|
else if (fileType == FileType::Script)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/script_file_icon.png");
|
|
}
|
|
else if (fileType == FileType::Audio)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/audio_file_icon.png");
|
|
}
|
|
else if (fileType == FileType::Prefab)
|
|
{
|
|
//auto image = ThumbnailManager::Get().GetThumbnail(file->GetRelativePath());
|
|
//if (image)
|
|
//{
|
|
// textureImage = image;
|
|
//}
|
|
}
|
|
else if (fileType == FileType::Mesh)
|
|
{
|
|
//auto image = ThumbnailManager::Get().GetThumbnail(file->GetRelativePath());
|
|
//if (image)
|
|
//{
|
|
// textureImage = image;
|
|
//}
|
|
}
|
|
else if (fileType == FileType::Solution)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/sln_icon.png");
|
|
}
|
|
else if (fileType == FileType::Map)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/trenchbroom_icon.png");
|
|
}
|
|
else if (fileType == FileType::Env)
|
|
{
|
|
textureImage = textureMgr->GetTexture2("Resources/Images/env_file_icon.png");
|
|
}
|
|
|
|
ImGui::SetCursorPos(prevCursor);
|
|
ImGui::Image(reinterpret_cast<ImTextureID>(textureImage->GetImGuiDescriptorSet()), ImVec2(100, 100));
|
|
ImGui::PopStyleVar();
|
|
|
|
auto& imguiStyle = ImGui::GetStyle();
|
|
|
|
ImVec2 startOffset = ImVec2(imguiStyle.CellPadding.x / 2.0f, 0);
|
|
ImVec2 offsetEnd = ImVec2(startOffset.x, imguiStyle.CellPadding.y / 2.0f);
|
|
ImU32 rectColor = IM_COL32(255, 255, 255, 16);
|
|
ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 100) - startOffset, prevScreenPos + ImVec2(100, 150) + offsetEnd, rectColor, 1.0f);
|
|
|
|
ImU32 rectColor2 = UI::PrimaryCol;
|
|
Color fileTypeColor = GetColorByFileType(file->GetFileType());
|
|
ImGui::GetWindowDrawList()->AddRectFilled(prevScreenPos + ImVec2(0, 100) - startOffset, prevScreenPos + ImVec2(100, 101) + offsetEnd, IM_COL32(fileTypeColor.r * 255.f, fileTypeColor.g * 255.f, fileTypeColor.b * 255.f, fileTypeColor.a * 255.f), 0.0f);
|
|
|
|
std::string visibleName = file->GetName();
|
|
const uint32_t MAX_CHAR_NAME = 32;
|
|
if (file->GetName().size() >= MAX_CHAR_NAME)
|
|
{
|
|
visibleName = std::string(visibleName.begin(), visibleName.begin() + MAX_CHAR_NAME - 3) + "...";
|
|
}
|
|
|
|
ImGui::TextWrapped(visibleName.c_str());
|
|
|
|
ImGui::SetCursorPosY(prevCursor.y + 150 - ImGui::GetTextLineHeight());
|
|
ImGui::TextColored({ 1, 1, 1, 0.5f }, file->GetFileTypeAsString().c_str());
|
|
|
|
//if (fileExtension == ".png" || fileExtension == ".jpg")
|
|
//{
|
|
//
|
|
//}
|
|
//else
|
|
//{
|
|
// const char* icon = ICON_FA_FILE;
|
|
// if (fileExtension == ".shader" || fileExtension == ".wren")
|
|
// icon = ICON_FA_FILE_CODE;
|
|
// if (fileExtension == ".map")
|
|
// icon = ICON_FA_BROOM;
|
|
// if (fileExtension == ".ogg" || fileExtension == ".mp3" || fileExtension == ".wav")
|
|
// icon = ICON_FA_FILE_AUDIO;
|
|
// if (fileExtension == ".gltf" || fileExtension == ".obj")
|
|
// icon = ICON_FA_FILE_IMAGE;
|
|
//
|
|
// std::string fullName = icon + std::string("##") + file->GetAbsolutePath();
|
|
//
|
|
// bool pressed = false;
|
|
// if (fileExtension == ".material")
|
|
// {
|
|
// ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
|
// pressed = ImGui::ImageButton(fullName.c_str(), (void*)ThumbnailManager::Get().GetThumbnail(file-//>GetRelativePath())->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0));
|
|
// ImGui::PopStyleVar();
|
|
// }
|
|
// else
|
|
// {
|
|
// ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
|
// pressed = ImGui::Button(fullName.c_str(), ImVec2(100, 100));
|
|
// ImGui::PopStyleVar();
|
|
// }
|
|
//
|
|
if (Editor->Selection.File == file && Editor->Selection.File->GetFileType() != FileType::Prefab)
|
|
{
|
|
ThumbnailManager::Get().MarkThumbnailAsDirty(file->GetRelativePath());
|
|
}
|
|
|
|
// if(pressed)
|
|
// {
|
|
// Editor->Selection = EditorSelection(file);
|
|
// }
|
|
//
|
|
// if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
|
|
// {
|
|
// OS::OpenTrenchbroomMap(file->GetAbsolutePath());
|
|
// }
|
|
//}
|
|
ImGui::PopStyleVar();
|
|
|
|
const std::string openSceneId = "Open Scene" + std::string("##") + hoverMenuId;
|
|
|
|
|
|
const std::string renameId = "Rename" + std::string("##") + hoverMenuId;
|
|
bool shouldRename = false;
|
|
|
|
const std::string deleteId = "Delete" + std::string("##") + hoverMenuId;
|
|
bool shouldDelete = false;
|
|
|
|
if (ImGui::BeginPopup(hoverMenuId.c_str()))
|
|
{
|
|
if (file->GetExtension() != ".scene")
|
|
{
|
|
if (ImGui::MenuItem("Open in Editor"))
|
|
{
|
|
OS::OpenIn(file->GetAbsolutePath());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ImGui::MenuItem("Load Scene"))
|
|
{
|
|
shouldOpenScene = true;
|
|
}
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::BeginMenu("Copy"))
|
|
{
|
|
if (ImGui::MenuItem("Full Path"))
|
|
{
|
|
OS::CopyToClipboard(file->GetAbsolutePath());
|
|
}
|
|
|
|
if (ImGui::MenuItem("File Name"))
|
|
{
|
|
OS::CopyToClipboard(file->GetName());
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
if (file->GetExtension() != ".project")
|
|
{
|
|
if (ImGui::MenuItem("Delete"))
|
|
{
|
|
shouldDelete = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 0.2f));
|
|
ImGui::MenuItem("Delete");
|
|
ImGui::PopStyleColor();
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::BeginTooltip();
|
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
|
ImGui::TextUnformatted("The file you're trying to delete is currently loaded by the game engine.");
|
|
ImGui::PopTextWrapPos();
|
|
ImGui::EndTooltip();
|
|
}
|
|
}
|
|
|
|
if (file->GetExtension() == ".wad")
|
|
{
|
|
if (ImGui::MenuItem("Convert to Materials"))
|
|
{
|
|
Nuake::ExtractWad(file->GetAbsolutePath(), FileSystem::Root);
|
|
}
|
|
}
|
|
|
|
if (ImGui::MenuItem("Rename"))
|
|
{
|
|
shouldRename = true;
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::MenuItem("Show in File Explorer"))
|
|
{
|
|
OS::ShowInFileExplorer(file->GetAbsolutePath());
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
// Open Scene Popup
|
|
|
|
if (shouldOpenScene)
|
|
{
|
|
PopupHelper::OpenPopup(openSceneId);
|
|
}
|
|
|
|
if (PopupHelper::DefineConfirmationDialog(openSceneId, " Open the scene? \n Changes will not be saved."))
|
|
{
|
|
Ref<Scene> scene = Scene::New();
|
|
const std::string projectPath = file->GetAbsolutePath();
|
|
if (!scene->Deserialize(json::parse(FileSystem::ReadFile(projectPath, true))))
|
|
{
|
|
Logger::Log("Failed loading scene: " + projectPath,"editor", CRITICAL);
|
|
ImGui::PopFont();
|
|
return;
|
|
}
|
|
|
|
scene->Path = FileSystem::AbsoluteToRelative(projectPath);
|
|
Engine::SetCurrentScene(scene);
|
|
}
|
|
|
|
// Rename Popup
|
|
|
|
if (shouldRename)
|
|
{
|
|
renameTempValue = file->GetName();
|
|
PopupHelper::OpenPopup(renameId);
|
|
}
|
|
|
|
if (PopupHelper::DefineTextDialog(renameId, renameTempValue))
|
|
{
|
|
if(OS::RenameFile(file, renameTempValue) != 0)
|
|
{
|
|
Logger::Log("Cannot rename file: " + renameTempValue, "editor", CRITICAL);
|
|
}
|
|
RefreshFileBrowser();
|
|
renameTempValue = "";
|
|
}
|
|
|
|
// Delete Popup
|
|
|
|
if(shouldDelete)
|
|
{
|
|
PopupHelper::OpenPopup(deleteId);
|
|
}
|
|
|
|
if(PopupHelper::DefineConfirmationDialog(deleteId, " Are you sure you want to delete the file?\n This action cannot be undone, and all data \n will be permanently lost."))
|
|
{
|
|
if (FileSystem::DeleteFileFromPath(file->GetAbsolutePath()) != 0)
|
|
{
|
|
Logger::Log("Failed to remove file: " + file->GetRelativePath(), "editor", CRITICAL);
|
|
}
|
|
RefreshFileBrowser();
|
|
}
|
|
|
|
ImGui::PopFont();
|
|
}
|
|
|
|
void FileSystemUI::DrawContextMenu()
|
|
{
|
|
if (!m_HasClickedOnFile && ImGui::IsMouseReleased(1) && ImGui::IsWindowHovered())
|
|
{
|
|
ImGui::OpenPopup("window_hover_menu");
|
|
}
|
|
|
|
if (ImGui::BeginPopup("window_hover_menu"))
|
|
{
|
|
if (ImGui::MenuItem("New folder"))
|
|
{
|
|
|
|
}
|
|
|
|
if (ImGui::MenuItem("New Scene"))
|
|
{
|
|
}
|
|
|
|
if (ImGui::BeginMenu("New Resource"))
|
|
{
|
|
if (ImGui::MenuItem("Material"))
|
|
{
|
|
const std::string path = FileDialog::SaveFile("*.material");
|
|
if (!path.empty())
|
|
{
|
|
std::string finalPath = path;
|
|
if (!String::EndsWith(path, ".material"))
|
|
{
|
|
finalPath = path + ".material";
|
|
}
|
|
|
|
Ref<Material> material = CreateRef<Material>();
|
|
auto jsonData = material->Serialize();
|
|
|
|
FileSystem::BeginWriteFile(finalPath, true);
|
|
FileSystem::WriteLine(jsonData.dump(4));
|
|
FileSystem::EndWriteFile();
|
|
|
|
RefreshFileBrowser();
|
|
}
|
|
}
|
|
if (ImGui::MenuItem("Sky"))
|
|
{
|
|
const std::string path = FileDialog::SaveFile("*.sky");
|
|
if (!path.empty())
|
|
{
|
|
std::string finalPath = path;
|
|
if (!String::EndsWith(path, ".sky"))
|
|
{
|
|
finalPath = path + ".sky";
|
|
}
|
|
|
|
Ref<SkyResource> sky = CreateRef<SkyResource>(FileSystem::AbsoluteToRelative(finalPath));
|
|
auto jsonData = sky->Serialize();
|
|
|
|
FileSystem::BeginWriteFile(finalPath, true);
|
|
FileSystem::WriteLine(jsonData.dump(4));
|
|
FileSystem::EndWriteFile();
|
|
|
|
RefreshFileBrowser();
|
|
}
|
|
}
|
|
if (ImGui::MenuItem("Environment"))
|
|
{
|
|
const std::string path = FileDialog::SaveFile("*.env");
|
|
if (!path.empty())
|
|
{
|
|
std::string finalPath = path;
|
|
if (!String::EndsWith(path, ".env"))
|
|
{
|
|
finalPath = path + ".env";
|
|
}
|
|
|
|
Ref<Environment> env = CreateRef<Environment>(FileSystem::AbsoluteToRelative(finalPath));
|
|
auto jsonData = env->Serialize();
|
|
|
|
FileSystem::BeginWriteFile(finalPath, true);
|
|
FileSystem::WriteLine(jsonData.dump(4));
|
|
FileSystem::EndWriteFile();
|
|
|
|
RefreshFileBrowser();
|
|
}
|
|
}
|
|
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
}
|
|
|
|
void FileSystemUI::RefreshFileBrowser()
|
|
{
|
|
Scan();
|
|
}
|
|
|
|
Color FileSystemUI::GetColorByFileType(FileType fileType)
|
|
{
|
|
switch (fileType)
|
|
{
|
|
case Nuake::FileType::Unknown:
|
|
break;
|
|
case Nuake::FileType::Image:
|
|
break;
|
|
case Nuake::FileType::Material:
|
|
break;
|
|
case Nuake::FileType::Mesh:
|
|
break;
|
|
case Nuake::FileType::Script:
|
|
return { 1.0, 0.0, 0.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::NetScript:
|
|
return { 1.0, 0.0, 0.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::Project:
|
|
return Engine::GetProject()->Settings.PrimaryColor;
|
|
break;
|
|
case Nuake::FileType::Prefab:
|
|
break;
|
|
case Nuake::FileType::Scene:
|
|
return { 0, 1.0f, 1.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::Wad:
|
|
break;
|
|
case Nuake::FileType::Map:
|
|
return { 0.0, 1.0, 0.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::Assembly:
|
|
break;
|
|
case Nuake::FileType::Solution:
|
|
break;
|
|
case Nuake::FileType::Audio:
|
|
return { 0.0, 0.0, 1.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::UI:
|
|
return { 1.0, 1.0, 0.0, 1.0 };
|
|
break;
|
|
case Nuake::FileType::CSS:
|
|
return { 1.0, 0.0, 1.0, 1.0 };
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return Color(0, 0, 0, 0);
|
|
}
|
|
|
|
void FileSystemUI::Scan()
|
|
{
|
|
if (!m_CurrentDirectory)
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::string previousPath = m_CurrentDirectory->FullPath;
|
|
|
|
FileSystem::Scan();
|
|
|
|
if (FileSystem::DirectoryExists(previousPath, true))
|
|
{
|
|
m_CurrentDirectory = FileSystem::GetDirectory(FileSystem::AbsoluteToRelative(previousPath));
|
|
}
|
|
else
|
|
{
|
|
m_CurrentDirectory = FileSystem::RootDirectory;
|
|
}
|
|
}
|
|
|
|
float h = 200;
|
|
static float sz1 = 300;
|
|
static float sz2 = 300;
|
|
void FileSystemUI::DrawDirectoryExplorer()
|
|
{
|
|
//if (ImGui::Begin("thumbnail debugger"))
|
|
//{
|
|
// auto texture = ThumbnailManager::Get().GetThumbnail("Materials/prototype_1_2/64_blood_2.material");
|
|
// ImGui::Image((void*)texture->GetID(), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
|
|
//}
|
|
//ImGui::End();
|
|
|
|
if (ImGui::Begin("File browser"))
|
|
{
|
|
Ref<Directory> rootDirectory = FileSystem::GetFileTree();
|
|
if (!rootDirectory)
|
|
return;
|
|
|
|
ImVec2 avail = ImGui::GetContentRegionAvail();
|
|
UI::Splitter(true, 4.0f, &sz1, &sz2, 100, 8, avail.y);
|
|
|
|
ImVec4* colors = ImGui::GetStyle().Colors;
|
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, colors[ImGuiCol_TitleBgCollapsed]);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 8);
|
|
if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y), true))
|
|
{
|
|
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_FramePadding;
|
|
|
|
bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory;
|
|
if (is_selected)
|
|
base_flags |= ImGuiTreeNodeFlags_Selected;
|
|
|
|
std::string icon = ICON_FA_FOLDER;
|
|
ImGui::PushFont(FontManager::GetFont(Bold));
|
|
bool open = ImGui::TreeNodeEx("PROJECT", base_flags);
|
|
if (ImGui::IsItemClicked())
|
|
{
|
|
m_CurrentDirectory = FileSystem::RootDirectory;
|
|
}
|
|
ImGui::PopFont();
|
|
|
|
for(auto& d : rootDirectory->Directories)
|
|
EditorInterfaceDrawFiletree(d);
|
|
|
|
ImGui::TreePop();
|
|
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopStyleColor();
|
|
ImGui::EndChild();
|
|
ImGui::SameLine();
|
|
|
|
std::vector<Ref<Directory>> paths = std::vector<Ref<Directory>>();
|
|
|
|
Ref<Directory> currentParent = m_CurrentDirectory;
|
|
paths.push_back(m_CurrentDirectory);
|
|
|
|
while (currentParent != nullptr)
|
|
{
|
|
paths.push_back(currentParent);
|
|
currentParent = currentParent->Parent;
|
|
}
|
|
|
|
avail = ImGui::GetContentRegionAvail();
|
|
if (ImGui::BeginChild("Wrapper", avail))
|
|
{
|
|
avail.y = 30;
|
|
if (ImGui::BeginChild("Path", avail, true))
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 2, 4 });
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
|
|
|
const auto buttonSize = ImVec2(26, 26);
|
|
std::string refreshIcon = ICON_FA_SYNC_ALT;
|
|
if (ImGui::Button((refreshIcon).c_str(), buttonSize))
|
|
{
|
|
RefreshFileBrowser();
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
const auto cursorStart = ImGui::GetCursorPosX();
|
|
if (ImGui::Button((std::string(ICON_FA_ANGLE_LEFT)).c_str(), buttonSize))
|
|
{
|
|
if (m_CurrentDirectory != FileSystem::RootDirectory)
|
|
{
|
|
m_CurrentDirectory = m_CurrentDirectory->Parent;
|
|
}
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
const auto cursorEnd = ImGui::GetCursorPosX();
|
|
const auto buttonWidth = cursorEnd - cursorStart;
|
|
if (ImGui::Button((std::string(ICON_FA_ANGLE_RIGHT)).c_str(), buttonSize))
|
|
{
|
|
if (Editor->Selection.Type == EditorSelectionType::Directory)
|
|
{
|
|
m_CurrentDirectory = Editor->Selection.Directory;
|
|
}
|
|
}
|
|
|
|
const uint32_t numButtonAfterPathBrowser = 2;
|
|
const uint32_t searchBarSize = 6;
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, colors[ImGuiCol_TitleBgCollapsed]);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
|
|
ImGui::BeginChild("pathBrowser", ImVec2((ImGui::GetContentRegionAvail().x - (numButtonAfterPathBrowser * buttonWidth * searchBarSize)) - 4.0, 24));
|
|
for (int i = paths.size() - 1; i > 0; i--)
|
|
{
|
|
if (i != paths.size())
|
|
ImGui::SameLine();
|
|
|
|
std::string pathLabel;
|
|
if (i == paths.size() - 1)
|
|
{
|
|
pathLabel = "Project files";
|
|
}
|
|
else
|
|
{
|
|
pathLabel = paths[i]->Name;
|
|
}
|
|
|
|
if (ImGui::Button(pathLabel.c_str()))
|
|
{
|
|
m_CurrentDirectory = paths[i];
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
ImGui::Text("/");
|
|
}
|
|
ImGui::EndChild();
|
|
ImGui::PopStyleVar();
|
|
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::BeginChild("searchBar", ImVec2(ImGui::GetContentRegionAvail().x - (numButtonAfterPathBrowser * buttonWidth), 24));
|
|
char buffer[256];
|
|
memset(buffer, 0, sizeof(buffer));
|
|
std::strncpy(buffer, m_SearchKeyword.c_str(), sizeof(buffer));
|
|
if (ImGui::InputTextEx("##Search", "Asset search & filter ..", buffer, sizeof(buffer), ImVec2(ImGui::GetContentRegionAvail().x, 24), ImGuiInputTextFlags_EscapeClearsAll))
|
|
{
|
|
m_SearchKeyword = std::string(buffer);
|
|
}
|
|
ImGui::EndChild();
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button((std::string(ICON_FA_FOLDER_OPEN)).c_str(), buttonSize))
|
|
{
|
|
OS::OpenIn(m_CurrentDirectory->FullPath);
|
|
}
|
|
|
|
ImGui::PopStyleColor(); // Button color
|
|
|
|
ImGui::SameLine();
|
|
ImGui::PopStyleVar();
|
|
}
|
|
ImGui::EndChild();
|
|
|
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
|
ImGui::GetWindowDrawList()->AddLine(ImVec2(ImGui::GetCursorPosX(), ImGui::GetCursorPosY()), ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetCursorPosY()), IM_COL32(255, 0, 0, 255), 1.0f);
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
|
|
avail = ImGui::GetContentRegionAvail();
|
|
|
|
bool child = ImGui::BeginChild("Content", avail);
|
|
ImGui::PopStyleVar();
|
|
ImGui::SameLine();
|
|
if (child)
|
|
{
|
|
int width = avail.x;
|
|
ImVec2 buttonSize = ImVec2(80, 80);
|
|
int amount = (int)(width / 110);
|
|
if (amount <= 0) amount = 1;
|
|
|
|
int i = 1; // current amount of item per row.
|
|
if (ImGui::BeginTable("ssss", amount))
|
|
{
|
|
// Button to go up a level.
|
|
//if (m_CurrentDirectory && m_CurrentDirectory != FileSystem::RootDirectory && m_CurrentDirectory->Parent)
|
|
//{
|
|
// ImGui::TableNextColumn();
|
|
// if (ImGui::Button("..", buttonSize))
|
|
// m_CurrentDirectory = m_CurrentDirectory->Parent;
|
|
// i++;
|
|
//}
|
|
|
|
if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0)
|
|
{
|
|
for (Ref<Directory>& d : m_CurrentDirectory->Directories)
|
|
{
|
|
if (d->GetName() == "bin" || d->GetName() == ".vs" || d->GetName() == "obj")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(String::Sanitize(d->Name).find(String::Sanitize(m_SearchKeyword)) != std::string::npos)
|
|
{
|
|
if (i + 1 % amount != 0)
|
|
ImGui::TableNextColumn();
|
|
else
|
|
ImGui::TableNextRow();
|
|
|
|
DrawDirectory(d, i);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0)
|
|
{
|
|
for (auto& f : m_CurrentDirectory->Files)
|
|
{
|
|
if(m_SearchKeyword.empty() || f->GetName().find(String::Sanitize(m_SearchKeyword)) != std::string::npos)
|
|
{
|
|
if (f->GetFileType() == FileType::Unknown || f->GetFileType() == FileType::Assembly)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (i + 1 % amount != 0 || i == 1)
|
|
{
|
|
ImGui::TableNextColumn();
|
|
}
|
|
else
|
|
{
|
|
ImGui::TableNextRow();
|
|
}
|
|
|
|
DrawFile(f, i);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
DrawContextMenu();
|
|
m_HasClickedOnFile = false;
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
}
|
|
ImGui::EndChild();
|
|
}
|
|
|
|
ThumbnailManager::Get().OnEndFrame();
|
|
|
|
ImGui::EndChild();
|
|
}
|
|
ImGui::End();
|
|
}
|
|
}
|