mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 00:23:59 +09:00
Merge branch 'master' into master
This commit is contained in:
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.415.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.416.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -0,0 +1,198 @@
|
|||||||
|
// 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.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneSliderLengthValidity : TestSceneOsuEditor
|
||||||
|
{
|
||||||
|
private OsuPlayfield playfield;
|
||||||
|
|
||||||
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false);
|
||||||
|
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
AddStep("get playfield", () => playfield = Editor.ChildrenOfType<OsuPlayfield>().First());
|
||||||
|
AddStep("seek to first timing point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDraggingStartingPointRemainsValid()
|
||||||
|
{
|
||||||
|
Slider slider = null;
|
||||||
|
|
||||||
|
AddStep("Add slider", () =>
|
||||||
|
{
|
||||||
|
slider = new Slider { StartTime = EditorClock.CurrentTime, Position = new Vector2(300) };
|
||||||
|
|
||||||
|
PathControlPoint[] points =
|
||||||
|
{
|
||||||
|
new PathControlPoint(new Vector2(0), PathType.Linear),
|
||||||
|
new PathControlPoint(new Vector2(100, 0)),
|
||||||
|
};
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(points);
|
||||||
|
EditorBeatmap.Add(slider);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("ensure object placed", () => EditorBeatmap.HitObjects.Count == 1);
|
||||||
|
|
||||||
|
moveMouse(new Vector2(300));
|
||||||
|
AddStep("select slider", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
double distanceBefore = 0;
|
||||||
|
|
||||||
|
AddStep("store distance", () => distanceBefore = slider.Path.Distance);
|
||||||
|
|
||||||
|
moveMouse(new Vector2(300, 300));
|
||||||
|
|
||||||
|
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
|
||||||
|
moveMouse(new Vector2(350, 300));
|
||||||
|
moveMouse(new Vector2(400, 300));
|
||||||
|
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
|
AddAssert("slider length shrunk", () => slider.Path.Distance < distanceBefore);
|
||||||
|
AddAssert("ensure slider still has valid length", () => slider.Path.Distance > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDraggingEndingPointRemainsValid()
|
||||||
|
{
|
||||||
|
Slider slider = null;
|
||||||
|
|
||||||
|
AddStep("Add slider", () =>
|
||||||
|
{
|
||||||
|
slider = new Slider { StartTime = EditorClock.CurrentTime, Position = new Vector2(300) };
|
||||||
|
|
||||||
|
PathControlPoint[] points =
|
||||||
|
{
|
||||||
|
new PathControlPoint(new Vector2(0), PathType.Linear),
|
||||||
|
new PathControlPoint(new Vector2(100, 0)),
|
||||||
|
};
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(points);
|
||||||
|
EditorBeatmap.Add(slider);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("ensure object placed", () => EditorBeatmap.HitObjects.Count == 1);
|
||||||
|
|
||||||
|
moveMouse(new Vector2(300));
|
||||||
|
AddStep("select slider", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
double distanceBefore = 0;
|
||||||
|
|
||||||
|
AddStep("store distance", () => distanceBefore = slider.Path.Distance);
|
||||||
|
|
||||||
|
moveMouse(new Vector2(400, 300));
|
||||||
|
|
||||||
|
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
|
||||||
|
moveMouse(new Vector2(350, 300));
|
||||||
|
moveMouse(new Vector2(300, 300));
|
||||||
|
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
|
AddAssert("slider length shrunk", () => slider.Path.Distance < distanceBefore);
|
||||||
|
AddAssert("ensure slider still has valid length", () => slider.Path.Distance > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If a control point is deleted which results in the slider becoming so short it can't exist,
|
||||||
|
/// for simplicity delete the slider rather than having it in an invalid state.
|
||||||
|
///
|
||||||
|
/// Eventually we may need to change this, based on user feedback. I think it's likely enough of
|
||||||
|
/// an edge case that we won't get many complaints, though (and there's always the undo button).
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestDeletingPointCausesSliderDeletion()
|
||||||
|
{
|
||||||
|
AddStep("Add slider", () =>
|
||||||
|
{
|
||||||
|
Slider slider = new Slider { StartTime = EditorClock.CurrentTime, Position = new Vector2(300) };
|
||||||
|
|
||||||
|
PathControlPoint[] points =
|
||||||
|
{
|
||||||
|
new PathControlPoint(new Vector2(0), PathType.PerfectCurve),
|
||||||
|
new PathControlPoint(new Vector2(100, 0)),
|
||||||
|
new PathControlPoint(new Vector2(0, 10))
|
||||||
|
};
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(points);
|
||||||
|
EditorBeatmap.Add(slider);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("ensure object placed", () => EditorBeatmap.HitObjects.Count == 1);
|
||||||
|
|
||||||
|
AddStep("select slider", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
moveMouse(new Vector2(400, 300));
|
||||||
|
AddStep("delete second point", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ShiftLeft);
|
||||||
|
InputManager.Click(MouseButton.Right);
|
||||||
|
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("ensure object deleted", () => EditorBeatmap.HitObjects.Count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If a scale operation is performed where a single slider is the only thing selected, the path's shape will change.
|
||||||
|
/// If the scale results in the path becoming too short, further mouse movement in the same direction will not change the shape.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestScalingSliderTooSmallRemainsValid()
|
||||||
|
{
|
||||||
|
Slider slider = null;
|
||||||
|
|
||||||
|
AddStep("Add slider", () =>
|
||||||
|
{
|
||||||
|
slider = new Slider { StartTime = EditorClock.CurrentTime, Position = new Vector2(300, 200) };
|
||||||
|
|
||||||
|
PathControlPoint[] points =
|
||||||
|
{
|
||||||
|
new PathControlPoint(new Vector2(0), PathType.Linear),
|
||||||
|
new PathControlPoint(new Vector2(0, 50)),
|
||||||
|
new PathControlPoint(new Vector2(0, 100))
|
||||||
|
};
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(points);
|
||||||
|
EditorBeatmap.Add(slider);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("ensure object placed", () => EditorBeatmap.HitObjects.Count == 1);
|
||||||
|
|
||||||
|
moveMouse(new Vector2(300));
|
||||||
|
AddStep("select slider", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
double distanceBefore = 0;
|
||||||
|
|
||||||
|
AddStep("store distance", () => distanceBefore = slider.Path.Distance);
|
||||||
|
|
||||||
|
AddStep("move mouse to handle", () => InputManager.MoveMouseTo(Editor.ChildrenOfType<SelectionBoxDragHandle>().Skip(1).First()));
|
||||||
|
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
|
||||||
|
moveMouse(new Vector2(300, 300));
|
||||||
|
moveMouse(new Vector2(300, 250));
|
||||||
|
moveMouse(new Vector2(300, 200));
|
||||||
|
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
|
AddAssert("slider length shrunk", () => slider.Path.Distance < distanceBefore);
|
||||||
|
AddAssert("ensure slider still has valid length", () => slider.Path.Distance > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveMouse(Vector2 pos) =>
|
||||||
|
AddStep($"move mouse to {pos}", () => InputManager.MoveMouseTo(playfield.ToScreenSpace(pos)));
|
||||||
|
}
|
||||||
|
}
|
@ -41,9 +41,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
addClickStep(MouseButton.Left);
|
addClickStep(MouseButton.Left);
|
||||||
addClickStep(MouseButton.Right);
|
addClickStep(MouseButton.Right);
|
||||||
|
|
||||||
assertPlaced(true);
|
assertPlaced(false);
|
||||||
assertLength(0);
|
|
||||||
assertControlPointType(0, PathType.Linear);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -185,6 +185,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
protected override void OnDrag(DragEvent e)
|
protected override void OnDrag(DragEvent e)
|
||||||
{
|
{
|
||||||
|
Vector2[] oldControlPoints = slider.Path.ControlPoints.Select(cp => cp.Position.Value).ToArray();
|
||||||
|
var oldPosition = slider.Position;
|
||||||
|
var oldStartTime = slider.StartTime;
|
||||||
|
|
||||||
if (ControlPoint == slider.Path.ControlPoints[0])
|
if (ControlPoint == slider.Path.ControlPoints[0])
|
||||||
{
|
{
|
||||||
// Special handling for the head control point - the position of the slider changes which means the snapped position and time have to be taken into account
|
// Special handling for the head control point - the position of the slider changes which means the snapped position and time have to be taken into account
|
||||||
@ -202,6 +206,16 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
else
|
else
|
||||||
ControlPoint.Position.Value = dragStartPosition + (e.MousePosition - e.MouseDownPosition);
|
ControlPoint.Position.Value = dragStartPosition + (e.MousePosition - e.MouseDownPosition);
|
||||||
|
|
||||||
|
if (!slider.Path.HasValidLength)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < slider.Path.ControlPoints.Count; i++)
|
||||||
|
slider.Path.ControlPoints[i].Position.Value = oldControlPoints[i];
|
||||||
|
|
||||||
|
slider.Position = oldPosition;
|
||||||
|
slider.StartTime = oldStartTime;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Maintain the path type in case it got defaulted to bezier at some point during the drag.
|
// Maintain the path type in case it got defaulted to bezier at some point during the drag.
|
||||||
PointsInSegment[0].Type.Value = dragPathType;
|
PointsInSegment[0].Type.Value = dragPathType;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
private void endCurve()
|
private void endCurve()
|
||||||
{
|
{
|
||||||
updateSlider();
|
updateSlider();
|
||||||
EndPlacement(true);
|
EndPlacement(HitObject.Path.HasValidLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
|
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
|
||||||
if (controlPoints.Count <= 1)
|
if (controlPoints.Count <= 1 || !slider.HitObject.Path.HasValidLength)
|
||||||
{
|
{
|
||||||
placementHandler?.Delete(HitObject);
|
placementHandler?.Delete(HitObject);
|
||||||
return;
|
return;
|
||||||
|
@ -228,7 +228,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
Quad scaledQuad = getSurroundingQuad(new OsuHitObject[] { slider });
|
Quad scaledQuad = getSurroundingQuad(new OsuHitObject[] { slider });
|
||||||
(bool xInBounds, bool yInBounds) = isQuadInBounds(scaledQuad);
|
(bool xInBounds, bool yInBounds) = isQuadInBounds(scaledQuad);
|
||||||
|
|
||||||
if (xInBounds && yInBounds)
|
if (xInBounds && yInBounds && slider.Path.HasValidLength)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var point in slider.Path.ControlPoints)
|
foreach (var point in slider.Path.ControlPoints)
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.TypeExtensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
@ -170,7 +171,12 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
target.UnbindFrom(sourceBindable);
|
target.UnbindFrom(sourceBindable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
target.Parse(source);
|
{
|
||||||
|
if (!(target is IParseable parseable))
|
||||||
|
throw new InvalidOperationException($"Bindable type {target.GetType().ReadableName()} is not {nameof(IParseable)}.");
|
||||||
|
|
||||||
|
parseable.Parse(source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IMod other) => other is Mod them && Equals(them);
|
public bool Equals(IMod other) => other is Mod them && Equals(them);
|
||||||
|
@ -30,6 +30,8 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Bindable<double?> ExpectedDistance = new Bindable<double?>();
|
public readonly Bindable<double?> ExpectedDistance = new Bindable<double?>();
|
||||||
|
|
||||||
|
public bool HasValidLength => Distance > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control points of the path.
|
/// The control points of the path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -40,7 +40,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
private Bindable<int> indexInCurrentComboBindable;
|
private Bindable<int> indexInCurrentComboBindable;
|
||||||
private Bindable<int> comboIndexBindable;
|
private Bindable<int> comboIndexBindable;
|
||||||
|
|
||||||
private readonly Drawable circle;
|
private readonly ExtendableCircle circle;
|
||||||
|
private readonly Border border;
|
||||||
|
|
||||||
private readonly Container colouredComponents;
|
private readonly Container colouredComponents;
|
||||||
private readonly OsuSpriteText comboIndexText;
|
private readonly OsuSpriteText comboIndexText;
|
||||||
@ -62,7 +63,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = circle_size;
|
Height = circle_size;
|
||||||
|
|
||||||
AddRangeInternal(new[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
circle = new ExtendableCircle
|
circle = new ExtendableCircle
|
||||||
{
|
{
|
||||||
@ -70,6 +71,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
},
|
},
|
||||||
|
border = new Border
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
},
|
||||||
colouredComponents = new Container
|
colouredComponents = new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
@ -116,11 +123,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
protected override void OnSelected()
|
protected override void OnSelected()
|
||||||
{
|
{
|
||||||
// base logic hides selected blueprints when not selected, but timeline doesn't do that.
|
// base logic hides selected blueprints when not selected, but timeline doesn't do that.
|
||||||
|
updateComboColour();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDeselected()
|
protected override void OnDeselected()
|
||||||
{
|
{
|
||||||
// base logic hides selected blueprints when not selected, but timeline doesn't do that.
|
// base logic hides selected blueprints when not selected, but timeline doesn't do that.
|
||||||
|
updateComboColour();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateComboIndex() => comboIndexText.Text = (indexInCurrentComboBindable.Value + 1).ToString();
|
private void updateComboIndex() => comboIndexText.Text = (indexInCurrentComboBindable.Value + 1).ToString();
|
||||||
@ -133,6 +142,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
var comboColours = skin.GetConfig<GlobalSkinColours, IReadOnlyList<Color4>>(GlobalSkinColours.ComboColours)?.Value ?? Array.Empty<Color4>();
|
var comboColours = skin.GetConfig<GlobalSkinColours, IReadOnlyList<Color4>>(GlobalSkinColours.ComboColours)?.Value ?? Array.Empty<Color4>();
|
||||||
var comboColour = combo.GetComboColour(comboColours);
|
var comboColour = combo.GetComboColour(comboColours);
|
||||||
|
|
||||||
|
if (IsSelected)
|
||||||
|
{
|
||||||
|
border.Show();
|
||||||
|
comboColour = comboColour.Lighten(0.3f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
border.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (HitObject is IHasDuration duration && duration.Duration > 0)
|
if (HitObject is IHasDuration duration && duration.Duration > 0)
|
||||||
circle.Colour = ColourInfo.GradientHorizontal(comboColour, comboColour.Lighten(0.4f));
|
circle.Colour = ColourInfo.GradientHorizontal(comboColour, comboColour.Lighten(0.4f));
|
||||||
else
|
else
|
||||||
@ -340,22 +359,38 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Border : ExtendableCircle
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Content.Child.Alpha = 0;
|
||||||
|
Content.Child.AlwaysPresent = true;
|
||||||
|
|
||||||
|
Content.BorderColour = colours.Yellow;
|
||||||
|
Content.EdgeEffect = new EdgeEffectParameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A circle with externalised end caps so it can take up the full width of a relative width area.
|
/// A circle with externalised end caps so it can take up the full width of a relative width area.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExtendableCircle : CompositeDrawable
|
public class ExtendableCircle : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly Circle content;
|
protected readonly Circle Content;
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => content.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos);
|
||||||
|
|
||||||
public override Quad ScreenSpaceDrawQuad => content.ScreenSpaceDrawQuad;
|
public override Quad ScreenSpaceDrawQuad => Content.ScreenSpaceDrawQuad;
|
||||||
|
|
||||||
public ExtendableCircle()
|
public ExtendableCircle()
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding { Horizontal = -circle_size / 2f };
|
Padding = new MarginPadding { Horizontal = -circle_size / 2f };
|
||||||
InternalChild = content = new Circle
|
InternalChild = Content = new Circle
|
||||||
{
|
{
|
||||||
|
BorderColour = OsuColour.Gray(0.75f),
|
||||||
|
BorderThickness = 4,
|
||||||
|
Masking = true,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.415.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.416.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.2.0" />
|
<PackageReference Include="Sentry" Version="3.2.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.415.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.416.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.412.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
@ -93,7 +93,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.415.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.416.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Reference in New Issue
Block a user