diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs index e1447af9c5..29ecdaf873 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs @@ -1,23 +1,100 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; +using System; +using System.Linq; +using Newtonsoft.Json; +using NUnit.Framework; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Tournament.Screens.Editors; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Dialog; +using osu.Game.Tournament.Screens.Editors.Components; +using osuTK; +using osuTK.Input; namespace osu.Game.Tournament.Tests.Screens { public partial class TestSceneLadderEditorScreen : TournamentScreenTestScene { - [BackgroundDependencyLoader] - private void load() + private LadderEditorScreen ladderEditorScreen = null!; + private OsuContextMenuContainer? osuContextMenuContainer; + + [SetUp] + public void Setup() => Schedule(() => { - Add(new OsuContextMenuContainer + ladderEditorScreen = new LadderEditorScreen(); + Add(osuContextMenuContainer = new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, - Child = new LadderEditorScreen() + Child = ladderEditorScreen = new LadderEditorScreen() }); + }); + + [Test] + public void TestResetBracketTeamsCancelled() + { + Bindable matchBeforeReset = new Bindable(); + AddStep("save current match state", () => + { + matchBeforeReset.Value = JsonConvert.SerializeObject(Ladder.CurrentMatch.Value); + }); + AddStep("pull up context menu", () => + { + InputManager.MoveMouseTo(ladderEditorScreen); + InputManager.Click(MouseButton.Right); + }); + AddStep("click Reset teams button", () => + { + InputManager.MoveMouseTo(osuContextMenuContainer.ChildrenOfType().Last(p => + ((OsuMenuItem)p.Item).Type == MenuItemType.Destructive), new Vector2(5, 0)); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("dialog displayed", () => DialogOverlay.CurrentDialog is LadderResetTeamsDialog); + AddStep("click cancel", () => + { + InputManager.MoveMouseTo(DialogOverlay.CurrentDialog.ChildrenOfType().Last()); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("dialog dismissed", () => DialogOverlay.CurrentDialog is not LadderResetTeamsDialog); + + AddAssert("assert ladder teams unchanged", () => string.Equals(matchBeforeReset.Value, JsonConvert.SerializeObject(Ladder.CurrentMatch.Value), StringComparison.Ordinal)); + } + + [Test] + public void TestResetBracketTeams() + { + AddStep("pull up context menu", () => + { + InputManager.MoveMouseTo(ladderEditorScreen); + InputManager.Click(MouseButton.Right); + }); + + AddStep("click Reset teams button", () => + { + InputManager.MoveMouseTo(osuContextMenuContainer.ChildrenOfType().Last(p => + ((OsuMenuItem)p.Item).Type == MenuItemType.Destructive), new Vector2(5, 0)); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("dialog displayed", () => DialogOverlay.CurrentDialog is LadderResetTeamsDialog); + + AddStep("click confirmation", () => + { + InputManager.MoveMouseTo(DialogOverlay.CurrentDialog.ChildrenOfType().First()); + InputManager.PressButton(MouseButton.Left); + }); + + AddUntilStep("dialog dismissed", () => DialogOverlay.CurrentDialog is not LadderResetTeamsDialog); + + AddStep("release mouse button", () => InputManager.ReleaseButton(MouseButton.Left)); + + AddAssert("assert ladder teams reset", () => Ladder.CurrentMatch.Value.Team1.Value == null && Ladder.CurrentMatch.Value.Team2.Value == null); } } } diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs index 4faaa3dd75..c5e03f7abd 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs @@ -1,13 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { public partial class TestSceneRoundEditorScreen : TournamentScreenTestScene { - public TestSceneRoundEditorScreen() + [BackgroundDependencyLoader] + private void load() { Add(new RoundEditorScreen { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs index add66ff83e..15d4fb1f3f 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs @@ -12,7 +12,8 @@ namespace osu.Game.Tournament.Tests.Screens [Cached] private readonly LadderInfo ladder = new LadderInfo(); - public TestSceneSeedingEditorScreen() + [BackgroundDependencyLoader] + private void load() { var match = CreateSampleMatch(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs index 9e999eaf9d..71f1afbb87 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs @@ -1,13 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { public partial class TestSceneTeamEditorScreen : TournamentScreenTestScene { - public TestSceneTeamEditorScreen() + [BackgroundDependencyLoader] + private void load() { Add(new TeamEditorScreen { diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index a00a0a6e5a..84e5da62f4 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -8,6 +8,7 @@ using osu.Framework.Platform; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Tests.Visual; using osu.Game.Tournament.IO; @@ -16,8 +17,11 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests { - public abstract partial class TournamentTestScene : OsuTestScene + public abstract partial class TournamentTestScene : OsuManualInputManagerTestScene { + [Cached(typeof(IDialogOverlay))] + protected readonly DialogOverlay DialogOverlay = new DialogOverlay { Depth = float.MinValue }; + [Cached] protected LadderInfo Ladder { get; private set; } = new LadderInfo(); @@ -43,6 +47,8 @@ namespace osu.Game.Tournament.Tests Ruleset.BindTo(Ladder.Ruleset); Dependencies.CacheAs(new StableInfo(storage)); + + Add(DialogOverlay); } [SetUpSteps] diff --git a/osu.Game.Tournament/Screens/Editors/Components/DeleteRoundDialog.cs b/osu.Game.Tournament/Screens/Editors/Components/DeleteRoundDialog.cs new file mode 100644 index 0000000000..769412bf94 --- /dev/null +++ b/osu.Game.Tournament/Screens/Editors/Components/DeleteRoundDialog.cs @@ -0,0 +1,20 @@ +// 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 osu.Framework.Graphics.Sprites; +using osu.Game.Overlays.Dialog; +using osu.Game.Tournament.Models; + +namespace osu.Game.Tournament.Screens.Editors.Components +{ + public partial class DeleteRoundDialog : DangerousActionDialog + { + public DeleteRoundDialog(TournamentRound round, Action action) + { + HeaderText = round.Name.Value.Length > 0 ? $@"Delete round ""{round.Name.Value}""?" : @"Delete unnamed round?"; + Icon = FontAwesome.Solid.Trash; + DangerousAction = action; + } + } +} diff --git a/osu.Game.Tournament/Screens/Editors/Components/DeleteTeamDialog.cs b/osu.Game.Tournament/Screens/Editors/Components/DeleteTeamDialog.cs new file mode 100644 index 0000000000..65fb47cf94 --- /dev/null +++ b/osu.Game.Tournament/Screens/Editors/Components/DeleteTeamDialog.cs @@ -0,0 +1,22 @@ +// 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 osu.Framework.Graphics.Sprites; +using osu.Game.Overlays.Dialog; +using osu.Game.Tournament.Models; + +namespace osu.Game.Tournament.Screens.Editors.Components +{ + public partial class DeleteTeamDialog : DangerousActionDialog + { + public DeleteTeamDialog(TournamentTeam team, Action action) + { + HeaderText = team.FullName.Value.Length > 0 ? $@"Delete team ""{team.FullName.Value}""?" : + team.Acronym.Value.Length > 0 ? $@"Delete team ""{team.Acronym.Value}""?" : + @"Delete unnamed team?"; + Icon = FontAwesome.Solid.Trash; + DangerousAction = action; + } + } +} diff --git a/osu.Game.Tournament/Screens/Editors/Components/LadderResetTeamsDialog.cs b/osu.Game.Tournament/Screens/Editors/Components/LadderResetTeamsDialog.cs new file mode 100644 index 0000000000..8ed1b381f6 --- /dev/null +++ b/osu.Game.Tournament/Screens/Editors/Components/LadderResetTeamsDialog.cs @@ -0,0 +1,19 @@ +// 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 osu.Framework.Graphics.Sprites; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Tournament.Screens.Editors.Components +{ + public partial class LadderResetTeamsDialog : DangerousActionDialog + { + public LadderResetTeamsDialog(Action action) + { + HeaderText = @"Reset teams?"; + Icon = FontAwesome.Solid.Undo; + DangerousAction = action; + } + } +} diff --git a/osu.Game.Tournament/Screens/Editors/Components/TournamentClearAllDialog.cs b/osu.Game.Tournament/Screens/Editors/Components/TournamentClearAllDialog.cs new file mode 100644 index 0000000000..1dc7c8231d --- /dev/null +++ b/osu.Game.Tournament/Screens/Editors/Components/TournamentClearAllDialog.cs @@ -0,0 +1,19 @@ +// 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 osu.Framework.Graphics.Sprites; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Tournament.Screens.Editors.Components +{ + public partial class TournamentClearAllDialog : DangerousActionDialog + { + public TournamentClearAllDialog(Action action) + { + HeaderText = @"Clear all?"; + Icon = FontAwesome.Solid.Trash; + DangerousAction = action; + } + } +} diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index e35dbaefc9..62d18ac9e5 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -6,6 +6,7 @@ using System; using System.Drawing; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,7 +17,9 @@ using osu.Framework.Input.States; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Tournament.Components; +using osu.Game.Overlays; using osu.Game.Tournament.Models; +using osu.Game.Tournament.Screens.Editors.Components; using osu.Game.Tournament.Screens.Ladder; using osu.Game.Tournament.Screens.Ladder.Components; using osuTK; @@ -34,6 +37,10 @@ namespace osu.Game.Tournament.Screens.Editors private WarningBox rightClickMessage; + [Resolved(canBeNull: true)] + [CanBeNull] + private IDialogOverlay dialogOverlay { get; set; } + protected override bool DrawLoserPaths => true; [BackgroundDependencyLoader] @@ -87,8 +94,11 @@ namespace osu.Game.Tournament.Screens.Editors }), new OsuMenuItem("Reset teams", MenuItemType.Destructive, () => { - foreach (var p in MatchesContainer) - p.Match.Reset(); + dialogOverlay?.Push(new LadderResetTeamsDialog(() => + { + foreach (var p in MatchesContainer) + p.Match.Reset(); + })); }) }; } diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 4a3b5c0846..ff6657324d 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -11,9 +11,11 @@ using osu.Game.Graphics; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.Settings; using osu.Game.Tournament.Components; using osu.Game.Tournament.Models; +using osu.Game.Tournament.Screens.Editors.Components; using osuTK; namespace osu.Game.Tournament.Screens.Editors @@ -29,6 +31,9 @@ namespace osu.Game.Tournament.Screens.Editors [Resolved] private LadderInfo ladderInfo { get; set; } = null!; + [Resolved] + private IDialogOverlay? dialogOverlay { get; set; } + public RoundRow(TournamentRound round) { Model = round; @@ -99,11 +104,11 @@ namespace osu.Game.Tournament.Screens.Editors RelativeSizeAxes = Axes.None, Width = 150, Text = "Delete Round", - Action = () => + Action = () => dialogOverlay?.Push(new DeleteRoundDialog(Model, () => { Expire(); ladderInfo.Rounds.Remove(Model); - }, + })) } }; diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index f8d839d2fc..241692d515 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -11,8 +11,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Overlays.Settings; using osu.Game.Tournament.Models; +using osu.Game.Tournament.Screens.Editors.Components; using osu.Game.Tournament.Screens.Drawings.Components; using osu.Game.Users; using osuTK; @@ -61,6 +63,9 @@ namespace osu.Game.Tournament.Screens.Editors [Resolved] private TournamentSceneManager? sceneManager { get; set; } + [Resolved] + private IDialogOverlay? dialogOverlay { get; set; } + [Resolved] private LadderInfo ladderInfo { get; set; } = null!; @@ -157,11 +162,11 @@ namespace osu.Game.Tournament.Screens.Editors Text = "Delete Team", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - Action = () => + Action = () => dialogOverlay?.Push(new DeleteTeamDialog(Model, () => { Expire(); ladderInfo.Teams.Remove(Model); - }, + })), }, } }, diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs index 8a90777300..9dd028fa79 100644 --- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs @@ -13,7 +13,9 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osu.Game.Tournament.Components; +using osu.Game.Tournament.Screens.Editors.Components; using osuTK; namespace osu.Game.Tournament.Screens.Editors @@ -24,6 +26,9 @@ namespace osu.Game.Tournament.Screens.Editors { protected abstract BindableList Storage { get; } + [Resolved] + private IDialogOverlay? dialogOverlay { get; set; } + private FillFlowContainer flow = null!; [Resolved] @@ -79,7 +84,10 @@ namespace osu.Game.Tournament.Screens.Editors RelativeSizeAxes = Axes.X, BackgroundColour = colours.Pink3, Text = "Clear all", - Action = Storage.Clear + Action = () => + { + dialogOverlay?.Push(new TournamentClearAllDialog(() => Storage.Clear())); + } }, } } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs index acf9ff76ab..c394877ae9 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components private readonly bool editor; protected readonly FillFlowContainer Flow; private readonly Drawable selectionBox; - protected readonly Drawable CurrentMatchSelectionBox; + private readonly Drawable currentMatchSelectionBox; private Bindable globalSelection; [Resolved(CanBeNull = true)] @@ -82,7 +82,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components Padding = new MarginPadding(-(spacing + border_thickness)), Anchor = Anchor.Centre, Origin = Anchor.Centre, - Child = CurrentMatchSelectionBox = new Container + Child = currentMatchSelectionBox = new Container { RelativeSizeAxes = Axes.Both, Alpha = 0, @@ -151,9 +151,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components private void updateCurrentMatch() { if (Match.Current.Value) - CurrentMatchSelectionBox.Show(); + currentMatchSelectionBox.Show(); else - CurrentMatchSelectionBox.Hide(); + currentMatchSelectionBox.Hide(); } private bool selected; diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs index 6b35102014..9232b4c689 100644 --- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs +++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs @@ -218,8 +218,6 @@ namespace osu.Game.Tournament.Screens.Schedule Scale = new Vector2(0.8f); - CurrentMatchSelectionBox.Scale = new Vector2(1.02f, 1.15f); - bool conditional = match is ConditionalTournamentMatch; if (conditional) diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 4d7dd97e96..c79cc9cd57 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -17,6 +17,7 @@ using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osu.Game.Tournament.Models; using osuTK.Graphics; @@ -41,6 +42,9 @@ namespace osu.Game.Tournament private LoadingSpinner loadingSpinner; + [Cached(typeof(IDialogOverlay))] + private readonly DialogOverlay dialogOverlay = new DialogOverlay(); + [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig, GameHost host) { @@ -95,12 +99,12 @@ namespace osu.Game.Tournament { RelativeSizeAxes = Axes.Both, Child = new TournamentSceneManager() - } + }, + dialogOverlay }, drawables => { loadingSpinner.Hide(); loadingSpinner.Expire(); - AddRange(drawables); windowSize.BindValueChanged(size => ScheduleAfterChildren(() =>