namespace MmdPdf.Services { /// /// Separates fast in-page wheel scrolling from page navigation at the edge. Momentum events /// immediately following a content scroll are ignored; after that, two standard wheel notches /// in the same direction confirm that the user intends to change pages (#205). /// internal sealed class WheelPageFlipGate { private static readonly TimeSpan MomentumQuietPeriod = TimeSpan.FromMilliseconds(250); private static readonly TimeSpan ConfirmationWindow = TimeSpan.FromMilliseconds(650); private const int ConfirmationDelta = 240; private DateTime _blockUntilUtc; private DateTime _lastEdgeWheelUtc; private int _direction; private int _accumulatedDelta; internal void NoteContentScroll(DateTime nowUtc) { _blockUntilUtc = nowUtc + MomentumQuietPeriod; ResetConfirmation(); } internal bool TryConfirm(int delta, DateTime nowUtc) { if (delta == 0 || nowUtc < _blockUntilUtc) { ResetConfirmation(); return false; } int direction = Math.Sign(delta); if (_direction != direction || nowUtc - _lastEdgeWheelUtc > ConfirmationWindow) { _direction = direction; _accumulatedDelta = 0; } _lastEdgeWheelUtc = nowUtc; _accumulatedDelta += Math.Abs(delta); if (_accumulatedDelta < ConfirmationDelta) return false; ResetConfirmation(); return true; } private void ResetConfirmation() { _lastEdgeWheelUtc = default; _direction = 0; _accumulatedDelta = 0; } } }