diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 4753effdb0..69bfe666ee 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -1,11 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; namespace osu.Game.Screens.Play.PlayerSettings { @@ -24,34 +30,115 @@ namespace osu.Game.Screens.Play.PlayerSettings private readonly OsuSpriteText multiplierText; + private readonly IconButton play; + + [Resolved] + private GameplayClockContainer gameplayClock { get; set; } = null!; + + [Resolved] + private GameplayState gameplayState { get; set; } = null!; + public PlaybackSettings() : base("playback") { + const double seek_amount = 5000; + const double seek_fast_amount = 10000; + Children = new Drawable[] { - new Container + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = padding }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, padding), Children = new Drawable[] { - new OsuSpriteText + new FillFlowContainer { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = "Playback speed", + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.Solid.FastBackward, + Action = () => seek(-1, seek_fast_amount), + }, + new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.Solid.Backward, + Action = () => seek(-1, seek_amount), + }, + play = new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1.4f), + IconScale = new Vector2(1.4f), + Icon = FontAwesome.Regular.PlayCircle, + Action = () => + { + if (gameplayClock != null) + { + if (gameplayClock.IsRunning) + gameplayClock.Stop(); + else + gameplayClock.Start(); + } + } + }, + new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.Solid.Forward, + Action = () => seek(1, seek_amount), + }, + new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.Solid.FastForward, + Action = () => seek(1, seek_fast_amount), + }, + }, }, - multiplierText = new OsuSpriteText + new Container { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Font = OsuFont.GetFont(weight: FontWeight.Bold), - } + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + rateSlider = new PlayerSliderBar + { + LabelText = "Playback speed", + Current = UserPlaybackRate, + }, + multiplierText = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 20 }, + } + }, + }, }, }, - rateSlider = new PlayerSliderBar { Current = UserPlaybackRate } }; + + void seek(int direction, double amount) + { + double target = Math.Clamp((gameplayClock?.CurrentTime ?? 0) + (direction * amount), 0, gameplayState.Beatmap.GetLastObjectTime()); + gameplayClock?.Seek(target); + } } protected override void LoadComplete() @@ -59,5 +146,11 @@ namespace osu.Game.Screens.Play.PlayerSettings base.LoadComplete(); rateSlider.Current.BindValueChanged(multiplier => multiplierText.Text = $"{multiplier.NewValue:0.0}x", true); } + + protected override void Update() + { + base.Update(); + play.Icon = gameplayClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; + } } }