Skip to content

Commit db03de8

Browse files
Resolved the EffectsView's long pressed issue
1 parent fa29e20 commit db03de8

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

maui/src/EffectsView/SfEffectsView.cs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ public partial class SfEffectsView : SfContentView, ITouchListener, ITapGestureL
5858

5959
bool _canRepeat;
6060

61+
#if WINDOWS
62+
// Flag to track if touch is currently pressed
63+
bool _isTouchDown;
64+
65+
// Timer for custom long press detection
66+
System.Timers.Timer? _longPressTimer;
67+
68+
// Default long press duration in milliseconds
69+
const int _longPressDuration = 500;
70+
#endif
6171
double _tempScaleFactor;
6272

6373
readonly string _rotationAnimation = "Rotation";
@@ -400,6 +410,9 @@ public SfEffectsView()
400410
{
401411
ThemeElement.InitializeThemeResources(this, "SfEffectsViewTheme");
402412
InitializeEffects();
413+
#if WINDOWS
414+
InitializeLongPressTimer();
415+
#endif
403416
this.AddGestureListener(this);
404417
this.AddTouchListener(this);
405418
}
@@ -1719,6 +1732,67 @@ void OnAnimationFinished(double value, bool completed)
17191732
}
17201733
}
17211734

1735+
#if WINDOWS
1736+
/// <summary>
1737+
/// Initialize the long press timer.
1738+
/// </summary>
1739+
void InitializeLongPressTimer()
1740+
{
1741+
// Create and configure a timer with a simple timer implementation
1742+
_longPressTimer = new System.Timers.Timer(_longPressDuration);
1743+
_longPressTimer.AutoReset = false;
1744+
_longPressTimer.Elapsed += OnLongPressTimerElapsed;
1745+
}
1746+
1747+
/// <summary>
1748+
/// Start the long press timer.
1749+
/// </summary>
1750+
/// <param name="touchPoint">The point where the touch started.</param>
1751+
void StartLongPressTimer(Point touchPoint)
1752+
{
1753+
// Store touch point and reset state
1754+
_touchDownPoint = touchPoint;
1755+
LongPressHandled = false;
1756+
1757+
// Start the timer - ensure it's stopped first
1758+
if (_longPressTimer != null)
1759+
{
1760+
_longPressTimer.Stop();
1761+
_longPressTimer.Start();
1762+
}
1763+
}
1764+
1765+
/// <summary>
1766+
/// Stop the long press timer.
1767+
/// </summary>
1768+
void StopLongPressTimer()
1769+
{
1770+
_longPressTimer?.Stop();
1771+
}
1772+
1773+
/// <summary>
1774+
/// Callback for the long press timer elapsed event.
1775+
/// </summary>
1776+
/// <param name="sender">The sender object.</param>
1777+
/// <param name="e">The event args.</param>
1778+
void OnLongPressTimerElapsed(object? sender, System.Timers.ElapsedEventArgs e)
1779+
{
1780+
// We need to dispatch back to the UI thread since timer callbacks occur on a background thread
1781+
Application.Current?.Dispatcher.Dispatch(() =>
1782+
{
1783+
// Check if touch is still active and not already handled
1784+
if (_isTouchDown && !LongPressHandled)
1785+
{
1786+
var args = new LongPressEventArgs(_touchDownPoint);
1787+
// Trigger the long press method
1788+
OnLongPress(args);
1789+
// Set handled flag to prevent multiple triggers
1790+
LongPressHandled = true;
1791+
}
1792+
});
1793+
}
1794+
#endif
1795+
17221796
#endregion
17231797

17241798
#region Override methods
@@ -1893,6 +1967,9 @@ public void OnTouch(PointerEventArgs e)
18931967
{
18941968
_touchDownPoint = e.TouchPoint;
18951969
LongPressHandled = false;
1970+
#if WINDOWS
1971+
_isTouchDown = true;
1972+
#endif
18961973

18971974
if (_rippleEffectLayer != null)
18981975
{
@@ -1909,10 +1986,19 @@ public void OnTouch(PointerEventArgs e)
19091986
{
19101987
AddEffects(TouchDownEffects, e.TouchPoint);
19111988
}
1989+
#if WINDOWS
1990+
// Start the long press timer
1991+
StartLongPressTimer(e.TouchPoint);
1992+
#endif
19121993
}
19131994

19141995
if (e.Action == PointerActions.Released)
19151996
{
1997+
#if WINDOWS
1998+
// Stop the long press timer
1999+
StopLongPressTimer();
2000+
_isTouchDown = false;
2001+
#endif
19162002
_elementBounds.X = 0;
19172003
_elementBounds.Y = 0;
19182004
_elementBounds.Height = (float)Height;
@@ -1975,6 +2061,11 @@ public void OnTouch(PointerEventArgs e)
19752061
}
19762062
else if (e.Action == PointerActions.Cancelled)
19772063
{
2064+
#if WINDOWS
2065+
// Stop the timer and reset state
2066+
StopLongPressTimer();
2067+
_isTouchDown = false;
2068+
#endif
19782069
LongPressHandled = false;
19792070
RemoveRippleEffect();
19802071
RemoveHighlightEffect();
@@ -1987,6 +2078,10 @@ public void OnTouch(PointerEventArgs e)
19872078

19882079
if (diffX >= 20 || diffY >= 20)
19892080
{
2081+
#if WINDOWS
2082+
// Cancel the long press timer since the finger has moved too much
2083+
StopLongPressTimer();
2084+
#endif
19902085
RemoveRippleEffect();
19912086
RemoveHighlightEffect();
19922087
}

0 commit comments

Comments
 (0)