[studio] Add support for adding and deleting directories
This commit is contained in:
@@ -175,9 +175,16 @@ enum class PopupResponse {
|
||||
Cancel,
|
||||
};
|
||||
|
||||
PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen);
|
||||
PopupResponse PopupControlsOkCancel(
|
||||
float popupWidth,
|
||||
bool &popupOpen,
|
||||
ox::CStringViewCR ok = "OK",
|
||||
ox::CStringViewCR cancel = "Cancel");
|
||||
|
||||
PopupResponse PopupControlsOkCancel(bool &popupOpen);
|
||||
PopupResponse PopupControlsOkCancel(
|
||||
bool &popupOpen,
|
||||
ox::CStringViewCR ok = "OK",
|
||||
ox::CStringViewCR cancel = "Cancel");
|
||||
|
||||
[[nodiscard]]
|
||||
bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show, ImVec2 const&sz = {285, 0});
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace studio {
|
||||
|
||||
enum class ProjectEvent {
|
||||
None,
|
||||
DirAdded,
|
||||
FileAdded,
|
||||
// FileRecognized is triggered for all matching files upon a new
|
||||
// subscription to a section of the project and upon the addition of a file.
|
||||
@@ -120,6 +121,7 @@ class Project: public ox::SignalHandler {
|
||||
// signals
|
||||
public:
|
||||
ox::Signal<ox::Error(ProjectEvent, ox::StringViewCR)> fileEvent;
|
||||
ox::Signal<ox::Error(ox::StringViewCR)> dirAdded;
|
||||
ox::Signal<ox::Error(ox::StringViewCR)> fileAdded;
|
||||
// FileRecognized is triggered for all matching files upon a new
|
||||
// subscription to a section of the project and upon the addition of a
|
||||
@@ -177,6 +179,9 @@ ox::Error Project::subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&s
|
||||
switch (e) {
|
||||
case ProjectEvent::None:
|
||||
break;
|
||||
case ProjectEvent::DirAdded:
|
||||
connect(this, &Project::dirAdded, tgt, slot);
|
||||
break;
|
||||
case ProjectEvent::FileAdded:
|
||||
connect(this, &Project::fileAdded, tgt, slot);
|
||||
break;
|
||||
|
||||
@@ -54,18 +54,22 @@ bool PushButton(ox::CStringViewCR lbl, ImVec2 const&btnSz) noexcept {
|
||||
return ImGui::Button(lbl.c_str(), btnSz);
|
||||
}
|
||||
|
||||
PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen) {
|
||||
PopupResponse PopupControlsOkCancel(
|
||||
float popupWidth,
|
||||
bool &popupOpen,
|
||||
ox::CStringViewCR ok,
|
||||
ox::CStringViewCR cancel) {
|
||||
auto out = PopupResponse::None;
|
||||
constexpr auto btnSz = ImVec2{50, BtnSz.y};
|
||||
ImGui::Separator();
|
||||
ImGui::SetCursorPosX(popupWidth - 118);
|
||||
if (ImGui::Button("OK", btnSz)) {
|
||||
if (ImGui::Button(ok.c_str(), btnSz)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
popupOpen = false;
|
||||
out = PopupResponse::OK;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsKeyDown(ImGuiKey_Escape) || ImGui::Button("Cancel", btnSz)) {
|
||||
if (ImGui::IsKeyDown(ImGuiKey_Escape) || ImGui::Button(cancel.c_str(), btnSz)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
popupOpen = false;
|
||||
out = PopupResponse::Cancel;
|
||||
@@ -73,8 +77,11 @@ PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen) {
|
||||
return out;
|
||||
}
|
||||
|
||||
PopupResponse PopupControlsOkCancel(bool &popupOpen) {
|
||||
return PopupControlsOkCancel(ImGui::GetContentRegionAvail().x + 17, popupOpen);
|
||||
PopupResponse PopupControlsOkCancel(
|
||||
bool &popupOpen,
|
||||
ox::CStringViewCR ok,
|
||||
ox::CStringViewCR cancel) {
|
||||
return PopupControlsOkCancel(ImGui::GetContentRegionAvail().x + 17, popupOpen, ok, cancel);
|
||||
}
|
||||
|
||||
bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show, ImVec2 const&sz) {
|
||||
|
||||
@@ -59,10 +59,10 @@ ox::Error Project::mkdir(ox::StringViewCR path) const noexcept {
|
||||
auto const [stat, err] = m_fs.stat(path);
|
||||
if (err) {
|
||||
OX_RETURN_ERROR(m_fs.mkdir(path, true));
|
||||
fileUpdated.emit(path, {});
|
||||
dirAdded.emit(path);
|
||||
}
|
||||
return stat.fileType == ox::FileType::Directory ?
|
||||
ox::Error{} : ox::Error(1, "path exists as normal file");
|
||||
ox::Error{} : ox::Error{1, "path exists as normal file"};
|
||||
}
|
||||
|
||||
ox::Result<ox::FileStat> Project::stat(ox::StringViewCR path) const noexcept {
|
||||
@@ -70,11 +70,28 @@ ox::Result<ox::FileStat> Project::stat(ox::StringViewCR path) const noexcept {
|
||||
}
|
||||
|
||||
ox::Error Project::deleteItem(ox::StringViewCR path) noexcept {
|
||||
auto const err = m_fs.remove(path);
|
||||
if (!err) {
|
||||
fileDeleted.emit(path);
|
||||
OX_REQUIRE(stat, m_fs.stat(path));
|
||||
if (stat.fileType == ox::FileType::Directory) {
|
||||
bool partialRemoval{};
|
||||
OX_REQUIRE(members, m_fs.ls(path));
|
||||
for (auto const&p : members) {
|
||||
partialRemoval = m_fs.remove(ox::sfmt("{}/{}", path, p)) || partialRemoval;
|
||||
}
|
||||
if (partialRemoval) {
|
||||
return ox::Error{1, "failed to remove one or more directory members"};
|
||||
}
|
||||
auto const err = m_fs.remove(path);
|
||||
if (!err) {
|
||||
fileDeleted.emit(path);
|
||||
}
|
||||
return err;
|
||||
} else {
|
||||
auto const err = m_fs.remove(path);
|
||||
if (!err) {
|
||||
fileDeleted.emit(path);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
bool Project::exists(ox::StringViewCR path) const noexcept {
|
||||
|
||||
Reference in New Issue
Block a user