[studio] Add ability to drag files between directories
All checks were successful
Build / build (push) Successful in 3m29s
All checks were successful
Build / build (push) Successful in 3m29s
This commit is contained in:
parent
a24bf7ffb9
commit
109e1898cc
@ -26,6 +26,10 @@ void ProjectExplorer::fileDeleted(ox::StringViewCR path) const noexcept {
|
|||||||
deleteItem.emit(path);
|
deleteItem.emit(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectExplorer::fileMoved(ox::StringViewCR src, ox::StringViewCR dst) const noexcept {
|
||||||
|
moveItem.emit(src, dst);
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectExplorer::fileContextMenu(ox::StringViewCR path) const noexcept {
|
void ProjectExplorer::fileContextMenu(ox::StringViewCR path) const noexcept {
|
||||||
if (ImGui::BeginPopupContextItem("FileMenu", ImGuiPopupFlags_MouseButtonRight)) {
|
if (ImGui::BeginPopupContextItem("FileMenu", ImGuiPopupFlags_MouseButtonRight)) {
|
||||||
if (ImGui::MenuItem("Delete")) {
|
if (ImGui::MenuItem("Delete")) {
|
||||||
|
@ -20,6 +20,7 @@ class ProjectExplorer final: public FileExplorer {
|
|||||||
ox::Signal<ox::Error(ox::StringViewCR)> addDir;
|
ox::Signal<ox::Error(ox::StringViewCR)> addDir;
|
||||||
ox::Signal<ox::Error(ox::StringViewCR)> deleteItem;
|
ox::Signal<ox::Error(ox::StringViewCR)> deleteItem;
|
||||||
ox::Signal<ox::Error(ox::StringViewCR)> renameItem;
|
ox::Signal<ox::Error(ox::StringViewCR)> renameItem;
|
||||||
|
ox::Signal<ox::Error(ox::StringViewCR src, ox::StringViewCR dst)> moveItem;
|
||||||
|
|
||||||
explicit ProjectExplorer(keel::Context &kctx) noexcept;
|
explicit ProjectExplorer(keel::Context &kctx) noexcept;
|
||||||
|
|
||||||
@ -30,6 +31,8 @@ class ProjectExplorer final: public FileExplorer {
|
|||||||
|
|
||||||
void fileDeleted(ox::StringViewCR path) const noexcept override;
|
void fileDeleted(ox::StringViewCR path) const noexcept override;
|
||||||
|
|
||||||
|
void fileMoved(ox::StringViewCR src, ox::StringViewCR dst) const noexcept override;
|
||||||
|
|
||||||
void fileContextMenu(ox::StringViewCR path) const noexcept override;
|
void fileContextMenu(ox::StringViewCR path) const noexcept override;
|
||||||
|
|
||||||
void dirContextMenu(ox::StringViewCR path) const noexcept override;
|
void dirContextMenu(ox::StringViewCR path) const noexcept override;
|
||||||
|
@ -59,6 +59,8 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringParam projectDataDir) noexce
|
|||||||
m_projectExplorer.addItem.connect(this, &StudioUI::addFile);
|
m_projectExplorer.addItem.connect(this, &StudioUI::addFile);
|
||||||
m_projectExplorer.deleteItem.connect(this, &StudioUI::deleteFile);
|
m_projectExplorer.deleteItem.connect(this, &StudioUI::deleteFile);
|
||||||
m_projectExplorer.renameItem.connect(this, &StudioUI::renameFile);
|
m_projectExplorer.renameItem.connect(this, &StudioUI::renameFile);
|
||||||
|
m_projectExplorer.moveItem.connect(this, &StudioUI::queueFileMove);
|
||||||
|
m_renameFile.moveFile.connect(this, &StudioUI::queueFileMove);
|
||||||
m_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
m_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
||||||
m_newMenu.finished.connect(this, &StudioUI::openFile);
|
m_newMenu.finished.connect(this, &StudioUI::openFile);
|
||||||
loadModules();
|
loadModules();
|
||||||
@ -135,6 +137,7 @@ void StudioUI::draw() noexcept {
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
handleKeyInput();
|
handleKeyInput();
|
||||||
m_taskRunner.update(m_tctx);
|
m_taskRunner.update(m_tctx);
|
||||||
|
procFileMoves();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StudioUI::drawMenu() noexcept {
|
void StudioUI::drawMenu() noexcept {
|
||||||
@ -409,7 +412,6 @@ ox::Error StudioUI::openProjectPath(ox::StringParam path) noexcept {
|
|||||||
m_sctx.project = m_project.get();
|
m_sctx.project = m_project.get();
|
||||||
turbine::setWindowTitle(m_tctx, ox::sfmt("{} - {}", keelCtx(m_tctx).appName, m_project->projectPath()));
|
turbine::setWindowTitle(m_tctx, ox::sfmt("{} - {}", keelCtx(m_tctx).appName, m_project->projectPath()));
|
||||||
m_deleteConfirmation.deleteFile.connect(m_sctx.project, &Project::deleteItem);
|
m_deleteConfirmation.deleteFile.connect(m_sctx.project, &Project::deleteItem);
|
||||||
m_renameFile.moveFile.connect(m_project.get(), &Project::moveItem);
|
|
||||||
m_newDirDialog.newDir.connect(m_sctx.project, &Project::mkdir);
|
m_newDirDialog.newDir.connect(m_sctx.project, &Project::mkdir);
|
||||||
m_project->dirAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
m_project->dirAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
||||||
m_project->fileAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
m_project->fileAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
||||||
@ -484,4 +486,16 @@ ox::Error StudioUI::closeFile(ox::StringViewCR path) noexcept {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error StudioUI::queueFileMove(ox::StringParam src, ox::StringParam dst) noexcept {
|
||||||
|
m_queuedMoves.emplace_back(std::move(src), std::move(dst));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void StudioUI::procFileMoves() noexcept {
|
||||||
|
for (auto const &m : m_queuedMoves) {
|
||||||
|
oxLogError(m_project->moveItem(m.a, m.b));
|
||||||
|
}
|
||||||
|
m_queuedMoves.clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
BaseEditor *m_activeEditorOnLastDraw = nullptr;
|
BaseEditor *m_activeEditorOnLastDraw = nullptr;
|
||||||
BaseEditor *m_activeEditor = nullptr;
|
BaseEditor *m_activeEditor = nullptr;
|
||||||
BaseEditor *m_activeEditorUpdatePending = nullptr;
|
BaseEditor *m_activeEditorUpdatePending = nullptr;
|
||||||
|
ox::Vector<ox::Pair<ox::String, ox::String>> m_queuedMoves;
|
||||||
NewMenu m_newMenu{keelCtx(m_tctx)};
|
NewMenu m_newMenu{keelCtx(m_tctx)};
|
||||||
DeleteConfirmation m_deleteConfirmation;
|
DeleteConfirmation m_deleteConfirmation;
|
||||||
NewDir m_newDirDialog;
|
NewDir m_newDirDialog;
|
||||||
@ -111,6 +112,11 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
ox::Error openFileActiveTab(ox::StringViewCR path, bool makeActiveTab) noexcept;
|
ox::Error openFileActiveTab(ox::StringViewCR path, bool makeActiveTab) noexcept;
|
||||||
|
|
||||||
ox::Error closeFile(ox::StringViewCR path) noexcept;
|
ox::Error closeFile(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
|
ox::Error queueFileMove(ox::StringParam src, ox::StringParam dst) noexcept;
|
||||||
|
|
||||||
|
void procFileMoves() noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ class FileExplorer: public ox::SignalHandler {
|
|||||||
|
|
||||||
virtual void fileDeleted(ox::StringViewCR path) const noexcept;
|
virtual void fileDeleted(ox::StringViewCR path) const noexcept;
|
||||||
|
|
||||||
|
virtual void fileMoved(ox::StringViewCR src, ox::StringViewCR dst) const noexcept;
|
||||||
|
|
||||||
void drawFileContextMenu(ox::CStringViewCR path) const noexcept;
|
void drawFileContextMenu(ox::CStringViewCR path) const noexcept;
|
||||||
|
|
||||||
void drawDirContextMenu(ox::CStringViewCR path) const noexcept;
|
void drawDirContextMenu(ox::CStringViewCR path) const noexcept;
|
||||||
|
@ -41,6 +41,8 @@ void FileExplorer::fileOpened(ox::StringViewCR) const noexcept {}
|
|||||||
|
|
||||||
void FileExplorer::fileDeleted(ox::StringViewCR) const noexcept {}
|
void FileExplorer::fileDeleted(ox::StringViewCR) const noexcept {}
|
||||||
|
|
||||||
|
void FileExplorer::fileMoved(ox::StringViewCR, ox::StringViewCR) const noexcept {}
|
||||||
|
|
||||||
void FileExplorer::drawFileContextMenu(ox::CStringViewCR path) const noexcept {
|
void FileExplorer::drawFileContextMenu(ox::CStringViewCR path) const noexcept {
|
||||||
ig::IDStackItem const idStackItem{path};
|
ig::IDStackItem const idStackItem{path};
|
||||||
fileContextMenu(path);
|
fileContextMenu(path);
|
||||||
@ -91,6 +93,13 @@ void FileTreeModel::draw(turbine::Context &tctx) const noexcept {
|
|||||||
}
|
}
|
||||||
ig::IDStackItem const idStackItem{m_name};
|
ig::IDStackItem const idStackItem{m_name};
|
||||||
m_explorer.drawDirContextMenu(m_fullPath);
|
m_explorer.drawDirContextMenu(m_fullPath);
|
||||||
|
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 (nodeOpen) {
|
if (nodeOpen) {
|
||||||
for (auto const&child : m_children) {
|
for (auto const&child : m_children) {
|
||||||
child->draw(tctx);
|
child->draw(tctx);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user