| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- using System.ComponentModel;
- namespace Terminal.Gui.ViewBase;
- /// <summary>
- /// INTERNAL: Manages the logic for handling a "mouse held down" state on a View. It is used to
- /// repeatedly trigger an action (via events) while the mouse button is held down, such as for auto-repeat in
- /// scrollbars or buttons.
- /// </summary>
- internal class MouseHeldDown : IMouseHeldDown
- {
- public MouseHeldDown (View host, ITimedEvents? timedEvents, IMouseGrabHandler? mouseGrabber)
- {
- _mouseGrabView = host;
- _timedEvents = timedEvents;
- _mouseGrabber = mouseGrabber;
- _smoothTimeout = new (TimeSpan.FromMilliseconds (500), TimeSpan.FromMilliseconds (50), 0.5, TickWhileMouseIsHeldDown);
- }
- private readonly View _mouseGrabView;
- private readonly ITimedEvents? _timedEvents;
- private readonly IMouseGrabHandler? _mouseGrabber;
- private readonly SmoothAcceleratingTimeout _smoothTimeout;
- private bool _isDown;
- private object? _timeout;
- public event EventHandler<CancelEventArgs>? MouseIsHeldDownTick;
- public void Start ()
- {
- if (_isDown)
- {
- return;
- }
- _isDown = true;
- _mouseGrabber?.GrabMouse (_mouseGrabView);
- // Then periodic ticks
- _timeout = _timedEvents?.Add (_smoothTimeout);
- }
- public void Stop ()
- {
- _smoothTimeout.Reset ();
- if (_mouseGrabber?.MouseGrabView == _mouseGrabView)
- {
- _mouseGrabber?.UngrabMouse ();
- }
- if (_timeout != null)
- {
- _timedEvents?.Remove (_timeout);
- }
- _mouseGrabView.MouseState = MouseState.None;
- _isDown = false;
- }
- public void Dispose ()
- {
- if (_mouseGrabber?.MouseGrabView == _mouseGrabView)
- {
- Stop ();
- }
- }
- protected virtual bool OnMouseIsHeldDownTick (CancelEventArgs eventArgs) { return false; }
- private bool RaiseMouseIsHeldDownTick ()
- {
- CancelEventArgs args = new ();
- args.Cancel = OnMouseIsHeldDownTick (args) || args.Cancel;
- if (!args.Cancel && MouseIsHeldDownTick is { })
- {
- MouseIsHeldDownTick?.Invoke (this, args);
- }
- // User event cancelled the mouse held down status so
- // stop the currently running operation.
- if (args.Cancel)
- {
- Stop ();
- }
- return args.Cancel;
- }
- private bool TickWhileMouseIsHeldDown ()
- {
- Logging.Debug ("Raising TickWhileMouseIsHeldDown...");
- if (_isDown)
- {
- _smoothTimeout.AdvanceStage ();
- RaiseMouseIsHeldDownTick ();
- }
- else
- {
- _smoothTimeout.Reset ();
- Stop ();
- }
- return _isDown;
- }
- }
|