Merge branch 'first-run-show-get-started' into first-run-behaviour-screen

This commit is contained in:
Dean Herbert
2022-04-26 16:10:16 +09:00
51 changed files with 1009 additions and 410 deletions

View File

@ -10,11 +10,12 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Screens.Menu;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneButtonSystem : OsuTestScene
public class TestSceneButtonSystem : OsuManualInputManagerTestScene
{
private OsuLogo logo;
private ButtonSystem buttons;
@ -64,6 +65,66 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("Enter mode", performEnterMode);
}
[TestCase(Key.P, true)]
[TestCase(Key.M, true)]
[TestCase(Key.L, true)]
[TestCase(Key.E, false)]
[TestCase(Key.D, false)]
[TestCase(Key.Q, false)]
[TestCase(Key.O, false)]
public void TestShortcutKeys(Key key, bool entersPlay)
{
int activationCount = -1;
AddStep("set up action", () =>
{
activationCount = 0;
void action() => activationCount++;
switch (key)
{
case Key.P:
buttons.OnSolo = action;
break;
case Key.M:
buttons.OnMultiplayer = action;
break;
case Key.L:
buttons.OnPlaylists = action;
break;
case Key.E:
buttons.OnEdit = action;
break;
case Key.D:
buttons.OnBeatmapListing = action;
break;
case Key.Q:
buttons.OnExit = action;
break;
case Key.O:
buttons.OnSettings = action;
break;
}
});
AddStep($"press {key}", () => InputManager.Key(key));
AddAssert("state is top level", () => buttons.State == ButtonSystemState.TopLevel);
if (entersPlay)
{
AddStep("press P", () => InputManager.Key(Key.P));
AddAssert("state is play", () => buttons.State == ButtonSystemState.Play);
}
AddStep($"press {key}", () => InputManager.Key(key));
AddAssert("action triggered", () => activationCount == 1);
}
private void performEnterMode()
{
buttons.State = ButtonSystemState.EnteringMode;

View File

@ -66,6 +66,7 @@ namespace osu.Game.Tests.Visual.UserInterface
}
[Test]
[Ignore("Enable when first run setup is being displayed on first run.")]
public void TestDoesntOpenOnSecondRun()
{
AddStep("set first run", () => LocalConfig.SetValue(OsuSetting.ShowFirstRunSetup, true));
@ -165,7 +166,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("click outside content", () =>
{
InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.TopLeft - new Vector2(1));
InputManager.MoveMouseTo(new Vector2(overlay.ScreenSpaceDrawQuad.TopLeft.X, overlay.ScreenSpaceDrawQuad.Centre.Y));
InputManager.Click(MouseButton.Left);
});

View File

@ -47,12 +47,22 @@ namespace osu.Game.Tests.Visual.UserInterface
{
IncompatibilityDisplayingModPanel panel = null;
AddStep("create panel with DT", () => Child = panel = new IncompatibilityDisplayingModPanel(new OsuModDoubleTime())
AddStep("create panel with DT", () =>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.None,
Width = 300
Child = panel = new IncompatibilityDisplayingModPanel(new OsuModDoubleTime())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.None,
Width = 300,
};
panel.Active.BindValueChanged(active =>
{
SelectedMods.Value = active.NewValue
? Array.Empty<Mod>()
: new[] { panel.Mod };
});
});
clickPanel();
@ -63,11 +73,6 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("set incompatible mod", () => SelectedMods.Value = new[] { new OsuModHalfTime() });
clickPanel();
AddAssert("panel not active", () => !panel.Active.Value);
AddStep("reset mods", () => SelectedMods.Value = Array.Empty<Mod>());
clickPanel();
AddAssert("panel active", () => panel.Active.Value);

View File

@ -1,6 +1,7 @@
// 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 NUnit.Framework;
using osu.Framework.Allocation;
@ -89,6 +90,27 @@ namespace osu.Game.Tests.Visual.UserInterface
changeRuleset(3);
}
[Test]
public void TestIncompatibilityToggling()
{
createScreen();
changeRuleset(0);
AddStep("activate DT", () => getPanelForMod(typeof(OsuModDoubleTime)).TriggerClick());
AddAssert("DT active", () => SelectedMods.Value.Single().GetType() == typeof(OsuModDoubleTime));
AddStep("activate NC", () => getPanelForMod(typeof(OsuModNightcore)).TriggerClick());
AddAssert("only NC active", () => SelectedMods.Value.Single().GetType() == typeof(OsuModNightcore));
AddStep("activate HR", () => getPanelForMod(typeof(OsuModHardRock)).TriggerClick());
AddAssert("NC+HR active", () => SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModNightcore))
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModHardRock)));
AddStep("activate MR", () => getPanelForMod(typeof(OsuModMirror)).TriggerClick());
AddAssert("NC+MR active", () => SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModNightcore))
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModMirror)));
}
[Test]
public void TestCustomisationToggleState()
{
@ -136,5 +158,8 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert($"customisation toggle is {(disabled ? "" : "not ")}disabled", () => getToggle().Active.Disabled == disabled);
AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => getToggle().Active.Value == active);
}
private ModPanel getPanelForMod(Type modType)
=> modSelectScreen.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.GetType() == modType);
}
}

View File

@ -3,45 +3,79 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneSectionsContainer : OsuManualInputManagerTestScene
{
private readonly SectionsContainer<TestSection> container;
private SectionsContainer<TestSection> container;
private float custom;
private const float header_height = 100;
public TestSceneSectionsContainer()
private const float header_expandable_height = 300;
private const float header_fixed_height = 100;
[SetUpSteps]
public void SetUpSteps()
{
container = new SectionsContainer<TestSection>
AddStep("setup container", () =>
{
RelativeSizeAxes = Axes.Y,
Width = 300,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
FixedHeader = new Box
container = new SectionsContainer<TestSection>
{
Alpha = 0.5f,
RelativeSizeAxes = Axes.Y,
Width = 300,
Height = header_height,
Colour = Color4.Red
}
};
container.SelectedSection.ValueChanged += section =>
{
if (section.OldValue != null)
section.OldValue.Selected = false;
if (section.NewValue != null)
section.NewValue.Selected = true;
};
Add(container);
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
};
container.SelectedSection.ValueChanged += section =>
{
if (section.OldValue != null)
section.OldValue.Selected = false;
if (section.NewValue != null)
section.NewValue.Selected = true;
};
Child = container;
});
AddToggleStep("disable expandable header", v => container.ExpandableHeader = v
? null
: new TestBox(@"Expandable Header")
{
RelativeSizeAxes = Axes.X,
Height = header_expandable_height,
BackgroundColour = new OsuColour().GreySky,
});
AddToggleStep("disable fixed header", v => container.FixedHeader = v
? null
: new TestBox(@"Fixed Header")
{
RelativeSizeAxes = Axes.X,
Height = header_fixed_height,
BackgroundColour = new OsuColour().Red.Opacity(0.5f),
});
AddToggleStep("disable footer", v => container.Footer = v
? null
: new TestBox("Footer")
{
RelativeSizeAxes = Axes.X,
Height = 200,
BackgroundColour = new OsuColour().Green4,
});
}
[Test]
@ -71,7 +105,6 @@ namespace osu.Game.Tests.Visual.UserInterface
{
const int sections_count = 11;
float[] alternating = { 0.07f, 0.33f, 0.16f, 0.33f };
AddStep("clear", () => container.Clear());
AddStep("fill with sections", () =>
{
for (int i = 0; i < sections_count; i++)
@ -84,9 +117,9 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("correct section selected", () => container.SelectedSection.Value == container.Children[scrollIndex]);
AddUntilStep("section top is visible", () =>
{
float scrollPosition = container.ChildrenOfType<UserTrackingScrollContainer>().First().Current;
float sectionTop = container.Children[scrollIndex].BoundingBox.Top;
return scrollPosition < sectionTop;
var scrollContainer = container.ChildrenOfType<UserTrackingScrollContainer>().Single();
float sectionPosition = scrollContainer.GetChildPosInContent(container.Children[scrollIndex]);
return scrollContainer.Current < sectionPosition;
});
}
@ -101,15 +134,56 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("correct section selected", () => container.SelectedSection.Value == container.Children[sections_count - 1]);
}
private static readonly ColourInfo selected_colour = ColourInfo.GradientVertical(Color4.Yellow, Color4.Gold);
[Test]
public void TestNavigation()
{
AddRepeatStep("add sections", () => append(1f), 3);
AddUntilStep("wait for load", () => container.Children.Any());
AddStep("hover sections container", () => InputManager.MoveMouseTo(container));
AddStep("press page down", () => InputManager.Key(Key.PageDown));
AddUntilStep("scrolled one page down", () =>
{
var scroll = container.ChildrenOfType<UserTrackingScrollContainer>().First();
return Precision.AlmostEquals(scroll.Current, Content.DrawHeight - header_fixed_height, 1f);
});
AddStep("press page down", () => InputManager.Key(Key.PageDown));
AddUntilStep("scrolled two pages down", () =>
{
var scroll = container.ChildrenOfType<UserTrackingScrollContainer>().First();
return Precision.AlmostEquals(scroll.Current, (Content.DrawHeight - header_fixed_height) * 2, 1f);
});
AddStep("press page up", () => InputManager.Key(Key.PageUp));
AddUntilStep("scrolled one page up", () =>
{
var scroll = container.ChildrenOfType<UserTrackingScrollContainer>().First();
return Precision.AlmostEquals(scroll.Current, Content.DrawHeight - header_fixed_height, 1f);
});
}
private static readonly ColourInfo selected_colour = ColourInfo.GradientVertical(new OsuColour().Orange2, new OsuColour().Orange3);
private static readonly ColourInfo default_colour = ColourInfo.GradientVertical(Color4.White, Color4.DarkGray);
private void append(float multiplier)
{
container.Add(new TestSection
float fixedHeaderHeight = container.FixedHeader?.Height ?? 0;
float expandableHeaderHeight = container.ExpandableHeader?.Height ?? 0;
float totalHeaderHeight = expandableHeaderHeight + fixedHeaderHeight;
float effectiveHeaderHeight = totalHeaderHeight;
// if we're in the "next page" of the sections container,
// height of the expandable header should not be accounted.
var scrollContent = container.ChildrenOfType<UserTrackingScrollContainer>().Single().ScrollContent;
if (totalHeaderHeight + scrollContent.Height >= Content.DrawHeight)
effectiveHeaderHeight -= expandableHeaderHeight;
container.Add(new TestSection($"Section #{container.Children.Count + 1}")
{
Width = 300,
Height = (container.ChildSize.Y - header_height) * multiplier,
Height = (Content.DrawHeight - effectiveHeaderHeight) * multiplier,
Colour = default_colour
});
}
@ -120,11 +194,50 @@ namespace osu.Game.Tests.Visual.UserInterface
InputManager.ScrollVerticalBy(direction);
}
private class TestSection : Box
private class TestSection : TestBox
{
public bool Selected
{
set => Colour = value ? selected_colour : default_colour;
set => BackgroundColour = value ? selected_colour : default_colour;
}
public TestSection(string label)
: base(label)
{
BackgroundColour = default_colour;
}
}
private class TestBox : Container
{
private readonly Box background;
private readonly OsuSpriteText text;
public ColourInfo BackgroundColour
{
set
{
background.Colour = value;
text.Colour = OsuColour.ForegroundTextColourFor(value.AverageColour);
}
}
public TestBox(string label)
{
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
},
text = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = label,
Font = OsuFont.Default.With(size: 36),
}
};
}
}
}

View File

@ -0,0 +1,102 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneShearedOverlayContainer : OsuManualInputManagerTestScene
{
private TestShearedOverlayContainer overlay;
[SetUpSteps]
public void SetUpSteps()
{
AddStep("create overlay", () =>
{
Child = overlay = new TestShearedOverlayContainer
{
State = { Value = Visibility.Visible }
};
});
}
[Test]
public void TestClickAwayToExit()
{
AddStep("click inside header", () =>
{
InputManager.MoveMouseTo(overlay.ChildrenOfType<ShearedOverlayHeader>().First().ScreenSpaceDrawQuad.Centre);
InputManager.Click(MouseButton.Left);
});
AddAssert("overlay not dismissed", () => overlay.State.Value == Visibility.Visible);
AddStep("click inside content", () =>
{
InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.Centre);
InputManager.Click(MouseButton.Left);
});
AddAssert("overlay not dismissed", () => overlay.State.Value == Visibility.Visible);
AddStep("click outside header", () =>
{
InputManager.MoveMouseTo(new Vector2(overlay.ScreenSpaceDrawQuad.TopLeft.X, overlay.ScreenSpaceDrawQuad.Centre.Y));
InputManager.Click(MouseButton.Left);
});
AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
}
public class TestShearedOverlayContainer : ShearedOverlayContainer
{
protected override OverlayColourScheme ColourScheme => OverlayColourScheme.Green;
[BackgroundDependencyLoader]
private void load()
{
Header.Title = "Sheared overlay header";
Header.Description = string.Join(" ", Enumerable.Repeat("This is a description.", 20));
MainAreaContent.Child = new InputBlockingContainer
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(0.9f),
Children = new Drawable[]
{
new Box
{
Colour = Color4.Blue,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Font = OsuFont.Default.With(size: 24),
Text = "Content",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}
}
};
}
}
}
}