diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
index 1f92929392..a13afdfffe 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
@@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
base.UpdateTimeAndPosition(result);
- if (PlacementActive)
+ if (PlacementActive == PlacementState.Active)
{
if (result.Time is double endTime)
{
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
index 5e09054667..8f25668dd0 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
base.UpdateTimeAndPosition(result);
- if (!PlacementActive)
+ if (PlacementActive == PlacementState.Waiting)
Column = result.Playfield as Column;
}
}
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
index 16e2a52279..efa249694a 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private InputManager inputManager;
- private PlacementState state;
+ private SliderPlacementState state;
private PathControlPoint segmentStart;
private PathControlPoint cursor;
private int currentSegmentLength;
@@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
controlPointVisualiser = new PathControlPointVisualiser(HitObject, false)
};
- setState(PlacementState.Initial);
+ setState(SliderPlacementState.Initial);
}
protected override void LoadComplete()
@@ -73,12 +73,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
switch (state)
{
- case PlacementState.Initial:
+ case SliderPlacementState.Initial:
BeginPlacement();
HitObject.Position = ToLocalSpace(result.ScreenSpacePosition);
break;
- case PlacementState.Body:
+ case SliderPlacementState.Body:
updateCursor();
break;
}
@@ -91,11 +91,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
switch (state)
{
- case PlacementState.Initial:
+ case SliderPlacementState.Initial:
beginCurve();
break;
- case PlacementState.Body:
+ case SliderPlacementState.Body:
if (canPlaceNewControlPoint(out var lastPoint))
{
// Place a new point by detatching the current cursor.
@@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
protected override void OnMouseUp(MouseUpEvent e)
{
- if (state == PlacementState.Body && e.Button == MouseButton.Right)
+ if (state == SliderPlacementState.Body && e.Button == MouseButton.Right)
endCurve();
base.OnMouseUp(e);
}
@@ -129,7 +129,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private void beginCurve()
{
BeginPlacement(commitStart: true);
- setState(PlacementState.Body);
+ setState(SliderPlacementState.Body);
}
private void endCurve()
@@ -219,12 +219,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
tailCirclePiece.UpdateFrom(HitObject.TailCircle);
}
- private void setState(PlacementState newState)
+ private void setState(SliderPlacementState newState)
{
state = newState;
}
- private enum PlacementState
+ private enum SliderPlacementState
{
Initial,
Body,
diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
index e53b331f46..59249e6bf4 100644
--- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
@@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
{
base.UpdateTimeAndPosition(result);
- if (PlacementActive)
+ if (PlacementActive == PlacementState.Active)
{
if (result.Time is double dragTime)
{
diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
index bfff93e7c5..6c1cd01796 100644
--- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
+++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Edit
///
/// Whether the is currently mid-placement, but has not necessarily finished being placed.
///
- public bool PlacementActive { get; private set; }
+ public PlacementState PlacementActive { get; private set; }
///
/// The that is being placed.
@@ -72,7 +72,8 @@ namespace osu.Game.Rulesets.Edit
protected void BeginPlacement(bool commitStart = false)
{
placementHandler.BeginPlacement(HitObject);
- PlacementActive |= commitStart;
+ if (commitStart)
+ PlacementActive = PlacementState.Active;
}
///
@@ -82,10 +83,19 @@ namespace osu.Game.Rulesets.Edit
/// Whether the object should be committed.
public void EndPlacement(bool commit)
{
- if (!PlacementActive)
- BeginPlacement();
+ switch (PlacementActive)
+ {
+ case PlacementState.Finished:
+ return;
+
+ case PlacementState.Waiting:
+ // ensure placement was started before ending to make state handling simpler.
+ BeginPlacement();
+ break;
+ }
+
placementHandler.EndPlacement(HitObject, commit);
- PlacementActive = false;
+ PlacementActive = PlacementState.Finished;
}
///
@@ -94,7 +104,7 @@ namespace osu.Game.Rulesets.Edit
/// The snap result information.
public virtual void UpdateTimeAndPosition(SnapResult result)
{
- if (!PlacementActive)
+ if (PlacementActive == PlacementState.Waiting)
HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current;
}
@@ -125,5 +135,12 @@ namespace osu.Game.Rulesets.Edit
return false;
}
}
+
+ public enum PlacementState
+ {
+ Waiting,
+ Active,
+ Finished
+ }
}
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs
index 5ab557804e..b0a6a091f0 100644
--- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs
@@ -196,7 +196,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void refreshTool()
{
removePlacement();
- createPlacement();
+ ensurePlacementCreated();
}
private void updatePlacementPosition()
@@ -215,15 +215,26 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
base.Update();
- if (Composer.CursorInPlacementArea)
- createPlacement();
- else if (currentPlacement?.PlacementActive == false)
- removePlacement();
-
if (currentPlacement != null)
{
- updatePlacementPosition();
+ switch (currentPlacement.PlacementActive)
+ {
+ case PlacementBlueprint.PlacementState.Waiting:
+ if (!Composer.CursorInPlacementArea)
+ removePlacement();
+ break;
+
+ case PlacementBlueprint.PlacementState.Finished:
+ removePlacement();
+ break;
+ }
}
+
+ if (Composer.CursorInPlacementArea)
+ ensurePlacementCreated();
+
+ if (currentPlacement != null)
+ updatePlacementPosition();
}
protected sealed override SelectionBlueprint CreateBlueprintFor(HitObject hitObject)
@@ -249,7 +260,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
NewCombo.Value = TernaryState.False;
}
- private void createPlacement()
+ private void ensurePlacementCreated()
{
if (currentPlacement != null) return;
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs
index 23069f6079..bea1aa2e3a 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs
@@ -133,7 +133,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
var comboColours = skin.GetConfig>(GlobalSkinColours.ComboColours)?.Value ?? Array.Empty();
var comboColour = combo.GetComboColour(comboColours);
- if (HitObject is IHasDuration)
+ if (HitObject is IHasDuration duration && duration.Duration > 0)
circle.Colour = ColourInfo.GradientHorizontal(comboColour, comboColour.Lighten(0.4f));
else
circle.Colour = comboColour;