diff --git a/osu.Game/Collections/CollectionFilterDropdown.cs b/osu.Game/Collections/CollectionFilterDropdown.cs index ec0e9d5a89..bb743d4ccc 100644 --- a/osu.Game/Collections/CollectionFilterDropdown.cs +++ b/osu.Game/Collections/CollectionFilterDropdown.cs @@ -29,6 +29,14 @@ namespace osu.Game.Collections /// protected virtual bool ShowManageCollectionsItem => true; + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public new Bindable Current + { + get => current.Current; + set => current.Current = value; + } + private readonly IBindableList collections = new BindableList(); private readonly IBindableList beatmaps = new BindableList(); private readonly BindableList filters = new BindableList(); @@ -36,25 +44,28 @@ namespace osu.Game.Collections [Resolved(CanBeNull = true)] private ManageCollectionsDialog manageCollectionsDialog { get; set; } + [Resolved(CanBeNull = true)] + private CollectionManager collectionManager { get; set; } + public CollectionFilterDropdown() { ItemSource = filters; - } - - [BackgroundDependencyLoader(permitNulls: true)] - private void load([CanBeNull] CollectionManager collectionManager) - { - if (collectionManager != null) - collections.BindTo(collectionManager.Collections); - - collections.CollectionChanged += (_, __) => collectionsChanged(); - collectionsChanged(); + Current.Value = new AllBeatmapsCollectionFilterMenuItem(); } protected override void LoadComplete() { base.LoadComplete(); + if (collectionManager != null) + collections.BindTo(collectionManager.Collections); + + // Dropdown has logic which triggers a change on the bindable with every change to the contained items. + // This is not desirable here, as it leads to multiple filter operations running even though nothing has changed. + // An extra bindable is enough to subvert this behaviour. + base.Current = Current; + + collections.BindCollectionChanged((_, __) => collectionsChanged(), true); Current.BindValueChanged(filterChanged, true); } diff --git a/osu.Game/Collections/CollectionFilterMenuItem.cs b/osu.Game/Collections/CollectionFilterMenuItem.cs index 4a489d2945..fe79358223 100644 --- a/osu.Game/Collections/CollectionFilterMenuItem.cs +++ b/osu.Game/Collections/CollectionFilterMenuItem.cs @@ -1,6 +1,7 @@ // 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 JetBrains.Annotations; using osu.Framework.Bindables; @@ -9,7 +10,7 @@ namespace osu.Game.Collections /// /// A filter. /// - public class CollectionFilterMenuItem + public class CollectionFilterMenuItem : IEquatable { /// /// The collection to filter beatmaps from. @@ -33,6 +34,11 @@ namespace osu.Game.Collections Collection = collection; CollectionName = Collection?.Name.GetBoundCopy() ?? new Bindable("All beatmaps"); } + + public bool Equals(CollectionFilterMenuItem other) + => other != null && CollectionName.Value == other.CollectionName.Value; + + public override int GetHashCode() => CollectionName.Value.GetHashCode(); } public class AllBeatmapsCollectionFilterMenuItem : CollectionFilterMenuItem diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 952a5d1eaa..eafd8a87d1 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Select Sort = sortMode.Value, AllowConvertedBeatmaps = showConverted.Value, Ruleset = ruleset.Value, - Collection = collectionDropdown?.Current.Value.Collection + Collection = collectionDropdown?.Current.Value?.Collection }; if (!minimumStars.IsDefault)