@@ -11,6 +11,10 @@ static ImGuizmo::OPERATION gizmo_mode = ImGuizmo::TRANSLATE;
1111static int renaming_index = -1 ;
1212static char rename_buf[128 ] = " " ;
1313
14+ const float icon_size = 64 .0f ;
15+ const float padding = 10 .0f ;
16+ const float cell_size = icon_size + padding;
17+
1418void Editor::handle_input () {
1519 float speed = 0 .1f ;
1620 Entity* e = scene.get_selected ();
@@ -40,6 +44,7 @@ void Editor::handle_input() {
4044
4145 UnloadDroppedFiles (dropped);
4246 refresh_textures (&scene);
47+ refresh_assets ();
4348 }
4449
4550}
@@ -296,21 +301,160 @@ void Editor::draw_ui() {
296301
297302 ImGui::End ();
298303
304+ draw_assets_ui ();
305+ }
306+
307+ void Editor::draw_assets_ui () {
299308 ImGui::SetNextWindowSize (ImVec2 (1270 , 165 ), ImGuiCond_Once);
300309 ImGui::SetNextWindowPos (ImVec2 (5 , 550 ), ImGuiCond_Once);
301310 ImGui::Begin (" Assets" , nullptr , ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
302311
303- if (fs::is_empty (" assets" )) {
304- const char * text = " Drag files here" ;
312+ static ImVec2 selection_start;
313+ static ImVec2 selection_end;
314+ static bool selecting = false ;
315+ static int rename_target = -1 ;
305316
306- ImVec2 windowSize = ImGui::GetWindowSize ();
307- ImVec2 textSize = ImGui::CalcTextSize (text);
317+ ImVec2 window_size = ImGui::GetWindowSize ();
308318
309- ImGui::SetCursorPosX ((windowSize.x - textSize.x ) * 0 .5f );
310- ImGui::SetCursorPosY ((windowSize.y - textSize.y ) * 0 .5f );
319+ if (asset_entries.empty ()) {
320+ const char * text = " Drag files here" ;
321+ ImVec2 text_size = ImGui::CalcTextSize (text);
311322
323+ ImGui::SetCursorPosX ((window_size.x - text_size.x ) * 0 .5f );
324+ ImGui::SetCursorPosY ((window_size.y - text_size.y ) * 0 .5f );
312325 ImGui::Text (" %s" , text);
326+ }
327+
328+ else {
329+ ImGui::BeginChild (" AssetScroll" , ImVec2 (0 , 0 ), false , ImGuiWindowFlags_AlwaysVerticalScrollbar);
330+
331+ if (ImGui::IsWindowHovered ()) {
332+ if (ImGui::IsMouseClicked (0 )) {
333+ selection_start = ImGui::GetMousePos ();
334+ selection_end = selection_start;
335+ selecting = true ;
336+ }
337+
338+ if (ImGui::IsMouseDown (0 ) && selecting) selection_end = ImGui::GetMousePos ();
339+ if (ImGui::IsMouseReleased (0 )) selecting = false ;
340+ }
341+
342+ float window_visible_x2 = ImGui::GetWindowPos ().x + ImGui::GetWindowContentRegionMax ().x ;
343+
344+ for (int i = 0 ; i < asset_entries.size (); i++) {
345+ ImGui::PushID (i);
346+ ImGui::BeginGroup ();
347+
348+ ImVec2 pos = ImGui::GetCursorScreenPos ();
349+ ImVec2 size (icon_size, icon_size + 20 .0f );
350+
351+ ImGui::InvisibleButton (" asset_btn" , size);
352+
353+ if (ImGui::IsItemHovered ()) ImGui::SetTooltip (" %s" , asset_entries[i].filename .c_str ());
354+ if (ImGui::IsItemClicked () && !ImGui::IsMouseDragging (0 )) selected_asset_index = i;
355+
356+ if (ImGui::BeginPopupContextItem (" AssetContext" )) {
357+ if (ImGui::MenuItem (" Delete" )) {
358+ fs::remove (fs::path (" assets" ) / asset_entries[i].filename );
359+ asset_entries.erase (asset_entries.begin () + i);
360+
361+ if (selected_asset_index == i) selected_asset_index = -1 ;
362+
363+ ImGui::EndPopup ();
364+ ImGui::EndGroup ();
365+ ImGui::PopID ();
366+ break ;
367+ }
368+
369+ if (ImGui::MenuItem (" Rename" )) {
370+ rename_target = i;
371+ size_t copied = asset_entries[i].filename .copy (rename_buf, sizeof (rename_buf) - 1 );
372+ rename_buf[copied] = ' \0 ' ;
373+
374+ ImGui::OpenPopup (" RenameAsset" );
375+ }
376+
377+ ImGui::EndPopup ();
378+ }
379+
380+ bool selected = (selected_asset_index == i);
381+
382+ if (selecting && (fabs (selection_start.x - selection_end.x ) > 5 .0f || fabs (selection_start.y - selection_end.y ) > 5 .0f )) {
383+ ImVec2 min = ImVec2 (std::min (selection_start.x , selection_end.x ), std::min (selection_start.y , selection_end.y ));
384+ ImVec2 max = ImVec2 (std::max (selection_start.x , selection_end.x ), std::max (selection_start.y , selection_end.y ));
385+
386+ if (!(pos.x + size.x < min.x || pos.x > max.x || pos.y + size.y < min.y || pos.y > max.y )) selected = true ;
387+ }
388+
389+ if (selected) {
390+ ImVec2 frame_max = ImVec2 (pos.x + size.x , pos.y + size.y );
391+ ImGui::GetWindowDrawList ()->AddRectFilled (pos, frame_max, IM_COL32 (80 , 140 , 255 , 150 ));
392+ }
393+
394+ ImGui::SetCursorScreenPos (pos);
395+ if (asset_entries[i].is_image ) ImGui::Image ((void *)(intptr_t )asset_entries[i].texture .id , ImVec2 (icon_size, icon_size));
396+ else ImGui::Button (" File" , ImVec2 (icon_size, icon_size));
397+
398+ ImGui::SetCursorScreenPos (ImVec2 (pos.x , pos.y + icon_size));
399+ std::string label = asset_entries[i].filename ;
400+
401+ if (label.size () > 12 ) label = label.substr (0 , 9 ) + " ..." ;
402+
403+ ImGui::TextWrapped (" %s" , label.c_str ());
404+ ImGui::EndGroup ();
405+
406+ float last_x2 = ImGui::GetItemRectMax ().x ;
407+ float next_x2 = last_x2 + ImGui::GetStyle ().ItemSpacing .x + icon_size;
408+
409+ if (i + 1 < asset_entries.size () && next_x2 < window_visible_x2)ImGui::SameLine ();
410+
411+ ImGui::PopID ();
412+ }
413+
414+ if (selecting && (fabs (selection_start.x - selection_end.x ) > 5 .0f || fabs (selection_start.y - selection_end.y ) > 5 .0f )) {
415+ ImVec2 min = ImVec2 (std::min (selection_start.x , selection_end.x ), std::min (selection_start.y , selection_end.y ));
416+ ImVec2 max = ImVec2 (std::max (selection_start.x , selection_end.x ), std::max (selection_start.y , selection_end.y ));
417+
418+ ImGui::GetForegroundDrawList ()->AddRectFilled (min, max, IM_COL32 (80 , 140 , 255 , 40 ));
419+ }
420+
421+ if (rename_target >= 0 ) {
422+ ImGui::OpenPopup (" RenameAsset" );
423+ rename_target = -2 ;
424+ }
425+
426+ if (rename_target == -2 && ImGui::BeginPopupModal (" RenameAsset" , nullptr , ImGuiWindowFlags_AlwaysAutoResize)) {
427+ ImGui::InputText (" ##rename" , rename_buf, IM_ARRAYSIZE (rename_buf));
428+ if (ImGui::Button (" OK" )) {
429+ if (selected_asset_index >= 0 && selected_asset_index < asset_entries.size ()) {
430+ fs::path old_path = fs::path (" assets" ) / asset_entries[selected_asset_index].filename ;
431+ fs::path new_path = fs::path (" assets" ) / rename_buf;
432+
433+ if (rename_buf[0 ] != ' \0 ' && old_path != new_path && fs::exists (old_path)) {
434+ try {
435+ fs::rename (old_path, new_path);
436+ asset_entries[selected_asset_index].filename = rename_buf;
437+ }
438+
439+ catch (...) {}
440+ }
441+ }
442+
443+ rename_target = -1 ;
444+ ImGui::CloseCurrentPopup ();
445+ }
446+
447+ ImGui::SameLine ();
448+ if (ImGui::Button (" Cancel" )) {
449+ rename_target = -1 ;
450+ ImGui::CloseCurrentPopup ();
451+ }
452+
453+ ImGui::EndPopup ();
454+ }
455+
456+ ImGui::EndChild ();
313457 }
314458
315459 ImGui::End ();
316- }
460+ }
0 commit comments