plot host: split rows share y, rulers per row

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-11-04 00:55:59 +01:00
1 parent 135310ceca
commit 5f0bc75c27
5 files changed
+174 -24

No files matched your search

+26 -16
View File
@@ -1752,7 +1752,8 @@ GtkWidget* cursors_header(App& app) {
/// The unit a row's y rulers are in: the one its bound channels agree on, or none when they
/// disagree -- a ruler sits on the row's y axis, and two signals of different units on one
/// axis make "the" unit a guess.
/// axis make "the" unit a guess. The cells of a split row share that axis, so the channels of
/// every cell of `row`'s figure row count.
///
/// The channel list is rebuilt by the producer, so it is read under the model mutex, like
/// every other read of it from this thread.
@@ -1760,18 +1761,23 @@ std::string row_unit(App& app, int row) {
std::lock_guard<std::mutex> lock(app.model->mutex());
std::string unit;
bool first = true;
for (int s = 0; s < RowSet::kSlotsPerRow; ++s) {
const std::size_t si = static_cast<std::size_t>(s);
const RowSet::Row& r = app.rows->row(row);
if (r.signal_name[si].empty()) continue;
const int ch = r.channel[si];
if (ch < 0 || static_cast<std::size_t>(ch) >= app.model->channels().size()) continue;
const std::string& u = app.model->channels()[static_cast<std::size_t>(ch)].unit;
if (first) {
unit = u;
first = false;
} else if (unit != u) {
return "";
const int fr = app.rows->figure_row_of(row);
const int begin = fr >= 0 ? app.rows->first_plot_of_row(fr) : row;
const int end = fr >= 0 ? begin + app.rows->cells_in_row(fr) : row + 1;
for (int p = begin; p < end; ++p) {
const RowSet::Row& r = app.rows->row(p);
for (int s = 0; s < RowSet::kSlotsPerRow; ++s) {
const std::size_t si = static_cast<std::size_t>(s);
if (r.signal_name[si].empty()) continue;
const int ch = r.channel[si];
if (ch < 0 || static_cast<std::size_t>(ch) >= app.model->channels().size()) continue;
const std::string& u = app.model->channels()[static_cast<std::size_t>(ch)].unit;
if (first) {
unit = u;
first = false;
} else if (unit != u) {
return "";
}
}
}
return unit;
@@ -1840,10 +1846,14 @@ void rebuild_cursors_pane(App& app) {
for (int r = 0; r < app.rows->row_count(); ++r) {
if (!rulers) break;
char who[64];
// A row split into cells names its plots the way the rest of the UI does ("plot 2a"); an
const int fr = app.rows->figure_row_of(r);
const bool split = app.rows->cells_in_row(fr) > 1;
// A ruler pair belongs to the figure row (its cells share one y axis), so a split row gets one
// line, on its first cell, named by the row's number -- the one `plot_label()` leads with. An
// unsplit row keeps the wording it always had.
if (app.rows->cells_in_row(app.rows->figure_row_of(r)) > 1) {
std::snprintf(who, sizeof(who), "plot %s", app.rows->plot_label(r).c_str());
if (split && app.rows->cell_of(r) != 0) continue;
if (split) {
std::snprintf(who, sizeof(who), "row %d", fr + 1);
} else {
std::snprintf(who, sizeof(who), "row %d", r);
}