diff --git a/osu-framework b/osu-framework index 67f3958036..f8e5b10f68 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 67f39580365f7d0a42f8788eae2b60881dde1c67 +Subproject commit f8e5b10f6883af83ffbc431b03fe4ee3e89797a6 diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs b/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs index acf98ea86b..23fe8f16db 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMenuOverlays.cs @@ -12,7 +12,7 @@ namespace osu.Desktop.VisualTests.Tests { public override string Description => @"Tests pause and fail overlays"; - private PauseOverlay pauseOverlay; + private PauseContainer.PauseOverlay pauseOverlay; private FailOverlay failOverlay; private int retryCount; @@ -22,7 +22,7 @@ namespace osu.Desktop.VisualTests.Tests retryCount = 0; - Add(pauseOverlay = new PauseOverlay + Add(pauseOverlay = new PauseContainer.PauseOverlay { OnResume = () => Logger.Log(@"Resume"), OnRetry = () => Logger.Log(@"Retry"), diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 93fd0a8956..2925c3ccb4 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -23,7 +23,7 @@ namespace osu.Game.Online.Chat [JsonProperty(@"channel_id")] public int Id; - public readonly SortedList Messages = new SortedList(Comparer.Default); + public readonly SortedList Messages = new SortedList((m1, m2) => m1.Id.CompareTo(m2.Id)); //internal bool Joined; diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index c1887e7824..bf53a68910 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -8,7 +8,7 @@ using osu.Game.Users; namespace osu.Game.Online.Chat { - public class Message : IComparable + public class Message { [JsonProperty(@"message_id")] public readonly long Id; @@ -42,7 +42,17 @@ namespace osu.Game.Online.Chat Id = id; } - public int CompareTo(Message other) => Id.CompareTo(other.Id); + public override bool Equals(object obj) + { + var objMessage = obj as Message; + + return Id == objMessage?.Id; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } } public enum TargetType diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7e16030ec3..2c39a82245 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -146,7 +146,7 @@ namespace osu.Game { base.LoadComplete(); - AddInternal(ratioContainer = new RatioAdjust + base.Content.Add(ratioContainer = new RatioAdjust { Children = new Drawable[] { diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index a85af251c5..2836be22ae 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -206,18 +206,12 @@ namespace osu.Game.Overlays private long? lastMessageId; - private List careChannels; + private readonly List careChannels = new List(); private readonly List loadedChannels = new List(); private void initializeChannels() { - currentChannelContainer.Clear(); - - loadedChannels.Clear(); - - careChannels = new List(); - SpriteText loading; Add(loading = new OsuSpriteText { @@ -232,8 +226,6 @@ namespace osu.Game.Overlays ListChannelsRequest req = new ListChannelsRequest(); req.Success += delegate (List channels) { - Debug.Assert(careChannels.Count == 0); - Scheduler.Add(delegate { loading.FadeOut(100); diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index ef6e635c49..4a561e6036 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -41,12 +41,11 @@ namespace osu.Game.Screens.Play get { return isCounting; } set { - if (value != isCounting) - { - isCounting = value; - foreach (var child in Children) - child.IsCounting = value; - } + if (value == isCounting) return; + + isCounting = value; + foreach (var child in Children) + child.IsCounting = value; } } diff --git a/osu.Game/Screens/Play/MenuOverlay.cs b/osu.Game/Screens/Play/MenuOverlay.cs index fa522956f7..424b26350f 100644 --- a/osu.Game/Screens/Play/MenuOverlay.cs +++ b/osu.Game/Screens/Play/MenuOverlay.cs @@ -8,11 +8,11 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Graphics.Sprites; -using osu.Game.Screens.Play.Pause; using OpenTK; using OpenTK.Graphics; using osu.Game.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Play @@ -89,7 +89,7 @@ namespace osu.Game.Screens.Play protected void AddButton(string text, Color4 colour, Action action) { - Buttons.Add(new PauseButton + Buttons.Add(new Button { Text = text, ButtonColour = colour, @@ -179,12 +179,6 @@ namespace osu.Game.Screens.Play } } }, - new PauseProgressBar - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Width = 1f - } }; Retries = 0; @@ -195,5 +189,15 @@ namespace osu.Game.Screens.Play AlwaysReceiveInput = true; RelativeSizeAxes = Axes.Both; } + + public class Button : DialogButton + { + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + SampleHover = audio.Sample.Get(@"Menu/menuclick"); + SampleClick = audio.Sample.Get(@"Menu/menuback"); + } + } } } diff --git a/osu.Game/Screens/Play/Pause/PauseButton.cs b/osu.Game/Screens/Play/Pause/PauseButton.cs deleted file mode 100644 index 7698913ea5..0000000000 --- a/osu.Game/Screens/Play/Pause/PauseButton.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Play.Pause -{ - public class PauseButton : DialogButton - { - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - SampleHover = audio.Sample.Get(@"Menu/menuclick"); - SampleClick = audio.Sample.Get(@"Menu/menuback"); - } - } -} diff --git a/osu.Game/Screens/Play/Pause/PauseProgressBar.cs b/osu.Game/Screens/Play/Pause/PauseProgressBar.cs deleted file mode 100644 index bfde7dd6d7..0000000000 --- a/osu.Game/Screens/Play/Pause/PauseProgressBar.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Beatmaps; -using OpenTK.Graphics; - -namespace osu.Game.Screens.Play.Pause -{ - public class PauseProgressBar : Container - { - private readonly Color4 fillColour = new Color4(221, 255, 255, 255); - private readonly Color4 glowColour = new Color4(221, 255, 255, 150); - - private readonly Container fill; - private WorkingBeatmap current; - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - current = osuGame.Beatmap.Value; - } - - protected override void Update() - { - base.Update(); - - if (current?.TrackLoaded ?? false) - { - fill.Width = (float)(current.Track.CurrentTime / current.Track.Length); - } - } - - public PauseProgressBar() - { - RelativeSizeAxes = Axes.X; - Height = 60; - - Children = new Drawable[] - { - new PauseProgressGraph - { - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - Height = 35, - Margin = new MarginPadding - { - Bottom = 5 - } - }, - new Container - { - Origin = Anchor.BottomRight, - Anchor = Anchor.BottomRight, - RelativeSizeAxes = Axes.X, - Height = 5, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f - } - } - }, - fill = new Container - { - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Width = 0, - Height = 60, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Masking = true, - Children = new Drawable[] - { - new Container - { - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 5, - Masking = true, - EdgeEffect = new EdgeEffect - { - Type = EdgeEffectType.Glow, - Colour = glowColour, - Radius = 5 - }, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = fillColour - } - } - } - } - }, - new Container - { - Origin = Anchor.BottomRight, - Anchor = Anchor.BottomRight, - Width = 2, - Height = 35, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White - }, - new Container - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.TopCentre, - Width = 14, - Height = 25, - CornerRadius = 5, - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White - } - } - } - } - } - } - } - }; - } - } -} diff --git a/osu.Game/Screens/Play/Pause/PauseProgressGraph.cs b/osu.Game/Screens/Play/Pause/PauseProgressGraph.cs deleted file mode 100644 index 89b9b42b86..0000000000 --- a/osu.Game/Screens/Play/Pause/PauseProgressGraph.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics.Containers; - -namespace osu.Game.Screens.Play.Pause -{ - public class PauseProgressGraph : Container - { - // TODO: Implement the pause progress graph - } -} diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs new file mode 100644 index 0000000000..1de62048b7 --- /dev/null +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -0,0 +1,155 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Framework.Timing; +using osu.Game.Graphics; +using OpenTK.Graphics; +using OpenTK.Input; + +namespace osu.Game.Screens.Play +{ + /// + /// A container which handles pausing children, displaying a pause overlay with choices etc. + /// This alleviates a lot of the intricate pause logic from being in + /// + public class PauseContainer : Container + { + public bool IsPaused { get; private set; } + + public bool AllowExit => IsPaused && pauseOverlay.Alpha == 1; + + public Func CheckCanPause; + + private const double pause_cooldown = 1000; + private double lastPauseActionTime; + + private readonly PauseOverlay pauseOverlay; + + private readonly Container content; + + protected override Container Content => content; + + public int Retries { set { pauseOverlay.Retries = value; } } + + public bool CanPause => (CheckCanPause?.Invoke() ?? true) && Time.Current >= lastPauseActionTime + pause_cooldown; + + public Action OnRetry; + public Action OnQuit; + + public Action OnResume; + public Action OnPause; + + public IAdjustableClock AudioClock; + public FramedClock FramedClock; + + public PauseContainer() + { + RelativeSizeAxes = Axes.Both; + + AddInternal(content = new Container { RelativeSizeAxes = Axes.Both }); + + AddInternal(pauseOverlay = new PauseOverlay + { + OnResume = delegate + { + Delay(400); + Schedule(Resume); + }, + OnRetry = () => OnRetry(), + OnQuit = () => OnQuit(), + }); + } + + public void Pause(bool force = false) + { + if (!CanPause && !force) return; + + if (IsPaused) return; + + // stop the decoupled clock (stops the audio eventually) + AudioClock.Stop(); + + // stop processing updatess on the offset clock (instantly freezes time for all our components) + FramedClock.ProcessSourceClockFrames = false; + + IsPaused = true; + + // we need to do a final check after all of our children have processed up to the paused clock time. + // this is to cover cases where, for instance, the player fails in the current processing frame. + Schedule(() => + { + if (!CanPause) return; + + lastPauseActionTime = Time.Current; + + OnPause?.Invoke(); + pauseOverlay.Show(); + }); + } + + public void Resume() + { + if (!IsPaused) return; + + IsPaused = false; + FramedClock.ProcessSourceClockFrames = true; + + lastPauseActionTime = Time.Current; + + OnResume?.Invoke(); + + pauseOverlay.Hide(); + AudioClock.Start(); + } + + private OsuGameBase game; + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + this.game = game; + } + + protected override void Update() + { + // eagerly pause when we lose window focus (if we are locally playing). + if (!game.IsActive && CanPause) + Pause(); + + base.Update(); + } + + public class PauseOverlay : MenuOverlay + { + public Action OnResume; + + public override string Header => "paused"; + public override string Description => "you're not going to do what i think you're going to do, are ya?"; + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (!args.Repeat && args.Key == Key.Escape) + { + Buttons.Children.First().TriggerClick(); + return true; + } + + return base.OnKeyDown(state, args); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AddButton("Continue", colours.Green, OnResume); + AddButton("Retry", colours.YellowDark, OnRetry); + AddButton("Quit", new Color4(170, 27, 39, 255), OnQuit); + } + } + } +} diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs deleted file mode 100644 index 9561979751..0000000000 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Linq; -using osu.Framework.Input; -using osu.Game.Graphics; -using OpenTK.Input; -using OpenTK.Graphics; -using osu.Framework.Allocation; - -namespace osu.Game.Screens.Play -{ - public class PauseOverlay : MenuOverlay - { - public Action OnResume; - - public override string Header => "paused"; - public override string Description => "you're not going to do what i think you're going to do, are ya?"; - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (!args.Repeat && args.Key == Key.Escape) - { - Buttons.Children.First().TriggerClick(); - return true; - } - - return base.OnKeyDown(state, args); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - AddButton("Continue", colours.Green, OnResume); - AddButton("Retry", colours.YellowDark, OnRetry); - AddButton("Quit", new Color4(170, 27, 39, 255), OnQuit); - } - } -} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8ee0de12b9..d9585b8c04 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -32,29 +32,24 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; - internal override bool HasLocalCursorDisplayed => !IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; + internal override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && HitRenderer.ProvidingUserCursor; public BeatmapInfo BeatmapInfo; public Action RestartRequested; - public bool IsPaused => !decoupledClock.IsRunning; - internal override bool AllowRulesetChange => false; public bool HasFailed { get; private set; } public int RestartCount; - private const double pause_cooldown = 1000; - private double lastPauseActionTime; - - private bool canPause => ValidForResume && !HasFailed && Time.Current >= lastPauseActionTime + pause_cooldown; - private IAdjustableClock adjustableSourceClock; private FramedOffsetClock offsetClock; private DecoupleableInterpolatingFramedClock decoupledClock; + private PauseContainer pauseContainer; + private RulesetInfo ruleset; private ScoreProcessor scoreProcessor; @@ -70,10 +65,7 @@ namespace osu.Game.Screens.Play private SkipButton skipButton; - private Container hitRendererContainer; - private HUDOverlay hudOverlay; - private PauseOverlay pauseOverlay; private FailOverlay failOverlay; [BackgroundDependencyLoader(permitNulls: true)] @@ -152,14 +144,63 @@ namespace osu.Game.Screens.Play decoupledClock.ChangeSource(adjustableSourceClock); }); - scoreProcessor = HitRenderer.CreateScoreProcessor(); - - hudOverlay = new StandardHUDOverlay() + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre + pauseContainer = new PauseContainer + { + AudioClock = decoupledClock, + FramedClock = offsetClock, + OnRetry = Restart, + OnQuit = Exit, + CheckCanPause = () => ValidForResume && !HasFailed, + Retries = RestartCount, + OnPause = () => { + hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; + }, + OnResume = () => { + hudOverlay.KeyCounter.IsCounting = true; + }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Clock = offsetClock, + Children = new Drawable[] + { + HitRenderer, + skipButton = new SkipButton + { + Alpha = 0, + Margin = new MarginPadding { Bottom = 140 } // this is temporary + }, + } + }, + hudOverlay = new StandardHUDOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, + } + }, + failOverlay = new FailOverlay + { + OnRetry = Restart, + OnQuit = Exit, + }, + new HotkeyRetryOverlay + { + Action = () => { + //we want to hide the hitrenderer immediately (looks better). + //we may be able to remove this once the mouse cursor trail is improved. + HitRenderer?.Hide(); + Restart(); + }, + } }; + scoreProcessor = HitRenderer.CreateScoreProcessor(); + hudOverlay.KeyCounter.Add(rulesetInstance.CreateGameplayKeys()); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindHitRenderer(HitRenderer); @@ -176,61 +217,6 @@ namespace osu.Game.Screens.Play //bind ScoreProcessor to ourselves (for a fail situation) scoreProcessor.Failed += onFail; - - Children = new Drawable[] - { - hitRendererContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Clock = offsetClock, - Children = new Drawable[] - { - HitRenderer, - skipButton = new SkipButton { Alpha = 0 }, - } - }, - } - }, - hudOverlay, - pauseOverlay = new PauseOverlay - { - OnResume = delegate - { - Delay(400); - Schedule(Resume); - }, - OnRetry = Restart, - OnQuit = Exit, - }, - failOverlay = new FailOverlay - { - OnRetry = Restart, - OnQuit = Exit, - }, - new HotkeyRetryOverlay - { - Action = () => { - //we want to hide the hitrenderer immediately (looks better). - //we may be able to remove this once the mouse cursor trail is improved. - HitRenderer?.Hide(); - Restart(); - }, - } - }; - } - - protected override void Update() - { - // eagerly pause when we lose window focus (if we are locally playing). - if (!Game.IsActive && !HitRenderer.HasReplayLoaded) - Pause(); - - base.Update(); } private void initializeSkipButton() @@ -260,44 +246,6 @@ namespace osu.Game.Screens.Play skipButton.Expire(); } - public void Pause(bool force = false) - { - if (!canPause && !force) return; - - // the actual pausing is potentially happening on a different thread. - // we want to wait for the source clock to stop so we can be sure all components are in a stable state. - if (!IsPaused) - { - decoupledClock.Stop(); - - Schedule(() => Pause(force)); - return; - } - - // we need to do a final check after all of our children have processed up to the paused clock time. - // this is to cover cases where, for instance, the player fails in the last processed frame (which would change canPause). - // as the scheduler runs before children updates, let's schedule for the next frame. - Schedule(() => - { - if (!canPause) return; - - lastPauseActionTime = Time.Current; - hudOverlay.KeyCounter.IsCounting = false; - hudOverlay.Progress.Show(); - pauseOverlay.Retries = RestartCount; - pauseOverlay.Show(); - }); - } - - public void Resume() - { - lastPauseActionTime = Time.Current; - hudOverlay.KeyCounter.IsCounting = true; - hudOverlay.Progress.Hide(); - pauseOverlay.Hide(); - decoupledClock.Start(); - } - public void Restart() { ValidForResume = false; @@ -363,8 +311,8 @@ namespace osu.Game.Screens.Play initializeSkipButton(); }); - hitRendererContainer.Alpha = 0; - hitRendererContainer.FadeIn(750, EasingTypes.OutQuint); + pauseContainer.Alpha = 0; + pauseContainer.FadeIn(750, EasingTypes.OutQuint); } protected override void OnSuspending(Screen next) @@ -375,23 +323,14 @@ namespace osu.Game.Screens.Play protected override bool OnExiting(Screen next) { - if (!HasFailed && ValidForResume) + if (HasFailed || !ValidForResume || pauseContainer.AllowExit || HitRenderer.HasReplayLoaded) { - if (pauseOverlay != null && !HitRenderer.HasReplayLoaded) - { - //pause screen override logic. - if (pauseOverlay?.State == Visibility.Hidden && !canPause) return true; - - if (!IsPaused) // For if the user presses escape quickly when entering the map - { - Pause(); - return true; - } - } + fadeOut(); + return base.OnExiting(next); } - fadeOut(); - return base.OnExiting(next); + pauseContainer.Pause(); + return true; } private void fadeOut() @@ -406,6 +345,6 @@ namespace osu.Game.Screens.Play Background?.FadeTo(1f, fade_out_duration); } - protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !IsPaused; + protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; } } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 887442b8c0..6b3f81628c 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -31,6 +31,8 @@ namespace osu.Game.Screens.Play public Action OnSeek; + public override bool HandleInput => AllowSeeking; + private IClock audioClock; public IClock AudioClock { set { audioClock = info.AudioClock = value; } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index fbdaa948cc..4df24c1314 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -107,6 +107,8 @@ namespace osu.Game.Screens.Select return; } + if (beatmap == SelectedBeatmap) return; + foreach (BeatmapGroup group in groups) { var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); @@ -204,7 +206,7 @@ namespace osu.Game.Screens.Select if (selectedGroup == null || selectedGroup.State == BeatmapGroupState.Hidden) SelectNext(); else - selectGroup(selectedGroup); + selectGroup(selectedGroup, selectedPanel); }; filterTask?.Cancel(); @@ -339,6 +341,8 @@ namespace osu.Game.Screens.Select selectedGroup.State = BeatmapGroupState.Collapsed; group.State = BeatmapGroupState.Expanded; + group.SelectedPanel = panel; + panel.State = PanelSelectedState.Selected; if (selectedPanel == panel) return; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index b750fc9bbe..abe54375cc 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -49,6 +49,8 @@ namespace osu.Game.Screens.Select get { return beatmap; } set { + if (beatmap == value) return; + beatmap = value; pendingBeatmapSwitch?.Cancel(); diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index a136e298b5..a7aa752d65 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -100,6 +100,8 @@ namespace osu.Game.Screens.Select.Leaderboards get { return beatmap; } set { + if (beatmap == value) return; + beatmap = value; Scores = null; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 4438b656b0..4982ca096f 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -313,15 +313,15 @@ namespace osu.Game.Screens.Select { bool beatmapSetChange = false; - if (!beatmap.Equals(Beatmap?.BeatmapInfo)) + if (beatmap.Equals(Beatmap?.BeatmapInfo)) + return; + + if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID) + sampleChangeDifficulty.Play(); + else { - if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID) - sampleChangeDifficulty.Play(); - else - { - sampleChangeBeatmap.Play(); - beatmapSetChange = true; - } + sampleChangeBeatmap.Play(); + beatmapSetChange = true; } selectionChangeNoBounce = beatmap; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 63acdb1914..6cd32d7fea 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -231,6 +231,7 @@ + @@ -254,8 +255,6 @@ - - @@ -395,8 +394,6 @@ - -