-
Notifications
You must be signed in to change notification settings - Fork 2
feat: implement drag-and-drop for entities and external files #342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ee70fbd
61be7ea
c6f0c69
7f753bf
9493ebb
32a2b3e
6f485a2
83ad8b5
096ea86
889c85d
174f6db
16aa0fb
129a2c4
43c6c34
bba3827
4aa6c93
eb28fc5
c1409b4
884c224
65ce3a0
6396821
9361f9f
1672339
a2e0688
1ce70a3
fb494e8
6589c39
f3bc8bd
0cd2b58
f5e308a
c08fcae
91034aa
24761b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| //// Path.cpp /////////////////////////////////////////////////////////////// | ||
| // | ||
| // zzzzz zzz zzzzzzzzzzzzz zzzz zzzz zzzzzz zzzzz | ||
| // zzzzzzz zzz zzzz zzzz zzzz zzzz | ||
| // zzz zzz zzz zzzzzzzzzzzzz zzzz zzzz zzz | ||
| // zzz zzz zzz z zzzz zzzz zzzz zzzz | ||
| // zzz zzz zzzzzzzzzzzzz zzzz zzz zzzzzzz zzzzz | ||
| // | ||
| // Author: Mehdy MORVAN | ||
| // Date: 24/07/2025 | ||
| // Description: Source file for the path utilities | ||
| // | ||
| /////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #include "Path.hpp" | ||
|
|
||
| namespace nexo { | ||
|
|
||
| const std::filesystem::path& Path::getExecutablePath() | ||
| { | ||
| if (!m_executablePathCached.empty() && !m_executableRootPathCached.empty()) | ||
| return m_executablePathCached; | ||
| const boost::dll::fs::path path = boost::dll::program_location(); | ||
| m_executablePathCached = path.c_str(); | ||
| m_executableRootPathCached = m_executablePathCached.parent_path(); | ||
| return m_executablePathCached; | ||
| } | ||
|
|
||
| std::filesystem::path Path::resolvePathRelativeToExe(const std::filesystem::path& path) | ||
| { | ||
| if (m_executableRootPathCached.empty()) | ||
| getExecutablePath(); | ||
| return (m_executableRootPathCached / path).lexically_normal(); | ||
| } | ||
|
|
||
| void Path::resetCache() | ||
| { | ||
| m_executablePathCached.clear(); | ||
| m_executableRootPathCached.clear(); | ||
| } | ||
|
|
||
| std::string normalizePathAndRemovePrefixSlash(const std::string &rawPath) | ||
| { | ||
| namespace fs = std::filesystem; | ||
| fs::path p = fs::path(rawPath).lexically_normal(); | ||
|
|
||
| std::string s = p.generic_string(); | ||
|
|
||
| if (s == "/" || s.empty()) | ||
| return {}; | ||
|
|
||
| size_t start = s.find_first_not_of('/'); | ||
| size_t end = s.find_last_not_of('/'); | ||
| return s.substr(start, end - start + 1); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| //// FileDrop.cpp ///////////////////////////////////////////////////////////// | ||
| // | ||
| // zzzzz zzz zzzzzzzzzzzzz zzzz zzzz zzzzzz zzzzz | ||
| // zzzzzzz zzz zzzz zzzz zzzz zzzz | ||
| // zzz zzz zzz zzzzzzzzzzzzz zzzz zzzz zzz | ||
| // zzz zzz zzz z zzzz zzzz zzzz zzzz | ||
| // zzz zzz zzzzzzzzzzzzz zzzz zzz zzzzzzz zzzzz | ||
| // | ||
| // Author: Jean CARDONNE | ||
| // Date: 30/06/2025 | ||
| // Description: Implementation of file drop handling for asset manager | ||
| // | ||
| /////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #include "AssetManagerWindow.hpp" | ||
| #include "assets/Asset.hpp" | ||
| #include "assets/AssetImporter.hpp" | ||
| #include "assets/AssetLocation.hpp" | ||
| #include "assets/Assets/Model/Model.hpp" | ||
| #include "assets/Assets/Texture/Texture.hpp" | ||
| #include "Logger.hpp" | ||
| #include <filesystem> | ||
| #include <algorithm> | ||
|
|
||
| namespace nexo::editor { | ||
|
|
||
| static assets::AssetType getAssetTypeFromExtension(const std::string &extension) | ||
| { | ||
| static const std::set<std::string> imageExtensions = { | ||
| ".png", ".jpg", ".jpeg", ".bmp", ".tga", ".gif", ".psd", ".hdr", ".pic", ".pnm", ".ppm", ".pgm" | ||
| }; | ||
| if (imageExtensions.contains(extension)) | ||
| return assets::AssetType::TEXTURE; | ||
| static const std::set<std::string> modelExtensions = { | ||
| ".gltf", ".glb", ".fbx", ".obj", ".dae", ".3ds", ".stl", ".ply", ".blend", ".x3d", ".ifc" | ||
| }; | ||
| if (modelExtensions.contains(extension)) | ||
| return assets::AssetType::MODEL; | ||
| return assets::AssetType::UNKNOWN; | ||
| } | ||
|
Comment on lines
+27
to
+40
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I did something wrong but I tried to do that : assets::AssetLocation location = getAssetLocation(path);
assets::AssetImporter importer;
assets::ImporterFileInput fileInput{path};
try {
auto assetRef = importer.importAssetAuto(location, fileInput);
if (!assetRef)
LOG(NEXO_ERROR, "Failed to import asset: {}", location.getPath().data());
} catch (const std::exception& e) {
LOG(NEXO_ERROR, "Exception while importing {}: {}", location.getPath().data(), e.what());
}And it does not work, it seems to be trying to import a model (i get the log in the output)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you give the log and the path of the file
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it works? I just tested it works, it justs logs an error because it tries every importer to see if they can import the file. We just need to remove this log if we try every importer.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You tried with a model ?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried with a texture, it works, the texture appears in the asset manager window. It tries to import a model because it tries to import EVERY type until it finds an importer that works. We just need to suppress this log in the case where we try every importers in importAssetAuto
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Send me the full function you used |
||
|
|
||
| const assets::AssetLocation AssetManagerWindow::getAssetLocation(const std::filesystem::path &path) const | ||
| { | ||
| std::string assetName = path.stem().string(); | ||
| std::filesystem::path folderPath; | ||
| std::string targetFolder = !m_hoveredFolder.empty() ? m_hoveredFolder : m_currentFolder; | ||
|
|
||
| std::string assetPath = targetFolder; | ||
| std::string locationString = assetName + "@" + assetPath; | ||
|
|
||
| LOG(NEXO_DEV, | ||
| "Creating asset location: {} (current folder: '{}', hovered: '{}')", | ||
| locationString, | ||
| m_currentFolder, | ||
| m_hoveredFolder); | ||
|
|
||
| assets::AssetLocation location(locationString); | ||
| return location; | ||
| } | ||
|
|
||
| void AssetManagerWindow::handleEvent(event::EventFileDrop& event) | ||
| { | ||
| m_pendingDroppedFiles.insert(m_pendingDroppedFiles.end(), | ||
| event.files.begin(), | ||
| event.files.end()); | ||
| } | ||
|
|
||
| void AssetManagerWindow::handleDroppedFiles() | ||
| { | ||
| if (m_pendingDroppedFiles.empty()) | ||
| return; | ||
|
|
||
| for (const auto& filePath : m_pendingDroppedFiles) | ||
| importDroppedFile(filePath); | ||
| m_pendingDroppedFiles.clear(); | ||
|
|
||
| m_folderStructure.clear(); | ||
| buildFolderStructure(); | ||
| } | ||
|
|
||
| void AssetManagerWindow::importDroppedFile(const std::string& filePath) | ||
| { | ||
| std::filesystem::path path(filePath); | ||
|
|
||
| if (!std::filesystem::exists(path)) { | ||
| LOG(NEXO_WARN, "Dropped file does not exist: {}", filePath); | ||
| return; | ||
| } | ||
|
|
||
| std::string extension = path.extension().string(); | ||
| std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); | ||
|
|
||
| assets::AssetType assetType = getAssetTypeFromExtension(extension); | ||
| if (assetType == assets::AssetType::UNKNOWN) { | ||
| LOG(NEXO_WARN, "Unsupported file type: {}", extension); | ||
| return; | ||
| } | ||
|
|
||
| assets::AssetLocation location = getAssetLocation(path); | ||
|
|
||
| assets::AssetImporter importer; | ||
| assets::ImporterFileInput fileInput{path}; | ||
| try { | ||
| auto assetRef = importer.importAssetAuto(location, fileInput); | ||
| if (!assetRef) | ||
| LOG(NEXO_ERROR, "Failed to import asset: {}", location.getPath().data()); | ||
| } catch (const std::exception& e) { | ||
| LOG(NEXO_ERROR, "Exception while importing {}: {}", location.getPath().data(), e.what()); | ||
| } | ||
| } | ||
| } | ||


Uh oh!
There was an error while loading. Please reload this page.