diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index 4fe7ed1..94d076c 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -138,6 +138,16 @@ namespace omath::hud EntityOverlay& add_bottom_progress_ring(const Color& color, const Color& bg, float radius, float ratio, float thickness = 2.f, float offset = 5.f, int segments = 0); + // ── Icons ──────────────────────────────────────────────────────── + EntityOverlay& add_right_icon(const std::any& texture_id, float width, float height, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}, float offset = 5.f); + EntityOverlay& add_left_icon(const std::any& texture_id, float width, float height, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}, float offset = 5.f); + EntityOverlay& add_top_icon(const std::any& texture_id, float width, float height, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}, float offset = 5.f); + EntityOverlay& add_bottom_icon(const std::any& texture_id, float width, float height, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}, float offset = 5.f); + // ── Misc ───────────────────────────────────────────────────────── EntityOverlay& add_snap_line(const Vector2& start_pos, const Color& color, float width); diff --git a/include/omath/hud/entity_overlay_widgets.hpp b/include/omath/hud/entity_overlay_widgets.hpp index db290fb..52757ba 100644 --- a/include/omath/hud/entity_overlay_widgets.hpp +++ b/include/omath/hud/entity_overlay_widgets.hpp @@ -4,6 +4,7 @@ #pragma once #include "omath/linear_algebra/vector2.hpp" #include "omath/utility/color.hpp" +#include #include #include #include @@ -137,11 +138,21 @@ namespace omath::hud::widget int segments = 32; }; + struct Icon + { + std::any texture_id; + float width; + float height; + Color tint{1.f, 1.f, 1.f, 1.f}; + float offset = 5.f; + }; + // ── Side widget variant ─────────────────────────────────────────────────── struct None { }; ///< No-op placeholder — used by widget::when for disabled elements. - using SideWidget = std::variant, SpaceVertical, SpaceHorizontal, ProgressRing>; + using SideWidget = + std::variant, SpaceVertical, SpaceHorizontal, ProgressRing, Icon>; // ── Side containers ─────────────────────────────────────────────────────── // Storing std::initializer_list is safe here: the backing array diff --git a/include/omath/hud/hud_renderer_interface.hpp b/include/omath/hud/hud_renderer_interface.hpp index e22b9b9..5a25e03 100644 --- a/include/omath/hud/hud_renderer_interface.hpp +++ b/include/omath/hud/hud_renderer_interface.hpp @@ -4,6 +4,7 @@ #pragma once #include "omath/linear_algebra/vector2.hpp" #include "omath/utility/color.hpp" +#include #include namespace omath::hud @@ -34,6 +35,10 @@ namespace omath::hud virtual void add_arc(const Vector2& center, float radius, float a_min, float a_max, const Color& color, float thickness, int segments = 0) = 0; + /// Draw a textured quad. texture_id is renderer-specific (e.g. ImTextureID for ImGui). + virtual void add_image(const std::any& texture_id, const Vector2& min, const Vector2& max, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}) = 0; + virtual void add_text(const Vector2& position, const Color& color, const std::string_view& text) = 0; [[nodiscard]] diff --git a/include/omath/hud/renderer_realizations/imgui_renderer.hpp b/include/omath/hud/renderer_realizations/imgui_renderer.hpp index bc1442c..8b8190b 100644 --- a/include/omath/hud/renderer_realizations/imgui_renderer.hpp +++ b/include/omath/hud/renderer_realizations/imgui_renderer.hpp @@ -23,6 +23,8 @@ namespace omath::hud int segments = 0) override; void add_arc(const Vector2& center, float radius, float a_min, float a_max, const Color& color, float thickness, int segments = 0) override; + void add_image(const std::any& texture_id, const Vector2& min, const Vector2& max, + const Color& tint = Color{1.f, 1.f, 1.f, 1.f}) override; void add_text(const Vector2& position, const Color& color, const std::string_view& text) override; [[nodiscard]] virtual Vector2 calc_text_size(const std::string_view& text) override; diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index 5330e3f..328dc7e 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -551,6 +551,43 @@ namespace omath::hud return *this; } + // ── Icons ──────────────────────────────────────────────────────────────────── + EntityOverlay& EntityOverlay::add_right_icon(const std::any& texture_id, const float width, const float height, + const Color& tint, const float offset) + { + const auto pos = m_text_cursor_right + Vector2{offset, 0.f}; + m_renderer->add_image(texture_id, pos, pos + Vector2{width, height}, tint); + m_text_cursor_right.y += height; + return *this; + } + + EntityOverlay& EntityOverlay::add_left_icon(const std::any& texture_id, const float width, const float height, + const Color& tint, const float offset) + { + const auto pos = m_text_cursor_left + Vector2{-(offset + width), 0.f}; + m_renderer->add_image(texture_id, pos, pos + Vector2{width, height}, tint); + m_text_cursor_left.y += height; + return *this; + } + + EntityOverlay& EntityOverlay::add_top_icon(const std::any& texture_id, const float width, const float height, + const Color& tint, const float offset) + { + m_text_cursor_top.y -= height; + const auto pos = m_text_cursor_top + Vector2{0.f, -offset}; + m_renderer->add_image(texture_id, pos, pos + Vector2{width, height}, tint); + return *this; + } + + EntityOverlay& EntityOverlay::add_bottom_icon(const std::any& texture_id, const float width, const float height, + const Color& tint, const float offset) + { + const auto pos = m_text_cursor_bottom + Vector2{0.f, offset}; + m_renderer->add_image(texture_id, pos, pos + Vector2{width, height}, tint); + m_text_cursor_bottom.y += height; + return *this; + } + // ── widget dispatch ─────────────────────────────────────────────────────── void EntityOverlay::dispatch(const widget::Box& box) { @@ -659,6 +696,10 @@ namespace omath::hud add_right_progress_ring(w.color, w.bg, w.radius, w.ratio, w.thickness, w.offset, w.segments); }, + [this](const widget::Icon& w) + { + add_right_icon(w.texture_id, w.width, w.height, w.tint, w.offset); + }, }, child); } @@ -701,6 +742,10 @@ namespace omath::hud add_left_progress_ring(w.color, w.bg, w.radius, w.ratio, w.thickness, w.offset, w.segments); }, + [this](const widget::Icon& w) + { + add_left_icon(w.texture_id, w.width, w.height, w.tint, w.offset); + }, }, child); } @@ -743,6 +788,10 @@ namespace omath::hud add_top_progress_ring(w.color, w.bg, w.radius, w.ratio, w.thickness, w.offset, w.segments); }, + [this](const widget::Icon& w) + { + add_top_icon(w.texture_id, w.width, w.height, w.tint, w.offset); + }, }, child); } @@ -785,6 +834,10 @@ namespace omath::hud add_bottom_progress_ring(w.color, w.bg, w.radius, w.ratio, w.thickness, w.offset, w.segments); }, + [this](const widget::Icon& w) + { + add_bottom_icon(w.texture_id, w.width, w.height, w.tint, w.offset); + }, }, child); } diff --git a/source/hud/renderer_realizations/imgui_renderer.cpp b/source/hud/renderer_realizations/imgui_renderer.cpp index d7d0c91..4194351 100644 --- a/source/hud/renderer_realizations/imgui_renderer.cpp +++ b/source/hud/renderer_realizations/imgui_renderer.cpp @@ -61,6 +61,13 @@ namespace omath::hud ImGui::GetBackgroundDrawList()->PathStroke(color.to_im_color(), ImDrawFlags_None, thickness); } + void ImguiHudRenderer::add_image(const std::any& texture_id, const Vector2& min, const Vector2& max, + const Color& tint) + { + ImGui::GetBackgroundDrawList()->AddImage(std::any_cast(texture_id), min.to_im_vec2(), + max.to_im_vec2(), {0, 0}, {1, 1}, tint.to_im_color()); + } + void ImguiHudRenderer::add_text(const Vector2& position, const Color& color, const std::string_view& text) { ImGui::GetBackgroundDrawList()->AddText(position.to_im_vec2(), color.to_im_color(), text.data(),