22// Created by johnk on 2026/7/18.
33//
44
5- #include < algorithm>
65#include < format>
76#include < system_error>
87
1918
2019namespace Editor ::Internal {
2120 constexpr float assetsFolderTreeWidth = 220 .0f ;
22- constexpr float gridCellWidth = 100 .0f ;
23- constexpr float gridCellHeight = 108 .0f ;
2421 constexpr const char * assetPathPayload = " EXPLOSION_ASSET_PATH" ;
2522
2623 static std::string FormatFileSize (uintmax_t inSize)
@@ -58,7 +55,6 @@ namespace Editor {
5855 : fileSystem(Core::Paths::GameAssetDir().String())
5956 , currentDirectory(fileSystem.Root())
6057 , clipboardMode(ClipboardMode::none)
61- , viewMode(ViewMode::grid)
6258 , statusIsError(false )
6359 , requestCreateFolderPopup(false )
6460 , requestRenamePopup(false )
@@ -158,19 +154,6 @@ namespace Editor {
158154 PasteInto (currentDirectory);
159155 }
160156 ImGui::EndDisabled ();
161-
162- const float itemSpacing = ImGui::GetStyle ().ItemSpacing .x ;
163- const float viewModeButtonWidth = ImGui::GetFrameHeight () * 2 .0f + itemSpacing;
164- ImGui::SameLine (ImGui::GetContentRegionMax ().x - viewModeButtonWidth);
165- ImGui::BeginGroup ();
166- if (Widgets::IconButton (" Grid View" , Icons::Tabler::layoutGrid, " Grid View" )) {
167- viewMode = ViewMode::grid;
168- }
169- ImGui::SameLine (0 .0f , itemSpacing);
170- if (Widgets::IconButton (" List View" , Icons::Tabler::layoutList, " List View" )) {
171- viewMode = ViewMode::list;
172- }
173- ImGui::EndGroup ();
174157 }
175158
176159 void AssetsPanel::RenderBreadcrumbs ()
@@ -234,16 +217,6 @@ namespace Editor {
234217 }
235218
236219 void AssetsPanel::RenderDirectoryContents ()
237- {
238- if (viewMode == ViewMode::grid) {
239- RenderDirectoryContentsGrid ();
240- } else {
241- RenderDirectoryContentsList ();
242- }
243- RenderBackgroundMenu ();
244- }
245-
246- void AssetsPanel::RenderDirectoryContentsList ()
247220 {
248221 if (ImGui::BeginTable (" AssetEntries" , 3 , ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY)) {
249222 ImGui::TableSetupColumn (" Name" , ImGuiTableColumnFlags_WidthStretch);
@@ -253,44 +226,17 @@ namespace Editor {
253226
254227 std::string error;
255228 for (const AssetFileEntry& entry : fileSystem.List (currentDirectory, error)) {
256- RenderEntryList (entry);
257- }
258- if (!error.empty ()) {
259- ReportResult (error, true );
260- }
261- ImGui::EndTable ();
262- }
263- }
264-
265- void AssetsPanel::RenderDirectoryContentsGrid ()
266- {
267- ImGui::BeginChild (" AssetGrid" , ImVec2 (0 .0f , 0 .0f ), ImGuiChildFlags_Borders);
268- const ImGuiStyle& style = ImGui::GetStyle ();
269- const float cellW = Internal::gridCellWidth + style.ItemSpacing .x ;
270- const float contentWidth = ImGui::GetContentRegionAvail ().x ;
271- const int columns = std::max (1 , static_cast <int >(contentWidth / cellW));
272-
273- if (ImGui::BeginTable (" AssetGridTable" , columns, ImGuiTableFlags_ScrollY)) {
274- ImGui::TableSetupScrollFreeze (0 , 0 );
275- std::string error;
276- int columnIndex = 0 ;
277- for (const AssetFileEntry& entry : fileSystem.List (currentDirectory, error)) {
278- if (columnIndex == 0 ) {
279- ImGui::TableNextRow ();
280- }
281- ImGui::TableSetColumnIndex (columnIndex);
282- RenderEntryGrid (entry);
283- columnIndex = (columnIndex + 1 ) % columns;
229+ RenderEntry (entry);
284230 }
285231 if (!error.empty ()) {
286232 ReportResult (error, true );
287233 }
288234 ImGui::EndTable ();
289235 }
290- ImGui::EndChild ();
236+ RenderBackgroundMenu ();
291237 }
292238
293- void AssetsPanel::RenderEntryList (const AssetFileEntry& inEntry)
239+ void AssetsPanel::RenderEntry (const AssetFileEntry& inEntry)
294240 {
295241 ImGui::TableNextRow ();
296242 ImGui::TableSetColumnIndex (0 );
@@ -314,7 +260,7 @@ namespace Editor {
314260 if (inEntry.directory ) {
315261 HandleDropTarget (inEntry.path );
316262 }
317- RenderEntryContextMenu (inEntry, " AssetEntryListMenu " );
263+ RenderEntryContextMenu (inEntry, " AssetEntryMenu " );
318264
319265 ImGui::TableSetColumnIndex (1 );
320266 ImGui::TextUnformatted (Internal::EntryType (inEntry).c_str ());
@@ -327,93 +273,6 @@ namespace Editor {
327273 ImGui::PopID ();
328274 }
329275
330- void AssetsPanel::RenderEntryGrid (const AssetFileEntry& inEntry)
331- {
332- const std::string pathId = inEntry.path .string ();
333- const std::string name = inEntry.path .filename ().string ();
334- const bool selected = selectedPath == inEntry.path ;
335- const bool isDirectory = inEntry.directory ;
336- const char * icon = isDirectory ? Icons::Tabler::folder : Icons::Tabler::file;
337-
338- const float cellW = Internal::gridCellWidth;
339- const float cellH = Internal::gridCellHeight;
340- const ImVec2 cursorStart = ImGui::GetCursorScreenPos ();
341-
342- ImGui::PushID (pathId.c_str ());
343-
344- if (ImGui::Selectable (" ##GridEntry" , selected,
345- ImGuiSelectableFlags_AllowDoubleClick,
346- ImVec2 (cellW, cellH))) {
347- selectedPath = inEntry.path ;
348- if (isDirectory && ImGui::IsMouseDoubleClicked (ImGuiMouseButton_Left)) {
349- NavigateTo (inEntry.path );
350- }
351- }
352-
353- if (ImGui::BeginDragDropSource ()) {
354- ImGui::SetDragDropPayload (Internal::assetPathPayload, pathId.c_str (), pathId.size () + 1 );
355- ImGui::TextUnformatted (name.c_str ());
356- ImGui::EndDragDropSource ();
357- }
358- if (isDirectory) {
359- HandleDropTarget (inEntry.path );
360- }
361- RenderEntryContextMenu (inEntry, " AssetEntryGridMenu" );
362-
363- const ImGuiStyle& style = ImGui::GetStyle ();
364- const float lineH = ImGui::GetTextLineHeight ();
365-
366- ImFont* const font = ImGui::GetFont ();
367- const float baseFontSize = ImGui::GetFontSize ();
368- const float iconScale = 2 .4f ;
369- const float iconFontSize = baseFontSize * iconScale;
370-
371- const float iconWidth = font->CalcTextSizeA (iconFontSize, FLT_MAX , 0 .0f , icon).x ;
372- const float iconX = cursorStart.x + (cellW - iconWidth) * 0 .5f ;
373- const float iconAreaTop = cursorStart.y + style.FramePadding .y ;
374- const float iconAreaH = cellH - style.FramePadding .y * 2 .0f - lineH * 2 .0f - 4 .0f ;
375- const float iconY = iconAreaTop + (iconAreaH - iconFontSize) * 0 .5f ;
376-
377- ImGui::GetWindowDrawList ()->AddText (font, iconFontSize, ImVec2 (iconX, iconY),
378- ImGui::GetColorU32 (ImGuiCol_Text), icon);
379-
380- const float textY = iconAreaTop + iconAreaH + 2 .0f ;
381- const float maxTextW = cellW - style.FramePadding .x * 2 .0f ;
382- const ImVec2 nameSize = ImGui::CalcTextSize (name.c_str ());
383- const float nameX = cursorStart.x + (cellW - std::min (nameSize.x , maxTextW)) * 0 .5f ;
384-
385- if (nameSize.x > maxTextW) {
386- ImGui::PushClipRect (
387- ImVec2 (cursorStart.x + style.FramePadding .x , textY),
388- ImVec2 (cursorStart.x + cellW - style.FramePadding .x , textY + lineH * 2 .0f ),
389- true );
390- ImGui::GetWindowDrawList ()->AddText (ImVec2 (nameX, textY),
391- ImGui::GetColorU32 (ImGuiCol_Text), name.c_str ());
392- ImGui::PopClipRect ();
393- } else {
394- ImGui::GetWindowDrawList ()->AddText (ImVec2 (nameX, textY),
395- ImGui::GetColorU32 (ImGuiCol_Text), name.c_str ());
396- }
397-
398- const std::string typeText = [&]() -> std::string {
399- if (isDirectory) {
400- return " Folder" ;
401- }
402- std::string ext = inEntry.path .extension ().string ();
403- if (ext.size () > 1 && ext.front () == ' .' ) {
404- ext.erase (ext.begin ());
405- }
406- return ext.empty () ? " File" : ext;
407- }();
408- const ImVec2 typeSize = ImGui::CalcTextSize (typeText.c_str ());
409- const float typeX = cursorStart.x + (cellW - typeSize.x ) * 0 .5f ;
410- const float typeY = textY + lineH;
411- ImGui::GetWindowDrawList ()->AddText (ImVec2 (typeX, typeY),
412- ImGui::GetColorU32 (ImGuiCol_TextDisabled), typeText.c_str ());
413-
414- ImGui::PopID ();
415- }
416-
417276 void AssetsPanel::RenderEntryContextMenu (const AssetFileEntry& inEntry, const char * inPopupId)
418277 {
419278 if (!ImGui::BeginPopupContextItem (inPopupId)) {
0 commit comments