Squashed 'deps/nostalgia/' changes from f847289b..671b8eda

671b8eda [ox/std] Make StringLiteral constructors consteval
952637a1 Merge commit 'cbf4414fcaf00c00a2abf73b5c04a055180ad980'
7569698e [nostalgia,studio] Add FileExts_TileSheet const, and corresponding FilePickerPopup constructor
21713ba9 [ox/std] Fix StringLiteral::operator= to work with DevkitARM
73273b6f [nostalgia/gfx] Add isTileSheet function for checking paths against both file extensions
9f040392 [olympic,nostalgia] Cleanup style
f4f7e5d0 Merge commit '9b5f7886cadc5c3dc826d00fa5b2e71696151dfd'
c27726a4 Merge commit '6bbcae10cc7b21b73171ec0ff196f4baf6304404'
bd24a775 Merge commit '7371df429534f264c179684412f6197f7968ebfa'
4419dff2 Merge commit '7688c05bac8c20bc267cae62ec78d55e5d0c493b'
536999c0 Merge commit '47eee1d56d591e3631d16e95a78ea3629ee312ee'
a5535ef5 Merge commit '08236fc790e711afe886b6ef545511d35e4e5c6c'
a90380f3 Merge commit 'e90dd887477452922f783535edb3d4c55e9a0d2c'
2000b2de [nostalgia/gfx/studio] Cleanup
7d92400f [nostalgia/gfx/studio] Add type specific navigateTo functions

git-subtree-dir: deps/nostalgia
git-subtree-split: 671b8edaadefe1872fb8954ad13d221b24f676c0
This commit is contained in:
2025-06-29 17:33:27 -05:00
parent 9b5f7886ca
commit b0726568df
36 changed files with 159 additions and 114 deletions

View File

@ -16,35 +16,28 @@ namespace ox {
* StringLiteral is used for functions that want to ensure that they are taking
* string literals, and not strings outside of the data section of the program
* that might get deleted.
* This type cannot force you to use it correctly, so don't give it something
* that is not a literal.
* If you do this:
* StringLiteral(str.c_str())
* the resulting segfault is on you.
*/
class StringLiteral: public detail::BaseStringView {
public:
constexpr StringLiteral() noexcept = default;
consteval StringLiteral() noexcept = default;
constexpr StringLiteral(StringLiteral const&sv) noexcept = default;
constexpr StringLiteral(StringLiteral const &sv) noexcept = default;
constexpr explicit StringLiteral(std::nullptr_t) noexcept {}
consteval explicit StringLiteral(std::nullptr_t) noexcept {}
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
consteval explicit StringLiteral(char const *str, std::size_t const len) noexcept: BaseStringView{str, len} {}
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
constexpr explicit StringLiteral(char const *str) noexcept: StringLiteral(str, ox::strlen(str)) {}
consteval explicit StringLiteral(char const *str) noexcept: StringLiteral{str, ox::strlen(str)} {}
OX_ALLOW_UNSAFE_BUFFERS_END
constexpr StringLiteral &operator=(StringLiteral const&other) noexcept {
if (&other != this) {
constexpr StringLiteral &operator=(StringLiteral const &other) noexcept {
set(other.data(), other.len());
}
return *this;
}
[[nodiscard]]
constexpr const char *c_str() const noexcept {
constexpr char const *c_str() const noexcept {
return data();
}

View File

@ -12,8 +12,18 @@ constexpr auto TileWidth = 8;
constexpr auto TileHeight = 8;
constexpr auto PixelsPerTile = TileWidth * TileHeight;
constexpr ox::StringLiteral FileExt_ng("ng");
constexpr ox::StringLiteral FileExt_nts("nts");
constexpr ox::StringLiteral FileExt_npal("npal");
constexpr ox::StringLiteral FileExt_ng{"ng"};
constexpr ox::StringLiteral FileExt_nts{"nts"};
constexpr ox::StringLiteral FileExt_npal{"npal"};
constexpr ox::Array<ox::StringLiteral, 2> FileExts_TileSheet{
FileExt_nts,
FileExt_ng,
};
[[nodiscard]]
constexpr bool isTileSheet(ox::StringViewCR path) noexcept {
return endsWith(path, FileExt_nts) || endsWith(path, FileExt_ng);
}
}

View File

@ -114,10 +114,10 @@ struct InitParams {
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const &params = {}) noexcept;
[[nodiscard]]
int tileColumns(Context&) noexcept;
int tileColumns(Context const&) noexcept;
[[nodiscard]]
int tileRows(Context&) noexcept;
int tileRows(Context const&) noexcept;
ox::Error loadBgPalette(
Context &ctx,

View File

@ -6,6 +6,28 @@
#include <studio/studio.hpp>
namespace nostalgia::core {
#include "tilesheet.hpp"
namespace nostalgia::gfx {
inline void navigateToTileSheet(
studio::Context &ctx, ox::StringParam path, SubSheetId const subsheetId) noexcept {
studio::navigateTo(ctx, std::move(path), ox::intToStr(subsheetId));
}
inline void navigateToPalette(studio::Context &ctx, ox::StringParam path) noexcept {
studio::navigateTo(ctx, std::move(path));
}
inline void navigateToPalette(
studio::Context &ctx,
ox::StringParam path,
size_t const colorIdx,
size_t const palPage) noexcept {
studio::navigateTo(
ctx,
std::move(path),
ox::sfmt("{};{}", colorIdx, palPage));
}
}

View File

@ -10,11 +10,11 @@ namespace nostalgia::gfx {
constexpr auto GbaTileColumns = 32;
constexpr auto GbaTileRows = 32;
int tileColumns(Context&) noexcept {
int tileColumns(Context const&) noexcept {
return GbaTileColumns;
}
int tileRows(Context&) noexcept {
int tileRows(Context const&) noexcept {
return GbaTileRows;
}

View File

@ -9,6 +9,8 @@
#include <keel/media.hpp>
#include <studio/studio.hpp>
#include <nostalgia/gfx/studio.hpp>
#include "tilesheeteditor-imgui.hpp"
namespace nostalgia::gfx {
@ -576,10 +578,10 @@ void TileSheetEditorImGui::drawPaletteMenu() noexcept {
m_view.setPalIdx(i);
}
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
studio::navigateTo(
navigateToPalette(
m_sctx,
m_model.palPath(),
ox::sfmt("{};{}", i, m_model.palettePage()));
i, m_model.palettePage());
}
// Column: color RGB
ImGui::TableNextColumn();

View File

@ -28,7 +28,7 @@ void ClawEditor::draw(Context&) noexcept {
ImGui::EndChild();
}
void ClawEditor::drawRow(ox::ModelValue const&value) noexcept {
void ClawEditor::drawRow(ox::ModelValue const &value) noexcept {
using Str = ox::BasicString<100>;
Str val, type;
switch (value.type()) {
@ -93,13 +93,13 @@ void ClawEditor::drawRow(ox::ModelValue const&value) noexcept {
ImGui::Text("%s", val.c_str());
}
void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept {
void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const &value) noexcept {
using Str = ox::BasicString<100>;
path.push_back(name);
if (value.type() == ox::ModelValue::Type::Object) {
drawTree(path, value.get<ox::ModelObject>());
} else if (value.type() == ox::ModelValue::Type::Vector) {
auto const&vec = value.get<ox::ModelValueVector>();
auto const &vec = value.get<ox::ModelValueVector>();
auto const pathStr = ox::join<Str>("##", path).unwrap();
auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr);
auto const flags = ImGuiTreeNodeFlags_SpanFullWidth
@ -110,7 +110,7 @@ void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue co
ImGui::SameLine();
drawRow(value);
if (open) {
for (auto i = 0lu; auto const&e: vec) {
for (auto i = 0lu; auto const &e: vec) {
auto const iStr = ox::sfmt<Str>("{}", i);
path.push_back(iStr);
ImGui::TableNextRow(0, 5);
@ -138,7 +138,7 @@ void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue co
path.pop_back();
}
void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept {
void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const &obj) noexcept {
using Str = ox::BasicString<100>;
for (auto const &c : obj) {
ImGui::TableNextRow(0, 5);

View File

@ -21,11 +21,11 @@ class ClawEditor: public Editor {
void draw(Context&) noexcept final;
private:
static void drawRow(ox::ModelValue const&value) noexcept;
static void drawRow(ox::ModelValue const &value) noexcept;
void drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept;
void drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const &value) noexcept;
void drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept;
void drawTree(ObjPath &path, ox::ModelObject const &obj) noexcept;
};
}

View File

@ -24,7 +24,7 @@ void NewMenu::open() noexcept {
m_useDefaultPath = true;
m_explorer.setModel(buildFileTreeModel(
m_explorer,
[](ox::StringViewCR, ox::FileStat const&s) {
[](ox::StringViewCR, ox::FileStat const &s) {
return s.fileType == ox::FileType::Directory;
}).or_value(ox::UPtr<FileTreeModel>{}));
}
@ -75,26 +75,26 @@ void NewMenu::addItemMaker(ox::UPtr<ItemMaker> &&im) noexcept {
m_types.emplace_back(std::move(im));
std::sort(
m_types.begin(), m_types.end(),
[](ox::UPtr<ItemMaker> const&im1, ox::UPtr<ItemMaker> const&im2) {
[](ox::UPtr<ItemMaker> const &im1, ox::UPtr<ItemMaker> const &im2) {
return im1->typeDisplayName() < im2->typeDisplayName();
});
}
void NewMenu::installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept {
for (auto const&im : m_types) {
for (auto const &im : m_types) {
if (im->installTemplate(std::move(tmplt))) {
break;
}
}
}
void NewMenu::drawNewItemType(Context const&sctx) noexcept {
void NewMenu::drawNewItemType(Context const &sctx) noexcept {
setSize({280, 180});
drawWindow(sctx.tctx, m_open, [this] {
ig::ListBox("Item Type", [&](size_t const i) -> ox::CStringView {
return m_types[i]->typeDisplayName();
}, m_types.size(), m_selectedType, {200, 100});
auto const&im = *m_types[m_selectedType];
auto const &im = *m_types[m_selectedType];
drawFirstPageButtons(im.itemTemplates().size() == 1 ?
Stage::NewItemTransitioningToPath : Stage::NewItemTemplate);
if (m_stage == Stage::NewItemTransitioningToPath || m_stage == Stage::NewItemTemplate) {
@ -105,10 +105,10 @@ void NewMenu::drawNewItemType(Context const&sctx) noexcept {
});
}
void NewMenu::drawNewItemTemplate(Context const&sctx) noexcept {
void NewMenu::drawNewItemTemplate(Context const &sctx) noexcept {
setSize({280, 180});
drawWindow(sctx.tctx, m_open, [this] {
auto const&templates =
auto const &templates =
m_types[m_selectedType]->itemTemplates();
ig::ListBox("Template", [&](size_t const i) -> ox::CStringView {
return templates[i]->name();

View File

@ -75,7 +75,7 @@ class NewMenu final: public Popup {
void installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept;
private:
void drawNewItemType(Context const&sctx) noexcept;
void drawNewItemType(Context const &sctx) noexcept;
void drawNewItemPath(Context &sctx) noexcept;

View File

@ -13,7 +13,7 @@
namespace studio {
class NewProject: public studio::Popup {
class NewProject: public Popup {
public:
enum class Stage {
Closed,

View File

@ -140,7 +140,7 @@ class Editor: public studio::BaseEditor {
ox::Error pushCommand(Args&&... args) noexcept {
try {
return m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...));
} catch (ox::Exception const&ex) {
} catch (ox::Exception const &ex) {
return ex.toError();
}
}
@ -148,7 +148,7 @@ class Editor: public studio::BaseEditor {
private:
ox::Error markUnsavedChanges(UndoCommand const*) noexcept;
ox::Error handleRename(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const&id) noexcept;
ox::Error handleRename(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const &id) noexcept;
};

View File

@ -21,7 +21,7 @@ struct FDFilterItem {
FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept;
};
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept;
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const &exts) noexcept;
ox::Result<ox::String> chooseDirectory() noexcept;

View File

@ -24,6 +24,8 @@ class FilePickerPopup {
public:
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::StringParam fileExt) noexcept;
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::SpanView<ox::StringLiteral> fileExts) noexcept;
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::Vector<ox::String> fileExts) noexcept;
void refresh() noexcept;

View File

@ -78,7 +78,7 @@ class FileExplorer: public ox::SignalHandler {
}
private:
ox::Result<bool> setSelectedPath(ox::StringViewCR path, FileTreeModel const&node) noexcept;
ox::Result<bool> setSelectedPath(ox::StringViewCR path, FileTreeModel const &node) noexcept;
};
@ -106,7 +106,7 @@ class FileTreeModel {
void setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept;
[[nodiscard]]
ox::Vector<ox::UPtr<FileTreeModel>> const&children() const noexcept {
ox::Vector<ox::UPtr<FileTreeModel>> const &children() const noexcept {
return m_children;
}
@ -129,13 +129,13 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::StringParam name,
ox::StringViewCR path,
FileTreeModel *parent = nullptr,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter =
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 =
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter =
[](ox::StringViewCR, ox::FileStat const&) {return true;},
bool showEmptyDirs = true) noexcept;

View File

@ -27,11 +27,11 @@ class ItemTemplate {
virtual ~ItemTemplate() = default;
[[nodiscard]]
constexpr ox::String const&name() const noexcept {
constexpr ox::String const &name() const noexcept {
return m_name;
}
constexpr bool operator<=>(ItemTemplate const&other) const noexcept {
constexpr bool operator<=>(ItemTemplate const &other) const noexcept {
return m_name != other.name() ? (m_name < other.name() ? -1 : 1) : 0;
}
@ -105,7 +105,7 @@ class ItemMaker {
virtual ~ItemMaker() noexcept = default;
[[nodiscard]]
ox::String const&typeDisplayName() const noexcept {
ox::String const &typeDisplayName() const noexcept {
return m_typeDisplayName;
}
@ -120,17 +120,17 @@ class ItemMaker {
return false;
}
constexpr ox::Vector<ox::UPtr<ItemTemplate>> const&itemTemplates() const noexcept {
constexpr ox::Vector<ox::UPtr<ItemTemplate>> const &itemTemplates() const noexcept {
return m_templates;
}
[[nodiscard]]
ox::String const&fileExt() const noexcept {
ox::String const &fileExt() const noexcept {
return m_fileExt;
}
[[nodiscard]]
ox::String const&defaultPath() const noexcept {
ox::String const &defaultPath() const noexcept {
return m_parentDir;
}
@ -212,7 +212,7 @@ class ItemMakerT final: public ItemMaker {
ox::StringParam pDisplayName,
ox::StringViewCR pParentDir,
ox::StringParam fileExt,
T const&pItem,
T const &pItem,
ox::ClawFormat const pFmt) noexcept:
ItemMaker(
std::move(pDisplayName),
@ -249,7 +249,7 @@ class ItemMakerT final: public ItemMaker {
ox::StringViewCR pPath,
size_t const pTemplateIdx) const noexcept override {
createUuidMapping(keelCtx(ctx.tctx), pPath, ox::UUID::generate().unwrap());
auto const&templates = itemTemplates();
auto const &templates = itemTemplates();
auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0;
OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem(
keelCtx(ctx), typeName(), typeVersion()));

View File

@ -43,11 +43,11 @@ class Popup: public Widget {
m_title = std::move(title);
}
constexpr ox::String const&title() const noexcept {
constexpr ox::String const &title() const noexcept {
return m_title;
}
void drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const&drawContents);
void drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const &drawContents);
};

View File

@ -64,7 +64,7 @@ class Project: public ox::SignalHandler {
ox::Error create() noexcept;
[[nodiscard]]
ox::String const&projectPath() const noexcept;
ox::String const &projectPath() const noexcept;
[[nodiscard]]
ox::FileSystem &romFs() noexcept;
@ -77,7 +77,7 @@ class Project: public ox::SignalHandler {
template<typename T>
ox::Error writeObj(
ox::StringViewCR path,
T const&obj,
T const &obj,
ox::ClawFormat fmt) noexcept;
/**
@ -86,7 +86,7 @@ class Project: public ox::SignalHandler {
template<typename T>
ox::Error writeObj(
ox::StringViewCR path,
T const&obj) noexcept;
T const &obj) noexcept;
template<typename T>
ox::Result<T> loadObj(ox::StringViewCR path) const noexcept;
@ -108,7 +108,7 @@ class Project: public ox::SignalHandler {
ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept;
[[nodiscard]]
ox::Vector<ox::String> const&fileList(ox::StringViewCR ext) noexcept;
ox::Vector<ox::String> const &fileList(ox::StringViewCR ext) noexcept;
ox::Error writeTypeStore() noexcept;
@ -117,7 +117,7 @@ class Project: public ox::SignalHandler {
void indexFile(ox::StringViewCR path) noexcept;
ox::Error writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept;
ox::Error writeBuff(ox::StringViewCR path, ox::BufferView const &buff) noexcept;
ox::Result<ox::Buffer> loadBuff(ox::StringViewCR path) const noexcept;
@ -136,13 +136,13 @@ class Project: public ox::SignalHandler {
ox::Signal<ox::Error(ox::StringViewCR)> fileRecognized;
ox::Signal<ox::Error(ox::StringViewCR)> fileDeleted;
ox::Signal<ox::Error(ox::StringViewCR)> dirDeleted;
ox::Signal<ox::Error(ox::StringViewCR path, ox::UUID const&id)> fileUpdated;
ox::Signal<ox::Error(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const&id)> fileMoved;
ox::Signal<ox::Error(ox::StringViewCR path, ox::UUID const &id)> fileUpdated;
ox::Signal<ox::Error(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const &id)> fileMoved;
};
template<typename T>
ox::Error Project::writeObj(ox::StringViewCR path, T const&obj, ox::ClawFormat fmt) noexcept {
ox::Error Project::writeObj(ox::StringViewCR path, T const &obj, ox::ClawFormat fmt) noexcept {
OX_REQUIRE_M(buff, ox::writeClaw(obj, fmt));
if (fmt == ox::ClawFormat::Organic) {
buff.pop_back();
@ -167,7 +167,7 @@ ox::Error Project::writeObj(ox::StringViewCR path, T const&obj, ox::ClawFormat f
}
template<typename T>
ox::Error Project::writeObj(ox::StringViewCR path, T const&obj) noexcept {
ox::Error Project::writeObj(ox::StringViewCR path, T const &obj) noexcept {
OX_REQUIRE(ext, fileExt(path));
auto const fmt = m_typeFmt[ext].or_value(ox::ClawFormat::Metal);
return writeObj(path, obj, fmt);
@ -197,7 +197,7 @@ ox::Error Project::subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&s
case ProjectEvent::FileRecognized:
{
OX_REQUIRE(files, listFiles());
for (auto const&f : files) {
for (auto const &f : files) {
slot(f);
}
connect(this, &Project::fileRecognized, tgt, slot);

View File

@ -16,19 +16,19 @@ namespace studio {
struct Selection {
ox::Point a, b;
constexpr Selection() noexcept = default;
constexpr Selection(ox::Point const&pA, ox::Point const&pB) noexcept: a(pA), b(pB) {}
constexpr Selection(ox::Point const &pA, ox::Point const &pB) noexcept: a(pA), b(pB) {}
[[nodiscard]]
constexpr ox::Size size() const noexcept {
return {b.x - a.x, b.y - a.y};
}
[[nodiscard]]
constexpr bool contains(ox::Point const&pt) const noexcept {
constexpr bool contains(ox::Point const &pt) const noexcept {
return a.x <= pt.x && a.y <= pt.y
&& b.x >= pt.x && b.y >= pt.y;
}
};
constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) {
constexpr auto iterateSelection(Selection const &sel, auto const &cb) {
constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>;
for (auto x = sel.a.x; x <= sel.b.x; ++x) {
for (auto y = sel.a.y; y <= sel.b.y; ++y) {
@ -44,7 +44,7 @@ constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) {
}
};
constexpr auto iterateSelectionRows(studio::Selection const&sel, auto const&cb) {
constexpr auto iterateSelectionRows(Selection const &sel, auto const &cb) {
constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>;
for (auto y = sel.a.y; y <= sel.b.y; ++y) {
for (auto x = sel.a.x; x <= sel.b.x; ++x) {

View File

@ -12,7 +12,7 @@ namespace studio {
class NoChangesException: public ox::Exception {
public:
inline NoChangesException(std::source_location sloc = std::source_location::current()):
explicit NoChangesException(std::source_location sloc = std::source_location::current()):
ox::Exception(1, "Command makes no changes.", sloc) {}
};

View File

@ -20,7 +20,7 @@ FDFilterItem::FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexc
OX_ALLOW_UNSAFE_BUFFERS_END
}
static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const&path) noexcept {
static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const &path) noexcept {
switch (r) {
case NFD_OKAY: {
ox::String out;
@ -39,11 +39,11 @@ OX_ALLOW_UNSAFE_BUFFERS_END
}
}
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept {
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const &exts) noexcept {
NFD::Guard const guard;
NFD::UniquePathN path;
ox::Vector<nfdnfilteritem_t, 5> filterItems(exts.size());
for (auto i = 0u; auto const&f : exts) {
for (auto i = 0u; auto const &f : exts) {
filterItems[i].name = f.name.data();
filterItems[i].spec = f.spec.data();
++i;

View File

@ -26,6 +26,22 @@ FilePickerPopup::FilePickerPopup(
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,

View File

@ -60,7 +60,7 @@ void FileExplorer::fileContextMenu(ox::StringViewCR) const noexcept {}
void FileExplorer::dirContextMenu(ox::StringViewCR) const noexcept {}
ox::Result<bool> FileExplorer::setSelectedPath(
ox::StringViewCR path, FileTreeModel const&node) noexcept {
ox::StringViewCR path, FileTreeModel const &node) noexcept {
if (path == node.path()) {
m_selected = &node;
return {};
@ -117,7 +117,7 @@ void FileTreeModel::draw(turbine::Context &tctx) const noexcept {
}
}
if (nodeOpen) {
for (auto const&child : m_children) {
for (auto const &child : m_children) {
child->draw(tctx);
}
ImGui::TreePop();
@ -160,16 +160,16 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::StringParam name,
ox::StringViewCR path,
FileTreeModel *parent,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter,
std::function<bool(ox::StringViewCR, ox::FileStat const &)> const &filter,
bool const showEmptyDirs) noexcept {
auto const&fs = explorer.romFs();
auto const &fs = explorer.romFs();
OX_REQUIRE(stat, fs.stat(path));
auto out = ox::make_unique<FileTreeModel>(explorer, std::move(name), stat.fileType, parent);
if (stat.fileType == ox::FileType::Directory) {
OX_REQUIRE_M(children, fs.ls(path));
std::sort(children.begin(), children.end());
ox::Vector<ox::UPtr<FileTreeModel>> outChildren;
for (auto const&childName : children) {
for (auto const &childName : children) {
if (childName[0] != '.') {
auto const childPath = ox::sfmt("{}/{}", path, childName);
OX_REQUIRE(childStat, fs.stat(childPath));
@ -195,7 +195,7 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
FileExplorer &explorer,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter,
bool const showEmptyDirs) noexcept {
return buildFileTreeModel(explorer, "Project", "/", nullptr, filter, showEmptyDirs);
}

View File

@ -7,8 +7,8 @@
namespace studio {
void Popup::drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const&drawContents) {
studio::ig::centerNextWindow(ctx);
void Popup::drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const &drawContents) {
ig::centerNextWindow(ctx);
ImGui::SetNextWindowSize(static_cast<ImVec2>(m_size));
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (ImGui::BeginPopupModal(m_title.c_str(), &open, modalFlags)) {

View File

@ -75,7 +75,7 @@ ox::Error Project::create() noexcept {
return ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed");
}
ox::String const&Project::projectPath() const noexcept {
ox::String const &Project::projectPath() const noexcept {
return m_path;
}
@ -137,7 +137,7 @@ ox::Error Project::deleteItem(ox::StringViewCR path) noexcept {
if (stat.fileType == ox::FileType::Directory) {
bool partialRemoval{};
OX_REQUIRE(members, m_fs.ls(path));
for (auto const&p : members) {
for (auto const &p : members) {
partialRemoval = m_fs.remove(ox::sfmt("{}/{}", path, p)) || partialRemoval;
}
if (partialRemoval) {
@ -161,7 +161,7 @@ bool Project::exists(ox::StringViewCR path) const noexcept {
return m_fs.stat(path).error == 0;
}
ox::Vector<ox::String> const&Project::fileList(ox::StringViewCR ext) noexcept {
ox::Vector<ox::String> const &Project::fileList(ox::StringViewCR ext) noexcept {
return m_fileExtFileMap[ext];
}
@ -185,7 +185,7 @@ void Project::buildFileIndex() noexcept {
}
m_fileExtFileMap.clear();
std::sort(files.begin(), files.end());
for (auto const&file : files) {
for (auto const &file : files) {
if (!beginsWith(file, ox::sfmt("/.{}/", m_projectDataDir))) {
indexFile(file);
}
@ -200,7 +200,7 @@ void Project::indexFile(ox::StringViewCR path) noexcept {
m_fileExtFileMap[ext].emplace_back(path);
}
ox::Error Project::writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept {
ox::Error Project::writeBuff(ox::StringViewCR path, ox::BufferView const &buff) noexcept {
constexpr auto HdrSz = 40;
ox::Buffer outBuff;
outBuff.reserve(buff.size() + HdrSz);
@ -227,7 +227,7 @@ ox::Result<ox::Buffer> Project::loadBuff(ox::StringViewCR path) const noexcept {
ox::Error Project::lsProcDir(ox::Vector<ox::String> &paths, ox::StringViewCR path) const noexcept {
OX_REQUIRE(files, m_fs.ls(path));
for (auto const&name : files) {
for (auto const &name : files) {
auto fullPath = ox::sfmt("{}/{}", path, name);
OX_REQUIRE(stat, m_fs.stat(ox::StringView(fullPath)));
switch (stat.fileType) {

View File

@ -28,7 +28,7 @@ class ClipboardObject: public BaseClipboardObject {
}
};
ox::String getClipboardText(Context &ctx) noexcept;
ox::String getClipboardText(Context const &ctx) noexcept;
void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept;

View File

@ -15,11 +15,11 @@ class Context;
void safeDelete(Context *p);
keel::Context const&keelCtx(Context const&ctx) noexcept;
keel::Context const &keelCtx(Context const &ctx) noexcept;
keel::Context &keelCtx(Context &ctx) noexcept;
inline ox::FileSystem const*rom(Context const&ctx) noexcept {
inline ox::FileSystem const*rom(Context const &ctx) noexcept {
return keelCtx(ctx).rom.get();
}
@ -27,7 +27,7 @@ inline ox::FileSystem *rom(Context &ctx) noexcept {
return keelCtx(ctx).rom.get();
}
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept;
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept;
template<typename T>
void setApplicationData(Context &ctx, T *applicationData) noexcept {
@ -35,7 +35,7 @@ void setApplicationData(Context &ctx, T *applicationData) noexcept {
}
[[nodiscard]]
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept;
ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept;
template<typename T>
[[nodiscard]]

View File

@ -41,7 +41,7 @@ ox::Size getScreenSize(Context const &ctx) noexcept;
ox::Bounds getWindowBounds(Context const &ctx) noexcept;
ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept;
ox::Error setWindowBounds(Context &ctx, ox::Bounds const &bnds) noexcept;
/**
* Tells Turbine to refresh the screen within the specified period of time.

View File

@ -89,7 +89,7 @@ void setMouseButtonEventHandler(Context &ctx, MouseButtonEventHandler h) noexcep
KeyEventHandler keyEventHandler(Context const &ctx) noexcept;
[[nodiscard]]
bool buttonDown(Context const&ctx, Key) noexcept;
bool buttonDown(Context const &ctx, Key) noexcept;
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> &&fs, ox::StringViewCR appName) noexcept;
@ -100,7 +100,7 @@ ox::Error run(Context &ctx) noexcept;
// Returns the number of milliseconds that have passed since the start of the
// program.
[[nodiscard]]
TimeMs ticksMs(Context const&ctx) noexcept;
TimeMs ticksMs(Context const &ctx) noexcept;
void requestShutdown(Context &ctx, bool force = false) noexcept;

View File

@ -9,7 +9,7 @@
namespace turbine {
ox::String getClipboardText(Context&) noexcept {
ox::String getClipboardText(Context const &) noexcept {
return {};
}

View File

@ -10,7 +10,7 @@ void safeDelete(Context *p) {
delete p;
}
keel::Context const&keelCtx(Context const&ctx) noexcept {
keel::Context const &keelCtx(Context const &ctx) noexcept {
return ctx.keelCtx;
}
@ -18,11 +18,11 @@ keel::Context &keelCtx(Context &ctx) noexcept {
return ctx.keelCtx;
}
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept {
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept {
ctx.applicationData = applicationData;
}
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept {
ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept {
return ctx.applicationData;
}

View File

@ -23,8 +23,8 @@ class Context final {
Context() noexcept = default;
Context(Context &other) noexcept = delete;
Context(Context const&other) noexcept = delete;
Context(Context const&&other) noexcept = delete;
Context(Context const &other) noexcept = delete;
Context(Context const &&other) noexcept = delete;
};

View File

@ -12,7 +12,7 @@
namespace turbine {
ox::String getClipboardText(Context &ctx) noexcept {
ox::String getClipboardText(Context const &ctx) noexcept {
return ox::String(glfwGetClipboardString(ctx.window));
}

View File

@ -12,7 +12,7 @@ void safeDelete(Context *p) {
delete p;
}
keel::Context const&keelCtx(Context const&ctx) noexcept {
keel::Context const &keelCtx(Context const &ctx) noexcept {
return ctx.keelCtx;
}
@ -20,11 +20,11 @@ keel::Context &keelCtx(Context &ctx) noexcept {
return ctx.keelCtx;
}
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept {
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept {
ctx.applicationData = applicationData;
}
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept {
ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept {
return ctx.applicationData;
}

View File

@ -35,8 +35,8 @@ class Context {
Context() noexcept = default;
Context(Context const&other) noexcept = delete;
Context(Context const&&other) noexcept = delete;
Context(Context const &other) noexcept = delete;
Context(Context const &&other) noexcept = delete;
};

View File

@ -214,7 +214,7 @@ ox::Bounds getWindowBounds(Context const &ctx) noexcept {
return bnds;
}
ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept {
ox::Error setWindowBounds(Context &ctx, ox::Bounds const &bnds) noexcept {
glfwSetWindowPos(ctx.window, bnds.x, bnds.y);
glfwSetWindowSize(ctx.window, bnds.width, bnds.height);
return {};
@ -430,13 +430,13 @@ ox::Error run(Context &ctx) noexcept {
return {};
}
TimeMs ticksMs(Context const&ctx) noexcept {
TimeMs ticksMs(Context const &ctx) noexcept {
using namespace std::chrono;
auto const now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
return static_cast<TimeMs>(now) - ctx.startTime;
}
bool buttonDown(Context const&ctx, Key const key) noexcept {
bool buttonDown(Context const &ctx, Key const key) noexcept {
return (ctx.keysDown >> static_cast<int>(key)) & 1;
}