1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-19 04:32:11 +08:00

SongSelectV2: Add back ability to manage collections from beatmap / set panel context menus

This commit is contained in:
Dean Herbert
2025-05-30 15:04:41 +09:00
Unverified
parent efbdd3fffb
commit 2bbd1ee384
4 changed files with 96 additions and 0 deletions
@@ -68,6 +68,10 @@ namespace osu.Game.Screens.SelectV2
foreach (OsuMenuItem item in SongSelect.GetForwardActions(beatmap.BeatmapInfo))
{
// We can't display menus with child items here, so just ignore them.
if (item.Items.Any())
continue;
if (item is OsuMenuItemSpacer)
{
buttonFlow.Add(new Container
@@ -14,6 +14,8 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Sprites;
@@ -188,6 +190,12 @@ namespace osu.Game.Screens.SelectV2
difficultiesDisplay.BeatmapSet = null;
}
[Resolved]
private RealmAccess realm { get; set; } = null!;
[Resolved]
private ManageCollectionsDialog? manageCollectionsDialog { get; set; }
public override MenuItem[] ContextMenuItems
{
get
@@ -215,6 +223,17 @@ namespace osu.Game.Screens.SelectV2
items.Add(new OsuMenuItemSpacer());
}
var collectionItems = realm.Realm.All<BeatmapCollection>()
.OrderBy(c => c.Name)
.AsEnumerable()
.Select(createCollectionMenuItem)
.ToList();
if (manageCollectionsDialog != null)
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
items.Add(new OsuMenuItem("Collections") { Items = collectionItems });
if (beatmapSet.Beatmaps.Any(b => b.Hidden))
items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => songSelect?.RestoreAllHidden(beatmapSet)));
@@ -222,5 +241,51 @@ namespace osu.Game.Screens.SelectV2
return items.ToArray();
}
}
private MenuItem createCollectionMenuItem(BeatmapCollection collection)
{
var beatmapSet = (BeatmapSetInfo)Item!.Model;
Debug.Assert(beatmapSet != null);
TernaryState state;
int countExisting = beatmapSet.Beatmaps.Count(b => collection.BeatmapMD5Hashes.Contains(b.MD5Hash));
if (countExisting == beatmapSet.Beatmaps.Count)
state = TernaryState.True;
else if (countExisting > 0)
state = TernaryState.Indeterminate;
else
state = TernaryState.False;
var liveCollection = collection.ToLive(realm);
return new TernaryStateToggleMenuItem(collection.Name, MenuItemType.Standard, s =>
{
liveCollection.PerformWrite(c =>
{
foreach (var b in beatmapSet.Beatmaps)
{
switch (s)
{
case TernaryState.True:
if (c.BeatmapMD5Hashes.Contains(b.MD5Hash))
continue;
c.BeatmapMD5Hashes.Add(b.MD5Hash);
break;
case TernaryState.False:
c.BeatmapMD5Hashes.Remove(b.MD5Hash);
break;
}
}
});
})
{
State = { Value = state }
};
}
}
}
@@ -73,6 +73,9 @@ namespace osu.Game.Screens.SelectV2
yield return new OsuMenuItemSpacer();
}
foreach (var i in CreateCollectionMenuActions(beatmap))
yield return i;
// TODO: replace with "remove from played" button when beatmap is already played.
yield return new OsuMenuItem(SongSelectStrings.MarkAsPlayed, MenuItemType.Standard, () => beatmaps.MarkPlayed(beatmap)) { Icon = FontAwesome.Solid.TimesCircle };
yield return new OsuMenuItem(SongSelectStrings.ClearAllLocalScores, MenuItemType.Standard, () => dialogOverlay?.Push(new BeatmapClearScoresDialog(beatmap)))
+24
View File
@@ -21,6 +21,7 @@ using osu.Framework.Screens;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
@@ -659,6 +660,12 @@ namespace osu.Game.Screens.SelectV2
#region Beatmap management
[Resolved]
private ManageCollectionsDialog? manageCollectionsDialog { get; set; }
[Resolved]
private RealmAccess realm { get; set; } = null!;
public virtual IEnumerable<OsuMenuItem> GetForwardActions(BeatmapInfo beatmap)
{
yield return new OsuMenuItem("Select", MenuItemType.Highlighted, () => SelectAndStart(beatmap))
@@ -675,6 +682,23 @@ namespace osu.Game.Screens.SelectV2
if (beatmap.GetOnlineURL(api, Ruleset.Value) is string url)
yield return new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => (game as OsuGame)?.CopyToClipboard(url));
}
yield return new OsuMenuItemSpacer();
foreach (var i in CreateCollectionMenuActions(beatmap))
yield return i;
}
protected IEnumerable<OsuMenuItem> CreateCollectionMenuActions(BeatmapInfo beatmap)
{
var collectionItems = realm.Realm.All<BeatmapCollection>()
.OrderBy(c => c.Name)
.AsEnumerable()
.Select(c => new CollectionToggleMenuItem(c.ToLive(realm), beatmap)).Cast<OsuMenuItem>().ToList();
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, () => manageCollectionsDialog?.Show()));
yield return new OsuMenuItem("Collections") { Items = collectionItems };
}
public void ManageCollections() => collectionsDialog?.Show();