From 42f1762c565a5d1cd3cece8664be31795ab6cce5 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 25 Oct 2026 16:46:47 -0400 Subject: [PATCH] fix(desktop): keep the cut simulator moving while the plate view pans Panning invalidates the view on every mouse move, so a paint is always pending and WM_TIMER never arrives; the torch froze until the pan ended. Paints now advance the playhead from the playback clock too. Co-Authored-By: Claude Opus 5.5 --- OpenNest/Controls/CutSimulationOverlay.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/OpenNest/Controls/CutSimulationOverlay.cs b/OpenNest/Controls/CutSimulationOverlay.cs index dc91c44f..7558bca9 100644 --- a/OpenNest/Controls/CutSimulationOverlay.cs +++ b/OpenNest/Controls/CutSimulationOverlay.cs @@ -132,11 +132,21 @@ internal sealed class CutSimulationOverlay : IDisposable } private void Tick() + { + Advance(); + view.Invalidate(); + } + + // Moves the playhead by the wall time since the last advance. Paints call it too: WM_TIMER + // is only delivered when no paint is pending, so a pan's stream of repaints starves the timer. + private void Advance() { var elapsed = clock.Elapsed; clock.Restart(); - Time = time + TimeSpan.FromTicks((long)(elapsed.Ticks * Speed)); - if (simulation == null || time >= simulation.TotalTime) + var next = time + TimeSpan.FromTicks((long)(elapsed.Ticks * Speed)); + time = next > simulation.TotalTime ? simulation.TotalTime : next; + Changed?.Invoke(this, EventArgs.Empty); + if (time >= simulation.TotalTime) Pause(); } @@ -171,6 +181,8 @@ internal sealed class CutSimulationOverlay : IDisposable { if (simulation == null || simulation.Steps.Count == 0) return; + if (IsPlaying) + Advance(); var state = graphics.Save(); try