[studio] Make reusable FileTreeModel
This commit is contained in:
51
src/olympic/studio/modlib/include/studio/filetreemodel.hpp
Normal file
51
src/olympic/studio/modlib/include/studio/filetreemodel.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
namespace studio {
|
||||
|
||||
class FileExplorer {
|
||||
|
||||
public:
|
||||
virtual ~FileExplorer() = default;
|
||||
|
||||
virtual void fileOpened(ox::StringViewCR path) const noexcept = 0;
|
||||
|
||||
virtual void drawFileContextMenu(ox::StringViewCR path) const noexcept = 0;
|
||||
|
||||
virtual void drawDirContextMenu(ox::StringViewCR path) const noexcept = 0;
|
||||
|
||||
};
|
||||
|
||||
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::Vector<ox::UPtr<FileTreeModel>> m_children;
|
||||
|
||||
public:
|
||||
virtual ~FileTreeModel() = default;
|
||||
|
||||
explicit FileTreeModel(
|
||||
FileExplorer &explorer, ox::StringParam name,
|
||||
FileTreeModel *parent = nullptr) noexcept;
|
||||
|
||||
FileTreeModel(FileTreeModel &&other) noexcept = default;
|
||||
|
||||
void draw(turbine::Context &tctx) const noexcept;
|
||||
|
||||
void setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ add_library(
|
||||
Studio
|
||||
configio.cpp
|
||||
editor.cpp
|
||||
filetreemodel.cpp
|
||||
imguiutil.cpp
|
||||
module.cpp
|
||||
popup.cpp
|
||||
|
||||
55
src/olympic/studio/modlib/src/filetreemodel.cpp
Normal file
55
src/olympic/studio/modlib/src/filetreemodel.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <studio/dragdrop.hpp>
|
||||
#include <studio/imguiutil.hpp>
|
||||
|
||||
#include <studio/filetreemodel.hpp>
|
||||
|
||||
namespace studio {
|
||||
|
||||
FileTreeModel::FileTreeModel(
|
||||
FileExplorer &explorer,
|
||||
ox::StringParam name,
|
||||
FileTreeModel *parent) noexcept:
|
||||
m_explorer{explorer},
|
||||
m_parent{parent},
|
||||
m_name{std::move(name)} {
|
||||
}
|
||||
|
||||
void FileTreeModel::draw(turbine::Context &tctx) const noexcept {
|
||||
constexpr auto dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
if (!m_children.empty()) {
|
||||
if (ImGui::TreeNodeEx(m_name.c_str(), dirFlags)) {
|
||||
m_explorer.drawDirContextMenu(m_fullPath);
|
||||
for (auto const&child : m_children) {
|
||||
child->draw(tctx);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
ig::IDStackItem const idStackItem{m_name};
|
||||
m_explorer.drawDirContextMenu(m_fullPath);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::TreeNodeEx(m_imguiNodeName.c_str(), ImGuiTreeNodeFlags_Leaf)) {
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
|
||||
m_explorer.fileOpened(m_fullPath);
|
||||
}
|
||||
m_explorer.drawFileContextMenu(m_fullPath);
|
||||
ImGui::TreePop();
|
||||
std::ignore = ig::dragDropSource([this] {
|
||||
ImGui::Text("%s", m_name.c_str());
|
||||
return ig::setDragDropPayload("FileRef", FileRef{ox::String{m_fullPath}});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileTreeModel::setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept {
|
||||
m_children = std::move(children);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user