xo-imgui: ex4: + ImSpan + restore working tooltip popups

This commit is contained in:
Roland Conybeare 2025-11-13 20:17:31 -05:00
commit 270c563899
4 changed files with 89 additions and 45 deletions

View file

@ -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 {

View file

@ -3,6 +3,7 @@
#pragma once
#include "imgui.h"
#include "ImSpan.hpp"
#include <algorithm>
#include <utility>
@ -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<float, float> x_span() const { return std::make_pair(top_left_.x, bottom_right_.x); }
std::pair<float, float> 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; }

View file

@ -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)); }

View file

@ -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 */