diff --git a/osu.Framework.Tests/Visual/TestCaseTooltip.cs b/osu.Framework.Tests/Visual/TestCaseTooltip.cs
index ca67cd3740..d2a8b9b7e0 100644
--- a/osu.Framework.Tests/Visual/TestCaseTooltip.cs
+++ b/osu.Framework.Tests/Visual/TestCaseTooltip.cs
@@ -150,6 +150,8 @@ private class CustomTooltipSpriteText : Container, IHasTooltip
public string TooltipText => tooltipText;
+ public double? AppearDelay => null;
+
public CustomTooltipSpriteText(string displayedText, string tooltipText)
{
this.tooltipText = tooltipText;
@@ -177,6 +179,8 @@ private class TooltipTooltipContainer : TooltipContainer, IHasTooltip
{
public string TooltipText { get; set; }
+ double? IHasTooltip.AppearDelay => null;
+
public TooltipTooltipContainer(string tooltipText)
{
TooltipText = tooltipText;
@@ -186,12 +190,16 @@ public TooltipTooltipContainer(string tooltipText)
private class TooltipTextbox : TextBox, IHasTooltip
{
public string TooltipText => Text;
+
+ public double? AppearDelay => null;
}
private class TooltipBox : Box, IHasTooltip
{
public string TooltipText { get; set; }
+ public double? AppearDelay => null;
+
public override bool HandleKeyboardInput => true;
public override bool HandleMouseInput => true;
}
diff --git a/osu.Framework/Graphics/Cursor/IHasTooltip.cs b/osu.Framework/Graphics/Cursor/IHasTooltip.cs
index eb44d17ede..6d2a520584 100644
--- a/osu.Framework/Graphics/Cursor/IHasTooltip.cs
+++ b/osu.Framework/Graphics/Cursor/IHasTooltip.cs
@@ -14,5 +14,10 @@ public interface IHasTooltip : IDrawable
/// Tooltip that shows when hovering the drawable.
///
string TooltipText { get; }
+
+ ///
+ /// The delay until the tooltip should be displayed. Null means the from the containing the implementing this interface will be used.
+ ///
+ double? AppearDelay { get; }
}
}
diff --git a/osu.Framework/Graphics/Cursor/TooltipContainer.cs b/osu.Framework/Graphics/Cursor/TooltipContainer.cs
index a0848d73fa..59b37c7e1b 100644
--- a/osu.Framework/Graphics/Cursor/TooltipContainer.cs
+++ b/osu.Framework/Graphics/Cursor/TooltipContainer.cs
@@ -155,6 +155,7 @@ protected override void Update()
private readonly List recentMousePositions = new List();
private double lastRecordedPositionTime;
+ private IHasTooltip lastCandidate;
///
/// Determines which drawable should currently receive a tooltip, taking into account
/// and . Returns null if no valid
@@ -167,8 +168,19 @@ private IHasTooltip findTooltipTarget()
if (inputManager.DraggedDrawable is IHasTooltip draggedTarget)
return hasValidTooltip(draggedTarget) ? draggedTarget : null;
+ IHasTooltip targetCandidate = FindTargets().FirstOrDefault(t => t.TooltipText != null);
+ // check this first - if we find no target candidate we still want to clear the recorded positions and update the lastCandidate.
+ if (targetCandidate != lastCandidate)
+ {
+ recentMousePositions.Clear();
+ lastCandidate = targetCandidate;
+ }
+ if (targetCandidate == null)
+ return null;
+
+ double appearDelay = targetCandidate.AppearDelay ?? AppearDelay;
// Always keep 10 positions at equally-sized time intervals that add up to AppearDelay.
- double positionRecordInterval = AppearDelay / 10;
+ double positionRecordInterval = appearDelay / 10;
if (Time.Current - lastRecordedPositionTime >= positionRecordInterval)
{
lastRecordedPositionTime = Time.Current;
@@ -179,11 +191,15 @@ private IHasTooltip findTooltipTarget()
});
}
- recentMousePositions.RemoveAll(t => Time.Current - t.Time > AppearDelay);
+ // check that we have recorded enough positions to make a judgement about whether or not the cursor has been standing still for the required amount of time.
+ // we can skip this if the appear-delay is set to 0, since then tooltips can appear instantly and we don't need to wait to record enough positions.
+ if (appearDelay > 0 && (recentMousePositions.Count == 0 || lastRecordedPositionTime - recentMousePositions[0].Time < appearDelay - positionRecordInterval))
+ return null;
+ recentMousePositions.RemoveAll(t => Time.Current - t.Time > appearDelay);
// For determining whether to show a tooltip we first select only those positions
// which happened within a shorter, alpha-adjusted appear delay.
- double alphaModifiedAppearDelay = (1 - currentTooltip.Alpha) * AppearDelay;
+ double alphaModifiedAppearDelay = (1 - currentTooltip.Alpha) * appearDelay;
var relevantPositions = recentMousePositions.Where(t => Time.Current - t.Time <= alphaModifiedAppearDelay);
// We then check whether all relevant positions fall within a radius of AppearRadius within the
@@ -194,7 +210,7 @@ private IHasTooltip findTooltipTarget()
float appearRadiusSq = AppearRadius * AppearRadius;
if (relevantPositions.All(t => Vector2Extensions.DistanceSquared(t.Position, first) < appearRadiusSq))
- return FindTargets().FirstOrDefault(t => t.TooltipText != null);
+ return targetCandidate;
return null;
}