cabana: stop chart tooltips over menus (#38905)

* cabana: keep chart tooltips below menus

* cabana: exclude popup menus from plot hover
This commit is contained in:
Trey Moen
2026-09-13 16:27:40 -07:00
committed by GitHub
parent c715ef4762
commit 164a3a1e30
4 changed files with 10 additions and 9 deletions
+7 -6
View File
@@ -504,13 +504,13 @@ void ChartView::draw(float width) {
updateLayout();
paint();
drawContextMenu();
// Keep the tip above the plot, but below popup menus and other windows.
ImRect visible_rect = charts_widget_->chartVisibleRect(this);
visible_rect.ClipWith(ImRect(ImVec2(layout_.rect.Min.x, layout_.plot_area.Min.y),
ImVec2(layout_.rect.Max.x, layout_.plot_area.Max.y)));
if (!drawing_ghost_ && visible_rect.GetWidth() > 0 && visible_rect.GetHeight() > 0) tip_label_.draw(visible_rect);
}
ImGui::EndChild();
// a chart scrolled out of the viewport draws no tip
ImRect visible_rect = charts_widget_->chartVisibleRect(this);
visible_rect.ClipWith(ImRect(ImVec2(layout_.rect.Min.x, layout_.plot_area.Min.y),
ImVec2(layout_.rect.Max.x, layout_.plot_area.Max.y)));
if (!drawing_ghost_ && visible_rect.GetWidth() > 0 && visible_rect.GetHeight() > 0) tip_label_.draw(visible_rect);
ImGui::PopID();
}
@@ -575,7 +575,8 @@ void ChartView::drawAxes() {
layout_.plot_area = ImRect(ImPlot::GetPlotPos(), ImPlot::GetPlotPos() + ImPlot::GetPlotSize());
// ImPlotFlags_NoInputs disables implot's own hover tracking
layout_.plot_hovered = layout_.plot_area.Contains(ImGui::GetMousePos()) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
// A popup is a descendant of the chart, but hovering its menu must not hover the plot underneath.
layout_.plot_hovered = layout_.plot_area.Contains(ImGui::GetMousePos()) && ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
drawSeries();
if (!drawing_ghost_) {
// Own plot clicks so custom scrubbing/zooming cannot also move the floating window.
@@ -551,7 +551,7 @@ void ChartsWidget::handleEvents() {
if (!value_tip_visible_) return;
// the tip is drawn on the foreground draw list, so the mouse is never "on the tip"
// The tip is drawn without an input item, so the mouse is never "on the tip".
const ImVec2 delta = ImGui::GetIO().MouseDelta;
if (!any_plot_hovered_ &&
(delta.x != 0 || delta.y != 0 || !ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows))) {
+1 -1
View File
@@ -134,7 +134,7 @@ void TipLabel::draw(const ImRect &rect) {
updateLayout();
if (!visible_) return;
ImDrawList *p = ImGui::GetForegroundDrawList();
ImDrawList *p = ImGui::GetWindowDrawList();
p->PushClipRect(area_.Min, area_.Max, true);
// filled panel with a 1px frame
p->AddRectFilled(pos_, pos_ + size_, ImGui::GetColorU32(ImGuiCol_PopupBg), ImGui::GetStyle().PopupRounding);
+1 -1
View File
@@ -20,7 +20,7 @@ public:
void showText(const ImVec2 &pt, const std::vector<TipLine> &text, const ImRect &rect);
void hide() { visible_ = false; }
bool isVisible() const { return visible_; }
void draw(const ImRect &rect); // draws the tip on the foreground draw list; call once per frame
void draw(const ImRect &rect); // call inside the owning chart window, after drawing the plot
private:
// lays the lines out from origin, drawing them when p is given; returns the size of the text block