diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index c84a6ab70f..e6696032ae 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -94,16 +94,16 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("load content", loadContent); - AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize) * userScale); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize) * userScale); AddStep("set user scale to 1", () => config.SetValue(OsuSetting.GameplayCursorSize, 1f)); - AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize)); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize)); AddStep("turn off autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, false)); - AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == 1); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == 1); AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale)); - AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == userScale); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == userScale); } [Test] diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs index 0bb27cff0f..25d0b0a3d3 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs @@ -1,38 +1,69 @@ // Copyright (c) ppy Pty Ltd . 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.Cursor; +using osu.Framework.Testing; +using osu.Game.Configuration; using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Screens.Play; +using osu.Game.Tests.Gameplay; using osu.Game.Tests.Visual; +using osuTK; namespace osu.Game.Rulesets.Osu.Tests { public partial class TestSceneResumeOverlay : OsuManualInputManagerTestScene { + private ManualOsuInputManager osuInputManager = null!; + private CursorContainer cursor = null!; + private ResumeOverlay resume = null!; + + private bool resumeFired; + + private OsuConfigManager localConfig = null!; + + [Cached] + private GameplayState gameplayState; + public TestSceneResumeOverlay() { - ManualOsuInputManager osuInputManager; - CursorContainer cursor; - ResumeOverlay resume; + gameplayState = TestGameplayState.Create(new OsuRuleset()); + } - bool resumeFired = false; + [BackgroundDependencyLoader] + private void load() + { + Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage)); + } - Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo) + protected override void LoadComplete() + { + base.LoadComplete(); + AddSliderStep("cursor size", 0.1f, 2f, 1f, v => localConfig.SetValue(OsuSetting.GameplayCursorSize, v)); + AddSliderStep("circle size", 0f, 10f, 0f, val => { - Children = new Drawable[] - { - cursor = new CursorContainer(), - resume = new OsuResumeOverlay - { - GameplayCursor = cursor - }, - } - }; + gameplayState.Beatmap.Difficulty.CircleSize = val; + SetUp(); + }); - resume.ResumeAction = () => resumeFired = true; + AddToggleStep("auto size", v => localConfig.SetValue(OsuSetting.AutoCursorSize, v)); + } + + [SetUp] + public void SetUp() => Schedule(loadContent); + + [TestCase(1)] + [TestCase(0.5f)] + [TestCase(2)] + public void TestResume(float cursorSize) + { + AddStep($"set cursor size to {cursorSize}", () => localConfig.SetValue(OsuSetting.GameplayCursorSize, cursorSize)); AddStep("move mouse to center", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre)); AddStep("show", () => resume.Show()); @@ -41,11 +72,39 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("click", () => osuInputManager.GameClick()); AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible); - AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre)); + AddStep("move mouse just out of range", () => + { + var resumeOverlay = this.ChildrenOfType().Single(); + var resumeOverlayCursor = resumeOverlay.ChildrenOfType().Single(); + + Vector2 offset = resumeOverlay.ToScreenSpace(new Vector2(OsuCursor.SIZE / 2)) - resumeOverlay.ToScreenSpace(Vector2.Zero); + InputManager.MoveMouseTo(resumeOverlayCursor.ScreenSpaceDrawQuad.Centre - offset - new Vector2(1)); + }); + + AddStep("click", () => osuInputManager.GameClick()); + AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible); + + AddStep("move mouse just within range", () => + { + var resumeOverlay = this.ChildrenOfType().Single(); + var resumeOverlayCursor = resumeOverlay.ChildrenOfType().Single(); + + Vector2 offset = resumeOverlay.ToScreenSpace(new Vector2(OsuCursor.SIZE / 2)) - resumeOverlay.ToScreenSpace(Vector2.Zero); + InputManager.MoveMouseTo(resumeOverlayCursor.ScreenSpaceDrawQuad.Centre - offset + new Vector2(1)); + }); + AddStep("click", () => osuInputManager.GameClick()); AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden); } + private void loadContent() + { + Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo) { Children = new Drawable[] { cursor = new CursorContainer(), resume = new OsuResumeOverlay { GameplayCursor = cursor }, } }; + + resumeFired = false; + resume.ResumeAction = () => resumeFired = true; + } + private partial class ManualOsuInputManager : OsuInputManager { public ManualOsuInputManager(RulesetInfo ruleset) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 66c86ee09d..ba9fda25e4 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -4,12 +4,16 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets.Osu.Skinning; +using osu.Game.Screens.Play; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -18,30 +22,42 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { public partial class OsuCursor : SkinReloadableDrawable { - private const float size = 28; + public const float SIZE = 28; + + private const float pressed_scale = 1.2f; + private const float released_scale = 1f; private bool cursorExpand; private SkinnableDrawable cursorSprite; + private Container cursorScaleContainer = null!; private Drawable expandTarget => (cursorSprite.Drawable as OsuCursorSprite)?.ExpandTarget ?? cursorSprite; + public IBindable CursorScale => cursorScale; + + private readonly Bindable cursorScale = new BindableFloat(1); + + private Bindable userCursorScale = null!; + private Bindable autoCursorScale = null!; + + [Resolved(canBeNull: true)] + private GameplayState state { get; set; } + + [Resolved] + private OsuConfigManager config { get; set; } + public OsuCursor() { Origin = Anchor.Centre; - Size = new Vector2(size); - } - - protected override void SkinChanged(ISkinSource skin) - { - cursorExpand = skin.GetConfig(OsuSkinConfiguration.CursorExpand)?.Value ?? true; + Size = new Vector2(SIZE); } [BackgroundDependencyLoader] private void load() { - InternalChild = new Container + InternalChild = cursorScaleContainer = new Container { RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, @@ -52,10 +68,39 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Anchor = Anchor.Centre, } }; + + userCursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); + userCursorScale.ValueChanged += _ => calculateCursorScale(); + + autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); + autoCursorScale.ValueChanged += _ => calculateCursorScale(); + + cursorScale.BindValueChanged(e => cursorScaleContainer.Scale = new Vector2(e.NewValue), true); } - private const float pressed_scale = 1.2f; - private const float released_scale = 1f; + protected override void LoadComplete() + { + base.LoadComplete(); + calculateCursorScale(); + } + + private void calculateCursorScale() + { + float scale = userCursorScale.Value; + + if (autoCursorScale.Value && state != null) + { + // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. + scale *= GetScaleForCircleSize(state.Beatmap.Difficulty.CircleSize); + } + + cursorScale.Value = scale; + } + + protected override void SkinChanged(ISkinSource skin) + { + cursorExpand = skin.GetConfig(OsuSkinConfiguration.CursorExpand)?.Value ?? true; + } public void Expand() { @@ -66,6 +111,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public void Contract() => expandTarget.ScaleTo(released_scale, 400, Easing.OutQuad); + /// + /// Get the scale applicable to the ActiveCursor based on a beatmap's circle size. + /// + public static float GetScaleForCircleSize(float circleSize) => + 1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY; + private partial class DefaultCursor : OsuCursorSprite { public DefaultCursor() @@ -83,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, - BorderThickness = size / 6, + BorderThickness = SIZE / 6, BorderColour = Color4.White, EdgeEffect = new EdgeEffectParameters { @@ -105,7 +156,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, - BorderThickness = size / 3, + BorderThickness = SIZE / 3, BorderColour = Color4.White.Opacity(0.5f), Children = new Drawable[] { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index bf1ff872dd..ba8a634ff7 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -11,11 +11,8 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; -using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using osu.Game.Skinning; using osuTK; @@ -23,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { public partial class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler { + public new OsuCursor ActiveCursor => (OsuCursor)base.ActiveCursor; + protected override Drawable CreateCursor() => new OsuCursor(); protected override Container Content => fadeContainer; @@ -33,13 +32,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly Drawable cursorTrail; - public IBindable CursorScale => cursorScale; - - private readonly Bindable cursorScale = new BindableFloat(1); - - private Bindable userCursorScale; - private Bindable autoCursorScale; - private readonly CursorRippleVisualiser rippleVisualiser; public OsuCursorContainer() @@ -56,12 +48,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }; } - [Resolved(canBeNull: true)] - private GameplayState state { get; set; } - - [Resolved] - private OsuConfigManager config { get; set; } - [BackgroundDependencyLoader(true)] private void load(OsuRulesetConfigManager rulesetConfig) { @@ -74,46 +60,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true); - userCursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); - userCursorScale.ValueChanged += _ => calculateScale(); - - autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); - autoCursorScale.ValueChanged += _ => calculateScale(); - - CursorScale.BindValueChanged(e => + ActiveCursor.CursorScale.BindValueChanged(e => { var newScale = new Vector2(e.NewValue); - ActiveCursor.Scale = newScale; rippleVisualiser.CursorScale = newScale; cursorTrail.Scale = newScale; }, true); - - calculateScale(); - } - - /// - /// Get the scale applicable to the ActiveCursor based on a beatmap's circle size. - /// - public static float GetScaleForCircleSize(float circleSize) => - 1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY; - - private void calculateScale() - { - float scale = userCursorScale.Value; - - if (autoCursorScale.Value && state != null) - { - // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. - scale *= GetScaleForCircleSize(state.Beatmap.Difficulty.CircleSize); - } - - cursorScale.Value = scale; - - var newScale = new Vector2(scale); - - ActiveCursor.ScaleTo(newScale, 400, Easing.OutQuint); - cursorTrail.Scale = newScale; } private int downCount; @@ -121,9 +74,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private void updateExpandedState() { if (downCount > 0) - (ActiveCursor as OsuCursor)?.Expand(); + ActiveCursor.Expand(); else - (ActiveCursor as OsuCursor)?.Contract(); + ActiveCursor.Contract(); } public bool OnPressed(KeyBindingPressEvent e) @@ -160,13 +113,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor protected override void PopIn() { fadeContainer.FadeTo(1, 300, Easing.OutQuint); - ActiveCursor.ScaleTo(CursorScale.Value, 400, Easing.OutQuint); + ActiveCursor.ScaleTo(1f, 400, Easing.OutQuint); } protected override void PopOut() { fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint); - ActiveCursor.ScaleTo(CursorScale.Value * 0.8f, 450, Easing.OutQuint); + ActiveCursor.ScaleTo(0.8f, 450, Easing.OutQuint); } private partial class DefaultCursorTrail : CursorTrail diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index 555610a3b6..ea49836772 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -14,7 +13,6 @@ using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Screens.Play; -using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI @@ -25,7 +23,6 @@ namespace osu.Game.Rulesets.Osu.UI private OsuClickToResumeCursor clickToResumeCursor; private OsuCursorContainer localCursorContainer; - private IBindable localCursorScale; public override CursorContainer LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null; @@ -49,13 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI clickToResumeCursor.Appear(); if (localCursorContainer == null) - { Add(localCursorContainer = new OsuCursorContainer()); - - localCursorScale = new BindableFloat(); - localCursorScale.BindTo(localCursorContainer.CursorScale); - localCursorScale.BindValueChanged(scale => cursorScaleContainer.Scale = new Vector2(scale.NewValue), true); - } } protected override void PopOut() @@ -98,7 +89,8 @@ namespace osu.Game.Rulesets.Osu.UI { case OsuAction.LeftButton: case OsuAction.RightButton: - if (!IsHovered) return false; + if (!IsHovered) + return false; this.ScaleTo(2, TRANSITION_TIME, Easing.OutQuint); diff --git a/osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk b/osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk new file mode 100644 index 0000000000..70c4ff64d7 Binary files /dev/null and b/osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk differ diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 98008a003d..67f9d20fce 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -54,7 +54,9 @@ namespace osu.Game.Tests.Skins // Covers key counters "Archives/modified-argon-pro-20230618.osk", // Covers "Argon" health display - "Archives/modified-argon-pro-20231001.osk" + "Archives/modified-argon-pro-20231001.osk", + // Covers player name text component. + "Archives/modified-argon-20231106.osk", }; /// diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 5a66a5c7a6..2d2b6c3bed 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -31,19 +31,66 @@ namespace osu.Game.Tests.Visual.Gameplay Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Spacing = new Vector2(72.7f), - Children = new KeyCounterDisplay[] + Spacing = new Vector2(20), + Children = new Drawable[] { new DefaultKeyCounterDisplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, }, + new DefaultKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Scale = new Vector2(1, -1) + }, + new ArgonKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + }, new ArgonKeyCounterDisplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, - } + Scale = new Vector2(1, -1) + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Spacing = new Vector2(20), + Children = new Drawable[] + { + new DefaultKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Rotation = -90, + }, + new DefaultKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Rotation = 90, + }, + new ArgonKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Rotation = -90, + }, + new ArgonKeyCounterDisplay + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Rotation = 90, + }, + } + }, } } }; @@ -77,8 +124,15 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Disable counting", () => controller.IsCounting.Value = false); addPressKeyStep(); AddAssert($"Check {testKey} count has not changed", () => testTrigger.ActivationCount.Value == 2); + AddStep("Enable counting", () => controller.IsCounting.Value = true); + addPressKeyStep(100); + addPressKeyStep(1000); - void addPressKeyStep() => AddStep($"Press {testKey} key", () => InputManager.Key(testKey)); + void addPressKeyStep(int repeat = 1) => AddStep($"Press {testKey} key {repeat} times", () => + { + for (int i = 0; i < repeat; i++) + InputManager.Key(testKey); + }); } } } diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 75d313d98c..a417164e27 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -162,7 +162,7 @@ namespace osu.Game.Graphics return Pink1; case ModType.System: - return Gray7; + return Yellow; default: throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type"); diff --git a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs index c4e2c4c6bd..df73b15101 100644 --- a/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinSelectionHandler.cs @@ -198,12 +198,26 @@ namespace osu.Game.Overlays.SkinEditor Items = createAnchorItems((d, o) => ((Drawable)d).Origin == o, applyOrigins).ToArray() }; + yield return new EditorMenuItemSpacer(); + yield return new OsuMenuItem("Reset position", MenuItemType.Standard, () => { foreach (var blueprint in SelectedBlueprints) ((Drawable)blueprint.Item).Position = Vector2.Zero; }); + yield return new OsuMenuItem("Reset rotation", MenuItemType.Standard, () => + { + foreach (var blueprint in SelectedBlueprints) + ((Drawable)blueprint.Item).Rotation = 0; + }); + + yield return new OsuMenuItem("Reset scale", MenuItemType.Standard, () => + { + foreach (var blueprint in SelectedBlueprints) + ((Drawable)blueprint.Item).Scale = Vector2.One; + }); + yield return new EditorMenuItemSpacer(); yield return new OsuMenuItem("Bring to front", MenuItemType.Standard, () => skinEditor.BringSelectionToFront()); diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 5fd1507039..d1776c5c0b 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -138,7 +138,6 @@ namespace osu.Game.Rulesets.UI { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Colour = OsuColour.Gray(84), Alpha = 0, Font = OsuFont.Numeric.With(null, 22f), UseFullGlyphHeight = false, @@ -148,7 +147,6 @@ namespace osu.Game.Rulesets.UI { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Colour = OsuColour.Gray(84), Size = new Vector2(45), Icon = FontAwesome.Solid.Question }, @@ -206,6 +204,8 @@ namespace osu.Game.Rulesets.UI private void updateColour() { + modAcronym.Colour = modIcon.Colour = OsuColour.Gray(84); + extendedText.Colour = background.Colour = Selected.Value ? backgroundColour.Lighten(0.2f) : backgroundColour; extendedBackground.Colour = Selected.Value ? backgroundColour.Darken(2.4f) : backgroundColour.Darken(2.8f); } diff --git a/osu.Game/Rulesets/UI/ModSwitchSmall.cs b/osu.Game/Rulesets/UI/ModSwitchSmall.cs index 927379c684..6e96cc8e6f 100644 --- a/osu.Game/Rulesets/UI/ModSwitchSmall.cs +++ b/osu.Game/Rulesets/UI/ModSwitchSmall.cs @@ -85,11 +85,13 @@ namespace osu.Game.Rulesets.UI tinySwitch.Scale = new Vector2(0.3f); } + var modTypeColour = colours.ForModType(mod.Type); + inactiveForegroundColour = colourProvider?.Background5 ?? colours.Gray3; - activeForegroundColour = colours.ForModType(mod.Type); + activeForegroundColour = modTypeColour; inactiveBackgroundColour = colourProvider?.Background2 ?? colours.Gray5; - activeBackgroundColour = Interpolation.ValueAt(0.1f, Colour4.Black, activeForegroundColour, 0, 1); + activeBackgroundColour = Interpolation.ValueAt(0.1f, Colour4.Black, modTypeColour, 0, 1); } protected override void LoadComplete() diff --git a/osu.Game/Rulesets/UI/ModSwitchTiny.cs b/osu.Game/Rulesets/UI/ModSwitchTiny.cs index a3e325ace8..4d50e702af 100644 --- a/osu.Game/Rulesets/UI/ModSwitchTiny.cs +++ b/osu.Game/Rulesets/UI/ModSwitchTiny.cs @@ -106,11 +106,13 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader(true)] private void load(OsuColour colours, OverlayColourProvider? colourProvider) { + var modTypeColour = colours.ForModType(Mod.Type); + inactiveBackgroundColour = colourProvider?.Background5 ?? colours.Gray3; - activeBackgroundColour = colours.ForModType(Mod.Type); + activeBackgroundColour = modTypeColour; inactiveForegroundColour = colourProvider?.Background2 ?? colours.Gray5; - activeForegroundColour = Interpolation.ValueAt(0.1f, Colour4.Black, activeForegroundColour, 0, 1); + activeForegroundColour = Interpolation.ValueAt(0.1f, Colour4.Black, modTypeColour, 0, 1); } protected override void LoadComplete() diff --git a/osu.Game/Screens/Edit/Verify/IssueList.cs b/osu.Game/Screens/Edit/Verify/IssueList.cs index 907949aee8..d07190fca0 100644 --- a/osu.Game/Screens/Edit/Verify/IssueList.cs +++ b/osu.Game/Screens/Edit/Verify/IssueList.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Edit.Verify new RoundedButton { Text = "Refresh", - Action = refresh, + Action = Refresh, Size = new Vector2(120, 40), Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, @@ -86,13 +86,13 @@ namespace osu.Game.Screens.Edit.Verify { base.LoadComplete(); - verify.InterpretedDifficulty.BindValueChanged(_ => refresh()); - verify.HiddenIssueTypes.BindCollectionChanged((_, _) => refresh()); + verify.InterpretedDifficulty.BindValueChanged(_ => Refresh()); + verify.HiddenIssueTypes.BindCollectionChanged((_, _) => Refresh()); - refresh(); + Refresh(); } - private void refresh() + public void Refresh() { var issues = generalVerifier.Run(context); diff --git a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs index b17cf3379e..b6e0450e23 100644 --- a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs +++ b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs @@ -56,5 +56,11 @@ namespace osu.Game.Screens.Edit.Verify } }; } + + protected override void PopIn() + { + base.PopIn(); + IssueList.Refresh(); + } } } diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs index 2d725898d8..874fcde329 100644 --- a/osu.Game/Screens/Play/ArgonKeyCounter.cs +++ b/osu.Game/Screens/Play/ArgonKeyCounter.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 System; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Screens.Play.HUD; -using osuTK; namespace osu.Game.Screens.Play { @@ -17,6 +19,8 @@ namespace osu.Game.Screens.Play private OsuSpriteText keyNameText = null!; private OsuSpriteText countText = null!; + private UprightAspectMaintainingContainer uprightContainer = null!; + // These values were taken from Figma private const float line_height = 3; private const float name_font_size = 10; @@ -25,6 +29,8 @@ namespace osu.Game.Screens.Play // Make things look bigger without using Scale private const float scale_factor = 1.5f; + private const float indicator_press_offset = 4; + [Resolved] private OsuColour colours { get; set; } = null!; @@ -40,26 +46,40 @@ namespace osu.Game.Screens.Play { inputIndicator = new Circle { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, Height = line_height * scale_factor, Alpha = 0.5f }, - keyNameText = new OsuSpriteText + new Container { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Position = new Vector2(0, -13) * scale_factor, - Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold), - Colour = colours.Blue0, - Text = Trigger.Name - }, - countText = new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold), + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = line_height * scale_factor + indicator_press_offset }, + Children = new Drawable[] + { + uprightContainer = new UprightAspectMaintainingContainer + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + keyNameText = new OsuSpriteText + { + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold), + Colour = colours.Blue0, + Text = Trigger.Name + }, + countText = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold), + }, + } + } + } }, }; @@ -76,6 +96,21 @@ namespace osu.Game.Screens.Play CountPresses.BindValueChanged(e => countText.Text = e.NewValue.ToString(@"#,0"), true); } + protected override void Update() + { + base.Update(); + + const float allowance = 6; + float absRotation = Math.Abs(uprightContainer.Rotation) % 180; + bool isRotated = absRotation > allowance && absRotation < (180 - allowance); + + keyNameText.Anchor = + keyNameText.Origin = isRotated ? Anchor.TopCentre : Anchor.TopLeft; + + countText.Anchor = + countText.Origin = isRotated ? Anchor.BottomCentre : Anchor.BottomLeft; + } + protected override void Activate(bool forwardPlayback = true) { base.Activate(forwardPlayback); @@ -87,7 +122,7 @@ namespace osu.Game.Screens.Play .FadeIn(10, Easing.OutQuint) .MoveToY(0) .Then() - .MoveToY(4, 60, Easing.OutQuint); + .MoveToY(indicator_press_offset, 60, Easing.OutQuint); } protected override void Deactivate(bool forwardPlayback = true) diff --git a/osu.Game/Skinning/Components/PlayerName.cs b/osu.Game/Skinning/Components/PlayerName.cs new file mode 100644 index 0000000000..34ace53d47 --- /dev/null +++ b/osu.Game/Skinning/Components/PlayerName.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Sprites; +using osu.Game.Screens.Play; + +namespace osu.Game.Skinning.Components +{ + [UsedImplicitly] + public partial class PlayerName : FontAdjustableSkinComponent + { + private readonly OsuSpriteText text; + + public PlayerName() + { + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + } + }; + } + + [BackgroundDependencyLoader] + private void load(GameplayState gameplayState) + { + text.Text = gameplayState.Score.ScoreInfo.User.Username; + } + + protected override void SetFont(FontUsage font) => text.Font = font.With(size: 40); + } +}