From 98c574c2ad3ae98ea67495aaf69830be1533be4b Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Tue, 7 Apr 2026 16:19:48 -0400 Subject: [PATCH] perf: defer Path.IsVisible hit-test to hover timer callback Move the expensive per-part hit-test out of OnMouseMove and into the hoverTimer callback. The hit-test now only runs once after 1000ms of stillness, not on every mouse move event. Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest/Controls/PlateView.cs | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/OpenNest/Controls/PlateView.cs b/OpenNest/Controls/PlateView.cs index c8be6ca..5c2d691 100644 --- a/OpenNest/Controls/PlateView.cs +++ b/OpenNest/Controls/PlateView.cs @@ -102,7 +102,7 @@ namespace OpenNest.Controls redrawTimer.Elapsed += redrawTimer_Elapsed; hoverTimer = new Timer() { AutoReset = false, Interval = 1000 }; - hoverTimer.Elapsed += (s, _) => { showTooltip = true; Invalidate(); }; + hoverTimer.Elapsed += hoverTimer_Elapsed; SetStyle( ControlStyles.AllPaintingInWmPaint | @@ -356,36 +356,15 @@ namespace OpenNest.Controls if (e.Button == MouseButtons.None && actionManager.CurrentAction is ActionSelect) { - var graphPt = PointControlToGraph(e.Location); - LayoutPart hitPart = null; - for (var i = parts.Count - 1; i >= 0; --i) - { - if (parts[i].Path.GetBounds().Contains(graphPt) && - parts[i].Path.IsVisible(graphPt)) - { - hitPart = parts[i]; - break; - } - } - - if (hitPart != hoveredPart) - hoveredPart = hitPart; + hoverPoint = e.Location; + showTooltip = false; + hoverTimer.Stop(); + hoverTimer.Start(); if (hoveredPart != null) - { - hoverPoint = e.Location; - showTooltip = false; - hoverTimer.Stop(); - hoverTimer.Start(); Invalidate(); - } - else - { - hoverTimer.Stop(); - showTooltip = false; - } } - else if (hoveredPart != null) + else if (hoveredPart != null || showTooltip) { hoveredPart = null; hoverTimer.Stop(); @@ -644,6 +623,27 @@ namespace OpenNest.Controls Invalidate(); } + private void hoverTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + var graphPt = PointControlToGraph(hoverPoint); + LayoutPart hitPart = null; + for (var i = parts.Count - 1; i >= 0; --i) + { + if (parts[i].Path.GetBounds().Contains(graphPt) && + parts[i].Path.IsVisible(graphPt)) + { + hitPart = parts[i]; + break; + } + } + + hoveredPart = hitPart; + showTooltip = hitPart != null; + + if (showTooltip) + Invalidate(); + } + private void plate_PartAdded(object sender, ItemAddedEventArgs e) { if (PartAdded != null)