[studio] Add a file explorer to NewMenu to choose where new files go
All checks were successful
Build / build (push) Successful in 4m16s

This commit is contained in:
2025-01-22 23:11:08 -06:00
parent d15a0df7da
commit 1cc1d561e2
13 changed files with 329 additions and 112 deletions

View File

@@ -4,41 +4,96 @@
#pragma once
#include <algorithm>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <turbine/context.hpp>
#include "widget.hpp"
namespace studio {
class FileExplorer {
constexpr void safeDelete(class FileTreeModel *m) noexcept;
class FileExplorer: public ox::SignalHandler {
friend class FileTreeModel;
private:
keel::Context &m_kctx;
class FileTreeModel const *m_selected{};
bool const m_fileDraggable{};
ox::UPtr<FileTreeModel> m_treeModel;
public:
explicit FileExplorer(keel::Context &kctx, bool const fileDraggable = false) noexcept:
m_kctx{kctx},
m_fileDraggable{fileDraggable} {}
virtual ~FileExplorer() = default;
virtual void fileOpened(ox::StringViewCR path) const noexcept = 0;
void draw(StudioContext &ctx, ImVec2 const &sz) const noexcept;
virtual void drawFileContextMenu(ox::StringViewCR path) const noexcept = 0;
void setModel(ox::UPtr<FileTreeModel> &&model, bool selectRoot = false) noexcept;
virtual void drawDirContextMenu(ox::StringViewCR path) const noexcept = 0;
ox::Error setSelectedPath(ox::StringViewCR path) noexcept;
[[nodiscard]]
ox::Optional<ox::String> selectedPath() const;
virtual void fileOpened(ox::StringViewCR path) const noexcept;
void drawFileContextMenu(ox::CStringViewCR path) const noexcept;
void drawDirContextMenu(ox::CStringViewCR path) const noexcept;
[[nodiscard]]
ox::FileSystem &romFs() const noexcept {
return *m_kctx.rom;
}
protected:
virtual void fileContextMenu(ox::StringViewCR path) const noexcept;
virtual void dirContextMenu(ox::StringViewCR path) const noexcept;
void setSelectedNode(FileTreeModel const *const node) noexcept {
m_selected = node;
}
[[nodiscard]]
bool selected(FileTreeModel const *const node) const noexcept {
return m_selected == node;
}
[[nodiscard]]
bool fileDraggable() const noexcept {
return m_fileDraggable;
}
private:
ox::Result<bool> setSelectedPath(ox::StringViewCR path, FileTreeModel const&node) noexcept;
};
class FileTreeModel {
private:
FileExplorer &m_explorer;
FileTreeModel *m_parent = nullptr;
ox::String m_name;
ox::String m_fullPath{m_parent ? m_parent->m_fullPath + "/" + m_name : ox::String{}};
ox::String m_imguiNodeName{ox::sfmt("{}##{}", m_name, m_fullPath)};
ox::String m_fullPath;
ox::Vector<ox::UPtr<FileTreeModel>> m_children;
ox::FileType const m_fileType{};
public:
virtual ~FileTreeModel() = default;
explicit FileTreeModel(
FileExplorer &explorer, ox::StringParam name,
FileTreeModel *parent = nullptr) noexcept;
FileExplorer &explorer,
ox::StringParam name,
ox::FileType fileType,
FileTreeModel const *parent = nullptr) noexcept;
virtual ~FileTreeModel() = default;
FileTreeModel(FileTreeModel &&other) noexcept = default;
@@ -46,6 +101,38 @@ class FileTreeModel {
void setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept;
[[nodiscard]]
ox::Vector<ox::UPtr<FileTreeModel>> const&children() const noexcept {
return m_children;
}
[[nodiscard]]
bool isEmptyDir() const noexcept;
[[nodiscard]]
ox::String const &path() const noexcept {
return m_fullPath;
}
};
constexpr void safeDelete(FileTreeModel *m) noexcept {
delete m;
}
ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
FileExplorer &explorer,
ox::StringParam name,
ox::StringViewCR path,
FileTreeModel *parent = nullptr,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter =
[](ox::StringViewCR, ox::FileStat const&) {return true;},
bool showEmptyDirs = true) noexcept;
ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
FileExplorer &explorer,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter =
[](ox::StringViewCR, ox::FileStat const&) {return true;},
bool showEmptyDirs = true) noexcept;
}

View File

@@ -95,9 +95,9 @@ class ItemMaker {
public:
constexpr ItemMaker(
ox::StringParam pName,
ox::StringParam pParentDir,
ox::StringViewCR pParentDir,
ox::StringParam pFileExt) noexcept:
m_parentDir{std::move(pParentDir)},
m_parentDir{sfmt("/{}", pParentDir)},
m_fileExt{std::move(pFileExt)},
m_typeDisplayName{std::move(pName)} {
}
@@ -128,6 +128,11 @@ class ItemMaker {
return m_templates;
}
[[nodiscard]]
ox::String const&fileExt() const noexcept {
return m_fileExt;
}
[[nodiscard]]
ox::String const&defaultPath() const noexcept {
return m_parentDir;
@@ -140,7 +145,7 @@ class ItemMaker {
[[nodiscard]]
ox::String itemPath(ox::StringViewCR pName) const noexcept {
return ox::sfmt("/{}/{}.{}", m_parentDir, pName, m_fileExt);
return ox::sfmt("{}/{}.{}", m_parentDir, pName, m_fileExt);
}
[[nodiscard]]
@@ -196,12 +201,12 @@ class ItemMakerT final: public ItemMaker {
public:
constexpr ItemMakerT(
ox::StringParam pDisplayName,
ox::StringParam pParentDir,
ox::StringViewCR pParentDir,
ox::StringParam fileExt,
ox::ClawFormat const pFmt = ox::ClawFormat::Metal) noexcept:
ItemMaker(
std::move(pDisplayName),
std::move(pParentDir),
pParentDir,
std::move(fileExt)),
m_fmt{pFmt} {
installTemplate(ox::make_unique<ItemTemplateT<T>>());
@@ -209,13 +214,13 @@ class ItemMakerT final: public ItemMaker {
constexpr ItemMakerT(
ox::StringParam pDisplayName,
ox::StringParam pParentDir,
ox::StringViewCR pParentDir,
ox::StringParam fileExt,
T const&pItem,
ox::ClawFormat const pFmt) noexcept:
ItemMaker(
std::move(pDisplayName),
std::move(pParentDir),
pParentDir,
std::move(fileExt)),
m_fmt{pFmt} {
installTemplate(ox::make_unique<ItemTemplateT<T>>("Default", std::move(pItem)));
@@ -223,13 +228,13 @@ class ItemMakerT final: public ItemMaker {
constexpr ItemMakerT(
ox::StringParam pDisplayName,
ox::StringParam pParentDir,
ox::StringViewCR pParentDir,
ox::StringParam fileExt,
T &&pItem,
ox::ClawFormat const pFmt) noexcept:
ItemMaker(
std::move(pDisplayName),
std::move(pParentDir),
pParentDir,
std::move(fileExt)),
m_fmt{pFmt} {
installTemplate(ox::make_unique<ItemTemplateT<T>>("Default", std::move(pItem)));

View File

@@ -0,0 +1,16 @@
/*
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <turbine/context.hpp>
#include <studio/filetreemodel.hpp>
namespace studio {
}

View File

@@ -9,6 +9,7 @@
#include <studio/dragdrop.hpp>
#include <studio/editor.hpp>
#include <studio/filedialog.hpp>
#include <studio/filetreemodel.hpp>
#include <studio/imguiutil.hpp>
#include <studio/module.hpp>
#include <studio/itemmaker.hpp>