mirror of
https://github.com/ppy/osu
synced 2024-12-29 10:22:43 +00:00
Merge branch 'master' into gameplay-hud-redesign/counters
This commit is contained in:
commit
18c71c95cc
@ -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]
|
||||
|
@ -1,38 +1,69 @@
|
||||
// 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.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<OsuResumeOverlay>().Single();
|
||||
var resumeOverlayCursor = resumeOverlay.ChildrenOfType<OsuResumeOverlay.OsuClickToResumeCursor>().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<OsuResumeOverlay>().Single();
|
||||
var resumeOverlayCursor = resumeOverlay.ChildrenOfType<OsuResumeOverlay.OsuClickToResumeCursor>().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)
|
||||
|
@ -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<float> CursorScale => cursorScale;
|
||||
|
||||
private readonly Bindable<float> cursorScale = new BindableFloat(1);
|
||||
|
||||
private Bindable<float> userCursorScale = null!;
|
||||
private Bindable<bool> 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, bool>(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<float>(OsuSetting.GameplayCursorSize);
|
||||
userCursorScale.ValueChanged += _ => calculateCursorScale();
|
||||
|
||||
autoCursorScale = config.GetBindable<bool>(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, bool>(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);
|
||||
|
||||
/// <summary>
|
||||
/// Get the scale applicable to the ActiveCursor based on a beatmap's circle size.
|
||||
/// </summary>
|
||||
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[]
|
||||
{
|
||||
|
@ -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<OsuAction>
|
||||
{
|
||||
public new OsuCursor ActiveCursor => (OsuCursor)base.ActiveCursor;
|
||||
|
||||
protected override Drawable CreateCursor() => new OsuCursor();
|
||||
|
||||
protected override Container<Drawable> Content => fadeContainer;
|
||||
@ -33,13 +32,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
|
||||
private readonly Drawable cursorTrail;
|
||||
|
||||
public IBindable<float> CursorScale => cursorScale;
|
||||
|
||||
private readonly Bindable<float> cursorScale = new BindableFloat(1);
|
||||
|
||||
private Bindable<float> userCursorScale;
|
||||
private Bindable<bool> 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<float>(OsuSetting.GameplayCursorSize);
|
||||
userCursorScale.ValueChanged += _ => calculateScale();
|
||||
|
||||
autoCursorScale = config.GetBindable<bool>(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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the scale applicable to the ActiveCursor based on a beatmap's circle size.
|
||||
/// </summary>
|
||||
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<OsuAction> 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
|
||||
|
@ -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<float> 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);
|
||||
|
||||
|
BIN
osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk
Normal file
BIN
osu.Game.Tests/Resources/Archives/modified-argon-20231106.osk
Normal file
Binary file not shown.
@ -55,8 +55,10 @@ namespace osu.Game.Tests.Skins
|
||||
"Archives/modified-argon-pro-20230618.osk",
|
||||
// Covers "Argon" health display
|
||||
"Archives/modified-argon-pro-20231001.osk",
|
||||
// Covers player name text component.
|
||||
"Archives/modified-argon-20231106.osk",
|
||||
// Covers "Argon" accuracy/score/combo counters, and wedges
|
||||
"Archives/modified-argon-pro-20231105.osk",
|
||||
"Archives/modified-argon-20231108.osk",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<Colour4>(0.1f, Colour4.Black, activeForegroundColour, 0, 1);
|
||||
activeBackgroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, modTypeColour, 0, 1);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -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<Colour4>(0.1f, Colour4.Black, activeForegroundColour, 0, 1);
|
||||
activeForegroundColour = Interpolation.ValueAt<Colour4>(0.1f, Colour4.Black, modTypeColour, 0, 1);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -56,5 +56,11 @@ namespace osu.Game.Screens.Edit.Verify
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
base.PopIn();
|
||||
IssueList.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
// 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 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)
|
||||
|
40
osu.Game/Skinning/Components/PlayerName.cs
Normal file
40
osu.Game/Skinning/Components/PlayerName.cs
Normal file
@ -0,0 +1,40 @@
|
||||
// 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 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user