1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 18:07:23 +08:00

Scroll now playing overlay text when overflowing

This commit is contained in:
Joseph Madamba 2024-03-18 12:24:02 -07:00
parent 48c608e016
commit d4951a093f
2 changed files with 115 additions and 5 deletions

View File

@ -6,6 +6,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Rulesets.Osu;
@ -22,8 +23,6 @@ namespace osu.Game.Tests.Visual.UserInterface
[BackgroundDependencyLoader]
private void load()
{
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
nowPlayingOverlay = new NowPlayingOverlay
{
Origin = Anchor.Centre,
@ -37,9 +36,26 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test]
public void TestShowHideDisable()
{
AddStep(@"set beatmap", () => Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo));
AddStep(@"show", () => nowPlayingOverlay.Show());
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
AddStep(@"hide", () => nowPlayingOverlay.Hide());
}
[Test]
public void TestLongMetadata()
{
AddStep(@"set beatmap", () => Beatmap.Value = CreateWorkingBeatmap(new Beatmap
{
Metadata =
{
Artist = "very very very very very very very very very very very long artist",
ArtistUnicode = "very very very very very very very very very very very long artist",
Title = "very very very very very very very very very very very long title",
TitleUnicode = "very very very very very very very very very very very long title",
}
}));
AddStep(@"show", () => nowPlayingOverlay.Show());
}
}
}

View File

@ -6,6 +6,7 @@ using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -48,7 +49,7 @@ namespace osu.Game.Overlays
private IconButton nextButton = null!;
private IconButton playlistButton = null!;
private SpriteText title = null!, artist = null!;
private ScrollingTextContainer title = null!, artist = null!;
private PlaylistOverlay? playlist;
@ -102,7 +103,7 @@ namespace osu.Game.Overlays
Children = new[]
{
background = Empty(),
title = new OsuSpriteText
title = new ScrollingTextContainer
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.TopCentre,
@ -111,7 +112,7 @@ namespace osu.Game.Overlays
Colour = Color4.White,
Text = @"Nothing to play",
},
artist = new OsuSpriteText
artist = new ScrollingTextContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
@ -470,5 +471,98 @@ namespace osu.Game.Overlays
base.OnHoverLost(e);
}
}
private partial class ScrollingTextContainer : CompositeDrawable
{
private const float initial_move_delay = 1000;
private const float pixels_per_second = 50;
private LocalisableString text;
private OsuSpriteText mainSpriteText = null!;
private OsuSpriteText fillerSpriteText = null!;
public LocalisableString Text
{
get => text;
set
{
text = value;
Schedule(updateText);
}
}
public FontUsage Font
{
set =>
Schedule(() =>
{
mainSpriteText.Font = value;
fillerSpriteText.Font = value;
updateText();
});
}
public ScrollingTextContainer()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new FillFlowContainer<OsuSpriteText>
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Children = new[]
{
mainSpriteText = new OsuSpriteText { Padding = new MarginPadding { Horizontal = margin } },
fillerSpriteText = new OsuSpriteText { Padding = new MarginPadding { Horizontal = margin }, Alpha = 0 },
}
};
}
private void updateText()
{
mainSpriteText.Text = text;
fillerSpriteText.Alpha = 0;
ClearTransforms();
X = 0;
float textOverflowWidth = mainSpriteText.Width - player_width;
if (textOverflowWidth > 0)
{
fillerSpriteText.Alpha = 1;
fillerSpriteText.Text = text;
float initialX;
float targetX;
if (Anchor.HasFlagFast(Anchor.x0))
{
initialX = 0;
targetX = -mainSpriteText.Width;
}
else if (Anchor.HasFlagFast(Anchor.x1))
{
initialX = (textOverflowWidth + mainSpriteText.Width) / 2;
targetX = (textOverflowWidth - mainSpriteText.Width) / 2;
}
else // Anchor.x2
{
initialX = textOverflowWidth + mainSpriteText.Width;
targetX = textOverflowWidth;
}
this.MoveToX(initialX)
.Delay(initial_move_delay)
.MoveToX(targetX, mainSpriteText.Width * 1000 / pixels_per_second)
.Loop();
}
}
}
}
}