fix(plot,render,glfw): a hue-neutral crosshair, an em-dash placeholder, one layout per figure event, and a usable readout switch
This commit is contained in:
1 parent
10d5129fbf
commit
a14f333dbe
10 files changed
+175
-70
No files matched your search
@@ -130,8 +130,11 @@ struct CrosshairRow {
|
||||
f64 y = 0.0;
|
||||
/// The trace's name, or the positional placeholder of an unnamed one.
|
||||
std::string label;
|
||||
/// The formatted value, written in the trace's y axis' own tick format (`Axis::format_value()`,
|
||||
/// so a readout reads exactly like the labels beside it), and empty when `!valid`.
|
||||
/// What the row's value column shows. For a `valid` row it is the formatted number, written in
|
||||
/// the trace's y axis' own tick format (`Axis::format_value()`, so a readout reads exactly like
|
||||
/// the labels beside it); for a row whose trace has **no sample at the crosshair's x** it is
|
||||
/// `kCrosshairNoValue`, the em dash. The absence is therefore *legible* -- a blank cell reads as
|
||||
/// "still loading" rather than as "nothing here" -- and nothing numeric is fabricated for it.
|
||||
std::string value;
|
||||
/// The trace's intersection with the crosshair, in framebuffer pixels: the pen the
|
||||
/// renderer draws the marker at. Placed through the *trace's own* axis pair, so the
|
||||
@@ -143,8 +146,10 @@ struct CrosshairRow {
|
||||
/// The label's line box: its top-left is the pen the run is staged at and its height one
|
||||
/// text line. Empty when `!listed`.
|
||||
Rect label_box{};
|
||||
/// The value's line box, one gutter (the legend's padding) after the label's. Empty when
|
||||
/// `!listed` or `!valid`: a row with no value stages no run.
|
||||
/// The value's line box, right-aligned on the panel's inner edge and one gutter's worth of
|
||||
/// measurement away from the label's own box. Empty when `!listed`: a row that is not in the panel
|
||||
/// stages neither run, while a listed row always stages something -- the number, or
|
||||
/// `kCrosshairNoValue`.
|
||||
Rect value_box{};
|
||||
};
|
||||
|
||||
@@ -185,6 +190,16 @@ struct CrosshairLayout {
|
||||
bool empty() const noexcept { return !active; }
|
||||
};
|
||||
|
||||
/// What a listed readout row shows in its value column when its trace has **no sample at the
|
||||
/// crosshair's x**: an em dash, not a blank.
|
||||
///
|
||||
/// The row is listed either way -- the trace *is* under the pointer, and a panel that grew and
|
||||
/// shrank with the pointer would be worse to read than one that says "nothing here" -- so the
|
||||
/// absence has to be *said*: a blank value cell reads as a value that has not arrived yet. The em
|
||||
/// dash is in the embedded font's coverage (spec §2 covers U+2013/U+2014), it is not a number, and
|
||||
/// it cannot be mistaken for one.
|
||||
inline constexpr const char* kCrosshairNoValue = "\u2014";
|
||||
|
||||
/// The label an **unnamed** trace's readout row carries: `#` and the trace's position, e.g.
|
||||
/// `#2`.
|
||||
///
|
||||
|
||||
@@ -567,6 +567,12 @@ class Plot {
|
||||
/// calls this when the pointer leaves the axes.
|
||||
void clear_crosshair() noexcept { crosshair_.active = false; }
|
||||
|
||||
/// Switches the readout panel off -- or back on -- without moving the crosshair: the lines and
|
||||
/// the per-trace markers stay, the panel is not measured and no row is listed. A host that wants
|
||||
/// the pointer's column marked but not a panel over its data sets this once; it is deliberately
|
||||
/// **not** part of `set_crosshair()`, so placing a hover cannot silently change it.
|
||||
void set_crosshair_readout(bool on) noexcept { crosshair_.show_readout = on; }
|
||||
|
||||
/// The crosshair's state: where it is, which lines it draws and whether the readout is
|
||||
/// on. Read-only -- `set_crosshair()` and `clear_crosshair()` are how it moves -- so the
|
||||
/// coordinates it holds and the geometry `layout()` places from them cannot disagree.
|
||||
|
||||
@@ -41,13 +41,18 @@ struct Style {
|
||||
Color axis_text = Color::hex(0xC8D0DC);
|
||||
Color cursor = Color::hex(0xFFB020);
|
||||
Color measure_fill = Color::hex(0xFFB020, 0.15f);
|
||||
/// The crosshair's colour: its two lines, its markers' own colour excepted, and the
|
||||
/// readout panel's border (spec §15). Deliberately **not** `cursor`: the cursor accent is
|
||||
/// an orange that a caller's own cursors, a region's bounds and its fill all already use,
|
||||
/// while the crosshair is a passive hover instrument that has to read as *chrome* over a
|
||||
/// dense trace rather than as another handle to grab. A pale cyan does that against the
|
||||
/// dark default theme, and it is a colour no default element of a frame shares.
|
||||
Color crosshair = Color::hex(0xB8E8FF);
|
||||
/// The crosshair's colour: its two lines and the readout panel's border (spec §15). Markers are
|
||||
/// deliberately *not* this colour -- they carry each trace's own, because a marker says *which*
|
||||
/// trace and the line says *where*.
|
||||
///
|
||||
/// **Hue-neutral by design**, and that is the whole choice: a saturated colour here would be
|
||||
/// confusable with a trace, and the library's own default trace colour is a saturated cyan
|
||||
/// (`Trace`'s default, 0x40C0FF) that a hue-based reading cannot tell from a cyan crosshair --
|
||||
/// only lightness would separate them, which no reader can rely on. A near-white can never be a
|
||||
/// saturated trace of *any* hue, and it is still plainly not `cursor`'s orange, which is what
|
||||
/// the spec asks for. The 1 px stroke is kept: form (a full-height thin line over a polyline) is
|
||||
/// already distinct, so no dashes.
|
||||
Color crosshair = Color::hex(0xE6EBF2);
|
||||
|
||||
// --- the scale ----------------------------------------------------------
|
||||
|
||||
|
||||
Reference in new issue
Block a user