Merge pull request #325 from SHADE-DP/SP3-4-Editor

Added Asset Browser Filters, double click asset id in inspector to highlight asset in asset browser
This commit is contained in:
XiaoQiDigipen 2023-01-31 19:05:21 +08:00 committed by GitHub
commit 71613143f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 253 additions and 14 deletions

View File

@ -27,6 +27,7 @@
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
#include "Filesystem/SHFileSystem.h"
#include <rttr/registration.h>
namespace SHADE
{
@ -733,3 +734,25 @@ namespace SHADE
}
}
}
namespace rttr
{
using namespace SHADE;
RTTR_REGISTRATION
{
registration::enumeration<AssetType>("Asset Type")
(
value("Invalid", AssetType::INVALID),
value("Shader", AssetType::SHADER),
value("Shader [Built-In]", AssetType::SHADER_BUILT_IN),
value("Texture", AssetType::TEXTURE),
value("Model", AssetType::MODEL),
value("Scene", AssetType::SCENE),
value("Prefab", AssetType::PREFAB),
value("Material", AssetType::MATERIAL),
value("Mesh", AssetType::MESH),
value("Script", AssetType::SCRIPT),
value("Font", AssetType::FONT)
);
}
}

View File

@ -16,6 +16,9 @@
#include "Editor/EditorWindow/SHEditorWindowManager.h"
#include "Scripting/SHVSUtilities.h"
#include "Scripting/SHScriptEngine.h"
#include "Tools/Utilities/SHStringUtilities.h"
#include <filesystem>
#include <rttr/type>
namespace SHADE
{
@ -27,6 +30,13 @@ namespace SHADE
void SHAssetBrowser::Init()
{
SHEditorWindow::Init();
rttr::array_range<rttr::string_view> typeNames = typeEnumAlign.get_names();
for(auto const& name : typeNames)
{
uint64_t val = typeEnumAlign.name_to_value(name).to_uint64();
typeFilters[val] = true;
}
}
void SHAssetBrowser::Update()
@ -34,7 +44,10 @@ namespace SHADE
SHEditorWindow::Update();
if (Begin())
{
RecursivelyDrawTree(rootFolder);
for(auto subFolder : rootFolder->subFolders)
{
RecursivelyDrawTree(subFolder);
}
DrawMenuBar();
DrawCurrentFolder();
DrawAssetBeingCreated();
@ -50,6 +63,11 @@ namespace SHADE
refreshQueued = true;
}
void SHAssetBrowser::SetScrollTo(AssetID assetid)
{
assetToScrollTo = assetid;
}
void SHAssetBrowser::Refresh() noexcept
{
SHAssetManager::RefreshDirectory();
@ -69,6 +87,7 @@ namespace SHADE
{
isAssetBeingCreated = true;
}
DrawAssetBrowserFilter();
ImGui::EndMenuBar();
}
}
@ -81,13 +100,34 @@ namespace SHADE
auto files = folder->files;
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
if(!filter.empty() && (!subFolders.empty() || !files.empty()))
{
ImGui::SetNextItemOpen(true);
}
if (isSelected)
flags |= ImGuiTreeNodeFlags_Selected;
if (folder == rootFolder)
flags |= ImGuiTreeNodeFlags_DefaultOpen;
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
ImGuiID folderID = ImGui::GetItemID();
if(assetToScrollTo != 0)
{
if(auto asset = SHAssetManager::GetAsset(assetToScrollTo))
{
if(!asset->path.empty())
{
ImGui::SetNextItemOpen(SHStringUtilities::StringFindInsensitive(asset->path.string(), folder->name.data()) != std::string::npos);
}
else if(auto parent = SHAssetManager::GetAsset(asset->parent))
{
ImGui::SetNextItemOpen(SHStringUtilities::StringFindInsensitive(parent->path.string(), folder->name.data()) != std::string::npos);
}
}
}
bool isOpen = false;
if(filter.empty())
isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
//if (ImGui::BeginPopupContextItem())
@ -101,7 +141,7 @@ namespace SHADE
selectedFolders.push_back(folder);
}
if (isOpen)
if (isOpen || !filter.empty())
{
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
const float horizontalOffset = 0.0f;
@ -127,7 +167,8 @@ namespace SHADE
}
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
ImGui::TreePop();
if(filter.empty())
ImGui::TreePop();
}
return nodeRect;
}
@ -167,8 +208,26 @@ namespace SHADE
{
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
static constexpr std::string_view icon = ICON_MD_FILE_PRESENT;
bool highlighted = false;
if (!filter.empty())
{
if (SHStringUtilities::StringFindInsensitive(file.name.data(), filter) == std::string::npos)
{
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
}
else
{
highlighted = true;
ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
}
}
ImGui::PushID(file.name.data());
bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data());
if(highlighted)
{
ImGui::PopStyleColor();
}
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(ImGui::BeginPopupContextItem())
{
@ -194,6 +253,27 @@ namespace SHADE
{
if (asset == nullptr)
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if (!typeFilters[static_cast<uint64_t>(asset->type)])
{
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
}
bool highlighted = false;
if(!filter.empty())
{
ImGui::SetNextItemOpen(true);
if(SHStringUtilities::StringFindInsensitive(asset->name.data(), filter) == std::string::npos)
{
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
}
else
{
highlighted = true;
ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
}
}
const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end();
ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf;
if (isSelected)
@ -215,7 +295,33 @@ namespace SHADE
default:;
}
if(assetToScrollTo != 0)
{
if(asset->id == assetToScrollTo)
{
ImGui::SetScrollHereY();
selectedAssets.clear();
selectedAssets.push_back(asset->id);
assetToScrollTo = 0;
}
else
{
for (auto const& subAsset : asset->subAssets)
{
if(subAsset->id == assetToScrollTo)
{
ImGui::SetNextItemOpen(true);
}
}
}
}
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data());
if(highlighted)
{
ImGui::PopStyleColor();
}
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if (SHDragDrop::BeginSource())
{
@ -339,4 +445,43 @@ namespace SHADE
// QueueRefresh();
//}
}
void SHAssetBrowser::DrawAssetBrowserFilter()
{
if (ImGui::InputTextWithHint("##hierarchyPanelFilter", "Filter", &filter))
{
}
if (ImGui::Button("x"))
{
filter.clear();
}
if(ImGui::BeginMenu("Type"))
{
if (ImGui::Button("All"))
{
for (auto& [id, value] : typeFilters)
value = true;
}
ImGui::SameLine();
if (ImGui::Button("None"))
{
for (auto& [id, value] : typeFilters)
value = false;
}
for (auto& [id, value] : typeFilters)
{
if(ImGui::Checkbox(typeEnumAlign.value_to_name(id).data(), &value))
{
}
if(ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
for (auto& [id2, value2] : typeFilters)
value2 = false;
value = true;
}
}
ImGui::EndMenu();
}
}
}

View File

@ -4,18 +4,21 @@
#include "Assets/SHAsset.h"
#include "Editor/EditorWindow/SHEditorWindow.h"
#include "Filesystem/SHFolder.h"
#include <rttr/enumeration.h>
namespace SHADE
{
class SHAssetBrowser final : public SHEditorWindow
{
public:
static constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
SHAssetBrowser();
void Init();
void Update();
void QueueRefresh() noexcept;
void SetScrollTo(AssetID assetid);
private:
void DrawMenuBar();
ImRect RecursivelyDrawTree(FolderPointer folder);
@ -23,6 +26,7 @@ namespace SHADE
ImRect DrawFile(SHFile& file) noexcept;
ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept;
void DrawAssetBeingCreated() noexcept;
void DrawAssetBrowserFilter();
void Refresh() noexcept;
@ -30,9 +34,13 @@ namespace SHADE
std::vector<FolderPointer> selectedFolders;
std::vector<AssetID> selectedAssets;
static constexpr float tileWidth = 50.0f;
static constexpr std::string_view newAssetPopup = "Create New Asset";
std::string nameOfAssetBeingCreated, filter;
rttr::enumeration typeEnumAlign = rttr::type::get<AssetType>().get_enumeration();
std::unordered_map<uint64_t, bool> typeFilters;
AssetID assetToScrollTo = 0;
bool refreshQueued = false;
bool isAssetBeingCreated = false;
static constexpr std::string_view newAssetPopup = "Create New Asset";
std::string nameOfAssetBeingCreated;
};
}

View File

@ -15,11 +15,11 @@
namespace SHADE
{
class SHSceneNode;
constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
class SHHierarchyPanel final : public SHEditorWindow
{
public:
static constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
SHHierarchyPanel();
void Init() override;
void Update() override;

View File

@ -24,6 +24,8 @@
#include "SHInspectorCommands.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Animation/SHAnimatorComponent.h"
#include "../SHEditorWindowManager.h"
#include "../AssetBrowser/SHAssetBrowser.h"
namespace SHADE
{
template<typename T>
@ -502,6 +504,15 @@ namespace SHADE
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
if(Handle<SHMesh> const& mesh = component->GetMesh())
{
AssetID assetID = SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0);
SHEditorWindowManager::GetEditorWindow<SHAssetBrowser>()->SetScrollTo(assetID);
}
}
const auto MAT_NAME = mat ? SHResourceManager::GetAssetName<SHMaterial>(mat->GetBaseMaterial()).value_or("") : "";
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", MAT_NAME,
[component]()
@ -521,6 +532,15 @@ namespace SHADE
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id)));
}, SHDragDrop::DRAG_RESOURCE);
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
if(Handle<SHMaterialInstance> const& mat = component->GetMaterial())
{
AssetID assetID = SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0);
SHEditorWindowManager::GetEditorWindow<SHAssetBrowser>()->SetScrollTo(assetID);
}
}
}
else
{
@ -558,7 +578,14 @@ namespace SHADE
component->SetFont(SHResourceManager::LoadOrGet<SHFont>(id));
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
if (Handle<SHFont> const& font = component->GetFont())
{
AssetID assetID = SHResourceManager::GetAssetID<SHFont>(font).value_or(0);
SHEditorWindowManager::GetEditorWindow<SHAssetBrowser>()->SetScrollTo(assetID);
}
}
SHEditorWidgets::InputText("Text",
[component](void)
{
@ -606,7 +633,14 @@ namespace SHADE
component->SetRig(SHResourceManager::LoadOrGet<SHRig>(id));
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
if (Handle<SHRig> const& rig = component->GetRig())
{
AssetID assetID = SHResourceManager::GetAssetID<SHRig>(rig).value_or(0);
SHEditorWindowManager::GetEditorWindow<SHAssetBrowser>()->SetScrollTo(assetID);
}
}
Handle<SHAnimationClip> const& clip = component->GetCurrentClip();
const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName<SHAnimationClip>(clip).value_or("") : "";
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Clip", CLIP_NAME,
@ -624,6 +658,14 @@ namespace SHADE
}
component->SetClip(SHResourceManager::LoadOrGet<SHAnimationClip>(id));
}, SHDragDrop::DRAG_RESOURCE);
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
if (Handle<SHAnimationClip> const& clip = component->GetCurrentClip())
{
AssetID assetID = SHResourceManager::GetAssetID<SHAnimationClip>(clip).value_or(0);
SHEditorWindowManager::GetEditorWindow<SHAssetBrowser>()->SetScrollTo(assetID);
}
}
}
else
{

View File

@ -97,7 +97,9 @@ namespace SHADE
}
}
#ifdef SHEDITOR
editorConfig = &SHConfigurationManager::LoadEditorConfig();
#endif
//Add editor windows
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
@ -131,8 +133,9 @@ namespace SHADE
InitBackend();
#ifdef SHEDITOR
SetStyle(static_cast<Style>(editorConfig->style));
#endif // SHEDITOR
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{
@ -340,13 +343,18 @@ namespace SHADE
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
#ifdef SHEDITOR
editorConfig->startMaximized = shWindow->GetWindowData().isMaximised;
SHConfigurationManager::SaveEditorConfig();
#endif // SHEDITOR
}
void SHEditor::SetStyle(Style style)
{
#ifdef SHEDITOR
editorConfig->style = static_cast<uint32_t>(style);
#endif // SHEDITOR
switch (style)
{
default:
@ -550,7 +558,10 @@ namespace SHADE
SHSceneManager::SetCurrentSceneName(newSceneName);
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName));
#ifdef SHEDITOR
editorConfig->workingSceneID = SHSceneManager::GetCurrentSceneAssetID();
#endif // SHEDITOR
}
//Get data, if data is null, asset doesn't exist, prompt for a name and create a new asset with the name
@ -559,7 +570,10 @@ namespace SHADE
{
if(shWindow->IsUnsavedChanges())
shWindow->ToggleUnsavedChanges();
#ifdef SHEDITOR
editorConfig->workingSceneID = SHSceneManager::GetCurrentSceneAssetID();
#endif // SHEDITOR
return true;
}
return false;
@ -624,7 +638,11 @@ namespace SHADE
editorState = SHEditor::State::STOP;
SHCommandManager::SwapStacks();
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
#ifdef SHEDITOR
LoadScene(editorConfig->workingSceneID);
#endif // SHEDITOR
}
void SHEditor::ProcessShortcuts()
@ -679,7 +697,9 @@ namespace SHADE
if(width > 0 && height > 0)
{
auto [width, height] = shWindow->GetWindowSize();
#ifdef SHEditor
editorConfig->windowSize = { static_cast<float>(width), static_cast<float>(height) };
#endif // SHEditor
}
});
}

View File

@ -127,8 +127,9 @@ namespace SHADE
std::vector<EntityID> selectedEntities;
State editorState = State::STOP;
#ifdef SHEDITOR
SHEditorConfig* editorConfig;
#endif // SHEDITOR
private:
/**

View File

@ -424,7 +424,7 @@ namespace SHADE
ImGui::BeginGroup();
ImGui::PushID(label.data());
TextLabel(label);
bool changed = ImGui::InputText("##inputText", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
bool changed = ImGui::InputText("##inputText", &text, ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_AutoSelectAll, nullptr, nullptr);
if(SHDragDrop::BeginTarget())
{
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))