diff --git a/src/olympic/keel/include/keel/typeconv.hpp b/src/olympic/keel/include/keel/typeconv.hpp index 3d9ea007..07a238f0 100644 --- a/src/olympic/keel/include/keel/typeconv.hpp +++ b/src/olympic/keel/include/keel/typeconv.hpp @@ -20,6 +20,8 @@ class Wrap { virtual ox::CStringView typeName() const noexcept = 0; [[nodiscard]] virtual int typeVersion() const noexcept = 0; + [[nodiscard]] + virtual ox::UAnyPtr moveToCopy() noexcept = 0; }; template @@ -27,6 +29,11 @@ class WrapT: public Wrap { public: [[nodiscard]] virtual constexpr T &obj() noexcept = 0; + + ox::UAnyPtr moveToCopy() noexcept final { + return new T{std::move(obj())}; + } + }; template @@ -184,7 +191,18 @@ ox::Result> convert( auto &src, ox::StringViewCR dstTypeName, int const dstTypeVersion) noexcept { - return convert(ctx, WrapRef{src}, dstTypeName, dstTypeVersion); + WrapRef ref{src}; + return convert(ctx, static_cast(ref), dstTypeName, dstTypeVersion); +} + +ox::Result> convert( + keel::Context &ctx, + auto const&src, + ox::StringViewCR dstTypeName, + int const dstTypeVersion) noexcept { + auto srcCpy = src; + WrapRef ref{srcCpy}; + return convert(ctx, ref, dstTypeName, dstTypeVersion); } template diff --git a/src/olympic/studio/applib/src/newmenu.cpp b/src/olympic/studio/applib/src/newmenu.cpp index 806e3dcf..1fbe1b64 100644 --- a/src/olympic/studio/applib/src/newmenu.cpp +++ b/src/olympic/studio/applib/src/newmenu.cpp @@ -14,7 +14,7 @@ namespace studio { NewMenu::NewMenu() noexcept { setTitle("New Item"); - setSize({230, 140}); + setSize({280, 180}); } void NewMenu::open() noexcept { @@ -33,7 +33,7 @@ bool NewMenu::isOpen() const noexcept { return m_open; } -void NewMenu::draw(studio::StudioContext &sctx) noexcept { +void NewMenu::draw(StudioContext &sctx) noexcept { switch (m_stage) { case Stage::Opening: ImGui::OpenPopup(title().c_str()); @@ -46,51 +46,73 @@ void NewMenu::draw(studio::StudioContext &sctx) noexcept { case Stage::NewItemName: drawNewItemName(sctx); break; + case Stage::NewItemTemplate: + drawNewItemTemplate(sctx); + break; case Stage::Closed: m_open = false; break; } } -void NewMenu::addItemMaker(ox::UniquePtr &&im) noexcept { +void NewMenu::addItemMaker(ox::UPtr &&im) noexcept { m_types.emplace_back(std::move(im)); std::sort( m_types.begin(), m_types.end(), [](ox::UPtr const&im1, ox::UPtr const&im2) { - return im1->typeName < im2->typeName; + return im1->typeDisplayName() < im2->typeDisplayName(); }); } -void NewMenu::drawNewItemType(studio::StudioContext &sctx) noexcept { - drawWindow(sctx.tctx, &m_open, [this] { - auto const allocSz = m_types.size() * sizeof(char const*); - auto mem = ox_malloca(allocSz, char const*, nullptr); - auto items = ox::Span{mem.get(), allocSz}; - for (auto i = 0u; auto const&im : m_types) { - items[i] = im->typeName.c_str(); - ++i; +void NewMenu::installItemTemplate(ox::UPtr &tmplt) noexcept { + for (auto const&im : m_types) { + if (im->installTemplate(tmplt)) { + break; } - ImGui::ListBox("Item Type", &m_selectedType, items.data(), static_cast(m_types.size())); - drawFirstPageButtons(); + } +} + +void NewMenu::drawNewItemType(StudioContext const&sctx) noexcept { + 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]; + drawFirstPageButtons(im.itemTemplates().size() == 1 ? + Stage::NewItemName : Stage::NewItemTemplate); }); } -void NewMenu::drawNewItemName(studio::StudioContext &sctx) noexcept { - drawWindow(sctx.tctx, &m_open, [this, &sctx] { - auto const typeIdx = static_cast(m_selectedType); - if (typeIdx < m_types.size()) { +void NewMenu::drawNewItemTemplate(StudioContext &sctx) noexcept { + drawWindow(sctx.tctx, m_open, [this] { + auto const&templates = + m_types[m_selectedType]->itemTemplates(); + ig::ListBox("Template", [&](size_t const i) -> ox::CStringView { + return templates[i]->name(); + }, templates.size(), m_selectedTemplate, {200, 100}); + drawButtons(Stage::NewItemType, Stage::NewItemName); + }); +} + +void NewMenu::drawNewItemName(StudioContext &sctx) noexcept { + drawWindow(sctx.tctx, m_open, [this, &sctx] { + if (m_selectedType < m_types.size()) { ig::InputText("Name", m_itemName); } drawLastPageButtons(sctx); }); } -void NewMenu::drawFirstPageButtons() noexcept { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 130); +void NewMenu::drawButtons(Stage const prev, Stage const next) noexcept { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 198); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20); - auto const btnSz = ImVec2(60, 20); + constexpr ImVec2 btnSz{60, 20}; + if (ImGui::Button("Back", btnSz)) { + m_stage = prev; + } + ImGui::SameLine(); if (ImGui::Button("Next", btnSz)) { - m_stage = Stage::NewItemName; + m_stage = next; } ImGui::SameLine(); if (ImGui::Button("Cancel", btnSz)) { @@ -99,34 +121,50 @@ void NewMenu::drawFirstPageButtons() noexcept { } } -void NewMenu::drawLastPageButtons(studio::StudioContext &sctx) noexcept { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 138); +void NewMenu::drawFirstPageButtons(Stage const next) noexcept { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 130); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20); - if (ImGui::Button("Back")) { - m_stage = Stage::NewItemType; + constexpr ImVec2 btnSz{60, 20}; + if (ImGui::Button("Next", btnSz)) { + m_stage = next; } ImGui::SameLine(); - if (ImGui::Button("Finish")) { - finish(sctx); - } - ImGui::SameLine(); - if (ImGui::Button("Quit")) { + if (ImGui::Button("Cancel", btnSz)) { ImGui::CloseCurrentPopup(); m_stage = Stage::Closed; } } -void NewMenu::finish(studio::StudioContext &sctx) noexcept { +void NewMenu::drawLastPageButtons(StudioContext &sctx) noexcept { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 198); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetContentRegionAvail().y - 20); + constexpr ImVec2 btnSz{60, 20}; + if (ImGui::Button("Back", btnSz)) { + m_stage = Stage::NewItemType; + } + ImGui::SameLine(); + if (ImGui::Button("Finish", btnSz)) { + finish(sctx); + } + ImGui::SameLine(); + if (ImGui::Button("Quit", btnSz)) { + ImGui::CloseCurrentPopup(); + m_stage = Stage::Closed; + } +} + +void NewMenu::finish(StudioContext &sctx) noexcept { if (m_itemName.len() == 0) { - oxLogError(ox::Error(1, "New file error: no file name")); + oxLogError(ox::Error{1, "New file error: no file name"}); return; } - auto const&typeMaker = *m_types[static_cast(m_selectedType)]; - if (sctx.project->exists(typeMaker.itemPath(m_itemName))) { - oxLogError(ox::Error(1, "New file error: file already exists")); + auto const&im = *m_types[static_cast(m_selectedType)]; + if (sctx.project->exists(im.itemPath(m_itemName))) { + oxLogError(ox::Error{1, "New file error: file already exists"}); return; } - auto const [path, err] = typeMaker.write(sctx, m_itemName); + auto const [path, err] = + im.write(sctx, m_itemName, m_selectedTemplate); if (err) { oxLogError(err); return; diff --git a/src/olympic/studio/applib/src/newmenu.hpp b/src/olympic/studio/applib/src/newmenu.hpp index c8ac34ed..c535764a 100644 --- a/src/olympic/studio/applib/src/newmenu.hpp +++ b/src/olympic/studio/applib/src/newmenu.hpp @@ -13,13 +13,14 @@ namespace studio { -class NewMenu: public studio::Popup { +class NewMenu final: public Popup { public: enum class Stage { Closed, Opening, NewItemType, NewItemName, + NewItemTemplate, }; // emits path parameter @@ -29,8 +30,9 @@ class NewMenu: public studio::Popup { Stage m_stage = Stage::Closed; ox::String m_typeName; ox::IString<255> m_itemName; - ox::Vector> m_types; - int m_selectedType = 0; + ox::Vector> m_types; + size_t m_selectedType = 0; + size_t m_selectedTemplate = 0; bool m_open = false; public: @@ -43,37 +45,70 @@ class NewMenu: public studio::Popup { [[nodiscard]] bool isOpen() const noexcept override; - void draw(studio::StudioContext &sctx) noexcept override; + void draw(StudioContext &sctx) noexcept override; template - void addItemType(ox::String name, ox::String parentDir, ox::String fileExt, T itemTempl, ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept; + void addItemType( + ox::StringParam displayName, + ox::StringParam parentDir, + ox::StringParam fileExt, + T itemTempl, + ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept; template - void addItemType(ox::String name, ox::String parentDir, ox::String fileExt, ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept; + void addItemType( + ox::StringParam displayName, + ox::StringParam parentDir, + ox::StringParam fileExt, + ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept; - void addItemMaker(ox::UniquePtr &&im) noexcept; + void addItemMaker(ox::UPtr &&im) noexcept; + + void installItemTemplate(ox::UPtr &tmplt) noexcept; private: - void drawNewItemType(studio::StudioContext &sctx) noexcept; + void drawNewItemType(StudioContext const&sctx) noexcept; - void drawNewItemName(studio::StudioContext &sctx) noexcept; + void drawNewItemName(StudioContext &sctx) noexcept; - void drawFirstPageButtons() noexcept; + void drawNewItemTemplate(StudioContext &sctx) noexcept; - void drawLastPageButtons(studio::StudioContext &sctx) noexcept; + void drawButtons(Stage prev, Stage next) noexcept; - void finish(studio::StudioContext &sctx) noexcept; + void drawFirstPageButtons(Stage next) noexcept; + + void drawLastPageButtons(StudioContext &sctx) noexcept; + + void finish(StudioContext &sctx) noexcept; }; template -void NewMenu::addItemType(ox::String displayName, ox::String parentDir, ox::String fileExt, T itemTempl, ox::ClawFormat pFmt) noexcept { - m_types.emplace_back(ox::make>(std::move(displayName), std::move(parentDir), std::move(fileExt), std::move(itemTempl), pFmt)); +void NewMenu::addItemType( + ox::StringParam displayName, + ox::StringParam parentDir, + ox::StringParam fileExt, + T itemTempl, + ox::ClawFormat const pFmt) noexcept { + m_types.emplace_back(ox::make>( + std::move(displayName), + std::move(parentDir), + std::move(fileExt), + std::move(itemTempl), + pFmt)); } template -void NewMenu::addItemType(ox::String displayName, ox::String parentDir, ox::String fileExt, ox::ClawFormat pFmt) noexcept { - m_types.emplace_back(ox::make>(std::move(displayName), std::move(parentDir), std::move(fileExt), pFmt)); +void NewMenu::addItemType( + ox::StringParam displayName, + ox::StringParam parentDir, + ox::StringParam fileExt, + ox::ClawFormat const pFmt) noexcept { + m_types.emplace_back(ox::make>( + std::move(displayName), + std::move(parentDir), + std::move(fileExt), + pFmt)); } } diff --git a/src/olympic/studio/applib/src/newproject.cpp b/src/olympic/studio/applib/src/newproject.cpp index 6a0cdbe1..136aa8c6 100644 --- a/src/olympic/studio/applib/src/newproject.cpp +++ b/src/olympic/studio/applib/src/newproject.cpp @@ -49,7 +49,7 @@ void NewProject::draw(studio::StudioContext &ctx) noexcept { } void NewProject::drawNewProjectName(studio::StudioContext &sctx) noexcept { - drawWindow(sctx.tctx, &m_open, [this, &sctx] { + drawWindow(sctx.tctx, m_open, [this, &sctx] { ig::InputText("Name", m_projectName); ImGui::Text("Path: %s", m_projectPath.c_str()); if (ImGui::Button("Browse")) { diff --git a/src/olympic/studio/applib/src/studioapp.cpp b/src/olympic/studio/applib/src/studioapp.cpp index 7ae49c57..c4193a8d 100644 --- a/src/olympic/studio/applib/src/studioapp.cpp +++ b/src/olympic/studio/applib/src/studioapp.cpp @@ -251,6 +251,10 @@ void StudioUI::loadModule(Module const&mod) noexcept { for (auto &im : mod.itemMakers(m_sctx)) { m_newMenu.addItemMaker(std::move(im)); } + auto tmplts = mod.itemTemplates(m_sctx); + for (auto &t : tmplts) { + m_newMenu.installItemTemplate(t); + } } void StudioUI::loadModules() noexcept { diff --git a/src/olympic/studio/modlib/include/studio/imguiutil.hpp b/src/olympic/studio/modlib/include/studio/imguiutil.hpp index 2ef22c38..01cd3e84 100644 --- a/src/olympic/studio/modlib/include/studio/imguiutil.hpp +++ b/src/olympic/studio/modlib/include/studio/imguiutil.hpp @@ -214,7 +214,8 @@ bool ListBox( ox::CStringViewCR name, std::function const&f, size_t strCnt, - size_t &selIdx) noexcept; + size_t &selIdx, + ImVec2 const&sz = {0, 0}) noexcept; /** * diff --git a/src/olympic/studio/modlib/include/studio/itemmaker.hpp b/src/olympic/studio/modlib/include/studio/itemmaker.hpp index ec2f79b6..edc536da 100644 --- a/src/olympic/studio/modlib/include/studio/itemmaker.hpp +++ b/src/olympic/studio/modlib/include/studio/itemmaker.hpp @@ -4,7 +4,9 @@ #pragma once -#include +#include + +#include #include #include @@ -13,75 +15,212 @@ namespace studio { -class ItemMaker { +class ItemTemplate { + private: + ox::String const m_name{"Default"}; + public: - ox::String const typeName; - ox::String const parentDir; - ox::String const fileExt; - constexpr explicit ItemMaker( + explicit ItemTemplate() noexcept = default; + + explicit ItemTemplate(ox::StringParam name) noexcept: m_name{std::move(name)} {} + + virtual ~ItemTemplate() = default; + + [[nodiscard]] + constexpr ox::String const&name() const noexcept { + return m_name; + } + + constexpr bool operator<=>(ItemTemplate const&other) const noexcept { + return m_name != other.name() ? (m_name < other.name() ? -1 : 1) : 0; + } + + [[nodiscard]] + ox::CStringView displayName() const noexcept { + return m_name; + } + + [[nodiscard]] + virtual ox::CStringView typeName() const noexcept = 0; + + [[nodiscard]] + virtual int typeVersion() const noexcept = 0; + + virtual ox::Result getItem( + keel::Context &ctx, ox::StringViewCR name, int version) noexcept = 0; + +}; + +template +class ItemTemplateT: public ItemTemplate { + private: + T const m_item; + + public: + constexpr ItemTemplateT() noexcept = default; + + explicit ItemTemplateT(ox::StringParam name, T item) noexcept: + ItemTemplate{std::move(name)}, m_item{std::move(item)} {} + + [[nodiscard]] + ox::CStringView typeName() const noexcept final { + return ox::ModelTypeName_v; + } + + [[nodiscard]] + int typeVersion() const noexcept final { + return ox::ModelTypeVersion_v; + } + + ox::Result getItem( + keel::Context &kctx, ox::StringViewCR name, int const version) noexcept final { + if (ox::ModelTypeVersion_v != version || ox::ModelTypeName_v != name) { + OX_REQUIRE_M(item, keel::convert(kctx, m_item, name, version)); + auto out = ox::Result{item->moveToCopy()}; + ox::safeDelete(item.release()); + return out; + } + return ox::UAnyPtr{new T{m_item}}; + } + +}; + +class ItemMaker { + private: + ox::Vector> m_templates; + ox::String const m_parentDir; + ox::String const m_fileExt; + ox::String const m_typeDisplayName; + + public: + constexpr ItemMaker( ox::StringParam pName, ox::StringParam pParentDir, ox::StringParam pFileExt) noexcept: - typeName{std::move(pName)}, - parentDir{std::move(pParentDir)}, - fileExt{std::move(pFileExt)} { + m_parentDir{std::move(pParentDir)}, + m_fileExt{std::move(pFileExt)}, + m_typeDisplayName{std::move(pName)} { } + virtual ~ItemMaker() noexcept = default; [[nodiscard]] - virtual ox::String itemPath(ox::StringView pName) const noexcept { - return ox::sfmt("/{}/{}.{}", parentDir, pName, fileExt); + ox::String const&typeDisplayName() const noexcept { + return m_typeDisplayName; } + bool installTemplate(ox::UPtr &tmpl) { + if (typeName() == tmpl->typeName() && + typeVersion() <= tmpl->typeVersion()) { + m_templates.emplace_back(std::move(tmpl)); + // begin() + 1 because 'Default' should always be first + std::sort(m_templates.begin() + 1, m_templates.end()); + return true; + } + return false; + } + + bool installTemplate(ox::UPtr &&tmpl) { + return installTemplate(tmpl); + } + + constexpr ox::Vector> const&itemTemplates() const noexcept { + return m_templates; + } + + [[nodiscard]] + ox::String itemPath(ox::StringViewCR pName) const noexcept { + return ox::sfmt("/{}/{}.{}", m_parentDir, pName, m_fileExt); + } + + [[nodiscard]] + virtual ox::StringView typeName() const noexcept = 0; + + [[nodiscard]] + virtual int typeVersion() const noexcept = 0; + /** * Returns path of the file created. * @param ctx * @param pName + * @param pTemplateIdx * @return path of file or error in Result */ - virtual ox::Result write(StudioContext &ctx, ox::StringView pName) const noexcept = 0; + virtual ox::Result write( + StudioContext &ctx, ox::StringViewCR pName, size_t pTemplateIdx) const noexcept = 0; }; template -class ItemMakerT: public ItemMaker { +class ItemMakerT final: public ItemMaker { private: - T const m_item; ox::ClawFormat const m_fmt; + public: constexpr ItemMakerT( ox::StringParam pDisplayName, ox::StringParam pParentDir, ox::StringParam fileExt, - ox::ClawFormat pFmt = ox::ClawFormat::Metal) noexcept: - ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)), - m_fmt(pFmt) { + ox::ClawFormat const pFmt = ox::ClawFormat::Metal) noexcept: + ItemMaker( + std::move(pDisplayName), + std::move(pParentDir), + std::move(fileExt)), + m_fmt{pFmt} { + installTemplate(ox::make_unique>()); } + constexpr ItemMakerT( ox::StringParam pDisplayName, ox::StringParam pParentDir, ox::StringParam fileExt, - T pItem, - ox::ClawFormat pFmt) noexcept: - ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)), - m_item(std::move(pItem)), - m_fmt(pFmt) { + T const&pItem, + ox::ClawFormat const pFmt) noexcept: + ItemMaker( + std::move(pDisplayName), + std::move(pParentDir), + std::move(fileExt)), + m_fmt{pFmt} { + installTemplate(ox::make_unique>(std::move(pItem))); } + constexpr ItemMakerT( ox::StringParam pDisplayName, ox::StringParam pParentDir, ox::StringParam fileExt, T &&pItem, - ox::ClawFormat pFmt) noexcept: - ItemMaker(std::move(pDisplayName), std::move(pParentDir), std::move(fileExt)), - m_item(std::move(pItem)), - m_fmt(pFmt) { + ox::ClawFormat const pFmt) noexcept: + ItemMaker( + std::move(pDisplayName), + std::move(pParentDir), + std::move(fileExt)), + m_fmt{pFmt} { + installTemplate(ox::make_unique>(std::move(pItem))); } - ox::Result write(studio::StudioContext &sctx, ox::StringView const pName) const noexcept override { + + ox::StringView typeName() const noexcept override { + return ox::ModelTypeName_v; + } + + int typeVersion() const noexcept override { + return ox::ModelTypeVersion_v; + } + + ox::Result write( + StudioContext &sctx, + ox::StringViewCR pName, + size_t const pTemplateIdx) const noexcept override { auto const path = itemPath(pName); createUuidMapping(keelCtx(sctx.tctx), path, ox::UUID::generate().unwrap()); - OX_RETURN_ERROR(sctx.project->writeObj(path, m_item, m_fmt)); + auto const&templates = itemTemplates(); + auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0; + OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem( + keelCtx(sctx), typeName(), typeVersion())); + auto item = tmpl.template get(); + OX_RETURN_ERROR(sctx.project->writeObj(path, *item, m_fmt)); + tmpl.free(); return path; } + }; } diff --git a/src/olympic/studio/modlib/include/studio/module.hpp b/src/olympic/studio/modlib/include/studio/module.hpp index 8019be0a..3844bdab 100644 --- a/src/olympic/studio/modlib/include/studio/module.hpp +++ b/src/olympic/studio/modlib/include/studio/module.hpp @@ -31,6 +31,8 @@ class Module { virtual ox::Vector> itemMakers(studio::StudioContext&) const; + virtual ox::Vector> itemTemplates(studio::StudioContext&) const; + }; template diff --git a/src/olympic/studio/modlib/include/studio/popup.hpp b/src/olympic/studio/modlib/include/studio/popup.hpp index 40ae00f3..9154b5c3 100644 --- a/src/olympic/studio/modlib/include/studio/popup.hpp +++ b/src/olympic/studio/modlib/include/studio/popup.hpp @@ -47,7 +47,7 @@ class Popup { return m_title; } - void drawWindow(turbine::Context &ctx, bool *open, std::function const&drawContents); + void drawWindow(turbine::Context &ctx, bool &open, std::function const&drawContents); }; diff --git a/src/olympic/studio/modlib/src/imguiutil.cpp b/src/olympic/studio/modlib/src/imguiutil.cpp index be7d946d..7618a2aa 100644 --- a/src/olympic/studio/modlib/src/imguiutil.cpp +++ b/src/olympic/studio/modlib/src/imguiutil.cpp @@ -136,11 +136,12 @@ bool FileComboBox( bool ListBox( ox::CStringViewCR name, std::function const&f, - size_t strCnt, - size_t &selIdx) noexcept { + size_t const strCnt, + size_t &selIdx, + ImVec2 const&sz) noexcept { auto out = false; - if (ImGui::BeginListBox(name.c_str())) { - for (auto i = 0u; i < strCnt; ++i) { + if (ImGui::BeginListBox(name.c_str(), sz)) { + for (size_t i = 0; i < strCnt; ++i) { auto str = f(i); ig::IDStackItem const idStackItem2(static_cast(i)); if (ImGui::Selectable(str.c_str(), selIdx == i)) { @@ -161,6 +162,12 @@ bool ListBox(ox::CStringViewCR name, ox::SpanView const&list, size_t }, list.size(), selIdx); } +bool ListBox(ox::CStringViewCR name, ox::SpanView const&list, size_t &selIdx) noexcept { + return ListBox(name, [list](size_t i) -> ox::CStringView { + return list[i]; + }, list.size(), selIdx); +} + FilePicker::FilePicker( StudioContext &sctx, diff --git a/src/olympic/studio/modlib/src/module.cpp b/src/olympic/studio/modlib/src/module.cpp index b2fccce4..4bd20ac8 100644 --- a/src/olympic/studio/modlib/src/module.cpp +++ b/src/olympic/studio/modlib/src/module.cpp @@ -6,11 +6,15 @@ namespace studio { -ox::Vector Module::editors(studio::StudioContext&) const { +ox::Vector Module::editors(StudioContext&) const { return {}; } -ox::Vector> Module::itemMakers(studio::StudioContext&) const { +ox::Vector> Module::itemMakers(StudioContext&) const { + return {}; +} + +ox::Vector> Module::itemTemplates(StudioContext&) const { return {}; } diff --git a/src/olympic/studio/modlib/src/popup.cpp b/src/olympic/studio/modlib/src/popup.cpp index a31e859f..04e7ba13 100644 --- a/src/olympic/studio/modlib/src/popup.cpp +++ b/src/olympic/studio/modlib/src/popup.cpp @@ -7,11 +7,11 @@ namespace studio { -void Popup::drawWindow(turbine::Context &ctx, bool *open, std::function const&drawContents) { +void Popup::drawWindow(turbine::Context &ctx, bool &open, std::function const&drawContents) { studio::ig::centerNextWindow(ctx); ImGui::SetNextWindowSize(static_cast(m_size)); constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - if (ImGui::BeginPopupModal(m_title.c_str(), open, modalFlags)) { + if (ImGui::BeginPopupModal(m_title.c_str(), &open, modalFlags)) { drawContents(); ImGui::EndPopup(); }