mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-31 02:53:58 +08:00
cabana: improve heatmap readability (#38955)
* cabana: improve heatmap readability * cabana: use shared colors for the heatmap * cabana: brighten dark theme text
This commit is contained in:
@@ -12,7 +12,7 @@ namespace fs = std::filesystem;
|
||||
namespace {
|
||||
|
||||
constexpr Palette DARK_PALETTE = {
|
||||
.text = rgb(0xdddddd), .text_disabled = rgb(0x7b7b7b), .text_selected = rgb(0xdddddd),
|
||||
.text = rgb(0xffffff), .text_disabled = rgb(0x7b7b7b), .text_selected = rgb(0xffffff),
|
||||
.window = rgb(0x353535), .surface = rgb(0x2b2c2d),
|
||||
.frame = rgb(0x2b2c2d), .frame_hovered = rgb(0x363738), .frame_active = rgb(0x434445),
|
||||
.button = rgb(0x3f4041), .button_hovered = rgb(0x525354), .button_active = rgb(0x303132),
|
||||
@@ -22,8 +22,6 @@ constexpr Palette DARK_PALETTE = {
|
||||
.slider_track = rgb(0x7b7b7b),
|
||||
.tab = rgb(0x2c2c2c), .tab_hovered = rgb(0x444647), .tab_selected = rgb(0x393a3b), .table_header = rgb(0x3f4041),
|
||||
.grid = rgb(0xdddddd, 50.0f / 255.0f), .badge = rgb(0x808080),
|
||||
.bit_background = rgb(0xffffff, 20.0f / 255.0f),
|
||||
.heatmap_signal_alpha = 70.0, .heatmap_bit_alpha = 28.0, .heatmap_gamma = 0.6,
|
||||
.sparkline_saturation = 1.0f, .sparkline_value = 1.0f,
|
||||
};
|
||||
|
||||
@@ -38,8 +36,6 @@ constexpr Palette LIGHT_PALETTE = {
|
||||
.slider_track = rgb(0xd0d0d0),
|
||||
.tab = rgb(0xe5e5e5), .tab_hovered = rgb(0xefefef), .tab_selected = rgb(0xffffff), .table_header = rgb(0xefefef),
|
||||
.grid = rgb(0x000000, 50.0f / 255.0f), .badge = rgb(0xa0a0a4),
|
||||
.bit_background = rgb(0xffffff, 0.0f),
|
||||
.heatmap_signal_alpha = 25.0, .heatmap_bit_alpha = 10.0, .heatmap_gamma = 1.0,
|
||||
.sparkline_saturation = 2.0f, .sparkline_value = 0.7f,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ struct Palette {
|
||||
ImVec4 tab, tab_hovered, tab_selected, table_header;
|
||||
ImVec4 grid;
|
||||
ImVec4 badge; // the fill behind the time labels drawn over a chart
|
||||
ImVec4 bit_background; // overlay beneath heatmap bits without a signal
|
||||
double heatmap_signal_alpha, heatmap_bit_alpha, heatmap_gamma;
|
||||
float sparkline_saturation, sparkline_value; // HSV multipliers for signal colors
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
namespace {
|
||||
|
||||
const int CELL_HEIGHT = 36;
|
||||
const float CELL_FONT_SIZE = UI_FONT_SIZE + 2.0f;
|
||||
const float SMALL_FONT_SIZE = 10.0f; // Inter needs 10 px for a 7 px cap height
|
||||
const int VERTICAL_HEADER_WIDTH = 30;
|
||||
inline int get_bit_pos(const BinaryIndex &index) { return flipBitPos(index.row * 8 + index.column); }
|
||||
@@ -122,9 +123,9 @@ void BinaryView::addShortcuts() {
|
||||
}
|
||||
|
||||
ImVec2 BinaryView::minimumSizeHint() const {
|
||||
// widest fixed-font glyph plus the header margins
|
||||
pushMonoFont();
|
||||
const float min_section_size = ImGui::CalcTextSize("W").x + 8.0f;
|
||||
// Match the enlarged hex font when reserving space for narrow panels.
|
||||
pushMonoFont(CELL_FONT_SIZE);
|
||||
const float min_section_size = std::ceil(ImGui::CalcTextSize("FF").x) + 10.0f;
|
||||
popMonoFont();
|
||||
return {(min_section_size + 1) * 9 + VERTICAL_HEADER_WIDTH + 2,
|
||||
static_cast<float>(CELL_HEIGHT * std::min(row_count_, 10) + 2)};
|
||||
@@ -306,17 +307,20 @@ void BinaryView::draw() {
|
||||
|
||||
const int rows = row_count_;
|
||||
// Keep hex bytes readable in narrow panels by scrolling instead of shrinking further.
|
||||
pushMonoFont(CELL_FONT_SIZE);
|
||||
const float min_column_width = std::ceil(ImGui::CalcTextSize("FF").x) + 10.0f;
|
||||
popMonoFont();
|
||||
const float width = std::max(ImGui::GetContentRegionAvail().x, VERTICAL_HEADER_WIDTH + min_column_width * COLUMN_COUNT);
|
||||
column_width_ = std::max(min_column_width, (width - VERTICAL_HEADER_WIDTH) / COLUMN_COUNT);
|
||||
grid_pos_ = ImGui::GetCursorScreenPos();
|
||||
ImGui::InvisibleButton("##binary_view", ImVec2(std::max(width, 1.0f), std::max(static_cast<float>(rows * CELL_HEIGHT), 1.0f)));
|
||||
ImDrawList *painter = ImGui::GetWindowDrawList();
|
||||
painter->AddRectFilled(grid_pos_, ImVec2(grid_pos_.x + width, grid_pos_.y + rows * CELL_HEIGHT), paletteBase());
|
||||
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
const ImRect r(grid_pos_.x, grid_pos_.y + row * CELL_HEIGHT, grid_pos_.x + VERTICAL_HEADER_WIDTH, grid_pos_.y + (row + 1) * CELL_HEIGHT);
|
||||
painter->AddRectFilled(r.Min, r.Max, ImGui::GetColorU32(ImGuiCol_WindowBg)); // plain header background
|
||||
drawText(painter, r, std::to_string(row).c_str(), ImGui::GetColorU32(ImGuiCol_Text));
|
||||
drawText(painter, r, std::to_string(row).c_str(), paletteText(true));
|
||||
}
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int column = 0; column < COLUMN_COUNT; ++column) {
|
||||
@@ -381,11 +385,10 @@ void BinaryView::updateState() {
|
||||
uint32_t max_byte_flip_count = 1;
|
||||
for (auto count : bit_flip_tracker_.counts.bytes) max_byte_flip_count = std::max(max_byte_flip_count, count);
|
||||
|
||||
const Palette &p = palette();
|
||||
// Use the same logarithmic intensity mapping in both themes.
|
||||
const double max_alpha = 255.0;
|
||||
const double min_alpha_with_signal = p.heatmap_signal_alpha; // Base alpha for small flip counts
|
||||
const double min_alpha_no_signal = p.heatmap_bit_alpha; // Base alpha for small flip counts for no signal bits
|
||||
const double alpha_gamma = p.heatmap_gamma;
|
||||
const double min_alpha_with_signal = 25.0; // Base alpha for small flip counts
|
||||
const double min_alpha_no_signal = 10.0; // Base alpha for small flip counts for no signal bits
|
||||
const double log_factor = 1.0 + 0.2;
|
||||
const double log_scaler = max_alpha / log2(1.0 + log_factor * max_bit_flip_count);
|
||||
|
||||
@@ -398,7 +401,6 @@ void BinaryView::updateState() {
|
||||
uint32_t flip_count = bit_flips[i][j];
|
||||
if (flip_count > 0) {
|
||||
double normalized_alpha = log2(1.0 + flip_count * log_factor) * log_scaler;
|
||||
normalized_alpha = max_alpha * std::pow(std::clamp(normalized_alpha / max_alpha, 0.0, 1.0), alpha_gamma);
|
||||
double min_alpha = item.sigs.empty() ? min_alpha_no_signal : min_alpha_with_signal;
|
||||
alpha = std::clamp(normalized_alpha, min_alpha, max_alpha);
|
||||
}
|
||||
@@ -411,7 +413,7 @@ void BinaryView::updateState() {
|
||||
if (!heatmap_live_mode_) {
|
||||
const auto count = bit_flip_tracker_.counts.bytes[i];
|
||||
const double intensity = std::log2(1.0 + count * log_factor) / std::log2(1.0 + max_byte_flip_count * log_factor);
|
||||
byte_color = CabanaColor(102, 86, 169, static_cast<uint8_t>(max_alpha * std::pow(intensity, alpha_gamma)));
|
||||
byte_color = CabanaColor(102, 86, 169, static_cast<uint8_t>(max_alpha * intensity));
|
||||
}
|
||||
setCell(i, HEX_COLUMN, binary[i], byte_color);
|
||||
}
|
||||
@@ -441,12 +443,12 @@ bool BinaryView::hasSignal(const BinaryIndex &index, int dx, int dy, const caban
|
||||
void BinaryView::paintCell(ImDrawList *painter, const ImRect &rect, const BinaryIndex &index) const {
|
||||
auto item = &cellAt(index);
|
||||
ImFont *font = ImGui::GetFont();
|
||||
float font_size = ImGui::GetFontSize();
|
||||
ImU32 pen = paletteText(is_message_active_);
|
||||
float font_size = CELL_FONT_SIZE;
|
||||
ImU32 pen = paletteText(true);
|
||||
|
||||
if (index.column == HEX_COLUMN) {
|
||||
if (item->valid) {
|
||||
pushMonoFont();
|
||||
pushMonoFont(CELL_FONT_SIZE);
|
||||
font = ImGui::GetFont();
|
||||
font_size = ImGui::GetFontSize();
|
||||
popMonoFont();
|
||||
@@ -454,7 +456,7 @@ void BinaryView::paintCell(ImDrawList *painter, const ImRect &rect, const Binary
|
||||
}
|
||||
} else if (isSelected(index)) {
|
||||
painter->AddRectFilled(rect.Min, rect.Max, resize_sig_ ? toImU32(resize_sig_->color) : paletteHighlight());
|
||||
if (resize_sig_) pen = IM_COL32_WHITE;
|
||||
pen = IM_COL32_WHITE;
|
||||
} else if (!hasSelection() || std::find(item->sigs.begin(), item->sigs.end(), resize_sig_) == item->sigs.end()) { // not resizing
|
||||
if (item->sigs.size() > 0) {
|
||||
for (auto &s : item->sigs) {
|
||||
@@ -465,7 +467,6 @@ void BinaryView::paintCell(ImDrawList *painter, const ImRect &rect, const Binary
|
||||
}
|
||||
}
|
||||
} else if (item->valid) {
|
||||
painter->AddRectFilled(rect.Min, rect.Max, ImGui::GetColorU32(palette().bit_background));
|
||||
if (item->bg_color.alpha() > 0) painter->AddRectFilled(rect.Min, rect.Max, toImU32(item->bg_color));
|
||||
}
|
||||
bool bright = std::find(item->sigs.begin(), item->sigs.end(), hovered_sig_) != item->sigs.end();
|
||||
|
||||
Reference in New Issue
Block a user