diff --git a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs index d6e59587a4..042b60b66b 100644 --- a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs @@ -15,13 +15,15 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Masks; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Layers; using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCaseHitObjectComposer : OsuTestCase + [Cached(Type = typeof(IPlacementHandler))] + public class TestCaseHitObjectComposer : OsuTestCase, IPlacementHandler { public override IReadOnlyList RequiredTypes => new[] { @@ -36,6 +38,9 @@ namespace osu.Game.Tests.Visual typeof(HitCirclePlacementMask), }; + public event Action PlacementStarted; + public event Action PlacementFinished; + [BackgroundDependencyLoader] private void load() { @@ -67,5 +72,9 @@ namespace osu.Game.Tests.Visual Child = new OsuHitObjectComposer(new OsuRuleset()); } + + public void BeginPlacement(HitObject hitObject) => PlacementStarted?.Invoke(hitObject); + + public void EndPlacement(HitObject hitObject) => PlacementFinished?.Invoke(hitObject); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index b5b7e6fe99..8cd26da166 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Layers; using osu.Game.Screens.Edit.Screens.Compose.RadioButtons; @@ -31,10 +32,15 @@ namespace osu.Game.Rulesets.Edit private readonly List layerContainers = new List(); private readonly IBindable beatmap = new Bindable(); + [Resolved] + private IPlacementHandler placementHandler { get; set; } + private HitObjectMaskLayer maskLayer; private Container placementContainer; private EditRulesetContainer rulesetContainer; + private HitObjectCompositionTool compositionTool; + protected HitObjectComposer(Ruleset ruleset) { this.ruleset = ruleset; @@ -117,6 +123,16 @@ namespace osu.Game.Rulesets.Edit .ToList(); toolboxCollection.Items[0].Select(); + + placementHandler.PlacementFinished += h => + { + var drawableObject = rulesetContainer.AddHitObject(h); + + maskLayer.AddMask(drawableObject); + + // Re-construct the mask + setCompositionTool(compositionTool); + }; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) @@ -151,23 +167,12 @@ namespace osu.Game.Rulesets.Edit private void setCompositionTool(HitObjectCompositionTool tool) { + compositionTool = tool; + placementContainer.Clear(true); if (tool != null) - { - var mask = tool.CreatePlacementMask(); - mask.PlacementFinished += h => - { - var drawableObject = rulesetContainer.AddHitObject(h); - - maskLayer.AddMask(drawableObject); - - // Re-construct the mask - setCompositionTool(tool); - }; - - placementContainer.Child = mask; - } + placementContainer.Child = tool.CreatePlacementMask(); } protected abstract EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap); diff --git a/osu.Game/Rulesets/Edit/PlacementMask.cs b/osu.Game/Rulesets/Edit/PlacementMask.cs index 109244c34f..d253638374 100644 --- a/osu.Game/Rulesets/Edit/PlacementMask.cs +++ b/osu.Game/Rulesets/Edit/PlacementMask.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -9,22 +8,13 @@ using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Edit.Screens.Compose; using OpenTK; namespace osu.Game.Rulesets.Edit { public class PlacementMask : CompositeDrawable, IRequireHighFrequencyMousePosition { - /// - /// Invoked when the placement of has started. - /// - public event Action PlacementStarted; - - /// - /// Invoked when the placement of has finished. - /// - public event Action PlacementFinished; - /// /// The that is being placed. /// @@ -32,6 +22,9 @@ namespace osu.Game.Rulesets.Edit protected IClock EditorClock { get; private set; } + [Resolved] + private IPlacementHandler placementHandler { get; set; } + public PlacementMask(HitObject hitObject) { HitObject = hitObject; @@ -52,7 +45,7 @@ namespace osu.Game.Rulesets.Edit /// protected void BeginPlacement() { - PlacementStarted?.Invoke(HitObject); + placementHandler.BeginPlacement(HitObject); placementBegun = true; } @@ -64,7 +57,7 @@ namespace osu.Game.Rulesets.Edit { if (!placementBegun) BeginPlacement(); - PlacementFinished?.Invoke(HitObject); + placementHandler.EndPlacement(HitObject); } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parent?.ReceivePositionalInputAt(screenSpacePos) ?? false; @@ -81,13 +74,5 @@ namespace osu.Game.Rulesets.Edit return false; } } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - PlacementStarted = null; - PlacementFinished = null; - } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index a862485fd6..7f720705e1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using JetBrains.Annotations; using osu.Framework.Allocation; using OpenTK.Graphics; @@ -9,15 +10,27 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Logging; +using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Screens.Edit.Screens.Compose { - public class Compose : EditorScreen + [Cached(Type = typeof(IPlacementHandler))] + public class Compose : EditorScreen, IPlacementHandler { private const float vertical_margins = 10; private const float horizontal_margins = 20; + /// + /// Invoked when the placement of a has started. + /// + public event Action PlacementStarted; + + /// + /// Invoked when the placement of a has finished. + /// + public event Action PlacementFinished; + private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); private Container composerContainer; @@ -111,5 +124,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose composerContainer.Child = composer; } + + public void BeginPlacement(HitObject hitObject) => PlacementStarted?.Invoke(hitObject); + + public void EndPlacement(HitObject hitObject) => PlacementFinished?.Invoke(hitObject); } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/IPlacementHandler.cs b/osu.Game/Screens/Edit/Screens/Compose/IPlacementHandler.cs new file mode 100644 index 0000000000..2bab9334a2 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/IPlacementHandler.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public interface IPlacementHandler + { + event Action PlacementStarted; + event Action PlacementFinished; + + void BeginPlacement(HitObject hitObject); + void EndPlacement(HitObject hitObject); + } +}