diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs b/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs new file mode 100644 index 0000000000..2d9cfcf4b1 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseTooltip : TestCase + { + public override string Description => "tests tooltips on various elements"; + + public override void Reset() + { + base.Reset(); + + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new[] + { + new TooltipSpriteText + { + Text = "Text with some tooltip", + }, + new TooltipSpriteText + { + Text = "and another one", + }, + + }, + }, + }; + } + + private class TooltipSpriteText : OsuSpriteText, IHasTooltip + { + public string Tooltip => Text; + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 1baf322750..b117515433 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -202,6 +202,7 @@ + diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 67b17fae5c..82422765a3 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -12,6 +12,11 @@ using osu.Framework.Input; using osu.Game.Configuration; using System; using osu.Framework.Graphics.Textures; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Threading; +using System.Linq; +using osu.Framework.Screens; +using System.Collections.Generic; namespace osu.Game.Graphics.Cursor { @@ -19,10 +24,34 @@ namespace osu.Game.Graphics.Cursor { protected override Drawable CreateCursor() => new Cursor(); + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + this.game = game; + } + private bool dragging; + private ScheduledDelegate show; + private OsuGameBase game; + protected override bool OnMouseMove(InputState state) { + if (state.Mouse.Position != state.Mouse.LastPosition) + { + Tooltip tooltip = ((Cursor)ActiveCursor).Tooltip; + show?.Cancel(); + tooltip.Hide(); + Delay(250); + show = Schedule(delegate + { + tooltip.TooltipText = ""; + searchTooltip(tooltip, ToScreenSpace(state.Mouse.Position), game); + if (tooltip.TooltipText != "") + tooltip.Show(); + }); + } + if (dragging) { Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown ?? state.Mouse.Delta; @@ -40,6 +69,23 @@ namespace osu.Game.Graphics.Cursor return base.OnMouseMove(state); } + private void searchTooltip(Tooltip tooltip, Vector2 mousePosition, IContainerEnumerable children) + { + IEnumerable next = children.Children.Where(drawable => drawable.Contains(mousePosition) && !(drawable is CursorContainer)); + + foreach (Drawable drawable in next) + { + string tooltipText = (drawable as IHasTooltip)?.Tooltip ?? ""; + if (tooltipText != "") tooltip.TooltipText = tooltipText; + + var childScreen = (drawable as Screen)?.ChildScreen; + if (childScreen != null) + searchTooltip(tooltip, mousePosition, childScreen); + else if (drawable is IContainer) + searchTooltip(tooltip, mousePosition, drawable as IContainerEnumerable); + } + } + protected override bool OnDragStart(InputState state) { dragging = true; @@ -94,6 +140,7 @@ namespace osu.Game.Graphics.Cursor public class Cursor : Container { private Container cursorContainer; + public Tooltip Tooltip; private Bindable cursorScale; public Sprite AdditiveLayer; @@ -127,7 +174,11 @@ namespace osu.Game.Graphics.Cursor Texture = textures.Get(@"Cursor/menu-cursor-additive"), }, } - } + }, + Tooltip = new Tooltip + { + Alpha = 0, + }, }; cursorScale = config.GetBindable(OsuConfig.MenuCursorSize); @@ -138,6 +189,7 @@ namespace osu.Game.Graphics.Cursor private void scaleChanged(object sender, EventArgs e) { cursorContainer.Scale = new Vector2((float)cursorScale); + Tooltip.Y = cursorContainer.Height * (float)cursorScale; } } } diff --git a/osu.Game/Graphics/UserInterface/IHasTooltip.cs b/osu.Game/Graphics/UserInterface/IHasTooltip.cs new file mode 100644 index 0000000000..d8997349bb --- /dev/null +++ b/osu.Game/Graphics/UserInterface/IHasTooltip.cs @@ -0,0 +1,10 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Graphics.UserInterface +{ + public interface IHasTooltip + { + string Tooltip { get; } + } +} diff --git a/osu.Game/Graphics/UserInterface/Tooltip.cs b/osu.Game/Graphics/UserInterface/Tooltip.cs new file mode 100644 index 0000000000..b392f89397 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/Tooltip.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using osu.Framework.Threading; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Graphics.UserInterface +{ + public class Tooltip : Container + { + private readonly Container actualTooltip; + private readonly Box tooltipBackground; + private readonly OsuSpriteText text; + + public string TooltipText { + get => text.Text; + set => text.Text = value; + } + + public Vector2 TooltipOffset = new Vector2(); + + public Tooltip() + { + Depth = float.MinValue; + AlwaysReceiveInput = true; + Children = new[] + { + actualTooltip = new Container + { + AutoSizeAxes = Axes.Both, + CornerRadius = 5, + Masking = true, + AlwaysPresent = true, + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(40), + Radius = 5, + }, + Children = new Drawable[] + { + tooltipBackground = new Box + { + RelativeSizeAxes = Axes.Both + }, + text = new OsuSpriteText + { + Padding = new MarginPadding(3), + Font = @"Exo2.0-Regular", + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour, OsuGameBase game) + { + tooltipBackground.Colour = colour.Gray3; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ecb3f5084c..c29f3a49f2 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -87,12 +87,14 @@ + +