diff --git a/examples/example_hud/gui/main_window.cpp b/examples/example_hud/gui/main_window.cpp index c56cecb..2dd4021 100644 --- a/examples/example_hud/gui/main_window.cpp +++ b/examples/example_hud/gui/main_window.cpp @@ -251,7 +251,6 @@ namespace imgui_desktop::gui const auto box_gradient_bottom = animated_color(m_box_gradient_bottom, 0.5f); const auto red = omath::Color{1.f, 0.f, 0.f, 1.f}; const auto green = omath::Color{0.f, 1.f, 0.f, 1.f}; - const auto bar_value_color = omath::Color{red.value() * (1.f - m_bar_value) + green.value() * m_bar_value}; const auto make_glow = [](const GlowSettings& settings) -> std::optional { if (!settings.enabled) @@ -263,16 +262,8 @@ namespace imgui_desktop::gui const auto bar_glow = make_glow(m_bar_glow); const auto label_glow = make_glow(m_label_glow); const auto canvas_glow = make_glow(m_canvas_glow); - const Paint vertical_bar_color = - m_gradient_bars ? Paint{omath::hud::Gradient{bar_value_color, bar_value_color, red, red}} - : Paint{m_bar_color}; - const Paint horizontal_bar_color = - m_gradient_bars ? Paint{omath::hud::Gradient{red, bar_value_color, bar_value_color, red}} - : Paint{m_bar_color}; - const Bar vertical_bar{vertical_bar_color, m_bar_outline_color, m_bar_bg_color, m_bar_width, - m_bar_value, m_bar_offset, bar_glow}; - const Bar horizontal_bar{horizontal_bar_color, m_bar_outline_color, m_bar_bg_color, m_bar_width, - m_bar_value, m_bar_offset, bar_glow}; + const BarPaint bar_color = m_gradient_bars ? BarPaint{BarGradient{red, green}} : BarPaint{m_bar_color}; + const Bar bar{bar_color, m_bar_outline_color, m_bar_bg_color, m_bar_width, m_bar_value, m_bar_offset, bar_glow}; const Paint box_fill = m_gradient_box_fill ? Paint{omath::hud::Gradient{box_gradient_top, box_gradient_top, box_gradient_bottom, box_gradient_bottom}} @@ -299,7 +290,7 @@ namespace imgui_desktop::gui m_corner_ratio, m_box_thickness, cornered_box_glow}), when(m_show_dashed_box, DashedBox{m_dash_color, m_dash_len, m_dash_gap, m_dash_thickness}), RightSide{ - when(m_show_right_bar, vertical_bar), + when(m_show_right_bar, bar), when(m_show_right_dashed_bar, dbar), when(m_show_right_labels, Label{{0.f, 1.f, 0.f, 1.f}, m_label_offset, @@ -319,7 +310,7 @@ namespace imgui_desktop::gui m_ring_thickness, m_ring_offset}), }, LeftSide{ - when(m_show_left_bar, vertical_bar), + when(m_show_left_bar, bar), when(m_show_left_dashed_bar, dbar), when(m_show_left_labels, Label{omath::Color::from_rgba(255, 128, 0, 255), m_label_offset, @@ -329,7 +320,7 @@ namespace imgui_desktop::gui outline_helper(m_outlined), "Level: 42"}), }, TopSide{ - when(m_show_top_bar, horizontal_bar), + when(m_show_top_bar, bar), when(m_show_top_dashed_bar, dbar), when(m_show_centered_top, Centered{Label{omath::Color::from_rgba(0, 255, 255, 255), m_label_offset, @@ -340,7 +331,7 @@ namespace imgui_desktop::gui outline_helper(m_outlined), "*BLEEDING*"}), }, BottomSide{ - when(m_show_bottom_bar, horizontal_bar), + when(m_show_bottom_bar, bar), when(m_show_bottom_dashed_bar, dbar), when(m_show_centered_bottom, Centered{Label{centered_label_color, m_label_offset, outline_helper(m_outlined), diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index c1f644a..feeb0d9 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -41,19 +41,19 @@ namespace omath::hud float thickness = 1.f); // ── Bars ───────────────────────────────────────────────────────── - EntityOverlay& add_right_bar(const widget::Paint& color, const Color& outline_color, const Color& bg_color, + EntityOverlay& add_right_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float offset = 5.f, const std::optional& glow = std::nullopt); - EntityOverlay& add_left_bar(const widget::Paint& color, const Color& outline_color, const Color& bg_color, + EntityOverlay& add_left_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, float width, float ratio, float offset = 5.f, const std::optional& glow = std::nullopt); - EntityOverlay& add_top_bar(const widget::Paint& color, const Color& outline_color, const Color& bg_color, + EntityOverlay& add_top_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float offset = 5.f, const std::optional& glow = std::nullopt); - EntityOverlay& add_bottom_bar(const widget::Paint& color, const Color& outline_color, const Color& bg_color, + EntityOverlay& add_bottom_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float offset = 5.f, const std::optional& glow = std::nullopt); @@ -272,6 +272,8 @@ namespace omath::hud void draw_canvas_glow(const widget::CanvasGlow& canvas_glow) const; void draw_filled_rectangle(const Vector2& min, const Vector2& max, const widget::Paint& paint) const; + [[nodiscard]] + static widget::Paint resolve_bar_paint(const widget::BarPaint& paint, float ratio, bool vertical); 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, diff --git a/include/omath/hud/entity_overlay_widgets.hpp b/include/omath/hud/entity_overlay_widgets.hpp index e1a820e..32f1505 100644 --- a/include/omath/hud/entity_overlay_widgets.hpp +++ b/include/omath/hud/entity_overlay_widgets.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace omath::hud::widget @@ -23,6 +24,32 @@ namespace omath::hud::widget } }; + struct BarGradient + { + Color empty_color; + Color full_color; + }; + + struct BarPaint : std::variant + { + using std::variant::variant; + + constexpr BarPaint(const float red, const float green, const float blue, const float alpha) + : std::variant(Color{red, green, blue, alpha}) + { + } + + BarPaint(const Paint& paint) + { + std::visit( + [this](const auto& value) + { + this->template emplace>(value); + }, + paint); + } + }; + // ── Overloaded helper for std::visit ────────────────────────────────────── template struct Overloaded : Ts... @@ -124,7 +151,7 @@ namespace omath::hud::widget /// A filled bar. `size` is width for left/right sides, height for top/bottom. struct Bar { - Paint color; + BarPaint color; Color outline; Color bg; float size; diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index 8f7a9c7..dc8f1b0 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -77,7 +77,7 @@ namespace omath::hud return *this; } - EntityOverlay& EntityOverlay::add_right_bar(const widget::Paint& color, const Color& outline_color, + EntityOverlay& EntityOverlay::add_right_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, const float width, float ratio, const float offset, const std::optional& glow) { @@ -91,14 +91,14 @@ namespace omath::hud m_renderer->add_filled_rectangle(bar_min, bar_max, bg_color); draw_glow_rectangle(fill_min, bar_max, glow); - draw_filled_rectangle(fill_min, bar_max, color); + draw_filled_rectangle(fill_min, bar_max, resolve_bar_paint(color, ratio, true)); m_renderer->add_rectangle(bar_min, bar_max, outline_color); m_text_cursor_right.x += offset + width; return *this; } - EntityOverlay& EntityOverlay::add_left_bar(const widget::Paint& color, const Color& outline_color, + EntityOverlay& EntityOverlay::add_left_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, const float width, float ratio, const float offset, const std::optional& glow) { @@ -112,7 +112,7 @@ namespace omath::hud m_renderer->add_filled_rectangle(bar_min, bar_max, bg_color); draw_glow_rectangle(fill_min, bar_max, glow); - draw_filled_rectangle(fill_min, bar_max, color); + draw_filled_rectangle(fill_min, bar_max, resolve_bar_paint(color, ratio, true)); m_renderer->add_rectangle(bar_min, bar_max, outline_color); m_text_cursor_left.x -= offset + width; @@ -139,7 +139,7 @@ namespace omath::hud return *this; } - EntityOverlay& EntityOverlay::add_top_bar(const widget::Paint& color, const Color& outline_color, + EntityOverlay& EntityOverlay::add_top_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, const float height, float ratio, const float offset, const std::optional& glow) { @@ -153,7 +153,7 @@ namespace omath::hud m_renderer->add_filled_rectangle(bar_min, bar_max, bg_color); draw_glow_rectangle(bar_min, fill_max, glow); - draw_filled_rectangle(bar_min, fill_max, color); + draw_filled_rectangle(bar_min, fill_max, resolve_bar_paint(color, ratio, false)); m_renderer->add_rectangle(bar_min, bar_max, outline_color); m_text_cursor_top.y -= offset + height; @@ -552,7 +552,33 @@ namespace omath::hud }, paint); } - EntityOverlay& EntityOverlay::add_bottom_bar(const widget::Paint& color, const Color& outline_color, + + widget::Paint EntityOverlay::resolve_bar_paint(const widget::BarPaint& paint, const float ratio, + const bool vertical) + { + return std::visit( + widget::Overloaded{ + [](const Color& color) -> widget::Paint + { + return color; + }, + [](const Gradient& gradient) -> widget::Paint + { + return gradient; + }, + [&](const widget::BarGradient& gradient) -> widget::Paint + { + const float value = std::clamp(ratio, 0.f, 1.f); + const auto current = Color{gradient.empty_color.value() * (1.f - value) + + gradient.full_color.value() * value}; + if (vertical) + return Gradient{current, current, gradient.empty_color, gradient.empty_color}; + return Gradient{gradient.empty_color, current, current, gradient.empty_color}; + }, + }, + paint); + } + EntityOverlay& EntityOverlay::add_bottom_bar(const widget::BarPaint& color, const Color& outline_color, const Color& bg_color, const float height, float ratio, const float offset, const std::optional& glow) { @@ -565,7 +591,7 @@ namespace omath::hud const auto fill_max = bar_start + Vector2{max_bar_width * ratio, height}; m_renderer->add_filled_rectangle(bar_min, bar_max, bg_color); draw_glow_rectangle(bar_min, fill_max, glow); - draw_filled_rectangle(bar_min, fill_max, color); + draw_filled_rectangle(bar_min, fill_max, resolve_bar_paint(color, ratio, false)); m_renderer->add_rectangle(bar_min, bar_max, outline_color); m_text_cursor_bottom.y += offset + height;