Skip to content

Commit

Permalink
Merge pull request #1553 from default0/custom-appear-delay
Browse files Browse the repository at this point in the history
Allow custom AppearDelay per tooltip
  • Loading branch information
Tom94 committed May 15, 2018
2 parents fac6886 + d0a426f commit 47855ca
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
8 changes: 8 additions & 0 deletions osu.Framework.Tests/Visual/TestCaseTooltip.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -177,6 +179,8 @@ private class TooltipTooltipContainer : TooltipContainer, IHasTooltip
{
public string TooltipText { get; set; }

double? IHasTooltip.AppearDelay => null;

public TooltipTooltipContainer(string tooltipText)
{
TooltipText = tooltipText;
Expand All @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions osu.Framework/Graphics/Cursor/IHasTooltip.cs
Expand Up @@ -14,5 +14,10 @@ public interface IHasTooltip : IDrawable
/// Tooltip that shows when hovering the drawable.
/// </summary>
string TooltipText { get; }

/// <summary>
/// The delay until the tooltip should be displayed. Null means the <see cref="TooltipContainer.AppearDelay"/> from the <see cref="TooltipContainer"/> containing the <see cref="Drawable"/> implementing this interface will be used.
/// </summary>
double? AppearDelay { get; }
}
}
24 changes: 20 additions & 4 deletions osu.Framework/Graphics/Cursor/TooltipContainer.cs
Expand Up @@ -155,6 +155,7 @@ protected override void Update()
private readonly List<TimedPosition> recentMousePositions = new List<TimedPosition>();
private double lastRecordedPositionTime;

private IHasTooltip lastCandidate;
/// <summary>
/// Determines which drawable should currently receive a tooltip, taking into account
/// <see cref="AppearDelay"/> and <see cref="AppearRadius"/>. Returns null if no valid
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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;
}
Expand Down

0 comments on commit 47855ca

Please sign in to comment.