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.
56 lines
2.6 KiB
C++
56 lines
2.6 KiB
C++
// SPDX-License-Identifier: MIT
|
|
// SPDX-FileCopyrightText: 2026 Martino Ferrari
|
|
//
|
|
// The preferences: what a user chose about this program rather than about a source, kept between runs
|
|
// in one file. Deliberately free of GTK and of the app's own state -- it is a handful of values, a
|
|
// file to read them from and a file to write them to -- so the dialog that edits them, the code that
|
|
// applies them and the tests that read them all go through the same struct.
|
|
|
|
#ifndef UDPSCOPE_SETTINGS_HPP
|
|
#define UDPSCOPE_SETTINGS_HPP
|
|
|
|
#include <string>
|
|
|
|
namespace udpscope {
|
|
|
|
/// Everything the preferences dialog can change.
|
|
///
|
|
/// The defaults are the *stated* ones: an absent file and a fresh install behave identically, so a
|
|
/// setting is only ever a user's decision and never an accident of what a file happened to contain.
|
|
struct Settings {
|
|
/// Where the event cache goes: the directory each source's folder is created in. Empty means the
|
|
/// standard `<cache>/udpscope/events`, and a path is used as given -- one directory for every
|
|
/// source, never one between them, because two sources writing one directory is two sources
|
|
/// overwriting each other's events.
|
|
std::string event_cache_dir;
|
|
/// How many events one source's cache keeps. 0 disables trimming, which is a decision about the
|
|
/// user's disk made deliberately rather than by default.
|
|
int event_cache_max = 32;
|
|
/// `--relative-time`'s setting, for a source whose wall-clock stamps jitter. A *startup* setting: the
|
|
/// buffers are planned before any stream is known, so it takes effect on the next start (the
|
|
/// preferences dialog says so, like the configurations dialog does).
|
|
bool relative_time = false;
|
|
/// "auto", "light" or "dark": what the interface should look like. Kept as the three names libadwaita
|
|
/// uses, so the file says what the setting is rather than what an enum happens to be numbered.
|
|
std::string theme = "auto";
|
|
};
|
|
|
|
/// The defaults, as a value rather than as a comment: what the dialog's *Defaults* button writes and
|
|
/// what a missing file yields.
|
|
Settings default_settings();
|
|
|
|
/// The file the settings live in: `<config>/udpscope/settings.toml`. Never empty.
|
|
std::string settings_path();
|
|
|
|
/// Reads the settings, filling anything the file does not mention from the defaults. A file that
|
|
/// cannot be read is not an error: it is a first run.
|
|
Settings load_settings();
|
|
|
|
/// Writes them. Returns false when the file cannot be written, which the dialog reports rather than
|
|
/// swallowing -- a preference that silently does not stick is worse than one that says it did not.
|
|
bool save_settings(const Settings& settings);
|
|
|
|
} // namespace udpscope
|
|
|
|
#endif // UDPSCOPE_SETTINGS_HPP
|