diff --git a/openpilot/tools/cabana/ui/theme.cc b/openpilot/tools/cabana/ui/theme.cc index 6a544ef05a..45212cb6d7 100644 --- a/openpilot/tools/cabana/ui/theme.cc +++ b/openpilot/tools/cabana/ui/theme.cc @@ -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, }; diff --git a/openpilot/tools/cabana/ui/theme.h b/openpilot/tools/cabana/ui/theme.h index e7346db6a6..0c565b55c7 100644 --- a/openpilot/tools/cabana/ui/theme.h +++ b/openpilot/tools/cabana/ui/theme.h @@ -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 }; diff --git a/openpilot/tools/cabana/ui/widgets/binaryview.cc b/openpilot/tools/cabana/ui/widgets/binaryview.cc index 0315279948..9cb1a6ad10 100644 --- a/openpilot/tools/cabana/ui/widgets/binaryview.cc +++ b/openpilot/tools/cabana/ui/widgets/binaryview.cc @@ -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(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(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(max_alpha * std::pow(intensity, alpha_gamma))); + byte_color = CabanaColor(102, 86, 169, static_cast(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();