From a0038a5faa8cc52045ba3821d3789cd25122d977 Mon Sep 17 00:00:00 2001 From: default0 Date: Mon, 14 May 2018 23:25:41 +0200 Subject: [PATCH 1/3] Allow custom AppearDelay per tooltip --- osu.Framework/Graphics/Cursor/IHasTooltip.cs | 5 ++++ .../Graphics/Cursor/TooltipContainer.cs | 24 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) 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..bbd95cb73c 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; + 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; } From 4e00abf852439111c0cbc39fe00fdd86134cc765 Mon Sep 17 00:00:00 2001 From: default0 Date: Mon, 14 May 2018 23:42:21 +0200 Subject: [PATCH 2/3] Fix TestCaseTooltip --- osu.Framework.Tests/Visual/TestCaseTooltip.cs | 8 ++++++++ osu.Framework/Graphics/Cursor/TooltipContainer.cs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Framework.Tests/Visual/TestCaseTooltip.cs b/osu.Framework.Tests/Visual/TestCaseTooltip.cs index ca67cd3740..8879fbd746 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; } + public double? 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/TooltipContainer.cs b/osu.Framework/Graphics/Cursor/TooltipContainer.cs index bbd95cb73c..0f38b1b8f8 100644 --- a/osu.Framework/Graphics/Cursor/TooltipContainer.cs +++ b/osu.Framework/Graphics/Cursor/TooltipContainer.cs @@ -155,7 +155,7 @@ protected override void Update() private readonly List recentMousePositions = new List(); private double lastRecordedPositionTime; - IHasTooltip lastCandidate; + private IHasTooltip lastCandidate; /// /// Determines which drawable should currently receive a tooltip, taking into account /// and . Returns null if no valid From d0a426fa3c04bafca183763b890465c0d3046e0a Mon Sep 17 00:00:00 2001 From: default0 Date: Mon, 14 May 2018 23:53:19 +0200 Subject: [PATCH 3/3] Appease CI Also makes order of operations and intent on the if-statement less clear as a small bonus --- osu.Framework.Tests/Visual/TestCaseTooltip.cs | 2 +- osu.Framework/Graphics/Cursor/TooltipContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Framework.Tests/Visual/TestCaseTooltip.cs b/osu.Framework.Tests/Visual/TestCaseTooltip.cs index 8879fbd746..d2a8b9b7e0 100644 --- a/osu.Framework.Tests/Visual/TestCaseTooltip.cs +++ b/osu.Framework.Tests/Visual/TestCaseTooltip.cs @@ -179,7 +179,7 @@ private class TooltipTooltipContainer : TooltipContainer, IHasTooltip { public string TooltipText { get; set; } - public double? AppearDelay => null; + double? IHasTooltip.AppearDelay => null; public TooltipTooltipContainer(string tooltipText) { diff --git a/osu.Framework/Graphics/Cursor/TooltipContainer.cs b/osu.Framework/Graphics/Cursor/TooltipContainer.cs index 0f38b1b8f8..59b37c7e1b 100644 --- a/osu.Framework/Graphics/Cursor/TooltipContainer.cs +++ b/osu.Framework/Graphics/Cursor/TooltipContainer.cs @@ -193,7 +193,7 @@ private IHasTooltip findTooltipTarget() // 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))) + if (appearDelay > 0 && (recentMousePositions.Count == 0 || lastRecordedPositionTime - recentMousePositions[0].Time < appearDelay - positionRecordInterval)) return null; recentMousePositions.RemoveAll(t => Time.Current - t.Time > appearDelay);