Compare commits
2 Commits
9d1155843e
...
800ca85176
Author | SHA1 | Date | |
---|---|---|---|
800ca85176 | |||
cc466a9f1d |
8
deps/ox/src/ox/std/string.hpp
vendored
8
deps/ox/src/ox/std/string.hpp
vendored
@ -423,9 +423,10 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
|
|||||||
const std::size_t strLen = src.len();
|
const std::size_t strLen = src.len();
|
||||||
const auto currentLen = len();
|
const auto currentLen = len();
|
||||||
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
||||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
cpy.m_buff.resize(m_buff.size() + strLen + 1);
|
||||||
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||||
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen + 1);
|
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen);
|
||||||
|
cpy.m_buff[cpy.m_buff.size() - 1] = 0;
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +437,8 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
|
|||||||
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
||||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||||
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||||
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen + 1);
|
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen);
|
||||||
|
cpy.m_buff[cpy.m_buff.size() - 1] = 0;
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ add_library(
|
|||||||
deleteconfirmation.cpp
|
deleteconfirmation.cpp
|
||||||
filedialogmanager.cpp
|
filedialogmanager.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
|
newdir.cpp
|
||||||
newmenu.cpp
|
newmenu.cpp
|
||||||
newproject.cpp
|
newproject.cpp
|
||||||
projectexplorer.cpp
|
projectexplorer.cpp
|
||||||
|
@ -43,7 +43,7 @@ void DeleteConfirmation::draw(StudioContext &ctx) noexcept {
|
|||||||
case Stage::Open:
|
case Stage::Open:
|
||||||
drawWindow(ctx.tctx, m_open, [this] {
|
drawWindow(ctx.tctx, m_open, [this] {
|
||||||
ImGui::Text("Are you sure you want to delete %s?", m_path.c_str());
|
ImGui::Text("Are you sure you want to delete %s?", m_path.c_str());
|
||||||
if (ig::PopupControlsOkCancel(m_open) != ig::PopupResponse::None) {
|
if (ig::PopupControlsOkCancel(m_open, "Yes", "No") != ig::PopupResponse::None) {
|
||||||
deleteFile.emit(m_path);
|
deleteFile.emit(m_path);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
59
src/olympic/studio/applib/src/newdir.cpp
Normal file
59
src/olympic/studio/applib/src/newdir.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <studio/imguiutil.hpp>
|
||||||
|
|
||||||
|
#include "newdir.hpp"
|
||||||
|
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
NewDir::NewDir() noexcept {
|
||||||
|
setTitle("New Directory");
|
||||||
|
setSize({280, 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewDir::openPath(ox::StringViewCR path) noexcept {
|
||||||
|
open();
|
||||||
|
m_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewDir::open() noexcept {
|
||||||
|
m_path = "";
|
||||||
|
m_stage = Stage::Opening;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewDir::close() noexcept {
|
||||||
|
m_stage = Stage::Closed;
|
||||||
|
m_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NewDir::isOpen() const noexcept {
|
||||||
|
return m_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewDir::draw(StudioContext &ctx) noexcept {
|
||||||
|
switch (m_stage) {
|
||||||
|
case Stage::Closed:
|
||||||
|
break;
|
||||||
|
case Stage::Opening:
|
||||||
|
ImGui::OpenPopup(title().c_str());
|
||||||
|
m_open = true;
|
||||||
|
[[fallthrough]];
|
||||||
|
case Stage::Open:
|
||||||
|
drawWindow(ctx.tctx, m_open, [this] {
|
||||||
|
if (m_stage == Stage::Opening) {
|
||||||
|
ImGui::SetKeyboardFocusHere();
|
||||||
|
}
|
||||||
|
ig::InputText("Name", m_str);
|
||||||
|
if (ig::PopupControlsOkCancel(m_open) == ig::PopupResponse::OK) {
|
||||||
|
newDir.emit(m_path + "/" + m_str);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_stage = Stage::Open;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
src/olympic/studio/applib/src/newdir.hpp
Normal file
49
src/olympic/studio/applib/src/newdir.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/string.hpp>
|
||||||
|
|
||||||
|
#include <studio/context.hpp>
|
||||||
|
#include <studio/popup.hpp>
|
||||||
|
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
class NewDir final: public Popup {
|
||||||
|
private:
|
||||||
|
enum class Stage {
|
||||||
|
Closed,
|
||||||
|
Opening,
|
||||||
|
Open,
|
||||||
|
};
|
||||||
|
Stage m_stage = Stage::Closed;
|
||||||
|
bool m_open{};
|
||||||
|
ox::String m_path;
|
||||||
|
ox::IString<255> m_str;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ox::Signal<ox::Error(ox::StringViewCR path)> newDir;
|
||||||
|
|
||||||
|
NewDir() noexcept;
|
||||||
|
|
||||||
|
void openPath(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
|
void open() noexcept override;
|
||||||
|
|
||||||
|
void close() noexcept override;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
bool isOpen() const noexcept override;
|
||||||
|
|
||||||
|
void draw(StudioContext &ctx) noexcept override;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr ox::CStringView value() const noexcept {
|
||||||
|
return m_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -27,13 +27,13 @@ ProjectTreeModel::ProjectTreeModel(ProjectTreeModel &&other) noexcept:
|
|||||||
m_children(std::move(other.m_children)) {
|
m_children(std::move(other.m_children)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectTreeModel::draw(turbine::Context &ctx) const noexcept {
|
void ProjectTreeModel::draw(turbine::Context &tctx) const noexcept {
|
||||||
constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||||
if (!m_children.empty()) {
|
if (!m_children.empty()) {
|
||||||
if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) {
|
if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) {
|
||||||
drawDirContextMenu();
|
drawDirContextMenu();
|
||||||
for (auto const&child : m_children) {
|
for (auto const&child : m_children) {
|
||||||
child->draw(ctx);
|
child->draw(tctx);
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
} else {
|
} else {
|
||||||
@ -54,6 +54,9 @@ void ProjectTreeModel::draw(turbine::Context &ctx) const noexcept {
|
|||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
|
ig::dragDropSource([this] {
|
||||||
|
ImGui::Text("%s", m_name.c_str());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,13 +73,16 @@ void ProjectTreeModel::drawDirContextMenu() const noexcept {
|
|||||||
if (ImGui::MenuItem("Add Directory")) {
|
if (ImGui::MenuItem("Add Directory")) {
|
||||||
m_explorer.addDir.emit(fullPath());
|
m_explorer.addDir.emit(fullPath());
|
||||||
}
|
}
|
||||||
|
if (ImGui::MenuItem("Delete")) {
|
||||||
|
m_explorer.deleteItem.emit(fullPath());
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::BasicString<255> ProjectTreeModel::fullPath() const noexcept {
|
ox::BasicString<255> ProjectTreeModel::fullPath() const noexcept {
|
||||||
if (m_parent) {
|
if (m_parent) {
|
||||||
return m_parent->fullPath() + "/" + ox::StringView(m_name);
|
return m_parent->fullPath() + "/" + m_name;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class ProjectTreeModel {
|
|||||||
|
|
||||||
ProjectTreeModel(ProjectTreeModel &&other) noexcept;
|
ProjectTreeModel(ProjectTreeModel &&other) noexcept;
|
||||||
|
|
||||||
void draw(turbine::Context &ctx) const noexcept;
|
void draw(turbine::Context &tctx) const noexcept;
|
||||||
|
|
||||||
void setChildren(ox::Vector<ox::UPtr<ProjectTreeModel>> children) noexcept;
|
void setChildren(ox::Vector<ox::UPtr<ProjectTreeModel>> children) noexcept;
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringParam projectDataDir) noexce
|
|||||||
m_aboutPopup(m_tctx) {
|
m_aboutPopup(m_tctx) {
|
||||||
turbine::setApplicationData(m_tctx, &m_sctx);
|
turbine::setApplicationData(m_tctx, &m_sctx);
|
||||||
m_projectExplorer.fileChosen.connect(this, &StudioUI::openFile);
|
m_projectExplorer.fileChosen.connect(this, &StudioUI::openFile);
|
||||||
|
m_projectExplorer.addDir.connect(this, &StudioUI::addDir);
|
||||||
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_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
m_newProject.finished.connect(this, &StudioUI::createOpenProject);
|
||||||
@ -344,6 +345,11 @@ void StudioUI::handleKeyInput() noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Error StudioUI::addDir(ox::StringViewCR path) noexcept {
|
||||||
|
m_newDirDialog.openPath(path);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error StudioUI::addFile(ox::StringViewCR path) noexcept {
|
ox::Error StudioUI::addFile(ox::StringViewCR path) noexcept {
|
||||||
m_newMenu.openPath(path);
|
m_newMenu.openPath(path);
|
||||||
return {};
|
return {};
|
||||||
@ -369,8 +375,10 @@ ox::Error StudioUI::openProjectPath(ox::StringParam path) noexcept {
|
|||||||
ox::make_unique_catch<Project>(keelCtx(m_tctx), std::move(path), m_projectDataDir)
|
ox::make_unique_catch<Project>(keelCtx(m_tctx), std::move(path), m_projectDataDir)
|
||||||
.moveTo(m_project));
|
.moveTo(m_project));
|
||||||
m_sctx.project = m_project.get();
|
m_sctx.project = m_project.get();
|
||||||
m_deleteConfirmation.deleteFile.connect(m_sctx.project, &Project::deleteItem);
|
|
||||||
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_newDirDialog.newDir.connect(m_sctx.project, &Project::mkdir);
|
||||||
|
m_project->dirAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
||||||
m_project->fileAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
m_project->fileAdded.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
||||||
m_project->fileDeleted.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
m_project->fileDeleted.connect(&m_projectExplorer, &ProjectExplorer::refreshProjectTreeModel);
|
||||||
m_openFiles.clear();
|
m_openFiles.clear();
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "aboutpopup.hpp"
|
#include "aboutpopup.hpp"
|
||||||
#include "deleteconfirmation.hpp"
|
#include "deleteconfirmation.hpp"
|
||||||
|
#include "newdir.hpp"
|
||||||
#include "newmenu.hpp"
|
#include "newmenu.hpp"
|
||||||
#include "newproject.hpp"
|
#include "newproject.hpp"
|
||||||
#include "projectexplorer.hpp"
|
#include "projectexplorer.hpp"
|
||||||
@ -41,13 +42,15 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
BaseEditor *m_activeEditorUpdatePending = nullptr;
|
BaseEditor *m_activeEditorUpdatePending = nullptr;
|
||||||
NewMenu m_newMenu;
|
NewMenu m_newMenu;
|
||||||
DeleteConfirmation m_deleteConfirmation;
|
DeleteConfirmation m_deleteConfirmation;
|
||||||
|
NewDir m_newDirDialog;
|
||||||
NewProject m_newProject;
|
NewProject m_newProject;
|
||||||
AboutPopup m_aboutPopup;
|
AboutPopup m_aboutPopup;
|
||||||
ox::Array<Popup*, 4> const m_popups = {
|
ox::Array<Popup*, 5> const m_popups = {
|
||||||
&m_newMenu,
|
&m_newMenu,
|
||||||
&m_newProject,
|
&m_newProject,
|
||||||
&m_aboutPopup,
|
&m_aboutPopup,
|
||||||
&m_deleteConfirmation,
|
&m_deleteConfirmation,
|
||||||
|
&m_newDirDialog,
|
||||||
};
|
};
|
||||||
bool m_showProjectExplorer = true;
|
bool m_showProjectExplorer = true;
|
||||||
|
|
||||||
@ -87,6 +90,8 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
|
|
||||||
void handleKeyInput() noexcept;
|
void handleKeyInput() noexcept;
|
||||||
|
|
||||||
|
ox::Error addDir(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
ox::Error addFile(ox::StringViewCR path) noexcept;
|
ox::Error addFile(ox::StringViewCR path) noexcept;
|
||||||
|
|
||||||
ox::Error deleteFile(ox::StringViewCR path) noexcept;
|
ox::Error deleteFile(ox::StringViewCR path) noexcept;
|
||||||
|
@ -175,9 +175,16 @@ enum class PopupResponse {
|
|||||||
Cancel,
|
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]]
|
[[nodiscard]]
|
||||||
bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show, ImVec2 const&sz = {285, 0});
|
bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show, ImVec2 const&sz = {285, 0});
|
||||||
|
@ -19,6 +19,7 @@ namespace studio {
|
|||||||
|
|
||||||
enum class ProjectEvent {
|
enum class ProjectEvent {
|
||||||
None,
|
None,
|
||||||
|
DirAdded,
|
||||||
FileAdded,
|
FileAdded,
|
||||||
// FileRecognized is triggered for all matching files upon a new
|
// FileRecognized is triggered for all matching files upon a new
|
||||||
// subscription to a section of the project and upon the addition of a file.
|
// subscription to a section of the project and upon the addition of a file.
|
||||||
@ -120,6 +121,7 @@ class Project: public ox::SignalHandler {
|
|||||||
// signals
|
// signals
|
||||||
public:
|
public:
|
||||||
ox::Signal<ox::Error(ProjectEvent, ox::StringViewCR)> fileEvent;
|
ox::Signal<ox::Error(ProjectEvent, ox::StringViewCR)> fileEvent;
|
||||||
|
ox::Signal<ox::Error(ox::StringViewCR)> dirAdded;
|
||||||
ox::Signal<ox::Error(ox::StringViewCR)> fileAdded;
|
ox::Signal<ox::Error(ox::StringViewCR)> fileAdded;
|
||||||
// FileRecognized is triggered for all matching files upon a new
|
// FileRecognized is triggered for all matching files upon a new
|
||||||
// subscription to a section of the project and upon the addition of a
|
// 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) {
|
switch (e) {
|
||||||
case ProjectEvent::None:
|
case ProjectEvent::None:
|
||||||
break;
|
break;
|
||||||
|
case ProjectEvent::DirAdded:
|
||||||
|
connect(this, &Project::dirAdded, tgt, slot);
|
||||||
|
break;
|
||||||
case ProjectEvent::FileAdded:
|
case ProjectEvent::FileAdded:
|
||||||
connect(this, &Project::fileAdded, tgt, slot);
|
connect(this, &Project::fileAdded, tgt, slot);
|
||||||
break;
|
break;
|
||||||
|
@ -54,18 +54,22 @@ bool PushButton(ox::CStringViewCR lbl, ImVec2 const&btnSz) noexcept {
|
|||||||
return ImGui::Button(lbl.c_str(), btnSz);
|
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;
|
auto out = PopupResponse::None;
|
||||||
constexpr auto btnSz = ImVec2{50, BtnSz.y};
|
constexpr auto btnSz = ImVec2{50, BtnSz.y};
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::SetCursorPosX(popupWidth - 118);
|
ImGui::SetCursorPosX(popupWidth - 118);
|
||||||
if (ImGui::Button("OK", btnSz)) {
|
if (ImGui::Button(ok.c_str(), btnSz)) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
popupOpen = false;
|
popupOpen = false;
|
||||||
out = PopupResponse::OK;
|
out = PopupResponse::OK;
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_Escape) || ImGui::Button("Cancel", btnSz)) {
|
if (ImGui::IsKeyDown(ImGuiKey_Escape) || ImGui::Button(cancel.c_str(), btnSz)) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
popupOpen = false;
|
popupOpen = false;
|
||||||
out = PopupResponse::Cancel;
|
out = PopupResponse::Cancel;
|
||||||
@ -73,8 +77,11 @@ PopupResponse PopupControlsOkCancel(float popupWidth, bool &popupOpen) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupResponse PopupControlsOkCancel(bool &popupOpen) {
|
PopupResponse PopupControlsOkCancel(
|
||||||
return PopupControlsOkCancel(ImGui::GetContentRegionAvail().x + 17, popupOpen);
|
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) {
|
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);
|
auto const [stat, err] = m_fs.stat(path);
|
||||||
if (err) {
|
if (err) {
|
||||||
OX_RETURN_ERROR(m_fs.mkdir(path, true));
|
OX_RETURN_ERROR(m_fs.mkdir(path, true));
|
||||||
fileUpdated.emit(path, {});
|
dirAdded.emit(path);
|
||||||
}
|
}
|
||||||
return stat.fileType == ox::FileType::Directory ?
|
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 {
|
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 {
|
ox::Error Project::deleteItem(ox::StringViewCR path) noexcept {
|
||||||
|
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);
|
auto const err = m_fs.remove(path);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
fileDeleted.emit(path);
|
fileDeleted.emit(path);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
} else {
|
||||||
|
auto const err = m_fs.remove(path);
|
||||||
|
if (!err) {
|
||||||
|
fileDeleted.emit(path);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Project::exists(ox::StringViewCR path) const noexcept {
|
bool Project::exists(ox::StringViewCR path) const noexcept {
|
||||||
|
Loading…
Reference in New Issue
Block a user