cabana: resize heatmap and prevent signal clipping (#38975)

* cabana: allow heatmap resizing without clipping

* cabana: keep outer grid lines inside the heatmap

* cabana: add a visible heatmap resize handle

* cabana: use the standard pane divider for resizing
This commit is contained in:
Trey Moen
2026-09-19 18:41:58 -07:00
committed by GitHub
parent 1b1b60ba93
commit 3b2a75a4e0
3 changed files with 22 additions and 9 deletions
@@ -348,8 +348,8 @@ void BinaryView::draw() {
const float x = std::clamp(grid_pos_.x + IM_ROUND(column * column_width_), grid_pos_.x + 0.5f, right - 0.5f);
painter->AddLine(ImVec2(x, grid_pos_.y), ImVec2(x, bottom), grid_color);
}
for (int row = 0; row <= rows; ++row) {
const float y = grid_pos_.y + row * CELL_HEIGHT;
for (int row = 0; rows > 0 && row <= rows; ++row) {
const float y = std::clamp(grid_pos_.y + row * CELL_HEIGHT, grid_pos_.y + 0.5f, bottom - 0.5f);
painter->AddLine(ImVec2(grid_pos_.x, y), ImVec2(right, y), grid_color);
}
@@ -233,16 +233,29 @@ void DetailWidget::drawTabWidget() {
page_tabs_.draw();
if (tab_widget_index_ == 0) {
if (heatmap_visible_) {
// Keep most of a short window available for signal rows.
// Allow the heatmap to grow while reserving room for signal rows.
const float handle_height = style.DockingSeparatorSize;
const float avail = ImGui::GetContentRegionAvail().y;
const float max_height = std::max(avail - style.ItemSpacing.y - SignalView::minimumHeight(), 1.0f);
const float height = std::min(binary_view_->minimumSizeHint().y, max_height);
ImGui::BeginChild("binary_view", ImVec2(0, std::max(height, 1.0f)), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar);
const float max_height = std::max(avail - handle_height - style.ItemSpacing.y * 2 - SignalView::minimumHeight(), 1.0f);
const float min_height = std::min(ImGui::GetFrameHeight(), max_height);
float height = std::clamp(heatmap_height_ < 0 ? binary_view_->minimumSizeHint().y : heatmap_height_, min_height, max_height);
ImGui::BeginChild("binary_view", ImVec2(0, height), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar);
binary_view_rect_ = ImGui::GetCurrentWindow()->Rect();
binary_view_->draw();
ImGui::EndChild();
const ImVec2 pos = ImGui::GetCursorScreenPos();
const ImVec2 size(std::max(ImGui::GetContentRegionAvail().x, 1.0f), handle_height);
const ImRect splitter(pos, ImVec2(pos.x + size.x, pos.y + size.y));
float signal_height = std::max(avail - height - handle_height - style.ItemSpacing.y * 2, SignalView::minimumHeight());
if (ImGui::SplitterBehavior(splitter, ImGui::GetID("##heatmap_resize"), ImGuiAxis_Y,
&height, &signal_height, min_height, SignalView::minimumHeight(), 4.0f)) {
heatmap_height_ = height;
}
ImGui::Dummy(size);
}
ImGui::BeginChild("signal_view", ImVec2(0, 0), ImGuiChildFlags_None,
const float signal_height = std::max(ImGui::GetContentRegionAvail().y, SignalView::minimumHeight());
ImGui::BeginChild("signal_view", ImVec2(0, signal_height), ImGuiChildFlags_None,
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
signal_view_rect_ = ImGui::GetCurrentWindow()->Rect();
signal_view_->draw();
@@ -254,8 +267,7 @@ void DetailWidget::drawTabWidget() {
void DetailWidget::draw() {
tabbar_.draw();
ImGui::BeginChild("message_content", ImVec2(0, 0), ImGuiChildFlags_AlwaysUseWindowPadding,
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
ImGui::BeginChild("message_content", ImVec2(0, 0), ImGuiChildFlags_AlwaysUseWindowPadding);
drawToolBar();
if (warning_widget_visible_) {
@@ -88,6 +88,7 @@ private:
bool action_remove_msg_enabled_ = false;
bool heatmap_live_ = true;
bool heatmap_visible_ = true;
float heatmap_height_ = -1.0f;
std::string heatmap_all_text_ = "All";
ImRect binary_view_rect_, signal_view_rect_; // child window rects of the last drawTabWidget
std::unique_ptr<LogsWidget> history_log_;