1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-24 21:15:31 +08:00

Rename song select v2 classes and namespaces

This aims to bring some conformity to naming to make it easier to
understand component structure for new components.

Renames are pulled out of the song select v2 changes and are more
relevant there due to many new classes being added.

- `V2` suffix is dropped, with v2 components being moved to a relevant V2 namespace.
- Related classes have a prefix of the area they are used.
- Experimenting with using partial/nested classes in the song select v2 implementation.
  Not committing to this yet but want to see how it plays out.
- Moved base carousel components to a generic namespace to avoid confusion with actual beatmap carousel implementation.
This commit is contained in:
Dean Herbert
2025-04-16 18:23:14 +09:00
Unverified
parent 572bc6d8b4
commit 0aff50fbf5
40 changed files with 308 additions and 292 deletions
@@ -15,7 +15,7 @@ using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.SelectV2.Leaderboards;
using osu.Game.Screens.SelectV2;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Visual.Metadata;
using osu.Game.Tests.Visual.OnlinePlay;
@@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.DailyChallenge
AddStep("force transforms to finish", () => FinishTransforms(true));
AddStep("right click second score", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<LeaderboardScoreV2>().ElementAt(1));
InputManager.MoveMouseTo(this.ChildrenOfType<BeatmapLeaderboardScore>().ElementAt(1));
InputManager.Click(MouseButton.Right);
});
AddAssert("use these mods not present",
@@ -16,6 +16,7 @@ using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Screens.Select;
@@ -27,9 +28,9 @@ using osuTK.Graphics;
using osuTK.Input;
using BeatmapCarousel = osu.Game.Screens.SelectV2.BeatmapCarousel;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
public abstract partial class BeatmapCarouselV2TestScene : OsuManualInputManagerTestScene
public abstract partial class BeatmapCarouselTestScene : OsuManualInputManagerTestScene
{
protected readonly BindableList<BeatmapSetInfo> BeatmapSets = new BindableList<BeatmapSetInfo>();
@@ -47,7 +48,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private int beatmapCount;
protected BeatmapCarouselV2TestScene()
protected BeatmapCarouselTestScene()
{
store = new TestBeatmapStore
{
@@ -191,7 +192,7 @@ namespace osu.Game.Tests.Visual.SongSelect
.Where(p => ((ICarouselPanel)p).Item?.IsVisible == true)
.OrderBy(p => p.Y)
.ElementAt(index)
.ChildrenOfType<PanelBase>().Single()
.ChildrenOfType<Panel>().Single()
.TriggerClick();
});
}
@@ -10,13 +10,13 @@ using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
/// <summary>
/// Covers common steps which can be used for manual testing.
/// </summary>
[TestFixture]
public partial class TestSceneBeatmapCarouselV2 : BeatmapCarouselV2TestScene
public partial class TestSceneBeatmapCarousel : BeatmapCarouselTestScene
{
[Test]
[Explicit]
@@ -9,10 +9,10 @@ using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Screens.SelectV2;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
[TestFixture]
public partial class TestSceneBeatmapCarouselV2ArtistGrouping : BeatmapCarouselV2TestScene
public partial class TestSceneBeatmapCarouselArtistGrouping : BeatmapCarouselTestScene
{
[SetUpSteps]
public void SetUpSteps()
@@ -5,15 +5,16 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Screens.SelectV2;
using osuTK;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
[TestFixture]
public partial class TestSceneBeatmapCarouselV2DifficultyGrouping : BeatmapCarouselV2TestScene
public partial class TestSceneBeatmapCarouselDifficultyGrouping : BeatmapCarouselTestScene
{
[SetUpSteps]
public void SetUpSteps()
@@ -5,16 +5,17 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Screens.SelectV2;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
[TestFixture]
public partial class TestSceneBeatmapCarouselV2NoGrouping : BeatmapCarouselV2TestScene
public partial class TestSceneBeatmapCarouselNoGrouping : BeatmapCarouselTestScene
{
[SetUpSteps]
public void SetUpSteps()
@@ -8,10 +8,10 @@ using osu.Framework.Testing;
using osu.Game.Screens.Select;
using osu.Game.Screens.SelectV2;
namespace osu.Game.Tests.Visual.SongSelect
namespace osu.Game.Tests.Visual.SongSelectV2
{
[TestFixture]
public partial class TestSceneBeatmapCarouselV2Scrolling : BeatmapCarouselV2TestScene
public partial class TestSceneBeatmapCarouselScrolling : BeatmapCarouselTestScene
{
[SetUpSteps]
public void SetUpSteps()
@@ -13,19 +13,19 @@ using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.SelectV2.Footer;
using osu.Game.Screens.SelectV2;
using osu.Game.Utils;
namespace osu.Game.Tests.Visual.UserInterface
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneScreenFooterButtonMods : OsuTestScene
public partial class TestSceneFooterButtonMods : OsuTestScene
{
private readonly TestScreenFooterButtonMods footerButtonMods;
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
public TestSceneScreenFooterButtonMods()
public TestSceneFooterButtonMods()
{
Add(footerButtonMods = new TestScreenFooterButtonMods(new TestModSelectOverlay())
{
@@ -98,9 +98,9 @@ namespace osu.Game.Tests.Visual.UserInterface
public void TestUnrankedBadge()
{
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<ScreenFooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<ScreenFooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);
}
private void changeMods(IReadOnlyList<Mod> mods) => footerButtonMods.Current.Value = mods;
@@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual.UserInterface
}
}
private partial class TestScreenFooterButtonMods : ScreenFooterButtonMods
private partial class TestScreenFooterButtonMods : FooterButtonMods
{
public new OsuSpriteText MultiplierText => base.MultiplierText;
@@ -20,7 +20,7 @@ using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens.SelectV2.Leaderboards;
using osu.Game.Screens.SelectV2;
using osu.Game.Tests.Resources;
using osu.Game.Users;
using osuTK;
@@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
foreach (var scoreInfo in getTestScores())
{
fillFlow.Add(new LeaderboardScoreV2(scoreInfo)
fillFlow.Add(new BeatmapLeaderboardScore(scoreInfo)
{
Rank = scoreInfo.Position,
IsPersonalBest = scoreInfo.User.Id == 2,
@@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
foreach (var scoreInfo in getTestScores())
{
fillFlow.Add(new LeaderboardScoreV2(scoreInfo)
fillFlow.Add(new BeatmapLeaderboardScore(scoreInfo)
{
Rank = scoreInfo.Position,
IsPersonalBest = scoreInfo.User.Id == 2,
@@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
[Test]
public void TestUseTheseModsDoesNotCopySystemMods()
{
LeaderboardScoreV2 score = null!;
BeatmapLeaderboardScore score = null!;
AddStep("create content", () =>
{
@@ -146,7 +146,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
Date = DateTimeOffset.Now.AddYears(-2),
};
fillFlow.Add(score = new LeaderboardScoreV2(scoreInfo)
fillFlow.Add(score = new BeatmapLeaderboardScore(scoreInfo)
{
Rank = scoreInfo.Position,
Shear = Vector2.Zero,
@@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Overlays;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
@@ -18,14 +19,14 @@ using osuTK;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneBeatmapCarouselV2DifficultyPanel : ThemeComparisonTestScene
public partial class TestScenePanelBeatmap : ThemeComparisonTestScene
{
[Resolved]
private BeatmapManager beatmaps { get; set; } = null!;
private BeatmapInfo beatmap = null!;
public TestSceneBeatmapCarouselV2DifficultyPanel()
public TestScenePanelBeatmap()
: base(false)
{
}
@@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Overlays;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Osu;
@@ -18,14 +19,14 @@ using osuTK;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneBeatmapCarouselV2StandalonePanel : ThemeComparisonTestScene
public partial class TestScenePanelBeatmapStandalone : ThemeComparisonTestScene
{
[Resolved]
private BeatmapManager beatmaps { get; set; } = null!;
private BeatmapInfo beatmap = null!;
public TestSceneBeatmapCarouselV2StandalonePanel()
public TestScenePanelBeatmapStandalone()
: base(false)
{
}
@@ -6,15 +6,16 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Graphics.Carousel;
using osu.Game.Screens.SelectV2;
using osu.Game.Tests.Visual.UserInterface;
using osuTK;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneBeatmapCarouselV2GroupPanel : ThemeComparisonTestScene
public partial class TestScenePanelGroup : ThemeComparisonTestScene
{
public TestSceneBeatmapCarouselV2GroupPanel()
public TestScenePanelGroup()
: base(false)
{
}
@@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Overlays;
using osu.Game.Screens.SelectV2;
using osu.Game.Tests.Resources;
@@ -16,14 +17,14 @@ using osuTK;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneBeatmapCarouselV2SetPanel : ThemeComparisonTestScene
public partial class TestScenePanelSet : ThemeComparisonTestScene
{
[Resolved]
private BeatmapManager beatmaps { get; set; } = null!;
private BeatmapSetInfo beatmapSet = null!;
public TestSceneBeatmapCarouselV2SetPanel()
public TestScenePanelSet()
: base(false)
{
}
@@ -9,14 +9,14 @@ using osu.Game.Screens.SelectV2;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneUpdateBeatmapSetButtonV2 : OsuTestScene
public partial class TestScenePanelUpdateBeatmapButton : OsuTestScene
{
private UpdateBeatmapSetButton button = null!;
private PanelUpdateBeatmapButton button = null!;
[SetUp]
public void SetUp() => Schedule(() =>
{
Child = button = new UpdateBeatmapSetButton
Child = button = new PanelUpdateBeatmapButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -15,9 +15,9 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Screens.Footer;
using osu.Game.Screens.SelectV2.Footer;
using osu.Game.Screens.SelectV2;
namespace osu.Game.Tests.Visual.UserInterface
namespace osu.Game.Tests.Visual.SongSelectV2
{
public partial class TestSceneScreenFooter : OsuManualInputManagerTestScene
{
@@ -51,9 +51,9 @@ namespace osu.Game.Tests.Visual.UserInterface
screenFooter.SetButtons(new ScreenFooterButton[]
{
new ScreenFooterButtonMods(modOverlay) { Current = SelectedMods },
new ScreenFooterButtonRandom(),
new ScreenFooterButtonOptions(),
new FooterButtonMods(modOverlay) { Current = SelectedMods },
new FooterButtonRandom(),
new FooterButtonOptions(),
});
});
@@ -22,7 +22,7 @@ using osu.Game.Rulesets.Taiko;
using osu.Game.Screens;
using osu.Game.Screens.Footer;
using osu.Game.Screens.Menu;
using osu.Game.Screens.SelectV2.Footer;
using osu.Game.Screens.SelectV2;
using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelectV2
@@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
{
base.SetUpSteps();
AddStep("load screen", () => Stack.Push(new Screens.SelectV2.SoloSongSelect()));
AddStep("load screen", () => Stack.Push(new SoloSongSelect()));
AddUntilStep("wait for load", () => Stack.CurrentScreen is Screens.SelectV2.SongSelect songSelect && songSelect.IsLoaded);
}
@@ -199,7 +199,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
{
AddStep("Press F1", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<ScreenFooterButtonMods>().Single());
InputManager.MoveMouseTo(this.ChildrenOfType<FooterButtonMods>().Single());
InputManager.Click(MouseButton.Left);
});
AddAssert("Overlay visible", () => this.ChildrenOfType<ModSelectOverlay>().Single().State.Value == Visibility.Visible);
@@ -24,7 +24,7 @@ using osu.Game.Input.Bindings;
using osuTK;
using osuTK.Input;
namespace osu.Game.Screens.SelectV2
namespace osu.Game.Graphics.Carousel
{
/// <summary>
/// A highly efficient vertical list display that is used primarily for the song select screen,
@@ -3,7 +3,7 @@
using System;
namespace osu.Game.Screens.SelectV2
namespace osu.Game.Graphics.Carousel
{
/// <summary>
/// Represents a single display item for display in a <see cref="Carousel{T}"/>.
@@ -5,7 +5,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace osu.Game.Screens.SelectV2
namespace osu.Game.Graphics.Carousel
{
/// <summary>
/// An interface representing a filter operation which can be run on a <see cref="Carousel{T}"/>.
@@ -5,7 +5,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Pooling;
namespace osu.Game.Screens.SelectV2
namespace osu.Game.Graphics.Carousel
{
/// <summary>
/// An interface to be attached to any <see cref="Drawable"/>s which are used for display inside a <see cref="Carousel{T}"/>.
@@ -17,7 +17,7 @@ using osu.Game.Online.Rooms;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.SelectV2.Leaderboards;
using osu.Game.Screens.SelectV2;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.DailyChallenge
@@ -40,7 +40,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
private readonly Room room;
private readonly PlaylistItem playlistItem;
private FillFlowContainer<LeaderboardScoreV2> scoreFlow = null!;
private FillFlowContainer<BeatmapLeaderboardScore> scoreFlow = null!;
private Container userBestContainer = null!;
private SectionHeader userBestHeader = null!;
private LoadingLayer loadingLayer = null!;
@@ -91,7 +91,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Child = scoreFlow = new FillFlowContainer<LeaderboardScoreV2>
Child = scoreFlow = new FillFlowContainer<BeatmapLeaderboardScore>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
@@ -158,7 +158,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
}
else
{
LoadComponentsAsync(best.Select((s, index) => new LeaderboardScoreV2(s, sheared: false)
LoadComponentsAsync(best.Select((s, index) => new BeatmapLeaderboardScore(s, sheared: false)
{
Rank = index + 1,
IsPersonalBest = s.UserID == api.LocalUser.Value.Id,
@@ -178,7 +178,7 @@ namespace osu.Game.Screens.OnlinePlay.DailyChallenge
if (userBest != null)
{
userBestContainer.Add(new LeaderboardScoreV2(userBest, sheared: false)
userBestContainer.Add(new BeatmapLeaderboardScore(userBest, sheared: false)
{
Rank = userBest.Position,
IsPersonalBest = true,
@@ -13,6 +13,7 @@ using osu.Framework.Graphics.Pooling;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select;
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
@@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Carousel;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
using osu.Game.Utils;
@@ -41,9 +41,9 @@ using osuTK;
using osuTK.Graphics;
using CommonStrings = osu.Game.Localisation.CommonStrings;
namespace osu.Game.Screens.SelectV2.Leaderboards
namespace osu.Game.Screens.SelectV2
{
public partial class LeaderboardScoreV2 : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip<ScoreInfo>
public partial class BeatmapLeaderboardScore : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip<ScoreInfo>
{
public Bindable<IReadOnlyList<Mod>> SelectedMods = new Bindable<IReadOnlyList<Mod>>();
@@ -117,7 +117,7 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
public ITooltip<ScoreInfo> GetCustomTooltip() => new LeaderboardScoreTooltip();
public virtual ScoreInfo TooltipContent => score;
public LeaderboardScoreV2(ScoreInfo score, bool sheared = true)
public BeatmapLeaderboardScore(ScoreInfo score, bool sheared = true)
{
this.score = score;
this.sheared = sheared;
@@ -1,195 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
namespace osu.Game.Screens.SelectV2.Footer
{
public partial class BeatmapOptionsPopover : OsuPopover
{
private FillFlowContainer buttonFlow = null!;
private readonly ScreenFooterButtonOptions footerButton;
[Cached]
private readonly OverlayColourProvider colourProvider;
private WorkingBeatmap beatmapWhenOpening = null!;
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
public BeatmapOptionsPopover(ScreenFooterButtonOptions footerButton, OverlayColourProvider colourProvider)
{
this.footerButton = footerButton;
this.colourProvider = colourProvider;
}
[BackgroundDependencyLoader]
private void load(ManageCollectionsDialog? manageCollectionsDialog, OsuColour colours, BeatmapManager? beatmapManager)
{
Content.Padding = new MarginPadding(5);
Child = buttonFlow = new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(3),
};
beatmapWhenOpening = beatmap.Value;
addHeader(CommonStrings.General);
addButton(SongSelectStrings.ManageCollections, FontAwesome.Solid.Book, () => manageCollectionsDialog?.Show());
addHeader(SongSelectStrings.ForAllDifficulties, beatmapWhenOpening.BeatmapSetInfo.ToString());
addButton(SongSelectStrings.DeleteBeatmap, FontAwesome.Solid.Trash, () => { }, colours.Red1); // songSelect?.DeleteBeatmap(beatmapWhenOpening.BeatmapSetInfo);
addHeader(SongSelectStrings.ForSelectedDifficulty, beatmapWhenOpening.BeatmapInfo.DifficultyName);
// TODO: make work, and make show "unplayed" or "played" based on status.
addButton(SongSelectStrings.MarkAsPlayed, FontAwesome.Regular.TimesCircle, null);
addButton(SongSelectStrings.ClearAllLocalScores, FontAwesome.Solid.Eraser, () => { }, colours.Red1); // songSelect?.ClearScores(beatmapWhenOpening.BeatmapInfo);
// if (songSelect != null && songSelect.AllowEditing)
addButton(SongSelectStrings.EditBeatmap, FontAwesome.Solid.PencilAlt, () => { }); // songSelect.Edit(beatmapWhenOpening.BeatmapInfo);
addButton(WebCommonStrings.ButtonsHide.ToSentence(), FontAwesome.Solid.Magic, () => beatmapManager?.Hide(beatmapWhenOpening.BeatmapInfo));
}
protected override void LoadComplete()
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingFocusManager()!.ChangeFocus(this));
beatmap.BindValueChanged(_ => Hide());
}
private void addHeader(LocalisableString text, string? context = null)
{
var textFlow = new OsuTextFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding(10),
};
textFlow.AddText(text, t => t.Font = OsuFont.Default.With(weight: FontWeight.SemiBold));
if (context != null)
{
textFlow.NewLine();
textFlow.AddText(context, t =>
{
t.Colour = colourProvider.Content2;
t.Font = t.Font.With(size: 13);
});
}
buttonFlow.Add(textFlow);
}
private void addButton(LocalisableString text, IconUsage icon, Action? action, Color4? colour = null)
{
var button = new OptionButton
{
Text = text,
Icon = icon,
TextColour = colour,
Action = () =>
{
Scheduler.AddDelayed(Hide, 50);
action?.Invoke();
},
};
buttonFlow.Add(button);
}
private partial class OptionButton : OsuButton
{
public IconUsage Icon { get; init; }
public Color4? TextColour { get; init; }
public OptionButton()
{
Size = new Vector2(265, 50);
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
BackgroundColour = colourProvider.Background3;
SpriteText.Colour = TextColour ?? Color4.White;
Content.CornerRadius = 10;
Add(new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(17),
X = 15,
Icon = Icon,
Colour = TextColour ?? Color4.White,
});
}
protected override SpriteText CreateText() => new OsuSpriteText
{
Depth = -1,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
X = 40
};
}
protected override bool OnKeyDown(KeyDownEvent e)
{
// don't absorb control as ToolbarRulesetSelector uses control + number to navigate
if (e.ControlPressed) return false;
if (!e.Repeat && e.Key >= Key.Number1 && e.Key <= Key.Number9)
{
int requested = e.Key - Key.Number1;
OptionButton? found = buttonFlow.Children.OfType<OptionButton>().ElementAtOrDefault(requested);
if (found != null)
{
found.TriggerClick();
return true;
}
}
return base.OnKeyDown(e);
}
protected override void UpdateState(ValueChangedEvent<Visibility> state)
{
base.UpdateState(state);
footerButton.OverlayState.Value = state.NewValue;
}
}
}
@@ -28,9 +28,9 @@ using osu.Game.Utils;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2.Footer
namespace osu.Game.Screens.SelectV2
{
public partial class ScreenFooterButtonMods : ScreenFooterButton, IHasCurrentValue<IReadOnlyList<Mod>>
public partial class FooterButtonMods : ScreenFooterButton, IHasCurrentValue<IReadOnlyList<Mod>>
{
private const float bar_height = 30f;
private const float mod_display_portion = 0.65f;
@@ -58,7 +58,7 @@ namespace osu.Game.Screens.SelectV2.Footer
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
public ScreenFooterButtonMods(ModSelectOverlay overlay)
public FooterButtonMods(ModSelectOverlay overlay)
: base(overlay)
{
}
@@ -5,15 +5,14 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osu.Game.Screens.Footer;
namespace osu.Game.Screens.SelectV2.Footer
namespace osu.Game.Screens.SelectV2
{
public partial class ScreenFooterButtonOptions : ScreenFooterButton, IHasPopover
public partial class FooterButtonOptions : ScreenFooterButton, IHasPopover
{
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
@@ -29,6 +28,6 @@ namespace osu.Game.Screens.SelectV2.Footer
Action = this.ShowPopover;
}
public Popover GetPopover() => new BeatmapOptionsPopover(this, colourProvider);
public Framework.Graphics.UserInterface.Popover GetPopover() => new Popover(this, colourProvider);
}
}
@@ -0,0 +1,198 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
namespace osu.Game.Screens.SelectV2
{
public partial class FooterButtonOptions
{
public partial class Popover : OsuPopover
{
private FillFlowContainer buttonFlow = null!;
private readonly FooterButtonOptions footerButton;
[Cached]
private readonly OverlayColourProvider colourProvider;
private WorkingBeatmap beatmapWhenOpening = null!;
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
public Popover(FooterButtonOptions footerButton, OverlayColourProvider colourProvider)
{
this.footerButton = footerButton;
this.colourProvider = colourProvider;
}
[BackgroundDependencyLoader]
private void load(ManageCollectionsDialog? manageCollectionsDialog, OsuColour colours, BeatmapManager? beatmapManager)
{
Content.Padding = new MarginPadding(5);
Child = buttonFlow = new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(3),
};
beatmapWhenOpening = beatmap.Value;
addHeader(CommonStrings.General);
addButton(SongSelectStrings.ManageCollections, FontAwesome.Solid.Book, () => manageCollectionsDialog?.Show());
addHeader(SongSelectStrings.ForAllDifficulties, beatmapWhenOpening.BeatmapSetInfo.ToString());
addButton(SongSelectStrings.DeleteBeatmap, FontAwesome.Solid.Trash, () => { }, colours.Red1); // songSelect?.DeleteBeatmap(beatmapWhenOpening.BeatmapSetInfo);
addHeader(SongSelectStrings.ForSelectedDifficulty, beatmapWhenOpening.BeatmapInfo.DifficultyName);
// TODO: make work, and make show "unplayed" or "played" based on status.
addButton(SongSelectStrings.MarkAsPlayed, FontAwesome.Regular.TimesCircle, null);
addButton(SongSelectStrings.ClearAllLocalScores, FontAwesome.Solid.Eraser, () => { }, colours.Red1); // songSelect?.ClearScores(beatmapWhenOpening.BeatmapInfo);
// if (songSelect != null && songSelect.AllowEditing)
addButton(SongSelectStrings.EditBeatmap, FontAwesome.Solid.PencilAlt, () => { }); // songSelect.Edit(beatmapWhenOpening.BeatmapInfo);
addButton(WebCommonStrings.ButtonsHide.ToSentence(), FontAwesome.Solid.Magic, () => beatmapManager?.Hide(beatmapWhenOpening.BeatmapInfo));
}
protected override void LoadComplete()
{
base.LoadComplete();
ScheduleAfterChildren(() => GetContainingFocusManager()!.ChangeFocus(this));
beatmap.BindValueChanged(_ => Hide());
}
private void addHeader(LocalisableString text, string? context = null)
{
var textFlow = new OsuTextFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding(10),
};
textFlow.AddText(text, t => t.Font = OsuFont.Default.With(weight: FontWeight.SemiBold));
if (context != null)
{
textFlow.NewLine();
textFlow.AddText(context, t =>
{
t.Colour = colourProvider.Content2;
t.Font = t.Font.With(size: 13);
});
}
buttonFlow.Add(textFlow);
}
private void addButton(LocalisableString text, IconUsage icon, Action? action, Color4? colour = null)
{
var button = new OptionButton
{
Text = text,
Icon = icon,
TextColour = colour,
Action = () =>
{
Scheduler.AddDelayed(Hide, 50);
action?.Invoke();
},
};
buttonFlow.Add(button);
}
private partial class OptionButton : OsuButton
{
public IconUsage Icon { get; init; }
public Color4? TextColour { get; init; }
public OptionButton()
{
Size = new Vector2(265, 50);
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
BackgroundColour = colourProvider.Background3;
SpriteText.Colour = TextColour ?? Color4.White;
Content.CornerRadius = 10;
Add(new SpriteIcon
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(17),
X = 15,
Icon = Icon,
Colour = TextColour ?? Color4.White,
});
}
protected override SpriteText CreateText() => new OsuSpriteText
{
Depth = -1,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
X = 40
};
}
protected override bool OnKeyDown(KeyDownEvent e)
{
// don't absorb control as ToolbarRulesetSelector uses control + number to navigate
if (e.ControlPressed) return false;
if (!e.Repeat && e.Key >= Key.Number1 && e.Key <= Key.Number9)
{
int requested = e.Key - Key.Number1;
OptionButton? found = buttonFlow.Children.OfType<OptionButton>().ElementAtOrDefault(requested);
if (found != null)
{
found.TriggerClick();
return true;
}
}
return base.OnKeyDown(e);
}
protected override void UpdateState(ValueChangedEvent<Visibility> state)
{
base.UpdateState(state);
footerButton.OverlayState.Value = state.NewValue;
}
}
}
}
@@ -14,9 +14,9 @@ using osu.Game.Screens.Footer;
using osuTK;
using osuTK.Input;
namespace osu.Game.Screens.SelectV2.Footer
namespace osu.Game.Screens.SelectV2
{
public partial class ScreenFooterButtonRandom : ScreenFooterButton
public partial class FooterButtonRandom : ScreenFooterButton
{
public Action? NextRandom { get; set; }
public Action? PreviousRandom { get; set; }
@@ -12,6 +12,7 @@ using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osuTK;
@@ -19,7 +20,7 @@ using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public abstract partial class PanelBase : PoolableDrawable, ICarouselPanel
public abstract partial class Panel : PoolableDrawable, ICarouselPanel
{
private const float corner_radius = 10;
+6 -5
View File
@@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@@ -22,7 +23,7 @@ using osuTK;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelBeatmap : PanelBase
public partial class PanelBeatmap : Panel
{
public const float HEIGHT = CarouselItem.DEFAULT_HEIGHT;
@@ -30,7 +31,7 @@ namespace osu.Game.Screens.SelectV2
private ConstrainedIconContainer difficultyIcon = null!;
private OsuSpriteText keyCountText = null!;
private StarRatingDisplay starRatingDisplay = null!;
private TopLocalRank difficultyRank = null!;
private PanelLocalRankDisplay localRank = null!;
private OsuSpriteText difficultyText = null!;
private OsuSpriteText authorText = null!;
@@ -100,7 +101,7 @@ namespace osu.Game.Screens.SelectV2
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
},
difficultyRank = new TopLocalRank
localRank = new PanelLocalRankDisplay
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
@@ -174,7 +175,7 @@ namespace osu.Game.Screens.SelectV2
difficultyIcon.Icon = beatmap.Ruleset.CreateInstance().CreateIcon();
difficultyRank.Beatmap = beatmap;
localRank.Beatmap = beatmap;
difficultyText.Text = beatmap.DifficultyName;
authorText.Text = BeatmapsetsStrings.ShowDetailsMappedBy(beatmap.Metadata.Author.Username);
@@ -186,7 +187,7 @@ namespace osu.Game.Screens.SelectV2
{
base.FreeAfterUse();
difficultyRank.Beatmap = null;
localRank.Beatmap = null;
starDifficultyBindable = null;
}
+6 -5
View File
@@ -11,22 +11,23 @@ using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelBeatmapSet : PanelBase
public partial class PanelBeatmapSet : Panel
{
public const float HEIGHT = CarouselItem.DEFAULT_HEIGHT * 1.6f;
private BeatmapSetPanelBackground background = null!;
private PanelSetBackground background = null!;
private OsuSpriteText titleText = null!;
private OsuSpriteText artistText = null!;
private Drawable chevronIcon = null!;
private UpdateBeatmapSetButton updateButton = null!;
private PanelUpdateBeatmapButton updateButton = null!;
private BeatmapSetOnlineStatusPill statusPill = null!;
private DifficultySpectrumDisplay difficultiesDisplay = null!;
@@ -60,7 +61,7 @@ namespace osu.Game.Screens.SelectV2
},
};
Background = background = new BeatmapSetPanelBackground
Background = background = new PanelSetBackground
{
RelativeSizeAxes = Axes.Both,
};
@@ -89,7 +90,7 @@ namespace osu.Game.Screens.SelectV2
Margin = new MarginPadding { Top = 5f },
Children = new Drawable[]
{
updateButton = new UpdateBeatmapSetButton
updateButton = new PanelUpdateBeatmapButton
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
@@ -13,6 +13,7 @@ using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
@@ -23,7 +24,7 @@ using osuTK;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelBeatmapStandalone : PanelBase
public partial class PanelBeatmapStandalone : Panel
{
public const float HEIGHT = CarouselItem.DEFAULT_HEIGHT * 1.6f;
@@ -48,17 +49,17 @@ namespace osu.Game.Screens.SelectV2
private IBindable<StarDifficulty?>? starDifficultyBindable;
private CancellationTokenSource? starDifficultyCancellationSource;
private BeatmapSetPanelBackground background = null!;
private PanelSetBackground background = null!;
private OsuSpriteText titleText = null!;
private OsuSpriteText artistText = null!;
private UpdateBeatmapSetButton updateButton = null!;
private PanelUpdateBeatmapButton updateButton = null!;
private BeatmapSetOnlineStatusPill statusPill = null!;
private ConstrainedIconContainer difficultyIcon = null!;
private FillFlowContainer difficultyLine = null!;
private StarRatingDisplay difficultyStarRating = null!;
private TopLocalRank difficultyRank = null!;
private PanelLocalRankDisplay difficultyRank = null!;
private OsuSpriteText difficultyKeyCountText = null!;
private OsuSpriteText difficultyName = null!;
private OsuSpriteText difficultyAuthor = null!;
@@ -80,7 +81,7 @@ namespace osu.Game.Screens.SelectV2
Colour = colourProvider.Background5,
};
Background = background = new BeatmapSetPanelBackground
Background = background = new PanelSetBackground
{
RelativeSizeAxes = Axes.Both,
};
@@ -109,7 +110,7 @@ namespace osu.Game.Screens.SelectV2
Margin = new MarginPadding { Top = 5f },
Children = new Drawable[]
{
updateButton = new UpdateBeatmapSetButton
updateButton = new PanelUpdateBeatmapButton
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
@@ -136,7 +137,7 @@ namespace osu.Game.Screens.SelectV2
Scale = new Vector2(8f / 9f),
Margin = new MarginPadding { Right = 5f },
},
difficultyRank = new TopLocalRank
difficultyRank = new PanelLocalRankDisplay
{
Scale = new Vector2(8f / 11),
Origin = Anchor.CentreLeft,
+2 -1
View File
@@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osuTK;
@@ -18,7 +19,7 @@ using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelGroup : PanelBase
public partial class PanelGroup : Panel
{
public const float HEIGHT = CarouselItem.DEFAULT_HEIGHT * 1.2f;
@@ -18,7 +18,7 @@ using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public partial class PanelGroupStarDifficulty : PanelBase
public partial class PanelGroupStarDifficulty : Panel
{
[Resolved]
private OsuColour colours { get; set; } = null!;
@@ -19,7 +19,7 @@ using Realms;
namespace osu.Game.Screens.SelectV2
{
public partial class TopLocalRank : CompositeDrawable
public partial class PanelLocalRankDisplay : CompositeDrawable
{
private BeatmapInfo? beatmap;
@@ -48,7 +48,7 @@ namespace osu.Game.Screens.SelectV2
private readonly UpdateableRank updateable;
public TopLocalRank(BeatmapInfo? beatmap = null)
public PanelLocalRankDisplay(BeatmapInfo? beatmap = null)
{
AutoSizeAxes = Axes.Both;
@@ -14,7 +14,7 @@ using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public partial class BeatmapSetPanelBackground : ModelBackedDrawable<WorkingBeatmap>
public partial class PanelSetBackground : ModelBackedDrawable<WorkingBeatmap>
{
protected override double TransformDuration => 400;
@@ -22,7 +22,7 @@ using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
public partial class UpdateBeatmapSetButton : OsuAnimatedButton
public partial class PanelUpdateBeatmapButton : OsuAnimatedButton
{
private BeatmapSetInfo? beatmapSet;
@@ -53,7 +53,7 @@ namespace osu.Game.Screens.SelectV2
[Resolved]
private IDialogOverlay? dialogOverlay { get; set; }
public UpdateBeatmapSetButton()
public PanelUpdateBeatmapButton()
{
Size = new Vector2(75f, 22f);
}
+3 -4
View File
@@ -11,7 +11,6 @@ using osu.Game.Overlays.Mods;
using osu.Game.Screens.Footer;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Select;
using osu.Game.Screens.SelectV2.Footer;
namespace osu.Game.Screens.SelectV2
{
@@ -77,9 +76,9 @@ namespace osu.Game.Screens.SelectV2
public override IReadOnlyList<ScreenFooterButton> CreateFooterButtons() => new ScreenFooterButton[]
{
new ScreenFooterButtonMods(modSelectOverlay) { Current = Mods },
new ScreenFooterButtonRandom(),
new ScreenFooterButtonOptions(),
new FooterButtonMods(modSelectOverlay) { Current = Mods },
new FooterButtonRandom(),
new FooterButtonOptions(),
};
protected override void LoadComplete()