source: capability panels as side-stack pages, with a probe for the path
This commit is contained in:
1 parent
79c33b25c5
commit
5cee00aaee
6 files changed
+209
-3
No files matched your search
@@ -6,6 +6,8 @@
|
||||
// automated check, and they are code of their own -- a third of what used to be `ui.cpp` -- so they
|
||||
// live in a translation unit of their own.
|
||||
|
||||
#include "source/probe_source.hpp"
|
||||
#include "source/registry.hpp"
|
||||
#include "ui_app.hpp"
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -1887,6 +1889,97 @@ gboolean side_tab_probe(gpointer user) {
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::uint64_t g_source_kinds_before = 0;
|
||||
}
|
||||
|
||||
/// Phase two: the command the Poke button posted must have been run by `poll()` on the producer.
|
||||
gboolean source_kinds_probe_report(gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
if (a->window == nullptr) return G_SOURCE_REMOVE;
|
||||
const ProbeSource* src = a->acq != nullptr ? dynamic_cast<const ProbeSource*>(a->acq->source())
|
||||
: nullptr;
|
||||
const std::uint64_t after = src != nullptr ? src->commands_applied() : 0;
|
||||
std::fprintf(stderr, "[source-kinds] command: before=%" G_GUINT64_FORMAT " after=%" G_GUINT64_FORMAT
|
||||
" drained=%d\n",
|
||||
g_source_kinds_before, after, after == g_source_kinds_before + 1 ? 1 : 0);
|
||||
std::fflush(stderr);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/// What the registry offers and what a source kind brings: the kinds, each config form's
|
||||
/// round trip, the panel page (insensitive while disconnected, still present), and a posted command.
|
||||
gboolean source_kinds_probe(gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
if (a->window == nullptr) return G_SOURCE_REMOVE;
|
||||
|
||||
std::string ids;
|
||||
for (const SourceKind* k : kinds()) ids += (ids.empty() ? "" : ",") + k->id();
|
||||
std::fprintf(stderr, "[source-kinds] kinds=%s\n", ids.c_str());
|
||||
|
||||
// Each kind's form must hand back what it was given.
|
||||
const auto sample = [](const std::string& id) {
|
||||
SourceConfig c;
|
||||
if (id == "udps") {
|
||||
c.set("server", "10.0.0.5");
|
||||
c.set("port", "9001");
|
||||
c.set("multicast", "239.1.2.3");
|
||||
c.set("interface", "10.0.0.9");
|
||||
} else if (id == "probe") {
|
||||
c.set("rate", "750");
|
||||
}
|
||||
return c;
|
||||
};
|
||||
for (const SourceKind* k : kinds()) {
|
||||
ConfigForm f = k->make_config_form();
|
||||
const SourceConfig in = sample(k->id());
|
||||
f.write(in);
|
||||
const SourceConfig out = f.read();
|
||||
bool same = !in.empty();
|
||||
for (const auto& kv : in.items()) same = same && out.get(kv.first) == kv.second;
|
||||
std::fprintf(stderr, "[source-kinds] form %s: round_trip=%d valid=%d\n", k->id().c_str(),
|
||||
same ? 1 : 0, f.valid() ? 1 : 0);
|
||||
// The rows were never parented; sink and release them so the form leaves nothing behind.
|
||||
for (GtkWidget* row : f.rows) {
|
||||
g_object_ref_sink(row);
|
||||
g_object_unref(row);
|
||||
}
|
||||
}
|
||||
|
||||
// The panel page: built, insensitive while disconnected, present either way.
|
||||
const SourcePanelPage* page = a->source_panels.empty() ? nullptr : &a->source_panels.front();
|
||||
const auto report = [&](const char* state) {
|
||||
const bool present =
|
||||
page != nullptr && a->side_stack != nullptr &&
|
||||
adw_view_stack_get_child_by_name(ADW_VIEW_STACK(a->side_stack), page->name.c_str()) !=
|
||||
nullptr;
|
||||
std::fprintf(stderr, "[source-kinds] panel %s: panels=%zu present=%d sensitive=%d\n", state,
|
||||
a->source_panels.size(), present ? 1 : 0,
|
||||
page != nullptr && gtk_widget_get_sensitive(page->content) ? 1 : 0);
|
||||
};
|
||||
apply_source_panels(*a, false);
|
||||
report("disconnected");
|
||||
apply_source_panels(*a, true);
|
||||
report("connected");
|
||||
|
||||
// The probe kind has no datagrams, so the packet-capture button stays disabled, and is still there.
|
||||
std::fprintf(stderr, "[source-kinds] capture button: present=%d sensitive=%d\n",
|
||||
a->capture_button != nullptr ? 1 : 0,
|
||||
a->capture_button != nullptr && gtk_widget_get_sensitive(a->capture_button) ? 1 : 0);
|
||||
|
||||
// Click the panel's button: it posts a command, and a later `poll()` runs it.
|
||||
ProbeSource* src = a->acq != nullptr ? dynamic_cast<ProbeSource*>(a->acq->source()) : nullptr;
|
||||
g_source_kinds_before = src != nullptr ? src->commands_applied() : 0;
|
||||
if (page != nullptr) {
|
||||
if (GtkWidget* poke = gtk_widget_get_last_child(page->content)) {
|
||||
g_signal_emit_by_name(poke, "clicked");
|
||||
}
|
||||
}
|
||||
std::fflush(stderr);
|
||||
g_timeout_add(500, source_kinds_probe_report, a);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gboolean pan_probe(gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
if (a->window == nullptr || a->rows->row_count() <= 0) return G_SOURCE_REMOVE;
|
||||
|
||||
Reference in new issue
Block a user