99 lines
3.4 KiB
C++
99 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <optional>
|
|
#include <set>
|
|
#include <string>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
#include "imgui.h"
|
|
#include "imgui_internal.h"
|
|
#include "tools/cabana/core/observable.h"
|
|
#include "tools/cabana/dbc/dbcmanager.h"
|
|
#include "tools/cabana/streams/abstractstream.h"
|
|
|
|
|
|
struct BinaryIndex {
|
|
int row = -1;
|
|
int column = -1;
|
|
bool isValid() const { return row >= 0 && column >= 0; }
|
|
bool operator==(const BinaryIndex &o) const { return row == o.row && column == o.column; }
|
|
bool operator<(const BinaryIndex &o) const { return std::tie(row, column) < std::tie(o.row, o.column); }
|
|
};
|
|
|
|
class BinaryView {
|
|
public:
|
|
static constexpr int COLUMN_COUNT = 9;
|
|
static constexpr int HEX_COLUMN = 8;
|
|
|
|
BinaryView();
|
|
void setMessage(const MessageId &message_id);
|
|
void highlight(const cabana::Signal *sig);
|
|
std::set<const cabana::Signal *> getOverlappingSignals() const;
|
|
void updateState();
|
|
|
|
void draw();
|
|
ImVec2 minimumSizeHint() const;
|
|
void setHeatmapLiveMode(bool live) { heatmap_live_mode_ = live; updateState(); }
|
|
std::string whatsThis() const;
|
|
|
|
Observable<const cabana::Signal *> signalClicked;
|
|
Observable<const cabana::Signal *> signalHovered;
|
|
Observable<const cabana::Signal *, cabana::Signal &> editSignal;
|
|
Observable<const MessageId &, const cabana::Signal *, bool, bool> showChart;
|
|
|
|
private:
|
|
struct Cell {
|
|
CabanaColor bg_color = CabanaColor(102, 86, 169, 255);
|
|
bool is_msb = false;
|
|
bool is_lsb = false;
|
|
uint8_t val;
|
|
std::vector<const cabana::Signal *> sigs;
|
|
bool valid = false;
|
|
};
|
|
|
|
void refresh();
|
|
void setCell(int row, int col, uint8_t val, const CabanaColor &color);
|
|
const std::vector<std::array<uint32_t, 8>> &bitFlipChanges(size_t msg_size);
|
|
Cell &cellAt(const BinaryIndex &index) { return cells_[index.row * COLUMN_COUNT + index.column]; }
|
|
const Cell &cellAt(const BinaryIndex &index) const { return cells_[index.row * COLUMN_COUNT + index.column]; }
|
|
|
|
void addShortcuts();
|
|
std::tuple<int, int, bool> getSelection(BinaryIndex index);
|
|
void setSelection();
|
|
void handleMousePress(const ImVec2 &pos);
|
|
void handleMouseMove(const ImVec2 &pos);
|
|
void handleMouseRelease(const ImVec2 &pos);
|
|
void highlightPosition(const ImVec2 &pt);
|
|
BinaryIndex indexAt(const ImVec2 &pos) const;
|
|
ImRect visualRect(const BinaryIndex &index) const;
|
|
bool hasSelection() const { return !selection_.empty(); }
|
|
bool isSelected(const BinaryIndex &index) const { return selection_.count(index) > 0; }
|
|
|
|
void paintCell(ImDrawList *painter, const ImRect &rect, const BinaryIndex &index) const;
|
|
bool hasSignal(const BinaryIndex &index, int dx, int dy, const cabana::Signal *sig) const;
|
|
void drawSignalCell(ImDrawList *painter, const ImRect &rect, const BinaryIndex &index, const cabana::Signal *sig) const;
|
|
|
|
MessageId msg_id_;
|
|
std::vector<Cell> cells_;
|
|
int row_count_ = 0;
|
|
bool heatmap_live_mode_ = true;
|
|
struct BitFlipTracker {
|
|
std::optional<std::pair<double, double>> time_range;
|
|
std::vector<std::array<uint32_t, 8>> flip_counts;
|
|
} bit_flip_tracker_;
|
|
|
|
BinaryIndex anchor_index_;
|
|
ImVec2 last_mouse_pos_{-1, -1};
|
|
bool is_message_active_ = false;
|
|
const cabana::Signal *resize_sig_ = nullptr;
|
|
const cabana::Signal *hovered_sig_ = nullptr;
|
|
std::set<BinaryIndex> selection_;
|
|
ImVec2 grid_pos_;
|
|
float column_width_ = 0;
|
|
bool under_mouse_ = false;
|
|
bool scroll_to_top_ = false;
|
|
Connections connections_;
|
|
};
|