Implemented new C++ logic

This commit is contained in:
Martino Ferrari
2026-06-12 15:25:13 +02:00
parent 617b5bd712
commit f25bd7f08e
220 changed files with 39185 additions and 850 deletions
+105
View File
@@ -0,0 +1,105 @@
/**
* @file SourcePanel.cpp
* @brief Source browser sidebar implementation.
*/
#include "SourcePanel.h"
#include "App.h"
#include "Protocol.h"
#include "imgui.h"
#include "implot.h"
#include "Icons.h"
#include <cstdio>
#include <algorithm>
namespace StreamHubClient {
void RenderSourcePanel(App& app) {
auto& sources = app.sources();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4.f, 2.f));
if (ImGui::CollapsingHeader("Sources", ImGuiTreeNodeFlags_DefaultOpen)) {
for (int srcIdx = 0; srcIdx < static_cast<int>(sources.size()); srcIdx++) {
Source& src = sources[srcIdx];
/* State color indicator */
ImVec4 stateColor = (src.state == "connected")
? ImVec4(0.1f, 0.9f, 0.3f, 1.f)
: ImVec4(0.8f, 0.3f, 0.3f, 1.f);
ImGui::PushID(srcIdx);
ImGui::TextColored(stateColor, ICON_FA_CIRCLE);
ImGui::SameLine();
std::string treeLabel = src.label.empty() ? src.id : src.label;
bool nodeOpen = ImGui::TreeNodeEx(treeLabel.c_str(),
ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth);
/* Per-source context menu: remove */
if (ImGui::BeginPopupContextItem("##srccmenu")) {
if (ImGui::MenuItem(ICON_FA_TRASH_CAN " Remove source")) {
app.ws().sendText(BuildRemoveSource(src.id));
}
ImGui::EndPopup();
}
if (nodeOpen) {
for (int sigIdx = 0; sigIdx < static_cast<int>(src.signals.size()); sigIdx++) {
Signal& sig = src.signals[sigIdx];
ImGui::PushID(sigIdx);
/* Color swatch */
ImVec4 col = sig.color;
if (ImGui::ColorButton("##col", col,
ImGuiColorEditFlags_NoTooltip |
ImGuiColorEditFlags_NoBorder,
ImVec2(12.f, 12.f))) {
ImGui::OpenPopup("##sigcolor");
}
if (ImGui::BeginPopup("##sigcolor")) {
ImGui::ColorPicker4("Signal Color", reinterpret_cast<float*>(&sig.color),
ImGuiColorEditFlags_NoAlpha);
ImGui::EndPopup();
}
ImGui::SameLine();
/* Unit / type label */
char label[128];
if (sig.meta.numElements > 1) {
snprintf(label, sizeof(label), "%s [%u]",
sig.meta.name.c_str(), sig.meta.numElements);
} else {
snprintf(label, sizeof(label), "%s", sig.meta.name.c_str());
}
if (!sig.meta.unit.empty()) {
strncat(label, " (", sizeof(label) - strlen(label) - 1);
strncat(label, sig.meta.unit.c_str(), sizeof(label) - strlen(label) - 1);
strncat(label, ")", sizeof(label) - strlen(label) - 1);
}
ImGui::Selectable(label, false, 0, ImVec2(0, 0));
/* Drag-and-drop source: payload = (srcIdx, sigIdx) */
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
struct DragPayload { int srcIdx; int sigIdx; };
DragPayload payload{srcIdx, sigIdx};
ImGui::SetDragDropPayload("SIGNAL_REF", &payload, sizeof(payload));
ImGui::TextUnformatted(sig.meta.name.c_str());
ImGui::EndDragDropSource();
}
ImGui::PopID();
}
ImGui::TreePop();
}
ImGui::PopID();
}
}
ImGui::PopStyleVar();
}
} /* namespace StreamHubClient */