// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mania.Edit.Blueprints.Components; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.UI.Scrolling; using osuTK; using osuTK.Input; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { public class HoldNotePlacementBlueprint : ManiaPlacementBlueprint { private readonly EditBodyPiece bodyPiece; private readonly EditNotePiece headPiece; private readonly EditNotePiece tailPiece; public HoldNotePlacementBlueprint() : base(new HoldNote()) { RelativeSizeAxes = Axes.Both; InternalChildren = new Drawable[] { bodyPiece = new EditBodyPiece { Origin = Anchor.TopCentre }, headPiece = new EditNotePiece { Origin = Anchor.Centre }, tailPiece = new EditNotePiece { Origin = Anchor.Centre } }; } protected override void Update() { base.Update(); if (Column != null) { headPiece.Y = positionAt(HitObject.StartTime); tailPiece.Y = positionAt(HitObject.EndTime); } var topPosition = new Vector2(headPiece.DrawPosition.X, Math.Min(headPiece.DrawPosition.Y, tailPiece.DrawPosition.Y)); var bottomPosition = new Vector2(headPiece.DrawPosition.X, Math.Max(headPiece.DrawPosition.Y, tailPiece.DrawPosition.Y)); bodyPiece.Position = topPosition; bodyPiece.Width = headPiece.Width; bodyPiece.Height = (bottomPosition - topPosition).Y; } protected override void OnMouseUp(MouseUpEvent e) { if (e.Button != MouseButton.Left) return; base.OnMouseUp(e); EndPlacement(true); } private double originalStartTime; public override void UpdatePosition(SnapResult result) { base.UpdatePosition(result); if (PlacementActive) { if (result.Time is double endTime) { HitObject.StartTime = endTime < originalStartTime ? endTime : originalStartTime; HitObject.Duration = Math.Abs(endTime - originalStartTime); } } else { if (result is ManiaSnapResult maniaResult) { headPiece.Width = tailPiece.Width = maniaResult.Column.DrawWidth; headPiece.X = tailPiece.X = ToLocalSpace(result.ScreenSpacePosition).X; } if (result.Time is double startTime) originalStartTime = HitObject.StartTime = startTime; } } [Resolved] private IScrollingInfo scrollingInfo { get; set; } private float positionAt(double time) { var pos = scrollingInfo.Algorithm.PositionAt(time, EditorClock.CurrentTime, scrollingInfo.TimeRange.Value, Column.HitObjectContainer.DrawHeight); if (scrollingInfo.Direction.Value == ScrollingDirection.Down) pos = Column.HitObjectContainer.DrawHeight - pos; return Column.HitObjectContainer.ToSpaceOfOtherDrawable(new Vector2(0, pos), Parent).Y; } } }