Elevate Engine 1
Loading...
Searching...
No Matches
AssetBrowserPanel.cpp
Go to the documentation of this file.
1#include "AssetBrowserPanel.h"
2
3#include <algorithm>
4#include <cmath>
5
6#include <imgui.h>
7#include <rapidjson/filereadstream.h>
8#include <rapidjson/document.h>
9#include <rapidjson/error/en.h>
10
16
17namespace fs = std::filesystem;
18
20{
21 LoadExtensionsMeta();
22 m_folderTexture = Texture::CreateFromFile(m_FileMetadata["DIRECTORY"].iconPath);
23 EE_CORE_INFO("Editor Assets Browser Initiated.");
24}
25
27{
28 if (m_shouldUpdate) {
29 UpdateRelatedPaths();
30 LoadFileItemsList();
31 m_shouldUpdate = false;
32 }
33}
34
36{
37 ImGui::Begin("Asset Browser");
38
39 ImGui::BeginGroup();
40 for (auto it = m_relatedPaths.rbegin(); it != m_relatedPaths.rend(); ++it)
41 {
42 ImGui::BeginDisabled(it->Path == m_CurrentPath);
43 if (ImGui::Button(it->DisplayName.c_str()))
44 {
45 m_CurrentPath = it->Path;
46 m_shouldUpdate = true;
47 }
48 ImGui::EndDisabled();
49
50 ImGui::SameLine();
51 ImGui::Text("/");
52 ImGui::SameLine();
53 }
54 ImGui::EndGroup();
55 ImGui::Separator();
56
57 ImVec2 buttonSize(72, 72);
58 float spacing = ImGui::GetStyle().ItemSpacing.x * 2;
59 float panelWidth = ImGui::GetWindowSize().x;
60 int colNb = (int) std::floor(panelWidth / (buttonSize.x + spacing));
61 colNb = std::max(1, colNb);
62
63 int index = 0;
64
65 if (m_CurrentPath != ".") {
66 ImGui::PushID(index);
67 ImGui::BeginGroup();
68 ImGui::ImageButton("back", (ImTextureID) m_folderTexture->GetNativeHandle(), buttonSize);
69
70 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
71 m_CurrentPath = m_CurrentPath.parent_path();
72 m_shouldUpdate = true;
73 }
74
75 ImGui::TextWrapped("../");
76
77 ImGui::EndGroup();
78 ImGui::PopID();
79 ImGui::SameLine();
80 index++;
81 }
82
83 int id = 0;
84 for (FileItem item : m_FileItems)
85 {
86 ImGui::PushID(index);
87 ImGui::BeginGroup();
88
89 if (ImGui::ImageButton("file_item", (ImTextureID) m_currentTextures[item.iconPath]->GetNativeHandle(), buttonSize)) {}
90
91 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
92 if (item.type == Directory) {
93 m_CurrentPath += "/" + item.name;
94 m_shouldUpdate = true;
95 }
96 else {
98 }
99 }
100
101 ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + buttonSize.x);
102 ImGui::TextWrapped("%s", item.name.c_str());
103 ImGui::PopTextWrapPos();
104
105 ImGui::EndGroup();
106 ImGui::PopID();
107
108 if ((index + 1) % colNb != 0)
109 {
110 ImGui::SameLine();
111 }
112 index++;
113 }
114 ImGui::End();
115}
116
117void Elevate::Editor::AssetBrowserPanel::UpdateRelatedPaths()
118{
119 m_relatedPaths.clear();
120
121 std::string displayName = m_CurrentPath == "." ? "Game Content" : m_CurrentPath.filename().string();
122 m_relatedPaths.push_back({ m_CurrentPath, displayName });
123 AddParentPaths(m_CurrentPath);
124}
125
126void Elevate::Editor::AssetBrowserPanel::AddParentPaths(std::filesystem::path path)
127{
128 if (path.has_parent_path())
129 {
130 std::filesystem::path parent = path.parent_path();
131 std::string displayName = parent == "." ? "Game Content" : parent.filename().string();
132 m_relatedPaths.push_back({ parent, displayName });
133 AddParentPaths(parent);
134 }
135}
136
137void Elevate::Editor::AssetBrowserPanel::LoadFileItemsList()
138{
139 m_FileItems.clear();
140 m_currentTextures.clear();
141
142 for (const auto& entry : fs::directory_iterator(m_CurrentPath)) {
143 FileMetadata meta;
144 std::string ext = "";
145
146 if (entry.is_directory()) {
147 if (fs::is_empty(entry.path())) {
148 meta = m_FileMetadata["EMPTY_DIRECTORY"];
149 }
150 else {
151 meta = m_FileMetadata["DIRECTORY"];
152 }
153 }
154 else {
155 ext = entry.path().extension().string();
156 if (!ext.empty() && ext[0] == '.') {
157 ext = ext.substr(1);
158 }
159
160 // if the current extension is ignored
161 if (std::find(m_ignoredExtensions.begin(), m_ignoredExtensions.end(), ext) != m_ignoredExtensions.end())
162 {
163 continue;
164 }
165 else
166 {
167 if (m_FileMetadata.find(ext) != m_FileMetadata.end()) {
168 meta = m_FileMetadata[ext];
169 }
170 else {
171 meta = m_FileMetadata["ANY"];
172 }
173 }
174 }
175 FileItem fileItem;
176 if (meta.type == Image) {
177 fileItem = FileItem(entry.path().string(), entry.path().filename().string(), ext, entry.path().string(), meta.type);
178 }
179 else {
180 fileItem = FileItem(entry.path().string(), entry.path().filename().string(), ext, meta.iconPath, meta.type);
181 }
182
183 m_currentTextures[fileItem.iconPath] = Texture::CreateFromFile(fileItem.iconPath);
184 m_FileItems.push_back(fileItem);
185 }
186
187 std::sort(m_FileItems.begin(), m_FileItems.end(), [](const FileItem& a, const FileItem& b) {
188 if (a.type == b.type)
189 {
190 return a.name < b.name;
191 }
192 else
193 {
194 return a.type < b.type;
195 }
196 });
197}
198
199void Elevate::Editor::AssetBrowserPanel::LoadExtensionsMeta(std::string filepath)
200{
201 std::string resolvedPath = PathResolver::Resolve(filepath);
202 FILE* fp = fopen(resolvedPath.c_str(), "r");
203 if (!fp) {
204 EE_CORE_ERROR("Cannot open JSON file : {}", resolvedPath);
205 return;
206 }
207
208 char readBuffer[65536];
209 rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));
210
211 rapidjson::Document doc;
212 doc.ParseStream(is);
213 fclose(fp);
214
215 if (doc.HasParseError()) {
216 EE_CORE_ERROR("Erreur parsing JSON : %s", rapidjson::GetParseError_En(doc.GetParseError()));
217 return;
218 }
219
220 if (doc.HasMember("ignore") && doc["ignore"].IsArray()) {
221 const rapidjson::Value& ignore = doc["ignore"];
222 for (rapidjson::SizeType i = 0; i < ignore.Size(); i++)
223 {
224 const rapidjson::Value& filetype = ignore[i];
225 if (filetype.IsString())
226 {
227 m_ignoredExtensions.push_back(filetype.GetString());
228 }
229 }
230 }
231
232 if (!doc.HasMember("assets") || !doc["assets"].IsArray()) {
233 EE_CORE_ERROR("Could not find valid assets key in JSON file.");
234 return;
235 }
236
237 const rapidjson::Value& assets = doc["assets"];
238 for (rapidjson::SizeType i = 0; i < assets.Size(); i++) {
239 const rapidjson::Value& asset = assets[i];
240
241 if (!asset.HasMember("extension") || !asset["extension"].IsString() ||
242 !asset.HasMember("iconPath") || !asset["iconPath"].IsString() ||
243 !asset.HasMember("type") || !asset["type"].IsString()) {
244 EE_CORE_ERROR("The asset %s is invalid (missing data or incorrect type)", i + 1);
245 continue;
246 }
247
248 std::string extension = asset["extension"].GetString();
249 std::string iconPath = asset["iconPath"].GetString();
250 std::string typeStr = asset["type"].GetString();
251
253 FileMetadata meta(type, iconPath);
254 m_FileMetadata[extension] = meta;
255 }
256}
static std::string Resolve(const std::string &virtualPath)
static TexturePtr CreateFromFile(const std::string &path, TextureType usage=TextureType::Diffuse)
Definition Texture.cpp:22
void OpenWithDefaultApp(const std::string &filePath)
Definition Files.h:14
static FileType ParseFileType(std::string typeStr)