From 270c563899cc8d93c4896f932ca2c57e4adb6823 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 13 Nov 2025 20:17:31 -0500 Subject: [PATCH] xo-imgui: ex4: + ImSpan + restore working tooltip popups --- xo-imgui/example/ex4/DrawState.cpp | 111 ++++++++++++++------------ xo-imgui/include/xo/imgui/ImRect.hpp | 13 ++- xo-imgui/include/xo/imgui/ImScale.hpp | 2 + xo-imgui/include/xo/imgui/ImSpan.hpp | 24 ++++++ 4 files changed, 97 insertions(+), 53 deletions(-) create mode 100644 xo-imgui/include/xo/imgui/ImSpan.hpp diff --git a/xo-imgui/example/ex4/DrawState.cpp b/xo-imgui/example/ex4/DrawState.cpp index fe835c03..6951200c 100644 --- a/xo-imgui/example/ex4/DrawState.cpp +++ b/xo-imgui/example/ex4/DrawState.cpp @@ -492,23 +492,26 @@ DrawState::draw_gc_history(const GcStateDescription & gcstate, if ((gen == stats.upto_) || (gen == generation::tenured)) { /* - * ys_span.y +--+ - * | | survive_z (survived 1st GC) + * screen native + * coords coords + * + * ys_span.y +--+ ypsz_nat.y + * | | survive_z (survived 1st GC) * | | * yp_span.y +--+ - * | | promote_z (sruvived 2nd GC) + * | | promote_z (sruvived 2nd GC) * | | * ypsz_span.y +--+ - * | | persist_z (survived 3+ GCs) + * | | persist_z (survived 3+ GCs) * | | - * y_zero +--+ ---------------------------------------- x-axis - * | | gN (killed on 3+ GC) + * y_zero +--+ ---------------------------------------------- x-axis + * | | gN (killed on 3+ GC) * | | * ygN_span.x +--+ - * | | g1 (killed on 2nd GC) + * | | g1 (killed on 2nd GC) * | | * yg1_span.x +--+ - * | | g0 (killed on 1st GC) + * | | g0 (killed on 1st GC) * | | * yg0_span.x +--+ */ @@ -516,87 +519,95 @@ DrawState::draw_gc_history(const GcStateDescription & gcstate, /* x-coordinates of bar */ float x_lo = bounding_rect.x_lo() + lm + i * bar_w; float x_hi = x_lo + bar_w - 1; - ImVec2 x_span{x_lo, x_hi}; + ImSpan x_span{x_lo, x_hi}; - /* screen y-coordinates of persist bar (survived 3+ GCs) */ - ImVec2 ypsz_span = y_scale.map_span(0, stats.persist_z_); - //float ypsz_lo = (y_zero - (display_h * stats.persist_z_ / y_range)); + /* native y-coordinates of persist bar */ + ImSpan ypsz_nat(0, stats.persist_z_); { + /* screen y-coordinates of persist bar (survived 3+ GCs) */ + ImSpan ypsz_span = y_scale.map_span(ypsz_nat); + write_gc_history_bar("##persist", gc_history_headline::persist, stats, - ImRect::from_xy_span(x_span, ypsz_span), - draw_list); - } - /* screen y-coordinates of promote bar (survived 2nd GC) */ - ImVec2 yp_span = y_scale.map_span(stats.persist_z_, - stats.persist_z_ + stats.promote_z_); - /* y-coordinates of promote bar (survived 2nd GC) */ - //float yp_hi = ypsz_lo; - //float yp_lo = (yp_hi - (display_h * stats.promote_z_ / y_range)); - { - write_gc_history_bar("##promote", - gc_history_headline::promote, - stats, - ImRect::from_xy_span(x_span, yp_span), + ImRect::from_xy_span(x_span, ypsz_span.normalize()), draw_list); } - /* screen y-coordinates of surive bar (survived 1st GC) */ - ImVec2 ys_span = y_scale.map_span(stats.persist_z_ + stats.promote_z_, - stats.persist_z_ + stats.promote_z_ + stats.survive_z_); - /* y-coordinates of survivor bar (survived 1st GC) */ - //float ys_hi = yp_lo; - //float ys_lo = (ys_hi - (display_h * stats.survive_z_ / y_range)); + /* native y-coordinates of promote bar */ + ImSpan yp_nat(ypsz_nat.hi(), ypsz_nat.hi() + stats.promote_z_); + + /* y-coordinates of promote bar (survived 2nd GC) */ { + /* screen y-coordinates of promote bar (survived 2nd GC) */ + ImSpan yp_span = y_scale.map_span(yp_nat); + + write_gc_history_bar("##promote", + gc_history_headline::promote, + stats, + ImRect::from_xy_span(x_span, yp_span.normalize()), + draw_list); + } + + /* native y-coordinates of survive bar */ + ImSpan ys_nat(yp_nat.hi(), yp_nat.hi() + stats.survive_z_); + + /* y-coordinates of survivor bar (survived 1st GC) */ + { + /* screen y-coordinates of surive bar (survived 1st GC) */ + ImSpan ys_span = y_scale.map_span(ys_nat); + write_gc_history_bar("##survivor", gc_history_headline::survive, stats, - ImRect::from_xy_span(x_span, ys_span), + ImRect::from_xy_span(x_span, ys_span.normalize()), draw_list); } // ----------------------------------------------------------- - /* screen y-coordinates of garbageN bar (killed on 3+ GC) */ - ImVec2 ygN_span = y_scale.map_span(0.0 - stats.garbageN_z_, 0.0); + /* native y-coordinates of garbageN bar */ + ImSpan ygN_nat(0.0 - stats.garbageN_z_, 0.0); + /* y-coordinates of garbageN bar (killed on 3+ GC) */ - //float ygN_lo = y_zero; - //float ygN_hi = (y_zero + (display_h * stats.garbageN_z_ / y_range)); { + /* screen y-coordinates of garbageN bar (killed on 3+ GC) */ + ImSpan ygN_span = y_scale.map_span(ygN_nat); + write_gc_history_bar("##garbageN", gc_history_headline::garbageN, stats, - ImRect::from_xy_span(x_span, ygN_span), + ImRect::from_xy_span(x_span, ygN_span.normalize()), draw_list); } + /* native y-coordinates of garbage1 bar */ + ImSpan yg1_nat(ygN_nat.lo() - stats.garbage1_z_, ygN_nat.lo()); + /* y-coordinates of garbage1 bar (killed on 2nd GC) */ - ImVec2 yg1_span = y_scale.map_span(0.0 - stats.garbageN_z_ - stats.garbage1_z_, - 0.0 - stats.garbageN_z_); - /* y-coordinates of garbage1 bar (killed on 2nd GC) */ - //float yg1_lo = ygN_hi; - //float yg1_hi = (yg1_lo + (display_h * stats.garbage1_z_ / y_range)); { + /* y-coordinates of garbage1 bar (killed on 2nd GC) */ + ImSpan yg1_span = y_scale.map_span(yg1_nat); + write_gc_history_bar("##garbage1", gc_history_headline::garbage1, stats, - ImRect::from_xy_span(x_span, yg1_span), + ImRect::from_xy_span(x_span, yg1_span.normalize()), draw_list); } - /* y-coordinates of garbage0 bar (killed on 1st GC) */ - ImVec2 yg0_span = y_scale.map_span(0.0 - stats.garbageN_z_ - stats.garbage1_z_ - stats.garbage0_z_, - 0.0 - stats.garbageN_z_ - stats.garbage1_z_); + /* native y-coordinates of garbage0 bar */ + ImSpan yg0_nat(yg1_nat.lo() - stats.garbage0_z_, yg1_nat.lo()); /* y-coordinates of garbage0 bar (killed on 1st GC) */ - //float yg0_lo = yg1_hi; - //float yg0_hi = (yg0_lo + (display_h * stats.garbage0_z_ / y_range)); { + /* y-coordinates of garbage0 bar (killed on 1st GC) */ + ImSpan yg0_span = y_scale.map_span(yg0_nat); + write_gc_history_bar("##garbage0", gc_history_headline::garbage0, stats, - ImRect::from_xy_span(x_span, yg0_span), + ImRect::from_xy_span(x_span, yg0_span.normalize()), draw_list); } } else { diff --git a/xo-imgui/include/xo/imgui/ImRect.hpp b/xo-imgui/include/xo/imgui/ImRect.hpp index 4b4eb6fe..607e47e6 100644 --- a/xo-imgui/include/xo/imgui/ImRect.hpp +++ b/xo-imgui/include/xo/imgui/ImRect.hpp @@ -3,6 +3,7 @@ #pragma once #include "imgui.h" +#include "ImSpan.hpp" #include #include @@ -16,7 +17,13 @@ struct ImRect { ImRect(float x_lo, float y_lo, float x_hi, float y_hi) : top_left_{x_lo, y_lo}, bottom_right_{x_hi, y_hi} {} static ImRect from_xy_span(const ImVec2 & x_span, const ImVec2 & y_span) { - return ImRect(ImVec2{x_span.x, y_span.x}, ImVec2{x_span.y, y_span.y}); + return ImRect(ImVec2{x_span.x, y_span.x}, + ImVec2{x_span.y, y_span.y}); + } + + static ImRect from_xy_span(const ImSpan & x_span, const ImSpan & y_span) { + return ImRect(ImVec2{x_span.lo(), y_span.lo()}, + ImVec2{x_span.hi(), y_span.hi()}); } static void draw_filled_rect_with_label(const char * text, @@ -34,8 +41,8 @@ struct ImRect { std::pair x_span() const { return std::make_pair(top_left_.x, bottom_right_.x); } std::pair y_span() const { return std::make_pair(top_left_.y, bottom_right_.y); } - const ImVec2 & top_left() const { return top_left_; } - const ImVec2 & bottom_right() const { return bottom_right_; } + ImVec2 top_left() const { return top_left_; } + ImVec2 bottom_right() const { return bottom_right_; } float x_lo() const { return top_left_.x; } float x_hi() const { return bottom_right_.x; } diff --git a/xo-imgui/include/xo/imgui/ImScale.hpp b/xo-imgui/include/xo/imgui/ImScale.hpp index 98e8fb2e..4d71dd7e 100644 --- a/xo-imgui/include/xo/imgui/ImScale.hpp +++ b/xo-imgui/include/xo/imgui/ImScale.hpp @@ -3,6 +3,7 @@ #pragma once #include "imgui.h" +#include "ImSpan.hpp" /** Linear scale for transforming between two coordinate systems. * f(x) = m.(x - x0) + y0 @@ -31,6 +32,7 @@ public: /** construct inverse function inv(f) **/ ImScale inverse() const { return ImScale(ImVec2(ref_.y, ref_.x), 1.0 / scale_); } + ImSpan map_span(ImSpan x_span) const { return ImSpan(at(x_span.lo()), at(x_span.hi())); } ImVec2 map_span(ImVec2 x_span) const { return ImVec2(at(x_span.x), at(x_span.y)); } ImVec2 map_span(float x1, float x2) const { return map_span(ImVec2(x1, x2)); } diff --git a/xo-imgui/include/xo/imgui/ImSpan.hpp b/xo-imgui/include/xo/imgui/ImSpan.hpp new file mode 100644 index 00000000..88f83d90 --- /dev/null +++ b/xo-imgui/include/xo/imgui/ImSpan.hpp @@ -0,0 +1,24 @@ +/* ImSpan.hpp */ + +#pragma once + +#include "imgui.h" + +/* similar to ImVec2, but firmly located in xo territory + */ +struct ImSpan { + ImSpan() : lo_{0.0}, hi_{0.0} {} + ImSpan(float lo, float hi) : lo_{lo}, hi_{hi} {} + + float lo() const { return lo_; } + float hi() const { return hi_; } + + ImSpan normalize() const { return (lo_ <= hi_) ? ImSpan(lo_, hi_) : ImSpan{hi_, lo_}; } + ImVec2 to_imvec2() const { return ImVec2(lo_, hi_); } + +private: + float lo_ = 0.0; + float hi_ = 0.0; +}; + +/* end ImSpan.hpp */