1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 16:02:55 +08:00

Merge pull request #28017 from Joehuu/scrollable-text

Scroll now playing overlay text when overflowing
This commit is contained in:
Dean Herbert 2024-05-03 20:05:58 +08:00 committed by GitHub
commit ecb9173e51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 137 additions and 10 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,38 @@ 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 metadata within tolerance", () => Beatmap.Value = CreateWorkingBeatmap(new Beatmap
{
Metadata =
{
Artist = "very very very very very very very very very very verry long artist",
ArtistUnicode = "very very very very very very very very very very verry long artist",
Title = "very very very very very verry long title",
TitleUnicode = "very very very very very verry long title",
}
}));
AddStep(@"set metadata outside bounds", () => Beatmap.Value = CreateWorkingBeatmap(new Beatmap
{
Metadata =
{
Artist = "very very very very very very very very very very verrry long artist",
ArtistUnicode = "very very very very very very very very very very verrry long artist",
Title = "very very very very very verrry long title",
TitleUnicode = "very very very very very verrry long title",
}
}));
AddStep(@"show", () => nowPlayingOverlay.Show());
}
}
}

View File

@ -33,6 +33,7 @@ namespace osu.Game.Overlays
public LocalisableString Title => NowPlayingStrings.HeaderTitle;
public LocalisableString Description => NowPlayingStrings.HeaderDescription;
private const float player_width = 400;
private const float player_height = 130;
private const float transition_length = 800;
private const float progress_height = 10;
@ -47,7 +48,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;
@ -70,7 +71,7 @@ namespace osu.Game.Overlays
public NowPlayingOverlay()
{
Width = 400;
Width = player_width;
Margin = new MarginPadding(margin);
}
@ -101,7 +102,7 @@ namespace osu.Game.Overlays
Children = new[]
{
background = Empty(),
title = new OsuSpriteText
title = new ScrollingTextContainer
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.TopCentre,
@ -110,7 +111,7 @@ namespace osu.Game.Overlays
Colour = Color4.White,
Text = @"Nothing to play",
},
artist = new OsuSpriteText
artist = new ScrollingTextContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
@ -319,15 +320,15 @@ namespace osu.Game.Overlays
switch (direction)
{
case TrackChangeDirection.Next:
newBackground.Position = new Vector2(400, 0);
newBackground.Position = new Vector2(player_width, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(-400, 500, Easing.OutCubic);
background.MoveToX(-player_width, 500, Easing.OutCubic);
break;
case TrackChangeDirection.Prev:
newBackground.Position = new Vector2(-400, 0);
newBackground.Position = new Vector2(-player_width, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(400, 500, Easing.OutCubic);
background.MoveToX(player_width, 500, Easing.OutCubic);
break;
}
@ -469,5 +470,103 @@ 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 OsuSpriteText mainSpriteText = null!;
private OsuSpriteText fillerSpriteText = null!;
private LocalisableString text;
public LocalisableString Text
{
get => text;
set
{
text = value;
if (IsLoaded)
updateText();
}
}
private FontUsage font = OsuFont.Default;
public FontUsage Font
{
get => font;
set
{
font = value;
if (IsLoaded)
updateFontAndText();
}
}
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 },
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
updateFontAndText();
}
private void updateFontAndText()
{
mainSpriteText.Font = font;
fillerSpriteText.Font = font;
updateText();
}
private void updateText()
{
mainSpriteText.Text = text;
fillerSpriteText.Alpha = 0;
ClearTransforms();
X = 0;
float textOverflowWidth = mainSpriteText.Width - player_width;
// apply half margin of tolerance on both sides before the text scrolls
if (textOverflowWidth > margin)
{
fillerSpriteText.Alpha = 1;
fillerSpriteText.Text = text;
float initialX = (textOverflowWidth + mainSpriteText.Width) / 2;
float targetX = (textOverflowWidth - mainSpriteText.Width) / 2;
this.MoveToX(initialX)
.Delay(initial_move_delay)
.MoveToX(targetX, mainSpriteText.Width * 1000 / pixels_per_second)
.Loop();
}
}
}
}
}