Implemented client datasource
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
* The trigger runs in the C++ StreamHub: this panel only edits the config
|
||||
* (signal/edge/threshold/window/pre%/mode), sends setTrigger + arm/disarm/
|
||||
* rearm/trigStop commands, and reflects the hub triggerState broadcasts.
|
||||
*
|
||||
* Single-row compact layout: all controls fit on one line on a ≥1280 px window;
|
||||
* ImGui wraps naturally on narrower screens without a scrollbar.
|
||||
*/
|
||||
|
||||
#include "TriggerPanel.h"
|
||||
@@ -22,12 +25,10 @@ namespace StreamHubClient {
|
||||
|
||||
/* Window presets (mirrors the web UI: 100 µs .. 10 s) */
|
||||
static const double kWinVals[] = {1e-4, 1e-3, 1e-2, 1e-1, 1.0, 10.0};
|
||||
static const char* kWinLabels[] = {"100 µs", "1 ms", "10 ms", "100 ms", "1 s", "10 s"};
|
||||
static const char* kWinLabels[] = {"100 us", "1 ms", "10 ms", "100 ms", "1 s", "10 s"};
|
||||
static const int kNumWins = 6;
|
||||
|
||||
static const char* kEdgeLabels[] = {ICON_FA_ARROW_TREND_UP " Rising",
|
||||
ICON_FA_ARROW_TREND_DOWN " Falling",
|
||||
ICON_FA_ARROWS_UP_DOWN " Both"};
|
||||
static const char* kEdgeLabels[] = {"Rising", "Falling", "Both"};
|
||||
static const char* kEdgeWire[] = {"rising", "falling", "both"};
|
||||
|
||||
/* Send the current config to the hub. */
|
||||
@@ -44,20 +45,14 @@ void RenderTriggerPanel(App& app) {
|
||||
auto& trig = app.trigger();
|
||||
auto& sources = app.sources();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.15f, 0.15f, 0.20f, 1.f));
|
||||
ImGui::BeginChild("##trigbar", ImVec2(0.f, 90.f), true);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.f, 4.f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4.f, 4.f));
|
||||
|
||||
bool cfgChanged = false;
|
||||
|
||||
/* ── Signal selector (full keys "src:sig") ─────────────────────────── *
|
||||
* Vector signals are flattened time-series on the hub: one key per
|
||||
* signal; the trigger engine checks every decoded sample of it. */
|
||||
ImGui::SetNextItemWidth(180.f);
|
||||
if (ImGui::BeginCombo("Signal##trig", trig.signalKey.empty()
|
||||
? "<select>" : trig.signalKey.c_str())) {
|
||||
/* ── Signal selector ──────────────────────────────────────────────── */
|
||||
ImGui::SetNextItemWidth(150.f);
|
||||
if (ImGui::BeginCombo("##trigsig", trig.signalKey.empty()
|
||||
? "<signal>" : trig.signalKey.c_str())) {
|
||||
for (const auto& src : sources) {
|
||||
for (const auto& sig : src.signals) {
|
||||
char key[192];
|
||||
@@ -76,14 +71,14 @@ void RenderTriggerPanel(App& app) {
|
||||
ImGui::SameLine();
|
||||
|
||||
/* ── Edge ─────────────────────────────────────────────────────────── */
|
||||
ImGui::SetNextItemWidth(95.f);
|
||||
if (ImGui::Combo("Edge##trig", &trig.edge, kEdgeLabels, 3)) {
|
||||
ImGui::SetNextItemWidth(70.f);
|
||||
if (ImGui::Combo("##trigedge", &trig.edge, kEdgeLabels, 3)) {
|
||||
cfgChanged = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
/* ── Threshold ───────────────────────────────────────────────────── */
|
||||
ImGui::SetNextItemWidth(80.f);
|
||||
ImGui::SetNextItemWidth(65.f);
|
||||
if (ImGui::InputDouble("Thr##trig", &trig.threshold, 0.0, 0.0, "%.4g",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
cfgChanged = true;
|
||||
@@ -97,7 +92,7 @@ void RenderTriggerPanel(App& app) {
|
||||
winIdx = w; break;
|
||||
}
|
||||
}
|
||||
ImGui::SetNextItemWidth(85.f);
|
||||
ImGui::SetNextItemWidth(75.f);
|
||||
if (ImGui::Combo("Win##trig", &winIdx, kWinLabels, kNumWins)) {
|
||||
trig.windowSec = kWinVals[winIdx];
|
||||
cfgChanged = true;
|
||||
@@ -105,24 +100,21 @@ void RenderTriggerPanel(App& app) {
|
||||
ImGui::SameLine();
|
||||
|
||||
/* ── Pre-trigger % ───────────────────────────────────────────────── */
|
||||
ImGui::SetNextItemWidth(100.f);
|
||||
ImGui::SetNextItemWidth(70.f);
|
||||
float preP = static_cast<float>(trig.prePercent);
|
||||
if (ImGui::SliderFloat("Pre%##trig", &preP, 0.f, 100.f, "%.0f%%")) {
|
||||
if (ImGui::SliderFloat("Pre##trig", &preP, 0.f, 100.f, "%.0f%%")) {
|
||||
trig.prePercent = static_cast<double>(preP);
|
||||
}
|
||||
if (ImGui::IsItemDeactivatedAfterEdit()) { cfgChanged = true; }
|
||||
ImGui::SameLine();
|
||||
|
||||
/* ── Mode ────────────────────────────────────────────────────────── */
|
||||
ImGui::TextUnformatted("Mode:");
|
||||
ImGui::SameLine();
|
||||
int singleInt = trig.single ? 1 : 0;
|
||||
if (ImGui::RadioButton("Normal", &singleInt, 0)) { cfgChanged = true; }
|
||||
if (ImGui::RadioButton("Norm##trig", &singleInt, 0)) { cfgChanged = true; }
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Single", &singleInt, 1)) { cfgChanged = true; }
|
||||
if (ImGui::RadioButton("1x##trig", &singleInt, 1)) { cfgChanged = true; }
|
||||
trig.single = (singleInt != 0);
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::SameLine(0.f, 10.f);
|
||||
|
||||
/* ── Status badge ────────────────────────────────────────────────── */
|
||||
ImVec4 badgeColor;
|
||||
@@ -132,44 +124,38 @@ void RenderTriggerPanel(App& app) {
|
||||
else if (trig.status == "triggered") { badgeColor = ImVec4(0.2f,0.9f,0.3f,1.f); badgeText = "TRIGGERED"; }
|
||||
else { badgeColor = ImVec4(0.6f,0.6f,0.6f,1.f); badgeText = "IDLE"; }
|
||||
ImGui::TextColored(badgeColor, "[%s]", badgeText);
|
||||
if (trig.hasTrigTime &&
|
||||
(trig.status == "collecting" || trig.status == "triggered")) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("t=%.6f", trig.trigTime);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
/* ── Arm / Disarm / Rearm / Stop ─────────────────────────────────── */
|
||||
/* ── Arm / Disarm / Stop ────────────────────────────────────────── */
|
||||
bool canArm = !trig.signalKey.empty();
|
||||
if (!canArm) { ImGui::BeginDisabled(); }
|
||||
if (ImGui::Button(ICON_FA_BOLT " Arm")) {
|
||||
if (ImGui::SmallButton(ICON_FA_BOLT " Arm")) {
|
||||
sendTrigConfig(app);
|
||||
app.ws().sendText(BuildArm());
|
||||
}
|
||||
if (!canArm) { ImGui::EndDisabled(); }
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Disarm")) {
|
||||
if (ImGui::SmallButton("Disarm")) {
|
||||
app.ws().sendText(BuildDisarm());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
if (trig.single && trig.status == "triggered") {
|
||||
if (ImGui::Button("Rearm")) {
|
||||
app.ws().sendText(BuildRearm());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (!trig.single) {
|
||||
if (ImGui::Button(trig.stopped ? ICON_FA_PLAY " Run" : ICON_FA_STOP " Stop")) {
|
||||
if (ImGui::SmallButton(trig.stopped ? ICON_FA_PLAY " Run" : ICON_FA_STOP " Stop")) {
|
||||
trig.stopped = !trig.stopped;
|
||||
app.ws().sendText(BuildTrigStop(trig.stopped));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
/* Trigger time readout (inline) */
|
||||
if (trig.hasTrigTime &&
|
||||
(trig.status == "collecting" || trig.status == "triggered")) {
|
||||
ImGui::TextDisabled("t=%.6f", trig.trigTime);
|
||||
} else {
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
/* Config edits while armed take effect immediately on the hub */
|
||||
if (cfgChanged && !trig.signalKey.empty()) {
|
||||
@@ -177,7 +163,6 @@ void RenderTriggerPanel(App& app) {
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::EndChild();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user