111 lines
2.4 KiB
C++
111 lines
2.4 KiB
C++
/*
|
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#include <turbine/turbine.hpp>
|
|
|
|
#include <studio/imguiutil.hpp>
|
|
|
|
#include <studio/filepickerpopup.hpp>
|
|
|
|
namespace studio {
|
|
|
|
FilePickerPopup::Explorer::Explorer(keel::Context &kctx):
|
|
FileExplorer{kctx} {
|
|
}
|
|
|
|
void FilePickerPopup::Explorer::fileOpened(ox::StringViewCR) const noexcept {
|
|
opened = true;
|
|
}
|
|
|
|
|
|
FilePickerPopup::FilePickerPopup(
|
|
ox::StringParam name,
|
|
keel::Context &kctx,
|
|
ox::StringParam fileExt) noexcept:
|
|
m_name{std::move(name)},
|
|
m_explorer{kctx},
|
|
m_fileExts{std::move(fileExt)} {
|
|
}
|
|
|
|
FilePickerPopup::FilePickerPopup(
|
|
ox::StringParam name,
|
|
keel::Context &kctx,
|
|
ox::SpanView<ox::StringLiteral> fileExts) noexcept:
|
|
m_name{std::move(name)},
|
|
m_explorer{kctx},
|
|
m_fileExts{[fileExts] {
|
|
ox::Vector<ox::String> out;
|
|
out.reserve(fileExts.size());
|
|
for (auto &s : fileExts) {
|
|
out.emplace_back(s);
|
|
}
|
|
return out;
|
|
}()} {
|
|
}
|
|
|
|
FilePickerPopup::FilePickerPopup(
|
|
ox::StringParam name,
|
|
keel::Context &kctx,
|
|
ox::Vector<ox::String> fileExts) noexcept:
|
|
m_name{std::move(name)},
|
|
m_explorer{kctx},
|
|
m_fileExts{std::move(fileExts)} {
|
|
}
|
|
|
|
void FilePickerPopup::refresh() noexcept {
|
|
m_explorer.setModel(buildFileTreeModel(
|
|
m_explorer,
|
|
[this](ox::StringViewCR path, ox::FileStat const &s) {
|
|
auto const [ext, err] = fileExt(path);
|
|
return
|
|
s.fileType == ox::FileType::Directory ||
|
|
(s.fileType == ox::FileType::NormalFile && !err && m_fileExts.contains(ext));
|
|
},
|
|
false).or_value(ox::UPtr<FileTreeModel>{}));
|
|
}
|
|
|
|
void FilePickerPopup::open() noexcept {
|
|
refresh();
|
|
m_open = true;
|
|
m_explorer.opened = false;
|
|
}
|
|
|
|
void FilePickerPopup::close() noexcept {
|
|
m_explorer.setModel(ox::UPtr<FileTreeModel>{});
|
|
m_open = false;
|
|
}
|
|
|
|
bool FilePickerPopup::isOpen() const noexcept {
|
|
return m_open;
|
|
}
|
|
|
|
ox::Optional<ox::String> FilePickerPopup::draw(Context &ctx) noexcept {
|
|
ox::Optional<ox::String> out;
|
|
if (!m_open) {
|
|
return out;
|
|
}
|
|
auto const scale = turbine::scale(ctx.tctx);
|
|
if (ig::BeginPopup(m_name, m_open, {380, 340})) {
|
|
auto const vp = ImGui::GetContentRegionAvail();
|
|
m_explorer.draw(ctx, {vp.x, vp.y - 30 * scale});
|
|
if (ig::PopupControlsOkCancel(m_open) == ig::PopupResponse::OK || m_explorer.opened) {
|
|
out = handlePick();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
return out;
|
|
}
|
|
|
|
ox::Optional<ox::String> FilePickerPopup::handlePick() noexcept {
|
|
ox::Optional<ox::String> out;
|
|
auto p = m_explorer.selectedPath();
|
|
if (p) {
|
|
out.emplace(*p);
|
|
}
|
|
close();
|
|
return out;
|
|
}
|
|
|
|
}
|