1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 03:27:24 +08:00

Merge branch 'master' into editor-new-change-diff

This commit is contained in:
Bartłomiej Dach 2021-09-06 21:42:32 +02:00
commit d13e00ed42
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
4 changed files with 146 additions and 28 deletions

View File

@ -1,14 +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.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Overlays;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections.Input;
using osuTK;
@ -17,22 +18,34 @@ namespace osu.Game.Tests.Visual.Settings
[TestFixture]
public class TestSceneTabletSettings : OsuTestScene
{
[BackgroundDependencyLoader]
private void load(GameHost host)
{
var tabletHandler = new TestTabletHandler();
private TestTabletHandler tabletHandler;
private TabletSettings settings;
AddRange(new Drawable[]
[SetUpSteps]
public void SetUpSteps()
{
AddStep("create settings", () =>
{
new TabletSettings(tabletHandler)
tabletHandler = new TestTabletHandler();
Children = new Drawable[]
{
RelativeSizeAxes = Axes.None,
Width = SettingsPanel.PANEL_WIDTH,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
}
settings = new TabletSettings(tabletHandler)
{
RelativeSizeAxes = Axes.None,
Width = SettingsPanel.PANEL_WIDTH,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
}
};
});
AddStep("set square size", () => tabletHandler.SetTabletSize(new Vector2(100, 100)));
}
[Test]
public void TestVariousTabletSizes()
{
AddStep("Test with wide tablet", () => tabletHandler.SetTabletSize(new Vector2(160, 100)));
AddStep("Test with square tablet", () => tabletHandler.SetTabletSize(new Vector2(300, 300)));
AddStep("Test with tall tablet", () => tabletHandler.SetTabletSize(new Vector2(100, 300)));
@ -40,6 +53,71 @@ namespace osu.Game.Tests.Visual.Settings
AddStep("Test no tablet present", () => tabletHandler.SetTabletSize(Vector2.Zero));
}
[Test]
public void TestWideAspectRatioValidity()
{
AddStep("Test with wide tablet", () => tabletHandler.SetTabletSize(new Vector2(160, 100)));
AddStep("Reset to full area", () => settings.ChildrenOfType<DangerousSettingsButton>().First().TriggerClick());
ensureValid();
AddStep("rotate 10", () => tabletHandler.Rotation.Value = 10);
ensureInvalid();
AddStep("scale down", () => tabletHandler.AreaSize.Value *= 0.9f);
ensureInvalid();
AddStep("scale down", () => tabletHandler.AreaSize.Value *= 0.9f);
ensureInvalid();
AddStep("scale down", () => tabletHandler.AreaSize.Value *= 0.9f);
ensureValid();
}
[Test]
public void TestRotationValidity()
{
AddAssert("area valid", () => settings.AreaSelection.IsWithinBounds);
AddStep("rotate 90", () => tabletHandler.Rotation.Value = 90);
ensureValid();
AddStep("rotate 180", () => tabletHandler.Rotation.Value = 180);
ensureValid();
AddStep("rotate 270", () => tabletHandler.Rotation.Value = 270);
ensureValid();
AddStep("rotate 360", () => tabletHandler.Rotation.Value = 360);
ensureValid();
AddStep("rotate 0", () => tabletHandler.Rotation.Value = 0);
ensureValid();
AddStep("rotate 45", () => tabletHandler.Rotation.Value = 45);
ensureInvalid();
AddStep("rotate 0", () => tabletHandler.Rotation.Value = 0);
ensureValid();
}
[Test]
public void TestOffsetValidity()
{
ensureValid();
AddStep("move right", () => tabletHandler.AreaOffset.Value = Vector2.Zero);
ensureInvalid();
AddStep("move back", () => tabletHandler.AreaOffset.Value = tabletHandler.AreaSize.Value / 2);
ensureValid();
}
private void ensureValid() => AddAssert("area valid", () => settings.AreaSelection.IsWithinBounds);
private void ensureInvalid() => AddAssert("area invalid", () => !settings.AreaSelection.IsWithinBounds);
public class TestTabletHandler : ITabletHandler
{
public Bindable<Vector2> AreaOffset { get; } = new Bindable<Vector2>();

View File

@ -8,8 +8,9 @@ namespace osu.Game.Online.API.Requests
{
public class GetUserRequest : APIRequest<User>
{
private readonly string userIdentifier;
private readonly string lookup;
public readonly RulesetInfo Ruleset;
private readonly LookupType lookupType;
/// <summary>
/// Gets the currently logged-in user.
@ -25,7 +26,8 @@ namespace osu.Game.Online.API.Requests
/// <param name="ruleset">The ruleset to get the user's info for.</param>
public GetUserRequest(long? userId = null, RulesetInfo ruleset = null)
{
this.userIdentifier = userId.ToString();
lookup = userId.ToString();
lookupType = LookupType.Id;
Ruleset = ruleset;
}
@ -36,10 +38,17 @@ namespace osu.Game.Online.API.Requests
/// <param name="ruleset">The ruleset to get the user's info for.</param>
public GetUserRequest(string username = null, RulesetInfo ruleset = null)
{
this.userIdentifier = username;
lookup = username;
lookupType = LookupType.Username;
Ruleset = ruleset;
}
protected override string Target => userIdentifier != null ? $@"users/{userIdentifier}/{Ruleset?.ShortName}" : $@"me/{Ruleset?.ShortName}";
protected override string Target => lookup != null ? $@"users/{lookup}/{Ruleset?.ShortName}?k={lookupType.ToString().ToLower()}" : $@"me/{Ruleset?.ShortName}";
private enum LookupType
{
Id,
Username
}
}
}

View File

@ -4,10 +4,13 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.MatrixExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osuTK;
@ -17,6 +20,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
public class TabletAreaSelection : CompositeDrawable
{
public bool IsWithinBounds { get; private set; }
private readonly ITabletHandler handler;
private Container tabletContainer;
@ -109,29 +114,30 @@ namespace osu.Game.Overlays.Settings.Sections.Input
areaOffset.BindTo(handler.AreaOffset);
areaOffset.BindValueChanged(val =>
{
usableAreaContainer.MoveTo(val.NewValue, 100, Easing.OutQuint)
.OnComplete(_ => checkBounds()); // required as we are using SSDQ.
usableAreaContainer.MoveTo(val.NewValue, 100, Easing.OutQuint);
checkBounds();
}, true);
areaSize.BindTo(handler.AreaSize);
areaSize.BindValueChanged(val =>
{
usableAreaContainer.ResizeTo(val.NewValue, 100, Easing.OutQuint)
.OnComplete(_ => checkBounds()); // required as we are using SSDQ.
usableAreaContainer.ResizeTo(val.NewValue, 100, Easing.OutQuint);
int x = (int)val.NewValue.X;
int y = (int)val.NewValue.Y;
int commonDivider = greatestCommonDivider(x, y);
usableAreaText.Text = $"{(float)x / commonDivider}:{(float)y / commonDivider}";
checkBounds();
}, true);
rotation.BindTo(handler.Rotation);
rotation.BindValueChanged(val =>
{
usableAreaContainer.RotateTo(val.NewValue, 100, Easing.OutQuint);
tabletContainer.RotateTo(-val.NewValue, 800, Easing.OutQuint);
usableAreaContainer.RotateTo(val.NewValue, 100, Easing.OutQuint)
.OnComplete(_ => checkBounds()); // required as we are using SSDQ.
checkBounds();
}, true);
tablet.BindTo(handler.Tablet);
@ -169,12 +175,35 @@ namespace osu.Game.Overlays.Settings.Sections.Input
if (tablet.Value == null)
return;
var usableSsdq = usableAreaContainer.ScreenSpaceDrawQuad;
// allow for some degree of floating point error, as we don't care about being perfect here.
const float lenience = 0.5f;
bool isWithinBounds = tabletContainer.ScreenSpaceDrawQuad.Contains(usableSsdq.TopLeft + new Vector2(1)) &&
tabletContainer.ScreenSpaceDrawQuad.Contains(usableSsdq.BottomRight - new Vector2(1));
var tabletArea = new Quad(-lenience, -lenience, tablet.Value.Size.X + lenience * 2, tablet.Value.Size.Y + lenience * 2);
usableFill.FadeColour(isWithinBounds ? colour.Blue : colour.RedLight, 100);
var halfUsableArea = areaSize.Value / 2;
var offset = areaOffset.Value;
var usableAreaQuad = new Quad(
new Vector2(-halfUsableArea.X, -halfUsableArea.Y),
new Vector2(halfUsableArea.X, -halfUsableArea.Y),
new Vector2(-halfUsableArea.X, halfUsableArea.Y),
new Vector2(halfUsableArea.X, halfUsableArea.Y)
);
var matrix = Matrix3.Identity;
MatrixExtensions.TranslateFromLeft(ref matrix, offset);
MatrixExtensions.RotateFromLeft(ref matrix, MathUtils.DegreesToRadians(rotation.Value));
usableAreaQuad *= matrix;
IsWithinBounds =
tabletArea.Contains(usableAreaQuad.TopLeft) &&
tabletArea.Contains(usableAreaQuad.TopRight) &&
tabletArea.Contains(usableAreaQuad.BottomLeft) &&
tabletArea.Contains(usableAreaQuad.BottomRight);
usableFill.FadeColour(IsWithinBounds ? colour.Blue : colour.RedLight, 100);
}
protected override void Update()

View File

@ -20,6 +20,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
public class TabletSettings : SettingsSubsection
{
public TabletAreaSelection AreaSelection { get; private set; }
private readonly ITabletHandler tabletHandler;
private readonly Bindable<bool> enabled = new BindableBool(true);
@ -121,7 +123,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new TabletAreaSelection(tabletHandler)
AreaSelection = new TabletAreaSelection(tabletHandler)
{
RelativeSizeAxes = Axes.X,
Height = 300,