[studio] Add ability to move directories
All checks were successful
Build / build (push) Successful in 3m29s

This commit is contained in:
2025-01-26 09:38:27 -06:00
parent 109e1898cc
commit 1207dadee8
10 changed files with 85 additions and 3 deletions

View File

@@ -13,10 +13,12 @@ struct FileRef {
static constexpr auto TypeName = "net.drinkingtea.studio.FileRef";
static constexpr auto TypeVersion = 1;
ox::String path;
bool isDir{};
};
OX_MODEL_BEGIN(FileRef)
OX_MODEL_FIELD(path)
OX_MODEL_FIELD(isDir)
OX_MODEL_END()
}

View File

@@ -47,6 +47,8 @@ class FileExplorer: public ox::SignalHandler {
virtual void fileMoved(ox::StringViewCR src, ox::StringViewCR dst) const noexcept;
virtual void dirMoved(ox::StringViewCR src, ox::StringViewCR dst) const noexcept;
void drawFileContextMenu(ox::CStringViewCR path) const noexcept;
void drawDirContextMenu(ox::CStringViewCR path) const noexcept;

View File

@@ -94,6 +94,8 @@ class Project: public ox::SignalHandler {
ox::Error moveItem(ox::StringViewCR src, ox::StringViewCR dest) noexcept;
ox::Error moveDir(ox::StringViewCR src, ox::StringViewCR dest) noexcept;
ox::Error deleteItem(ox::StringViewCR path) noexcept;
[[nodiscard]]

View File

@@ -43,6 +43,8 @@ void FileExplorer::fileDeleted(ox::StringViewCR) const noexcept {}
void FileExplorer::fileMoved(ox::StringViewCR, ox::StringViewCR) const noexcept {}
void FileExplorer::dirMoved(ox::StringViewCR, ox::StringViewCR) const noexcept {}
void FileExplorer::drawFileContextMenu(ox::CStringViewCR path) const noexcept {
ig::IDStackItem const idStackItem{path};
fileContextMenu(path);
@@ -93,11 +95,21 @@ void FileTreeModel::draw(turbine::Context &tctx) const noexcept {
}
ig::IDStackItem const idStackItem{m_name};
m_explorer.drawDirContextMenu(m_fullPath);
if (m_explorer.fileDraggable()) {
std::ignore = ig::dragDropSource([this] {
ImGui::Text("%s", m_name.c_str());
return ig::setDragDropPayload("FileRef", FileRef{ox::String{m_fullPath}, true});
});
}
if (ig::DragDropTarget const dragDropTarget; dragDropTarget) {
auto const [ref, err] = ig::getDragDropPayload<FileRef>("FileRef");
if (!err) {
auto const name = substr(ref.path, find(ref.path.rbegin(), ref.path.rend(), '/').offset() + 1);
m_explorer.fileMoved(ref.path, sfmt("{}/{}", m_fullPath, name));
if (ref.isDir) {
m_explorer.dirMoved(ref.path, sfmt("{}/{}", m_fullPath, name));
} else {
m_explorer.fileMoved(ref.path, sfmt("{}/{}", m_fullPath, name));
}
}
}
if (nodeOpen) {

View File

@@ -26,6 +26,26 @@ static void generateTypes(ox::TypeStore &ts) noexcept {
}
}
static ox::Result<ox::Vector<ox::String>> listAllRecursive(ox::FileSystem &fs, ox::StringViewCR path) {
// there really isn't much recourse if this function fails, just log it and move on
auto [out, outErr] = fs.ls(path);
oxLogError(outErr);
for (auto const &p : out) {
auto const [stat, statErr] = fs.stat(path);
if (statErr) {
oxLogError(statErr);
continue;
}
if (stat.fileType == ox::FileType::Directory) {
OX_REQUIRE_M(l, listAllRecursive(fs, sfmt("{}/{}", path, p)));
for (auto &c : l) {
out.emplace_back(std::move(c));
}
}
}
return std::move(out);
}
Project::Project(keel::Context &ctx, ox::String path, ox::StringViewCR projectDataDir):
m_kctx(ctx),
@@ -78,6 +98,21 @@ ox::Error Project::moveItem(ox::StringViewCR src, ox::StringViewCR dest) noexcep
return {};
}
ox::Error Project::moveDir(ox::StringViewCR src, ox::StringViewCR dest) noexcept {
OX_REQUIRE(files, listAllRecursive(m_fs, src));
OX_RETURN_ERROR(m_fs.move(src, dest));
fileMoved.emit(src, dest, ox::UUID{});
for (auto const &op : files) {
auto const name =
substr(op, ox::find(op.rbegin(), op.rend(), '/').offset() + 1);
auto const np = sfmt("{}/{}", dest, name);
OX_RETURN_ERROR(keel::updatePath(m_kctx, op, np));
OX_REQUIRE(uuid, keel::pathToUuid(m_kctx, dest));
fileMoved.emit(src, dest, uuid);
}
return {};
}
ox::Error Project::deleteItem(ox::StringViewCR path) noexcept {
OX_REQUIRE(stat, m_fs.stat(path));
if (stat.fileType == ox::FileType::Directory) {