From 7a3ebcd0b1c77b7caaac8c88f0a722353acd4a25 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 15:52:38 +0900 Subject: [PATCH 01/16] Fix path changes not updating tail circle --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 010bf072e8..f60b7e67b2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -37,6 +37,8 @@ namespace osu.Game.Rulesets.Osu.Objects { PathBindable.Value = value; endPositionCache.Invalidate(); + + updateNestedPositions(); } } @@ -48,14 +50,9 @@ namespace osu.Game.Rulesets.Osu.Objects set { base.Position = value; - endPositionCache.Invalidate(); - if (HeadCircle != null) - HeadCircle.Position = value; - - if (TailCircle != null) - TailCircle.Position = EndPosition; + updateNestedPositions(); } } @@ -197,6 +194,15 @@ namespace osu.Game.Rulesets.Osu.Objects } } + private void updateNestedPositions() + { + if (HeadCircle != null) + HeadCircle.Position = Position; + + if (TailCircle != null) + TailCircle.Position = EndPosition; + } + private List getNodeSamples(int nodeIndex) => nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples; From e23a75c64a400705b202122570ca1f41d09c0735 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 16:23:54 +0900 Subject: [PATCH 02/16] Implement control point selection --- .../Components/PathControlPointPiece.cs | 84 +++++++++++++++---- .../Components/PathControlPointVisualiser.cs | 21 +++++ 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 7afb8fcf49..3b0b9bce1f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; @@ -11,18 +12,21 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class PathControlPointPiece : BlueprintPiece { public Action ControlPointsChanged; + public readonly Bindable IsSelected = new Bindable(); + + public readonly int Index; private readonly Slider slider; - private readonly int index; - private readonly Path path; - private readonly CircularContainer marker; + private readonly Container marker; + private readonly Drawable markerRing; [Resolved] private OsuColour colours { get; set; } @@ -30,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components public PathControlPointPiece(Slider slider, int index) { this.slider = slider; - this.index = index; + Index = index; Origin = Anchor.Centre; AutoSizeAxes = Axes.Both; @@ -42,13 +46,36 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components Anchor = Anchor.Centre, PathRadius = 1 }, - marker = new CircularContainer + marker = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(10), - Masking = true, - Child = new Box { RelativeSizeAxes = Axes.Both } + AutoSizeAxes = Axes.Both, + Children = new[] + { + new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(10), + }, + markerRing = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(14), + Masking = true, + BorderThickness = 2, + BorderColour = Color4.White, + Alpha = 0, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + } } }; } @@ -57,21 +84,42 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { base.Update(); - Position = slider.StackedPosition + slider.Path.ControlPoints[index]; + Position = slider.StackedPosition + slider.Path.ControlPoints[Index]; - marker.Colour = isSegmentSeparator ? colours.Red : colours.Yellow; + updateMarkerDisplay(); + updateConnectingPath(); + } + /// + /// Updates the state of the circular control point marker. + /// + private void updateMarkerDisplay() + { + markerRing.Alpha = IsSelected.Value ? 1 : 0; + + Color4 colour = isSegmentSeparator ? colours.Red : colours.Yellow; + if (IsHovered || IsSelected.Value) + colour = Color4.White; + marker.Colour = colour; + } + + /// + /// Updates the path connecting this control point to the previous one. + /// + private void updateConnectingPath() + { path.ClearVertices(); - if (index != slider.Path.ControlPoints.Length - 1) + if (Index != slider.Path.ControlPoints.Length - 1) { path.AddVertex(Vector2.Zero); - path.AddVertex(slider.Path.ControlPoints[index + 1] - slider.Path.ControlPoints[index]); + path.AddVertex(slider.Path.ControlPoints[Index + 1] - slider.Path.ControlPoints[Index]); } path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero); } + // The connecting path is excluded from positional input public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => marker.ReceivePositionalInputAt(screenSpacePos); protected override bool OnDragStart(DragStartEvent e) => true; @@ -80,7 +128,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { var newControlPoints = slider.Path.ControlPoints.ToArray(); - if (index == 0) + if (Index == 0) { // Special handling for the head - only the position of the slider changes slider.Position += e.Delta; @@ -90,13 +138,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components newControlPoints[i] -= e.Delta; } else - newControlPoints[index] += e.Delta; + newControlPoints[Index] += e.Delta; if (isSegmentSeparatorWithNext) - newControlPoints[index + 1] = newControlPoints[index]; + newControlPoints[Index + 1] = newControlPoints[Index]; if (isSegmentSeparatorWithPrevious) - newControlPoints[index - 1] = newControlPoints[index]; + newControlPoints[Index - 1] = newControlPoints[Index]; ControlPointsChanged?.Invoke(newControlPoints); @@ -107,8 +155,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private bool isSegmentSeparator => isSegmentSeparatorWithNext || isSegmentSeparatorWithPrevious; - private bool isSegmentSeparatorWithNext => index < slider.Path.ControlPoints.Length - 1 && slider.Path.ControlPoints[index + 1] == slider.Path.ControlPoints[index]; + private bool isSegmentSeparatorWithNext => Index < slider.Path.ControlPoints.Length - 1 && slider.Path.ControlPoints[Index + 1] == slider.Path.ControlPoints[Index]; - private bool isSegmentSeparatorWithPrevious => index > 0 && slider.Path.ControlPoints[index - 1] == slider.Path.ControlPoints[index]; + private bool isSegmentSeparatorWithPrevious => Index > 0 && slider.Path.ControlPoints[Index - 1] == slider.Path.ControlPoints[Index]; } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 0385824b27..b0e579907d 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.Objects; using osuTK; @@ -21,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { this.slider = slider; + RelativeSizeAxes = Axes.Both; + InternalChild = pieces = new Container { RelativeSizeAxes = Axes.Both }; } @@ -33,5 +36,23 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components while (slider.Path.ControlPoints.Length < pieces.Count) pieces.Remove(pieces[pieces.Count - 1]); } + + protected override bool OnMouseDown(MouseDownEvent e) + { + bool anySelected = false; + + foreach (var piece in pieces) + { + if (piece.IsHovered) + { + piece.IsSelected.Value = true; + anySelected = true; + } + else + piece.IsSelected.Value = false; + } + + return anySelected; + } } } From cfdf7106764b904c733e001eeba71b1e6b005d97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 16:51:58 +0900 Subject: [PATCH 03/16] Add test --- .../TestSceneSliderSelectionBlueprint.cs | 33 +++++++++++++++++++ .../Components/PathControlPointVisualiser.cs | 16 ++++----- .../Sliders/SliderSelectionBlueprint.cs | 3 +- .../Visual/SelectionBlueprintTestScene.cs | 2 +- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs index 5df0b70f12..0e7d8c9c08 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Tests.Visual; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests { @@ -85,6 +86,25 @@ namespace osu.Game.Rulesets.Osu.Tests checkPositions(); } + [Test] + public void TestSingleControlPointSelection() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + checkControlPointSelected(0, true); + checkControlPointSelected(1, false); + + moveMouseToControlPoint(1); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + checkControlPointSelected(0, false); + checkControlPointSelected(1, true); + + AddStep("move mouse outside control point", () => InputManager.MoveMouseTo(drawableObject)); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + checkControlPointSelected(0, false); + checkControlPointSelected(1, false); + } + private void moveHitObject() { AddStep("move hitobject", () => @@ -104,11 +124,24 @@ namespace osu.Game.Rulesets.Osu.Tests () => Precision.AlmostEquals(blueprint.TailBlueprint.CirclePiece.ScreenSpaceDrawQuad.Centre, drawableObject.TailCircle.ScreenSpaceDrawQuad.Centre)); } + private void moveMouseToControlPoint(int index) + { + AddStep($"move mouse to control point {index}", () => + { + Vector2 position = slider.Position + slider.Path.ControlPoints[index]; + InputManager.MoveMouseTo(drawableObject.Parent.ToScreenSpace(position)); + }); + } + + private void checkControlPointSelected(int index, bool selected) + => AddAssert($"control point {index} {(selected ? "selected" : "not selected")}", () => blueprint.ControlPointVisualiser.Pieces[index].IsSelected.Value == selected); + private class TestSliderBlueprint : SliderSelectionBlueprint { public new SliderBodyPiece BodyPiece => base.BodyPiece; public new TestSliderCircleBlueprint HeadBlueprint => (TestSliderCircleBlueprint)base.HeadBlueprint; public new TestSliderCircleBlueprint TailBlueprint => (TestSliderCircleBlueprint)base.TailBlueprint; + public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; public TestSliderBlueprint(DrawableSlider slider) : base(slider) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index b0e579907d..6efa0ef550 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -14,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public Action ControlPointsChanged; - private readonly Slider slider; + internal Container Pieces { get; } - private readonly Container pieces; + private readonly Slider slider; public PathControlPointVisualiser(Slider slider) { @@ -24,24 +24,24 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components RelativeSizeAxes = Axes.Both; - InternalChild = pieces = new Container { RelativeSizeAxes = Axes.Both }; + InternalChild = Pieces = new Container { RelativeSizeAxes = Axes.Both }; } protected override void Update() { base.Update(); - while (slider.Path.ControlPoints.Length > pieces.Count) - pieces.Add(new PathControlPointPiece(slider, pieces.Count) { ControlPointsChanged = c => ControlPointsChanged?.Invoke(c) }); - while (slider.Path.ControlPoints.Length < pieces.Count) - pieces.Remove(pieces[pieces.Count - 1]); + while (slider.Path.ControlPoints.Length > Pieces.Count) + Pieces.Add(new PathControlPointPiece(slider, Pieces.Count) { ControlPointsChanged = c => ControlPointsChanged?.Invoke(c) }); + while (slider.Path.ControlPoints.Length < Pieces.Count) + Pieces.Remove(Pieces[Pieces.Count - 1]); } protected override bool OnMouseDown(MouseDownEvent e) { bool anySelected = false; - foreach (var piece in pieces) + foreach (var piece in Pieces) { if (piece.IsHovered) { diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index b09f598bcc..ba502d3a7c 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected readonly SliderBodyPiece BodyPiece; protected readonly SliderCircleSelectionBlueprint HeadBlueprint; protected readonly SliderCircleSelectionBlueprint TailBlueprint; + protected readonly PathControlPointVisualiser ControlPointVisualiser; [Resolved(CanBeNull = true)] private HitObjectComposer composer { get; set; } @@ -32,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece = new SliderBodyPiece(), HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start), TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End), - new PathControlPointVisualiser(sliderObject) { ControlPointsChanged = onNewControlPoints }, + ControlPointVisualiser = new PathControlPointVisualiser(sliderObject) { ControlPointsChanged = onNewControlPoints }, }; } diff --git a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs index f53c12b047..3233ee160d 100644 --- a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs +++ b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Edit; namespace osu.Game.Tests.Visual { - public abstract class SelectionBlueprintTestScene : OsuTestScene + public abstract class SelectionBlueprintTestScene : ManualInputManagerTestScene { protected override Container Content => content ?? base.Content; private readonly Container content; From 8d50b155e8022f43bca1a9c824ee8697aa4acf70 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 17:13:10 +0900 Subject: [PATCH 04/16] Make selection happen on click only --- .../Components/PathControlPointPiece.cs | 25 ++++++++++++++-- .../Components/PathControlPointVisualiser.cs | 30 ++++++++++--------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 3b0b9bce1f..bd6a905b38 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -18,9 +18,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class PathControlPointPiece : BlueprintPiece { + public Action RequestSelection; public Action ControlPointsChanged; - public readonly Bindable IsSelected = new Bindable(); + public readonly Bindable IsSelected = new Bindable(); public readonly int Index; private readonly Slider slider; @@ -28,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private readonly Container marker; private readonly Drawable markerRing; + private bool isClicked; + [Resolved] private OsuColour colours { get; set; } @@ -98,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components markerRing.Alpha = IsSelected.Value ? 1 : 0; Color4 colour = isSegmentSeparator ? colours.Red : colours.Yellow; - if (IsHovered || IsSelected.Value) + if (IsHovered || isClicked || IsSelected.Value) colour = Color4.White; marker.Colour = colour; } @@ -122,6 +125,24 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components // The connecting path is excluded from positional input public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => marker.ReceivePositionalInputAt(screenSpacePos); + protected override bool OnMouseDown(MouseDownEvent e) + { + isClicked = true; + return true; + } + + protected override bool OnMouseUp(MouseUpEvent e) + { + isClicked = false; + return true; + } + + protected override bool OnClick(ClickEvent e) + { + RequestSelection?.Invoke(Index); + return true; + } + protected override bool OnDragStart(DragStartEvent e) => true; protected override bool OnDrag(DragEvent e) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 6efa0ef550..160168eb37 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -32,27 +32,29 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components base.Update(); while (slider.Path.ControlPoints.Length > Pieces.Count) - Pieces.Add(new PathControlPointPiece(slider, Pieces.Count) { ControlPointsChanged = c => ControlPointsChanged?.Invoke(c) }); + { + Pieces.Add(new PathControlPointPiece(slider, Pieces.Count) + { + ControlPointsChanged = c => ControlPointsChanged?.Invoke(c), + RequestSelection = selectPiece + }); + } + while (slider.Path.ControlPoints.Length < Pieces.Count) Pieces.Remove(Pieces[Pieces.Count - 1]); } - protected override bool OnMouseDown(MouseDownEvent e) + protected override bool OnClick(ClickEvent e) { - bool anySelected = false; - foreach (var piece in Pieces) - { - if (piece.IsHovered) - { - piece.IsSelected.Value = true; - anySelected = true; - } - else - piece.IsSelected.Value = false; - } + piece.IsSelected.Value = false; + return false; + } - return anySelected; + private void selectPiece(int index) + { + foreach (var piece in Pieces) + piece.IsSelected.Value = piece.Index == index; } } } From 20aeb7aaffe4fe48bfcfa820a49f7765dc544bce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 17:25:30 +0900 Subject: [PATCH 05/16] Implement multiple selection --- .../TestSceneSliderSelectionBlueprint.cs | 68 +++++++++++++++++++ .../Components/PathControlPointVisualiser.cs | 22 ++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs index 0e7d8c9c08..dde2aa53e0 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSelectionBlueprint.cs @@ -93,11 +93,79 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("click", () => InputManager.Click(MouseButton.Left)); checkControlPointSelected(0, true); checkControlPointSelected(1, false); + } + + [Test] + public void TestSingleControlPointDeselectionViaOtherControlPoint() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); moveMouseToControlPoint(1); AddStep("click", () => InputManager.Click(MouseButton.Left)); checkControlPointSelected(0, false); checkControlPointSelected(1, true); + } + + [Test] + public void TestSingleControlPointDeselectionViaClickOutside() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + AddStep("move mouse outside control point", () => InputManager.MoveMouseTo(drawableObject)); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + checkControlPointSelected(0, false); + checkControlPointSelected(1, false); + } + + [Test] + public void TestMultipleControlPointSelection() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + moveMouseToControlPoint(1); + AddStep("ctrl + click", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.Click(MouseButton.Left); + InputManager.ReleaseKey(Key.ControlLeft); + }); + checkControlPointSelected(0, true); + checkControlPointSelected(1, true); + } + + [Test] + public void TestMultipleControlPointDeselectionViaOtherControlPoint() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + moveMouseToControlPoint(1); + AddStep("ctrl + click", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.Click(MouseButton.Left); + InputManager.ReleaseKey(Key.ControlLeft); + }); + + moveMouseToControlPoint(2); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + checkControlPointSelected(0, false); + checkControlPointSelected(1, false); + } + + [Test] + public void TestMultipleControlPointDeselectionViaClickOutside() + { + moveMouseToControlPoint(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + moveMouseToControlPoint(1); + AddStep("ctrl + click", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.Click(MouseButton.Left); + InputManager.ReleaseKey(Key.ControlLeft); + }); AddStep("move mouse outside control point", () => InputManager.MoveMouseTo(drawableObject)); AddStep("click", () => InputManager.Click(MouseButton.Left)); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 160168eb37..bbe771d8b0 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.Objects; using osuTK; @@ -14,10 +15,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public Action ControlPointsChanged; - internal Container Pieces { get; } - + internal readonly Container Pieces; private readonly Slider slider; + private InputManager inputManager; + public PathControlPointVisualiser(Slider slider) { this.slider = slider; @@ -27,6 +29,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components InternalChild = Pieces = new Container { RelativeSizeAxes = Axes.Both }; } + protected override void LoadComplete() + { + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + } + protected override void Update() { base.Update(); @@ -53,8 +62,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private void selectPiece(int index) { - foreach (var piece in Pieces) - piece.IsSelected.Value = piece.Index == index; + if (inputManager.CurrentState.Keyboard.ControlPressed) + Pieces[index].IsSelected.Value = true; + else + { + foreach (var piece in Pieces) + piece.IsSelected.Value = piece.Index == index; + } } } } From 9f28b1905b50b19511d10b698d1d97da0a2267f9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 18:15:19 +0900 Subject: [PATCH 06/16] Expose composer method to update hitobject --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 5922bfba78..1c942e52ce 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap = new EditorBeatmap(playableBeatmap); EditorBeatmap.HitObjectAdded += addHitObject; EditorBeatmap.HitObjectRemoved += removeHitObject; - EditorBeatmap.StartTimeChanged += updateHitObject; + EditorBeatmap.StartTimeChanged += UpdateHitObject; var dependencies = new DependencyContainer(parent); dependencies.CacheAs(EditorBeatmap); @@ -225,11 +225,7 @@ namespace osu.Game.Rulesets.Edit private ScheduledDelegate scheduledUpdate; - private void addHitObject(HitObject hitObject) => updateHitObject(hitObject); - - private void removeHitObject(HitObject hitObject) => updateHitObject(null); - - private void updateHitObject([CanBeNull] HitObject hitObject) + public override void UpdateHitObject(HitObject hitObject) { scheduledUpdate?.Cancel(); scheduledUpdate = Schedule(() => @@ -240,6 +236,10 @@ namespace osu.Game.Rulesets.Edit }); } + private void addHitObject(HitObject hitObject) => UpdateHitObject(hitObject); + + private void removeHitObject(HitObject hitObject) => UpdateHitObject(null); + public override IEnumerable HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects; public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position); @@ -351,11 +351,22 @@ namespace osu.Game.Rulesets.Edit [CanBeNull] protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable selectedHitObjects) => null; + /// + /// Updates a , invoking and re-processing the beatmap. + /// + /// The to update. + public abstract void UpdateHitObject([CanBeNull] HitObject hitObject); + public abstract (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time); + public abstract float GetBeatSnapDistanceAt(double referenceTime); + public abstract float DurationToDistance(double referenceTime, double duration); + public abstract double DistanceToDuration(double referenceTime, float distance); + public abstract double GetSnappedDurationFromDistance(double referenceTime, float distance); + public abstract float GetSnappedDistanceFromDistance(double referenceTime, float distance); } } From 41ae66d517e7a005f5f17e3faf1e583eb26b2151 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 31 Oct 2019 18:24:38 +0900 Subject: [PATCH 07/16] Update slider when control points change --- .../Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 ++ osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index b09f598bcc..585a477aba 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -49,6 +49,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders var snappedDistance = composer?.GetSnappedDistanceFromDistance(HitObject.StartTime, (float)unsnappedPath.Distance) ?? (float)unsnappedPath.Distance; HitObject.Path = new SliderPath(unsnappedPath.Type, controlPoints, snappedDistance); + + UpdateHitObject(); } public override Vector2 SelectionPoint => HeadBlueprint.SelectionPoint; diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 44f38acfd4..0701513933 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -3,10 +3,12 @@ using System; using osu.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osuTK; @@ -36,6 +38,9 @@ namespace osu.Game.Rulesets.Edit public override bool HandlePositionalInput => ShouldBeAlive; public override bool RemoveWhenNotAlive => false; + [Resolved(CanBeNull = true)] + private HitObjectComposer composer { get; set; } + protected SelectionBlueprint(DrawableHitObject drawableObject) { DrawableObject = drawableObject; @@ -89,6 +94,11 @@ namespace osu.Game.Rulesets.Edit public bool IsSelected => State == SelectionState.Selected; + /// + /// Updates the , invoking and re-processing the beatmap. + /// + protected void UpdateHitObject() => composer?.UpdateHitObject(DrawableObject.HitObject); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); /// From ac02bb005d982603c55002d8212af592453a584d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 14:11:18 +0900 Subject: [PATCH 08/16] Fix GameplayClockContainer operating on beatmap's track after scren exited --- osu.Game/Screens/Play/GameplayClockContainer.cs | 15 ++++++++++++++- osu.Game/Screens/Play/Player.cs | 4 ++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 6a03271b86..f2efbe6073 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -29,7 +30,7 @@ namespace osu.Game.Screens.Play /// /// The original source (usually a 's track). /// - private readonly IAdjustableClock sourceClock; + private IAdjustableClock sourceClock; public readonly BindableBool IsPaused = new BindableBool(); @@ -153,6 +154,18 @@ namespace osu.Game.Screens.Play IsPaused.Value = true; } + /// + /// Changes the backing clock to avoid using the originally provided beatmap's track. + /// + public void StopUsingBeatmapClock() + { + if (sourceClock != beatmap.Track) + return; + + sourceClock = new TrackVirtual(beatmap.Track.Length); + adjustableClock.ChangeSource(sourceClock); + } + public void ResetLocalAdjustments() { // In the case of replays, we may have changed the playback rate. diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0b363eac4d..4820c62da3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -527,6 +527,10 @@ namespace osu.Game.Screens.Play GameplayClockContainer.ResetLocalAdjustments(); + // GameplayClockContainer performs seeks / start / stop operations on the beatmap's track. + // as we are no longer the current screen, we cannot guarantee the track is still usable. + GameplayClockContainer.StopUsingBeatmapClock(); + fadeOut(); return base.OnExiting(next); } From 14fec6f1f35e4cf9e9a0e65a535e407c68ba9ed5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 15:06:36 +0900 Subject: [PATCH 09/16] Move ReplayDownloadButton to correct namespace --- .../Visual/Gameplay/TestSceneReplayDownloadButton.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs | 1 + .../{Play => Ranking/Pages}/ReplayDownloadButton.cs | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) rename osu.Game/Screens/{Play => Ranking/Pages}/ReplayDownloadButton.cs (98%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs index 0dfcda122f..4c870e04f5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs @@ -7,11 +7,11 @@ using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; -using osu.Game.Screens.Play; using osu.Game.Users; using osuTK; using System; using System.Collections.Generic; +using osu.Game.Screens.Ranking.Pages; namespace osu.Game.Tests.Visual.Gameplay { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs index f3c8f89db7..c4b42f6356 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs @@ -26,6 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay typeof(Results), typeof(ResultsPage), typeof(ScoreResultsPage), + typeof(ReplayDownloadButton), typeof(LocalLeaderboardPage) }; diff --git a/osu.Game/Screens/Play/ReplayDownloadButton.cs b/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs similarity index 98% rename from osu.Game/Screens/Play/ReplayDownloadButton.cs rename to osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs index 290e00f287..c8f4ecd2d5 100644 --- a/osu.Game/Screens/Play/ReplayDownloadButton.cs +++ b/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs @@ -4,12 +4,12 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Online; -using osu.Game.Scoring; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Graphics.UserInterface; +using osu.Game.Online; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Scoring; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Ranking.Pages { public class ReplayDownloadButton : DownloadTrackingComposite { From 84d17f3702bdf25f37a1bfffa34a216a8ab031f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 15:32:06 +0900 Subject: [PATCH 10/16] Add retry button --- .../Gameplay/TestSceneReplayDownloadButton.cs | 2 - .../Visual/Gameplay/TestSceneResults.cs | 2 +- osu.Game/Screens/Play/Player.cs | 8 +-- .../Ranking/Pages/ReplayDownloadButton.cs | 2 + osu.Game/Screens/Ranking/Pages/RetryButton.cs | 59 +++++++++++++++++++ .../Screens/Ranking/Pages/ScoreResultsPage.cs | 11 +++- 6 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 osu.Game/Screens/Ranking/Pages/RetryButton.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs index 4c870e04f5..7b22fedbd5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs @@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; using osu.Game.Users; -using osuTK; using System; using System.Collections.Generic; using osu.Game.Screens.Ranking.Pages; @@ -42,7 +41,6 @@ namespace osu.Game.Tests.Visual.Gameplay { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(80, 40), }; }); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs index c4b42f6356..bf26892539 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs @@ -22,10 +22,10 @@ namespace osu.Game.Tests.Visual.Gameplay public override IReadOnlyList RequiredTypes => new[] { - typeof(ScoreInfo), typeof(Results), typeof(ResultsPage), typeof(ScoreResultsPage), + typeof(RetryButton), typeof(ReplayDownloadButton), typeof(LocalLeaderboardPage) }; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0b363eac4d..38068ec751 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -30,6 +30,7 @@ using osu.Game.Users; namespace osu.Game.Screens.Play { + [Cached] public class Player : ScreenWithBeatmapBackground { public override bool AllowBackButton => false; // handled by HoldForMenuButton @@ -313,12 +314,11 @@ namespace osu.Game.Screens.Play public void Restart() { - if (!this.IsCurrentScreen()) return; - sampleRestart?.Play(); - RestartRequested?.Invoke(); - performImmediateExit(); + + if (this.IsCurrentScreen()) + performImmediateExit(); } private ScheduledDelegate completionProgressDelegate; diff --git a/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs b/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs index c8f4ecd2d5..73c647d6fa 100644 --- a/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs +++ b/osu.Game/Screens/Ranking/Pages/ReplayDownloadButton.cs @@ -8,6 +8,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Scoring; +using osuTK; namespace osu.Game.Screens.Ranking.Pages { @@ -33,6 +34,7 @@ namespace osu.Game.Screens.Ranking.Pages public ReplayDownloadButton(ScoreInfo score) : base(score) { + Size = new Vector2(50, 30); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/Ranking/Pages/RetryButton.cs b/osu.Game/Screens/Ranking/Pages/RetryButton.cs new file mode 100644 index 0000000000..c4f63b265d --- /dev/null +++ b/osu.Game/Screens/Ranking/Pages/RetryButton.cs @@ -0,0 +1,59 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Screens; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Play; +using osuTK; + +namespace osu.Game.Screens.Ranking.Pages +{ + public class RetryButton : OsuAnimatedButton + { + private readonly Box background; + + [Resolved(canBeNull: true)] + private Player player { get; set; } + + public RetryButton() + { + Size = new Vector2(50, 30); + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(13), + Icon = FontAwesome.Solid.ArrowCircleLeft, + }, + }; + + TooltipText = "Retry"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Green; + + if (player != null) + Action = () => + { + player.Restart(); + player.MakeCurrent(); + }; + } + } +} diff --git a/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs index 56ae069a26..27cea99f1c 100644 --- a/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs +++ b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs @@ -169,12 +169,19 @@ namespace osu.Game.Screens.Ranking.Pages }, }, }, - new ReplayDownloadButton(score) + new FillFlowContainer { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Margin = new MarginPadding { Bottom = 10 }, - Size = new Vector2(50, 30), + Spacing = new Vector2(5), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new ReplayDownloadButton(score), + new RetryButton() + } }, }; From c532f7765737b6dfd9e7609eba0dde8fddc324ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 15:49:36 +0900 Subject: [PATCH 11/16] Add hold-to-retry support to results --- osu.Game/Screens/Ranking/Results.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index cac26b3dbf..a7ff1fe6a0 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -19,6 +19,7 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; using osu.Game.Scoring; +using osu.Game.Screens.Play; namespace osu.Game.Screens.Ranking { @@ -34,6 +35,9 @@ namespace osu.Game.Screens.Ranking private ResultModeTabControl modeChangeButtons; + [Resolved(canBeNull: true)] + private Player player { get; set; } + public override bool DisallowExternalBeatmapRulesetChanges => true; protected readonly ScoreInfo Score; @@ -100,10 +104,7 @@ namespace osu.Game.Screens.Ranking public override bool OnExiting(IScreen next) { - allCircles.ForEach(c => - { - c.ScaleTo(0, transition_time, Easing.OutSine); - }); + allCircles.ForEach(c => { c.ScaleTo(0, transition_time, Easing.OutSine); }); Background.ScaleTo(1f, transition_time / 4, Easing.OutQuint); @@ -253,7 +254,17 @@ namespace osu.Game.Screens.Ranking } } } - } + }, + new HotkeyRetryOverlay + { + Action = () => + { + if (!this.IsCurrentScreen()) return; + + player.Restart(); + player.MakeCurrent(); + }, + }, }; var pages = CreateResultPages(); From 14453da1d2b254af738c322f9fd9ba25bb078b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 15:51:10 +0900 Subject: [PATCH 12/16] Centralise MakeCurrent call --- osu.Game/Screens/Play/Player.cs | 2 ++ osu.Game/Screens/Ranking/Pages/RetryButton.cs | 7 +------ osu.Game/Screens/Ranking/Results.cs | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 38068ec751..769688e829 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -319,6 +319,8 @@ namespace osu.Game.Screens.Play if (this.IsCurrentScreen()) performImmediateExit(); + else + this.MakeCurrent(); } private ScheduledDelegate completionProgressDelegate; diff --git a/osu.Game/Screens/Ranking/Pages/RetryButton.cs b/osu.Game/Screens/Ranking/Pages/RetryButton.cs index c4f63b265d..2a281224c1 100644 --- a/osu.Game/Screens/Ranking/Pages/RetryButton.cs +++ b/osu.Game/Screens/Ranking/Pages/RetryButton.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Play; @@ -49,11 +48,7 @@ namespace osu.Game.Screens.Ranking.Pages background.Colour = colours.Green; if (player != null) - Action = () => - { - player.Restart(); - player.MakeCurrent(); - }; + Action = () => player.Restart(); } } } diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index a7ff1fe6a0..ca2ee5adae 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -262,7 +262,6 @@ namespace osu.Game.Screens.Ranking if (!this.IsCurrentScreen()) return; player.Restart(); - player.MakeCurrent(); }, }, }; From daa0ebe2b57916f5408cdd5b3dbc1b0b6591e9f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 15:51:45 +0900 Subject: [PATCH 13/16] Add xmldoc --- osu.Game/Screens/Play/Player.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 769688e829..f97114f929 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -312,6 +312,10 @@ namespace osu.Game.Screens.Play this.Exit(); } + /// + /// Restart gameplay via a parent . + /// This can be called from a child screen in order to trigger the restart process. + /// public void Restart() { sampleRestart?.Play(); From 156d0ae9b91c1bd6ea03a7b753807b0bcb4260a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Nov 2019 16:08:44 +0900 Subject: [PATCH 14/16] Remove braces Co-Authored-By: Salman Ahmed --- osu.Game/Screens/Ranking/Results.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index ca2ee5adae..d89932e105 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Ranking public override bool OnExiting(IScreen next) { - allCircles.ForEach(c => { c.ScaleTo(0, transition_time, Easing.OutSine); }); + allCircles.ForEach(c => c.ScaleTo(0, transition_time, Easing.OutSine)); Background.ScaleTo(1f, transition_time / 4, Easing.OutQuint); From 5be7d439ae2f149772372bdce9356c1d88163764 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Sat, 2 Nov 2019 10:32:23 +0900 Subject: [PATCH 15/16] Add null check for nullable dependency --- osu.Game/Screens/Ranking/Results.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index d89932e105..3640197dad 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -261,7 +261,7 @@ namespace osu.Game.Screens.Ranking { if (!this.IsCurrentScreen()) return; - player.Restart(); + player?.Restart(); }, }, }; From 4dbdfcdd3c601a547887b9b563c06692feb6c53f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Nov 2019 18:41:29 +0900 Subject: [PATCH 16/16] Change control to toggle rather than always select --- .../Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs | 2 +- .../Blueprints/Sliders/Components/PathControlPointVisualiser.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index bd6a905b38..e2ea6a12d7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components public Action RequestSelection; public Action ControlPointsChanged; - public readonly Bindable IsSelected = new Bindable(); + public readonly BindableBool IsSelected = new BindableBool(); public readonly int Index; private readonly Slider slider; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index bbe771d8b0..b70c11427a 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private void selectPiece(int index) { if (inputManager.CurrentState.Keyboard.ControlPressed) - Pieces[index].IsSelected.Value = true; + Pieces[index].IsSelected.Toggle(); else { foreach (var piece in Pieces)