From 6eb7590ab0151b86a047e157b4369bdf59978691 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:41:35 +0900 Subject: [PATCH 1/3] Make MusicController handle all movement to previous/next tracks --- osu.Game/Overlays/Music/PlaylistList.cs | 95 +++++++++------------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 77 +++--------------- osu.Game/Overlays/MusicController.cs | 49 +++++++++-- 3 files changed, 90 insertions(+), 131 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index d63babf3b6..8c8ff89420 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -4,7 +4,8 @@ using System; using System.Collections.Generic; using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Music { public class PlaylistList : CompositeDrawable { - public Action OnSelect; + public Action Selected; + public Action OrderChanged; private readonly ItemsScrollContainer items; @@ -25,7 +27,8 @@ namespace osu.Game.Overlays.Music InternalChild = items = new ItemsScrollContainer { RelativeSizeAxes = Axes.Both, - OnSelect = set => OnSelect?.Invoke(set) + Selected = set => Selected?.Invoke(set), + OrderChanged = (s, i) => OrderChanged?.Invoke(s, i) }; } @@ -35,34 +38,20 @@ namespace osu.Game.Overlays.Music set { base.Padding = value; } } - public IEnumerable BeatmapSets - { - get { return items.Sets; } - set { items.Sets = value; } - } - public BeatmapSetInfo FirstVisibleSet => items.FirstVisibleSet; - public BeatmapSetInfo NextSet => items.NextSet; - public BeatmapSetInfo PreviousSet => items.PreviousSet; - - public BeatmapSetInfo SelectedSet - { - get { return items.SelectedSet; } - set { items.SelectedSet = value; } - } - - public void AddBeatmapSet(BeatmapSetInfo beatmapSet) => items.AddBeatmapSet(beatmapSet); - public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => items.RemoveBeatmapSet(beatmapSet); public void Filter(string searchTerm) => items.SearchTerm = searchTerm; private class ItemsScrollContainer : OsuScrollContainer { - public Action OnSelect; + public Action Selected; + public Action OrderChanged; private readonly SearchContainer search; private readonly FillFlowContainer items; + private readonly IBindable beatmapBacking = new Bindable(); + public ItemsScrollContainer() { Children = new Drawable[] @@ -83,14 +72,36 @@ namespace osu.Game.Overlays.Music }; } - public IEnumerable Sets + [BackgroundDependencyLoader] + private void load(BeatmapManager beatmaps, OsuGameBase osuGame) { - get { return items.Select(x => x.BeatmapSetInfo).ToList(); } - set - { - items.Clear(); - value.ForEach(AddBeatmapSet); - } + beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet); + beatmaps.ItemAdded += addBeatmapSet; + beatmaps.ItemRemoved += removeBeatmapSet; + + beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.ValueChanged += _ => updateSelectedSet(); + } + + private void addBeatmapSet(BeatmapSetInfo obj) + { + var newItem = new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) }; + + items.Add(newItem); + items.SetLayoutPosition(newItem, items.Count - 1); + } + + private void removeBeatmapSet(BeatmapSetInfo obj) + { + var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == obj.ID); + if (itemToRemove != null) + items.Remove(itemToRemove); + } + + private void updateSelectedSet() + { + foreach (PlaylistItem s in items.Children) + s.Selected = s.BeatmapSetInfo.ID == beatmapBacking.Value.BeatmapSetInfo.ID; } public string SearchTerm @@ -99,34 +110,7 @@ namespace osu.Game.Overlays.Music set { search.SearchTerm = value; } } - public void AddBeatmapSet(BeatmapSetInfo beatmapSet) - { - var newItem = new PlaylistItem(beatmapSet) { OnSelect = set => OnSelect?.Invoke(set) }; - - items.Add(newItem); - items.SetLayoutPosition(newItem, items.Count); - } - - public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) - { - var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == beatmapSet.ID); - if (itemToRemove != null) - items.Remove(itemToRemove); - } - - public BeatmapSetInfo SelectedSet - { - get { return items.FirstOrDefault(i => i.Selected)?.BeatmapSetInfo; } - set - { - foreach (PlaylistItem s in items.Children) - s.Selected = s.BeatmapSetInfo.ID == value?.ID; - } - } - public BeatmapSetInfo FirstVisibleSet => items.FirstOrDefault(i => i.MatchingFilter)?.BeatmapSetInfo; - public BeatmapSetInfo NextSet => (items.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? items.FirstOrDefault())?.BeatmapSetInfo; - public BeatmapSetInfo PreviousSet => (items.TakeWhile(i => !i.Selected).LastOrDefault() ?? items.LastOrDefault())?.BeatmapSetInfo; private Vector2 nativeDragPosition; private PlaylistItem draggedItem; @@ -227,6 +211,7 @@ namespace osu.Game.Overlays.Music } items.SetLayoutPosition(draggedItem, dstIndex); + OrderChanged?.Invoke(draggedItem.BeatmapSetInfo, dstIndex); } private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 3496c044fb..76c2222f8b 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -19,18 +19,16 @@ namespace osu.Game.Overlays.Music public class PlaylistOverlay : OverlayContainer { private const float transition_duration = 600; - private const float playlist_height = 510; + public Action OrderChanged; + + private BeatmapManager beatmaps; private FilterControl filter; private PlaylistList list; - private BeatmapManager beatmaps; - private readonly Bindable beatmapBacking = new Bindable(); - public IEnumerable BeatmapSets => list.BeatmapSets; - [BackgroundDependencyLoader] private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours) { @@ -60,7 +58,8 @@ namespace osu.Game.Overlays.Music { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, - OnSelect = itemSelected, + Selected = itemSelected, + OrderChanged = (s, i) => OrderChanged?.Invoke(s, i) }, filter = new FilterControl { @@ -74,30 +73,16 @@ namespace osu.Game.Overlays.Music }, }; - beatmaps.ItemAdded += handleBeatmapAdded; - beatmaps.ItemRemoved += handleBeatmapRemoved; - - list.BeatmapSets = beatmaps.GetAllUsableBeatmapSets(); - beatmapBacking.BindTo(game.Beatmap); filter.Search.OnCommit = (sender, newText) => { - var beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); - if (beatmap != null) playSpecified(beatmap); + BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); + if (beatmap != null) + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap); }; } - protected override void LoadComplete() - { - base.LoadComplete(); - beatmapBacking.ValueChanged += b => list.SelectedSet = b?.BeatmapSetInfo; - beatmapBacking.TriggerChange(); - } - - private void handleBeatmapAdded(BeatmapSetInfo setInfo) => Schedule(() => list.AddBeatmapSet(setInfo)); - private void handleBeatmapRemoved(BeatmapSetInfo setInfo) => Schedule(() => list.RemoveBeatmapSet(setInfo)); - protected override void PopIn() { filter.Search.HoldFocus = true; @@ -123,49 +108,7 @@ namespace osu.Game.Overlays.Music return; } - playSpecified(set.Beatmaps.First()); - } - - public void PlayPrevious() - { - var playable = list.PreviousSet; - - if (playable != null) - { - playSpecified(playable.Beatmaps.First()); - list.SelectedSet = playable; - } - } - - public void PlayNext() - { - var playable = list.NextSet; - - if (playable != null) - { - playSpecified(playable.Beatmaps.First()); - list.SelectedSet = playable; - } - } - - private void playSpecified(BeatmapInfo info) - { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); - - var track = beatmapBacking.Value.Track; - - track.Restart(); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (beatmaps != null) - { - beatmaps.ItemAdded -= handleBeatmapAdded; - beatmaps.ItemRemoved -= handleBeatmapRemoved; - } + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b4021f2808..c348a8f7d5 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -50,7 +51,10 @@ namespace osu.Game.Overlays private LocalisationEngine localisation; + private BeatmapManager beatmaps; private readonly Bindable beatmapBacking = new Bindable(); + private List beatmapSets; + private BeatmapSetInfo currentSet; private Container dragContainer; private Container playerContainer; @@ -93,8 +97,9 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation) + private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { + this.beatmaps = beatmaps; this.localisation = localisation; Children = new Drawable[] @@ -111,6 +116,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.X, Y = player_height + 10, + OrderChanged = playlistOrderChanged }, playerContainer = new Container { @@ -185,7 +191,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = next, + Action = () => next(), Icon = FontAwesome.fa_step_forward, }, } @@ -214,11 +220,24 @@ namespace osu.Game.Overlays } }; + beatmapSets = beatmaps.GetAllUsableBeatmapSets(); + beatmaps.ItemAdded += handleBeatmapAdded; + beatmaps.ItemRemoved += handleBeatmapRemoved; + beatmapBacking.BindTo(game.Beatmap); playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } + private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index) + { + beatmapSets.Remove(beatmapSetInfo); + beatmapSets.Insert(index, beatmapSetInfo); + } + + private void handleBeatmapAdded(BeatmapSetInfo obj) => beatmapSets.Add(obj); + private void handleBeatmapRemoved(BeatmapSetInfo obj) => beatmapSets.RemoveAll(s => s.ID == obj.ID); + protected override void LoadComplete() { beatmapBacking.ValueChanged += beatmapChanged; @@ -257,7 +276,7 @@ namespace osu.Game.Overlays playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && playlist.BeatmapSets.Any()) + if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any()) next(); } else @@ -271,7 +290,7 @@ namespace osu.Game.Overlays if (track == null) { if (!beatmapBacking.Disabled) - playlist.PlayNext(); + next(true); return; } @@ -284,13 +303,25 @@ namespace osu.Game.Overlays private void prev() { queuedDirection = TransformDirection.Prev; - playlist.PlayPrevious(); + + var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); + if (playable != null) + playSpecified(playable.Beatmaps.First()); } - private void next() + private void next(bool instant = false) { queuedDirection = TransformDirection.Next; - playlist.PlayNext(); + + var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); + if (playable != null) + playSpecified(playable.Beatmaps.First()); + } + + private void playSpecified(BeatmapInfo info) + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); + beatmapBacking.Value.Track.Restart(); } private WorkingBeatmap current; @@ -314,8 +345,8 @@ namespace osu.Game.Overlays else { //figure out the best direction based on order in playlist. - var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); - var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); + var last = beatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); + var next = beatmap == null ? -1 : beatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } From 4ceae6ba1f806f4cae2983c32e58c867d74ddad4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:45:11 +0900 Subject: [PATCH 2/3] Inline method --- osu.Game/Overlays/MusicController.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c348a8f7d5..d7884bf53a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -306,7 +306,10 @@ namespace osu.Game.Overlays var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); if (playable != null) - playSpecified(playable.Beatmaps.First()); + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); + beatmapBacking.Value.Track.Restart(); + } } private void next(bool instant = false) @@ -315,13 +318,10 @@ namespace osu.Game.Overlays var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null) - playSpecified(playable.Beatmaps.First()); - } - - private void playSpecified(BeatmapInfo info) - { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); - beatmapBacking.Value.Track.Restart(); + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); + beatmapBacking.Value.Track.Restart(); + } } private WorkingBeatmap current; From 027f6c3fa4a55e2dafb6b15588d282de465e14eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:47:38 +0900 Subject: [PATCH 3/3] Fix instant movement not doing anything --- osu.Game/Overlays/MusicController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d7884bf53a..fb4e278b0c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -314,7 +314,8 @@ namespace osu.Game.Overlays private void next(bool instant = false) { - queuedDirection = TransformDirection.Next; + if (!instant) + queuedDirection = TransformDirection.Next; var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null)