fix: only a window change sets the time scale; a fit states the whole of it
The time scale is more than the axis: it is also the trigger's event span, the buffer partition and the control's readout. A zoom or a pan was already clean -- the controller writes the member axis and `clamp_to_data()` caps the span -- but both fits moved `window_s_` alone and only restated the control. The event span then stayed on the previous window until the next decade step or unit change applied the fitted value for real, so one action changed the time scale twice. `apply_window_scale()` is split out of `apply_time_window()` for the fits to use: it moves the partition, the event span, the control and the session, and leaves the view alone, because `set_time_window()` re-arms the live follow and would throw a held event or a paused view back onto the stream. The fits report the span they framed, `fit_all()` delegates its x half to `fit_x()` so the two cannot drift, and the probe drives the menu handlers rather than `RowSet` so it sees the half that lives there. `[fit-probe]` gained `event_span=`, which must equal `window=` on every line. Also moves the plotter pin to 03c41ad (three build warnings, no behaviour). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f6738031a
commit
9888fd9977
7 files changed
+128
-63
No files matched your search
+17
-26
@@ -657,21 +657,24 @@ void RowSet::unpin_pause_window() {
|
||||
set_time_window(window_s_);
|
||||
}
|
||||
|
||||
void RowSet::fit_x() {
|
||||
bool RowSet::fit_x(double& span) {
|
||||
Row& first = row(0);
|
||||
if (!first.plot || !figure_) return;
|
||||
if (!first.plot || !figure_) return false;
|
||||
first.plot->auto_fit_x();
|
||||
const plot::Range fitted = first.plot->x_range(first.axis_x);
|
||||
const double span = fitted.span();
|
||||
if (!std::isfinite(span) || !(span > 0.0)) return;
|
||||
// The same two paths `fit_all()` takes: a held event owns its window and states it
|
||||
// through the link group, a live view re-arms the follow and frames the newest span.
|
||||
const double fitted_span = fitted.span();
|
||||
if (!std::isfinite(fitted_span) || !(fitted_span > 0.0)) return false;
|
||||
if (pinned_) {
|
||||
window_s_ = span;
|
||||
// Fitting a captured or paused view: the window is the snapshot's own span, and
|
||||
// `set_time_window()` would re-arm the follow and re-frame on a live edge that a frozen
|
||||
// view has nothing bound to.
|
||||
window_s_ = fitted_span;
|
||||
figure_->set_x_link_range(x_group_, fitted);
|
||||
} else {
|
||||
set_time_window(span);
|
||||
set_time_window(fitted_span);
|
||||
}
|
||||
span = window_s_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RowSet::sync_cursors(int drag_row) {
|
||||
@@ -785,28 +788,16 @@ void RowSet::pin_event_window(double pre_s, double post_s) {
|
||||
figure_->set_x_link_range(x_group_, {-pre_s, post_s});
|
||||
}
|
||||
|
||||
void RowSet::fit_all() {
|
||||
bool RowSet::fit_all(double& span) {
|
||||
for (int i = 0; i < rows_; ++i) {
|
||||
Row& r = row(i);
|
||||
if (r.plot) r.plot->auto_fit_y(r.axis_y);
|
||||
}
|
||||
Row& first = row(0);
|
||||
if (!first.plot || !figure_) return;
|
||||
// Row 0 fits its own x to the data it holds; that span becomes the shared window, and
|
||||
// stating it through the group is what puts every row on it.
|
||||
first.plot->auto_fit_x();
|
||||
const plot::Range fitted = first.plot->x_range(first.axis_x);
|
||||
const double span = fitted.span();
|
||||
if (!std::isfinite(span) || !(span > 0.0)) return;
|
||||
if (pinned_) {
|
||||
// Fitting a captured event: the window is the snapshot's own `[-pre, +post]` span,
|
||||
// and `set_time_window()` would re-arm the follow and re-frame on a live edge that
|
||||
// trigger mode has nothing bound to.
|
||||
window_s_ = span;
|
||||
figure_->set_x_link_range(x_group_, fitted);
|
||||
} else {
|
||||
set_time_window(span);
|
||||
}
|
||||
// The x half is `fit_x()`'s exactly -- row 0's data span, stated through the link group so
|
||||
// every row lands on it -- and sharing it is what keeps the two fits from drifting apart.
|
||||
// The y fit above has already happened either way: a row 0 that holds nothing still gets
|
||||
// every row's y scaled, it just has no span to report.
|
||||
return fit_x(span);
|
||||
}
|
||||
|
||||
void RowSet::note_y_gutter(double need_px) {
|
||||
|
||||
Reference in new issue
Block a user