mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:47:26 +08:00
Merge branch 'master' into editor-new-change-diff
This commit is contained in:
commit
d13e00ed42
@ -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>();
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user