udpscope: an oscilloscope view for a UDPStreamer source
GTK4 and libadwaita. It receives one UDP stream through the vendored udpsclient, buffers it in a large ring, and draws it with the vendored plotter: a trigger with a pre/post event window, a pause that freezes the window, cursors, measurements, math channels in a node editor, an event cache, named configurations, preferences, and an export of the visible window to .npy/.csv. Waveform files can be opened and analysed in place. The interface is two threads -- a producer that owns the socket and the GTK main thread that owns every widget and the GL context -- sharing one model under one mutex, with samples crossing through lock-free rings. deps/plotter is a submodule pinned to the commit this tree builds against; deps/udpsclient is vendored in place. docs/claude/ documents the rules that cost a defect to learn, and SPECS.md is the requirement document.
This commit is contained in:
1 parent
8f54841c2c
commit
0e256764d5
41 files changed
+2081
-154
No files matched your search
@@ -24,6 +24,8 @@ LayoutState collect_layout(App& app) {
|
||||
for (int s = 0; s < RowSet::kSlotsPerRow; ++s) {
|
||||
row.signals.push_back(r.signal_name[static_cast<std::size_t>(s)]);
|
||||
}
|
||||
const std::vector<float>& weights = app.rows->row_weights();
|
||||
if (static_cast<std::size_t>(i) < weights.size()) row.weight = weights[static_cast<std::size_t>(i)];
|
||||
st.rows.push_back(std::move(row));
|
||||
}
|
||||
for (std::size_t si = 0; si < model.signals().size(); ++si) {
|
||||
@@ -313,6 +315,15 @@ void apply_layout(App& app, const LayoutState& st) {
|
||||
if (rows > RowSet::kMaxRows) rows = RowSet::kMaxRows;
|
||||
if (rows > 0) app.rows->set_row_count(rows);
|
||||
|
||||
// The rows' shares of the height come from the same file as their signals: a sizing a user dragged is
|
||||
// an arrangement, and the layout is where an arrangement lives. Absent from an older file, the weights
|
||||
// are all 1 -- equal rows -- which is what such a file was saved with.
|
||||
{
|
||||
std::vector<float> weights;
|
||||
weights.reserve(st.rows.size());
|
||||
for (const LayoutState::Row& wr : st.rows) weights.push_back(static_cast<float>(wr.weight));
|
||||
app.rows->set_row_weights(std::move(weights));
|
||||
}
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
int slot = 0;
|
||||
for (const std::string& name : st.rows[static_cast<std::size_t>(i)].signals) {
|
||||
|
||||
Reference in new issue
Block a user