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
+17
-13
@@ -1305,9 +1305,10 @@ void Plot::build_crosshair() {
|
||||
row.label_box = Rect{};
|
||||
row.value_box = Rect{};
|
||||
row.label.assign(trace.name.empty() ? crosshair_unnamed_label(i) : trace.name);
|
||||
row.value.clear();
|
||||
// The value, and with it the marker: a trace with no sample at this x writes no number
|
||||
// and gets no marker, rather than a value clamped to the end of its series.
|
||||
// The value: the interpolated number where the trace has a sample at this x, and the em dash
|
||||
// where it does not. The row is listed either way, so the absence has to be *said* -- a blank
|
||||
// value cell reads as a value that has not arrived -- and the dash is measured into the panel's
|
||||
// width like any other value, so the row's boxes are placed by one rule.
|
||||
if (crosshair_value(i, crosshair_.x, row.y)) {
|
||||
row.valid = true;
|
||||
char value[32];
|
||||
@@ -1319,6 +1320,8 @@ void Plot::build_crosshair() {
|
||||
// actually drawn however its axes are scaled.
|
||||
row.marker = Vec2{static_cast<f32>(x_transform(trace.axis_x).to_screen_x(crosshair_.x)),
|
||||
static_cast<f32>(y_transform(trace.axis_y).to_screen_y(row.y))};
|
||||
} else {
|
||||
row.value.assign(kCrosshairNoValue);
|
||||
}
|
||||
}
|
||||
crosshair.rows.resize(count);
|
||||
@@ -1328,13 +1331,13 @@ void Plot::build_crosshair() {
|
||||
if (count == 0u || !crosshair_.show_readout || text_ == nullptr) return;
|
||||
|
||||
const ReadoutChrome chrome = readout_chrome(legend_, style_, *text_);
|
||||
// Each row's content: its label, the gutter, and its value when it has one -- an invalid
|
||||
// row is narrower, and the panel is sized by the widest row that will be listed, which the
|
||||
// prefix-max reads in O(1) after a row was dropped from the end.
|
||||
// Each row's content: its label, the gutter, and its value -- which is a number or the em dash,
|
||||
// so every row is the same two runs and the panel is sized by the widest *listed* one, read in
|
||||
// O(1) by the prefix-max after a row was dropped from the end.
|
||||
crosshair_content_px_.clear();
|
||||
for (const CrosshairRow& row : crosshair.rows) {
|
||||
f32 content = text_->measure(row.label.c_str());
|
||||
if (row.valid) content += chrome.pad + text_->measure(row.value.c_str());
|
||||
const f32 content =
|
||||
text_->measure(row.label.c_str()) + chrome.pad + text_->measure(row.value.c_str());
|
||||
crosshair_content_px_.push_back(crosshair_content_px_.empty()
|
||||
? content
|
||||
: std::max(crosshair_content_px_.back(), content));
|
||||
@@ -1393,11 +1396,12 @@ void Plot::build_crosshair() {
|
||||
row.swatch = readout_swatch(chrome, crosshair.panel, i);
|
||||
const Vec2 pen = readout_text_pen(chrome, crosshair.panel, i);
|
||||
row.label_box = Rect{pen.x, pen.y, text_->measure(row.label.c_str()), chrome.line_h};
|
||||
if (row.valid) {
|
||||
const f32 width = text_->measure(row.value.c_str());
|
||||
row.value_box =
|
||||
Rect{crosshair.panel.right() - chrome.pad - width, pen.y, width, chrome.line_h};
|
||||
}
|
||||
// Every listed row stages a value run: the number, or `kCrosshairNoValue` where the trace has
|
||||
// no sample here. A blank cell would read as a value still to come, which is a different thing
|
||||
// from "nothing at this x".
|
||||
const f32 width = text_->measure(row.value.c_str());
|
||||
row.value_box =
|
||||
Rect{crosshair.panel.right() - chrome.pad - width, pen.y, width, chrome.line_h};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user