130 lines
4.9 KiB
C++
130 lines
4.9 KiB
C++
#pragma once
|
||
|
||
#include "config.h"
|
||
#include "source.h"
|
||
#include "trigger_engine.h"
|
||
#include <memory>
|
||
#include <mutex>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
struct GLFWwindow;
|
||
struct ImFont;
|
||
|
||
/**
|
||
* ImGui + ImPlot renderer.
|
||
*
|
||
* Features:
|
||
* - Multiple sources, signal sidebar with colour/style controls
|
||
* - 8 plot grid layouts (1×1 … 4×1, 1×2 … 1×4, 2×2)
|
||
* - Resizable sidebar via drag-splitter
|
||
* - Live scrolling, pause/zoom, dual A/B cursors with ΔT
|
||
* - Trigger: any signal, edge, pre/post window, single/normal modes
|
||
* - Per-source statistics panel
|
||
* - Polished dark theme with Inter + JetBrains Mono fonts
|
||
*/
|
||
class Renderer {
|
||
public:
|
||
explicit Renderer(const AppConfig& cfg);
|
||
~Renderer();
|
||
|
||
bool init();
|
||
void run();
|
||
|
||
void add_source(const std::string& label,
|
||
const std::string& host, uint16_t port,
|
||
const std::string& multicast_group = "",
|
||
uint16_t data_port = 0);
|
||
|
||
private:
|
||
// ── Frame ─────────────────────────────────────────────────────────
|
||
void render_frame();
|
||
|
||
// ── Style / fonts ─────────────────────────────────────────────────
|
||
void apply_dark_style();
|
||
void apply_implot_style();
|
||
void load_fonts();
|
||
|
||
// ── UI panels ─────────────────────────────────────────────────────
|
||
void draw_toolbar();
|
||
void draw_sidebar();
|
||
void draw_layout_popup(); // called from toolbar
|
||
void draw_plots(float w, float h);
|
||
void draw_single_plot(int plot_id, float w, float h);
|
||
void draw_trigger_panel();
|
||
void draw_stats_panel();
|
||
void draw_add_source_modal();
|
||
void draw_signal_style_popup();
|
||
|
||
// ── Helpers ───────────────────────────────────────────────────────
|
||
double compute_latest_time() const;
|
||
void poll_trigger();
|
||
|
||
// ── Configuration ─────────────────────────────────────────────────
|
||
AppConfig cfg_;
|
||
|
||
// ── Window / fonts ────────────────────────────────────────────────
|
||
GLFWwindow* window_ = nullptr;
|
||
ImFont* font_ui_ = nullptr;
|
||
ImFont* font_mono_= nullptr;
|
||
|
||
// ── Sources ───────────────────────────────────────────────────────
|
||
mutable std::mutex sources_mutex_;
|
||
std::vector<std::shared_ptr<Source>> sources_;
|
||
|
||
// ── Global UI state ───────────────────────────────────────────────
|
||
bool paused_ = false;
|
||
bool live_mode_ = true;
|
||
double window_sec_= 5.0;
|
||
double view_t_max_= 0.0;
|
||
|
||
public:
|
||
enum class Layout {
|
||
L1x1, L1x2, L1x3, L1x4,
|
||
L2x1, L2x2, L3x1, L4x1
|
||
};
|
||
|
||
private:
|
||
Layout layout_ = Layout::L1x1;
|
||
|
||
// Resizable sidebar
|
||
float sidebar_w_ = 240.f;
|
||
|
||
// Panel visibility toggles
|
||
bool show_trigger_ = false;
|
||
bool show_stats_ = false;
|
||
|
||
// ── Cursor state ──────────────────────────────────────────────────
|
||
bool cursor_a_active_ = false;
|
||
bool cursor_b_active_ = false;
|
||
double cursor_a_time_ = 0.0;
|
||
double cursor_b_time_ = 0.0;
|
||
|
||
// ── Trigger state ─────────────────────────────────────────────────
|
||
TriggerEngine trig_engine_;
|
||
int trig_src_idx_ = 0;
|
||
int trig_sig_idx_ = 0;
|
||
bool trig_show_capture_ = false;
|
||
|
||
std::vector<double> cap_t_, cap_v_;
|
||
size_t trig_last_written_ = 0;
|
||
|
||
// Trigger controls (UI state)
|
||
int trig_edge_sel_ = 0;
|
||
int trig_mode_sel_ = 0;
|
||
float trig_threshold_ = 0.f;
|
||
float trig_pre_sec_ = 0.01f;
|
||
float trig_post_sec_ = 0.09f;
|
||
|
||
// ── Popups ────────────────────────────────────────────────────────
|
||
bool open_add_source_modal_ = false;
|
||
char new_label_[128] = {};
|
||
char new_host_ [256] = {};
|
||
int new_port_ = 44500;
|
||
char new_mcast_group_[64] = {}; // "" = unicast
|
||
int new_data_port_ = 0; // 0 = port+1
|
||
|
||
int style_src_idx_ = -1;
|
||
int style_sig_idx_ = -1;
|
||
};
|