2019-09-11 04:30:07 +00:00
|
|
|
// 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.
|
|
|
|
|
2022-06-17 07:37:17 +00:00
|
|
|
#nullable disable
|
|
|
|
|
2019-09-11 04:30:07 +00:00
|
|
|
using System;
|
2021-06-22 07:19:55 +00:00
|
|
|
using System.Collections.Generic;
|
2024-04-22 05:58:45 +00:00
|
|
|
using System.Linq;
|
2019-09-11 04:30:07 +00:00
|
|
|
using NUnit.Framework;
|
|
|
|
using osu.Framework.Allocation;
|
|
|
|
using osu.Framework.Audio.Sample;
|
|
|
|
using osu.Framework.Bindables;
|
|
|
|
using osu.Framework.Graphics;
|
|
|
|
using osu.Framework.Graphics.Containers;
|
2022-08-02 10:50:57 +00:00
|
|
|
using osu.Framework.Graphics.Rendering;
|
2019-09-11 04:30:07 +00:00
|
|
|
using osu.Framework.Graphics.Textures;
|
2024-04-22 05:58:45 +00:00
|
|
|
using osu.Framework.Testing;
|
2019-09-11 04:30:07 +00:00
|
|
|
using osu.Framework.Testing.Input;
|
|
|
|
using osu.Game.Audio;
|
2020-12-04 11:21:53 +00:00
|
|
|
using osu.Game.Rulesets.Osu.Skinning.Legacy;
|
2019-09-11 04:30:07 +00:00
|
|
|
using osu.Game.Rulesets.Osu.UI.Cursor;
|
|
|
|
using osu.Game.Skinning;
|
|
|
|
using osu.Game.Tests.Visual;
|
|
|
|
using osuTK;
|
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Osu.Tests
|
|
|
|
{
|
|
|
|
public partial class TestSceneCursorTrail : OsuTestScene
|
|
|
|
{
|
2022-08-02 11:18:45 +00:00
|
|
|
[Resolved]
|
|
|
|
private IRenderer renderer { get; set; }
|
|
|
|
|
2019-09-11 04:30:07 +00:00
|
|
|
[Test]
|
|
|
|
public void TestSmoothCursorTrail()
|
|
|
|
{
|
2019-09-11 04:40:53 +00:00
|
|
|
Container scalingContainer = null;
|
|
|
|
|
|
|
|
createTest(() => scalingContainer = new Container
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Child = new CursorTrail()
|
|
|
|
});
|
|
|
|
|
|
|
|
AddStep("set large scale", () => scalingContainer.Scale = new Vector2(10));
|
2019-09-11 04:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestLegacySmoothCursorTrail()
|
|
|
|
{
|
2021-06-06 13:26:27 +00:00
|
|
|
createTest(() =>
|
2019-09-11 04:30:07 +00:00
|
|
|
{
|
2024-04-22 07:07:11 +00:00
|
|
|
var skinContainer = new LegacySkinContainer(renderer, provideMiddle: false);
|
2021-06-06 13:26:27 +00:00
|
|
|
var legacyCursorTrail = new LegacyCursorTrail(skinContainer);
|
|
|
|
|
|
|
|
skinContainer.Child = legacyCursorTrail;
|
|
|
|
|
|
|
|
return skinContainer;
|
2019-09-11 04:30:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestLegacyDisjointCursorTrail()
|
|
|
|
{
|
2021-06-06 13:26:27 +00:00
|
|
|
createTest(() =>
|
2019-09-11 04:30:07 +00:00
|
|
|
{
|
2024-04-22 07:07:11 +00:00
|
|
|
var skinContainer = new LegacySkinContainer(renderer, provideMiddle: true);
|
2021-06-06 13:26:27 +00:00
|
|
|
var legacyCursorTrail = new LegacyCursorTrail(skinContainer);
|
|
|
|
|
|
|
|
skinContainer.Child = legacyCursorTrail;
|
|
|
|
|
|
|
|
return skinContainer;
|
2019-09-11 04:30:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-04-22 05:58:45 +00:00
|
|
|
[Test]
|
|
|
|
public void TestLegacyDisjointCursorTrailViaNoCursor()
|
|
|
|
{
|
|
|
|
createTest(() =>
|
|
|
|
{
|
2024-04-22 07:07:11 +00:00
|
|
|
var skinContainer = new LegacySkinContainer(renderer, provideMiddle: false, provideCursor: false);
|
2024-04-22 05:58:45 +00:00
|
|
|
var legacyCursorTrail = new LegacyCursorTrail(skinContainer);
|
|
|
|
|
|
|
|
skinContainer.Child = legacyCursorTrail;
|
|
|
|
|
|
|
|
return skinContainer;
|
|
|
|
});
|
|
|
|
|
|
|
|
AddAssert("trail is disjoint", () => this.ChildrenOfType<LegacyCursorTrail>().Single().DisjointTrail, () => Is.True);
|
|
|
|
}
|
|
|
|
|
2024-08-20 06:20:48 +00:00
|
|
|
[Test]
|
|
|
|
public void TestClickExpand()
|
|
|
|
{
|
|
|
|
createTest(() => new Container
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Scale = new Vector2(10),
|
|
|
|
Child = new CursorTrail(),
|
|
|
|
});
|
|
|
|
|
|
|
|
AddStep("expand", () => this.ChildrenOfType<CursorTrail>().Single().NewPartScale = new Vector2(3));
|
|
|
|
AddWaitStep("let the cursor trail draw a bit", 5);
|
|
|
|
AddStep("contract", () => this.ChildrenOfType<CursorTrail>().Single().NewPartScale = Vector2.One);
|
|
|
|
}
|
|
|
|
|
2019-09-11 04:30:07 +00:00
|
|
|
private void createTest(Func<Drawable> createContent) => AddStep("create trail", () =>
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
Add(new Container
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Size = new Vector2(0.8f),
|
2023-10-25 08:55:55 +00:00
|
|
|
Child = new MovingCursorInputManager { Child = createContent() }
|
2019-09-11 04:30:07 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
[Cached(typeof(ISkinSource))]
|
|
|
|
private partial class LegacySkinContainer : Container, ISkinSource
|
|
|
|
{
|
2022-08-02 11:18:45 +00:00
|
|
|
private readonly IRenderer renderer;
|
2024-04-22 07:07:11 +00:00
|
|
|
private readonly bool provideMiddle;
|
2024-04-22 05:58:45 +00:00
|
|
|
private readonly bool provideCursor;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
2024-04-22 07:07:11 +00:00
|
|
|
public LegacySkinContainer(IRenderer renderer, bool provideMiddle, bool provideCursor = true)
|
2019-09-11 04:30:07 +00:00
|
|
|
{
|
2022-08-02 11:18:45 +00:00
|
|
|
this.renderer = renderer;
|
2024-04-22 07:07:11 +00:00
|
|
|
this.provideMiddle = provideMiddle;
|
2024-04-22 05:58:45 +00:00
|
|
|
this.provideCursor = provideCursor;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
|
|
|
RelativeSizeAxes = Axes.Both;
|
|
|
|
}
|
|
|
|
|
2022-11-09 07:04:56 +00:00
|
|
|
public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
2020-07-17 07:54:30 +00:00
|
|
|
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
|
2019-09-11 04:30:07 +00:00
|
|
|
{
|
|
|
|
switch (componentName)
|
|
|
|
{
|
2024-04-22 05:58:45 +00:00
|
|
|
case "cursor":
|
|
|
|
return provideCursor ? new Texture(renderer.WhitePixel) : null;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
2024-04-22 05:58:45 +00:00
|
|
|
case "cursortrail":
|
|
|
|
return new Texture(renderer.WhitePixel);
|
2019-09-11 04:30:07 +00:00
|
|
|
|
|
|
|
case "cursormiddle":
|
2024-04-22 07:07:11 +00:00
|
|
|
return provideMiddle ? null : renderer.WhitePixel;
|
2019-09-11 04:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-04-14 05:17:35 +00:00
|
|
|
public ISample GetSample(ISampleInfo sampleInfo) => null;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
2021-04-14 05:17:35 +00:00
|
|
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => null;
|
2019-09-11 04:30:07 +00:00
|
|
|
|
2021-06-22 09:02:21 +00:00
|
|
|
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => lookupFunction(this) ? this : null;
|
2021-05-31 08:25:21 +00:00
|
|
|
|
2021-06-22 09:02:21 +00:00
|
|
|
public IEnumerable<ISkin> AllSources => new[] { this };
|
2021-06-22 07:19:55 +00:00
|
|
|
|
2019-10-30 15:43:13 +00:00
|
|
|
public event Action SourceChanged
|
|
|
|
{
|
|
|
|
add { }
|
|
|
|
remove { }
|
|
|
|
}
|
2019-09-11 04:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private partial class MovingCursorInputManager : ManualInputManager
|
|
|
|
{
|
|
|
|
public MovingCursorInputManager()
|
|
|
|
{
|
|
|
|
UseParentInput = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void Update()
|
|
|
|
{
|
|
|
|
base.Update();
|
|
|
|
|
|
|
|
const double spin_duration = 1000;
|
|
|
|
double currentTime = Time.Current;
|
|
|
|
|
|
|
|
double angle = (currentTime % spin_duration) / spin_duration * 2 * Math.PI;
|
|
|
|
Vector2 rPos = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
|
|
|
|
|
|
|
|
MoveMouseTo(ToScreenSpace(DrawSize / 2 + DrawSize / 3 * rPos));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|