// // Created by orange on 13.03.2026. // #pragma once #include "canvas_box.hpp" #include "entity_overlay_widgets.hpp" #include "hud_renderer_interface.hpp" #include "omath/linear_algebra/vector2.hpp" #include "omath/utility/color.hpp" #include #include namespace omath::hud { class EntityOverlay final { public: EntityOverlay(const Vector2& top, const Vector2& bottom, const std::shared_ptr& renderer); // ── Boxes ──────────────────────────────────────────────────────── EntityOverlay& add_2d_box(const Color& box_color, const Color& fill_color = Color{0.f, 0.f, 0.f, 0.f}, float thickness = 1.f); EntityOverlay& add_cornered_2d_box(const Color& box_color, const Color& fill_color = Color{0.f, 0.f, 0.f, 0.f}, float corner_ratio_len = 0.2f, float thickness = 1.f); EntityOverlay& add_dashed_box(const Color& color, float dash_len = 8.f, float gap_len = 5.f, float thickness = 1.f); // ── Bars ───────────────────────────────────────────────────────── EntityOverlay& add_right_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float offset = 5.f); EntityOverlay& add_left_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float offset = 5.f); EntityOverlay& add_top_bar(const Color& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float offset = 5.f); EntityOverlay& add_bottom_bar(const Color& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float offset = 5.f); EntityOverlay& add_right_dashed_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float dash_len, float gap_len, float offset = 5.f); EntityOverlay& add_left_dashed_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float dash_len, float gap_len, float offset = 5.f); EntityOverlay& add_top_dashed_bar(const Color& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float dash_len, float gap_len, float offset = 5.f); EntityOverlay& add_bottom_dashed_bar(const Color& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float dash_len, float gap_len, float offset = 5.f); // ── Labels ─────────────────────────────────────────────────────── EntityOverlay& add_right_label(const Color& color, float offset, bool outlined, const std::string_view& text); EntityOverlay& add_left_label(const Color& color, float offset, bool outlined, const std::string_view& text); EntityOverlay& add_top_label(const Color& color, float offset, bool outlined, std::string_view text); EntityOverlay& add_bottom_label(const Color& color, float offset, bool outlined, std::string_view text); EntityOverlay& add_centered_top_label(const Color& color, float offset, bool outlined, const std::string_view& text); EntityOverlay& add_centered_bottom_label(const Color& color, float offset, bool outlined, const std::string_view& text); template EntityOverlay& add_right_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_right_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } template EntityOverlay& add_left_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_left_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } template EntityOverlay& add_top_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_top_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } template EntityOverlay& add_bottom_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_bottom_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } template EntityOverlay& add_centered_top_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_centered_top_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } template EntityOverlay& add_centered_bottom_label(const Color& color, const float offset, const bool outlined, std::format_string fmt, Args&&... args) { return add_centered_bottom_label(color, offset, outlined, std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))}); } // ── Spacers ───────────────────────────────────────────────────── EntityOverlay& add_right_space_vertical(float size); EntityOverlay& add_right_space_horizontal(float size); EntityOverlay& add_left_space_vertical(float size); EntityOverlay& add_left_space_horizontal(float size); EntityOverlay& add_top_space_vertical(float size); EntityOverlay& add_top_space_horizontal(float size); EntityOverlay& add_bottom_space_vertical(float size); EntityOverlay& add_bottom_space_horizontal(float size); // ── Progress rings ────────────────────────────────────────────── EntityOverlay& add_right_progress_ring(const Color& color, const Color& bg, float radius, float ratio, float thickness = 2.f, float offset = 5.f, int segments = 0); EntityOverlay& add_left_progress_ring(const Color& color, const Color& bg, float radius, float ratio, float thickness = 2.f, float offset = 5.f, int segments = 0); EntityOverlay& add_top_progress_ring(const Color& color, const Color& bg, float radius, float ratio, float thickness = 2.f, float offset = 5.f, int segments = 0); 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); EntityOverlay& add_skeleton(const Color& color, float thickness = 1.f); // ── Declarative interface ───────────────────────────────────────── /// Pass any combination of widget:: descriptor structs (and std::optional /// from when()) to render them all in declaration order. template EntityOverlay& contents(Widgets&&... widgets) { (dispatch(std::forward(widgets)), ...); return *this; } private: // optional dispatch — enables when() conditional widgets template void dispatch(const std::optional& w) { if (w) dispatch(*w); } void dispatch(const widget::Box& box); void dispatch(const widget::CorneredBox& cornered_box); void dispatch(const widget::DashedBox& dashed_box); void dispatch(const widget::RightSide& right_side); void dispatch(const widget::LeftSide& left_side); void dispatch(const widget::TopSide& top_side); void dispatch(const widget::BottomSide& bottom_side); void dispatch(const widget::Skeleton& skeleton); void dispatch(const widget::SnapLine& snap_line); void dispatch(const widget::ScanMarker& scan_marker); void dispatch(const widget::AimDot& aim_dot); void dispatch(const widget::ProjectileAim& proj_widget); void draw_progress_ring(const Vector2& center, const widget::ProgressRing& ring); void draw_outlined_text(const Vector2& position, const Color& color, const std::string_view& text); void draw_dashed_line(const Vector2& from, const Vector2& to, const Color& color, float dash_len, float gap_len, float thickness) const; void draw_dashed_fill(const Vector2& origin, const Vector2& step_dir, const Vector2& perp_dir, float full_len, float filled_len, const Color& fill_color, const Color& split_color, float dash_len, float gap_len) const; CanvasBox m_canvas; Vector2 m_text_cursor_right; Vector2 m_text_cursor_top; Vector2 m_text_cursor_bottom; Vector2 m_text_cursor_left; std::shared_ptr m_renderer; }; } // namespace omath::hud