143 lines
3.5 KiB
C++
143 lines
3.5 KiB
C++
/*
|
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
|
|
#include <ox/std/memory.hpp>
|
|
#include <ox/std/string.hpp>
|
|
|
|
#include <turbine/context.hpp>
|
|
|
|
#include "widget.hpp"
|
|
|
|
namespace studio {
|
|
|
|
constexpr void safeDelete(class FileTreeModel const *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} {}
|
|
|
|
void draw(Context &ctx, ImVec2 const &sz) const noexcept;
|
|
|
|
void setModel(ox::UPtr<FileTreeModel> &&model, bool selectRoot = false) noexcept;
|
|
|
|
ox::Error setSelectedPath(ox::StringViewCR path) noexcept;
|
|
|
|
[[nodiscard]]
|
|
ox::Optional<ox::String> selectedPath() const;
|
|
|
|
virtual void fileOpened(ox::StringViewCR path) const noexcept;
|
|
|
|
virtual void fileDeleted(ox::StringViewCR path) const noexcept;
|
|
|
|
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;
|
|
|
|
[[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;
|
|
ox::String m_name;
|
|
ox::String m_fullPath;
|
|
ox::Vector<ox::UPtr<FileTreeModel>> m_children;
|
|
ox::FileType const m_fileType{};
|
|
|
|
public:
|
|
explicit FileTreeModel(
|
|
FileExplorer &explorer,
|
|
ox::StringParam name,
|
|
ox::FileType fileType,
|
|
FileTreeModel const *parent = nullptr) noexcept;
|
|
|
|
virtual ~FileTreeModel() = default;
|
|
|
|
FileTreeModel(FileTreeModel &&other) noexcept = default;
|
|
|
|
void draw(turbine::Context &tctx) const noexcept;
|
|
|
|
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 const *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;
|
|
|
|
}
|