diff --git a/src/olympic/studio/modlib/include/studio/imguiutil.hpp b/src/olympic/studio/modlib/include/studio/imguiutil.hpp index aff6db87..8038660f 100644 --- a/src/olympic/studio/modlib/include/studio/imguiutil.hpp +++ b/src/olympic/studio/modlib/include/studio/imguiutil.hpp @@ -8,6 +8,8 @@ #include +#include + #include #include @@ -15,6 +17,91 @@ namespace studio::ig { inline constexpr auto BtnSz = ImVec2{52, 22}; + +constexpr ImTextureID toImTextureID(ox::Unsigned_c auto id) noexcept + requires(sizeof(id) <= sizeof(ox::Uint)) { + return std::bit_cast(ox::Uint{id}); +} + +template +ox::Result getDragDropPayload(ox::CStringView name) noexcept { + auto const payload = ImGui::AcceptDragDropPayload(name.c_str()); + if (!payload) { + return OxError(1, "No drag/drop payload"); + } + return ox::readClaw( + reinterpret_cast(payload->Data), + static_cast(payload->DataSize)); +} + +ox::Error setDragDropPayload(ox::CStringView name, auto const &obj) noexcept { + oxRequire(buff, ox::writeClaw(obj, ox::ClawFormat::Metal)); + ImGui::SetDragDropPayload(name.c_str(), buff.data(), buff.size()); + return {}; +} + + +class DragDropSource { + private: + bool const m_active{}; + public: + inline DragDropSource() noexcept: + m_active(ImGui::BeginDragDropSource()) { + } + inline ~DragDropSource() noexcept { + if (m_active) { + ImGui::EndDragDropSource(); + } + } + constexpr operator bool() const noexcept { + return m_active; + } +}; + +inline auto dragDropSource(auto const&cb) noexcept { + if constexpr(ox::is_same_v) { + if (ig::DragDropSource const tgt; tgt) [[unlikely]] { + return cb(); + } + } else { + if (ig::DragDropSource const tgt; tgt) [[unlikely]] { + cb(); + } + } +} + + +class DragDropTarget { + private: + bool const m_active{}; + public: + inline DragDropTarget() noexcept: + m_active(ImGui::BeginDragDropTarget()) { + } + inline ~DragDropTarget() noexcept { + if (m_active) { + ImGui::EndDragDropTarget(); + } + } + constexpr operator bool() const noexcept { + return m_active; + } +}; + +inline auto dragDropTarget(auto const&cb) noexcept { + if constexpr(ox::is_same_v) { + if (ig::DragDropTarget const tgt; tgt) [[unlikely]] { + return cb(); + } + return ox::Error{}; + } else { + if (ig::DragDropTarget const tgt; tgt) [[unlikely]] { + cb(); + } + } +} + + class ChildStackItem { public: explicit ChildStackItem(ox::CStringView id, ImVec2 const&sz = {}) noexcept;