diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleMask.cs index 9576e0fa91..696726e8bf 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleMask.cs @@ -18,22 +18,28 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks public HitCircleMask(HitCircle hitCircle) { this.hitCircle = hitCircle; - Anchor = Anchor.Centre; + Origin = Anchor.Centre; Size = new Vector2((float)OsuHitObject.OBJECT_RADIUS * 2); - CornerRadius = Size.X / 2; - AddInternal(new RingPiece()); + InternalChild = new RingPiece(); + + hitCircle.PositionChanged += _ => UpdatePosition(); + hitCircle.StackHeightChanged += _ => UpdatePosition(); } [BackgroundDependencyLoader] private void load(OsuColour colours) { Colour = colours.Yellow; + + UpdatePosition(); } + protected virtual void UpdatePosition() => Position = hitCircle.StackedPosition; + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.cs index ca250e25e6..2c259f562d 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.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 osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; @@ -15,12 +14,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks public HitCirclePlacementMask() : base(new HitCircle()) { - Origin = Anchor.Centre; - AutoSizeAxes = Axes.Both; - InternalChild = new HitCircleMask(HitObject); - - HitObject.PositionChanged += _ => Position = HitObject.StackedPosition; } protected override void LoadComplete() diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleSelectionMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleSelectionMask.cs index f4e4bb2145..49ff955896 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleSelectionMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/HitCircleSelectionMask.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 osu.Framework.Graphics; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; @@ -13,14 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks public HitCircleSelectionMask(DrawableHitCircle hitCircle) : base(hitCircle) { - Origin = Anchor.Centre; - AutoSizeAxes = Axes.Both; - Position = hitCircle.Position; - InternalChild = new HitCircleMask((HitCircle)hitCircle.HitObject); - - hitCircle.HitObject.PositionChanged += _ => Position = hitCircle.HitObject.StackedPosition; - hitCircle.HitObject.StackHeightChanged += _ => Position = hitCircle.HitObject.StackedPosition; } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderBodyMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderBodyMask.cs new file mode 100644 index 0000000000..c95b2d7722 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderBodyMask.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Edit.Masks +{ + public class SliderBodyMask : CompositeDrawable + { + private readonly Slider slider; + private readonly SliderBody body; + + public SliderBodyMask(Slider slider) + { + this.slider = slider; + InternalChild = body = new SliderBody(slider) + { + AccentColour = Color4.Transparent, + PathWidth = slider.Scale * 64 + }; + + slider.PositionChanged += _ => updatePosition(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + body.BorderColour = colours.Yellow; + + updatePosition(); + } + + private void updatePosition() => Position = slider.StackedPosition; + + protected override void Update() + { + base.Update(); + + Size = body.Size; + OriginPosition = body.PathOffset; + + // Need to cause one update + body.UpdateProgress(0); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleMask.cs new file mode 100644 index 0000000000..de128552c6 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleMask.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Edit.Masks +{ + public class SliderCircleMask : HitCircleMask + { + private readonly Slider slider; + private readonly SliderPosition position; + + public SliderCircleMask(Slider slider, SliderPosition position) + : base(slider.HeadCircle) + { + this.slider = slider; + this.position = position; + } + + protected override void UpdatePosition() + { + switch (position) + { + case SliderPosition.Start: + Position = slider.StackedPosition + slider.Curve.PositionAt(0); + break; + case SliderPosition.End: + Position = slider.StackedPosition + slider.Curve.PositionAt(1); + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleSelectionMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleSelectionMask.cs index 1ed22c2ac1..ebbb050c18 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleSelectionMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderCircleSelectionMask.cs @@ -1,60 +1,22 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Masks { public class SliderCircleSelectionMask : SelectionMask { - public SliderCircleSelectionMask(DrawableHitCircle sliderHead, DrawableSlider slider) - : this(sliderHead, Vector2.Zero, slider) - { - } - - public SliderCircleSelectionMask(DrawableSliderTail sliderTail, DrawableSlider slider) - : this(sliderTail, ((Slider)slider.HitObject).Curve.PositionAt(1), slider) - { - } - - private readonly DrawableOsuHitObject hitObject; - - private SliderCircleSelectionMask(DrawableOsuHitObject hitObject, Vector2 position, DrawableSlider slider) + public SliderCircleSelectionMask(DrawableOsuHitObject hitObject, Slider slider, SliderPosition position) : base(hitObject) { - this.hitObject = hitObject; - - Origin = Anchor.Centre; - - Position = position; - Size = slider.HeadCircle.Size; - Scale = slider.HeadCircle.Scale; - - AddInternal(new RingPiece()); + InternalChild = new SliderCircleMask(slider, position); Select(); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Colour = colours.Yellow; - } - - protected override void Update() - { - base.Update(); - - RelativeAnchorPosition = hitObject.RelativeAnchorPosition; - } - // Todo: This is temporary, since the slider circle masks don't do anything special yet. In the future they will handle input. public override bool HandlePositionalInput => false; } diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPosition.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPosition.cs new file mode 100644 index 0000000000..dc5f670d48 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPosition.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Osu.Edit.Masks +{ + public enum SliderPosition + { + Start, + End + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs index b775854038..c330641bcf 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs @@ -1,67 +1,31 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Primitives; -using osu.Game.Graphics; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Masks { public class SliderSelectionMask : SelectionMask { - private readonly SliderBody body; - private readonly DrawableSlider slider; + private readonly SliderCircleSelectionMask headMask; public SliderSelectionMask(DrawableSlider slider) : base(slider) { - this.slider = slider; - - Position = slider.Position; - var sliderObject = (Slider)slider.HitObject; InternalChildren = new Drawable[] { - body = new SliderBody(sliderObject) - { - AccentColour = Color4.Transparent, - PathWidth = sliderObject.Scale * 64 - }, - new SliderCircleSelectionMask(slider.HeadCircle, slider), - new SliderCircleSelectionMask(slider.TailCircle, slider), + new SliderBodyMask(sliderObject), + headMask = new SliderCircleSelectionMask(slider.HeadCircle, sliderObject, SliderPosition.Start), + new SliderCircleSelectionMask(slider.TailCircle, sliderObject, SliderPosition.End), }; - - sliderObject.PositionChanged += _ => Position = slider.Position; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - body.BorderColour = colours.Yellow; - } - - protected override void Update() - { - base.Update(); - - Size = slider.Size; - OriginPosition = slider.OriginPosition; - - // Need to cause one update - body.UpdateProgress(0); - } - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); - - public override Vector2 SelectionPoint => ToScreenSpace(OriginPosition); - public override Quad SelectionQuad => body.PathDrawQuad; + public override Vector2 SelectionPoint => headMask.SelectionPoint; } } diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index ab8f01f5d3..140f875a6f 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Objects private Vector2 position; - public Vector2 Position + public virtual Vector2 Position { get => position; set diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 7a0dcc77a6..9a3bae96b0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -70,6 +70,21 @@ namespace osu.Game.Rulesets.Osu.Objects set { Curve.Distance = value; } } + public override Vector2 Position + { + get => base.Position; + set + { + base.Position = value; + + if (HeadCircle != null) + HeadCircle.Position = value; + + if (TailCircle != null) + TailCircle.Position = EndPosition; + } + } + public double? LegacyLastTickOffset { get; set; } /// diff --git a/osu.Game/Rulesets/Edit/PlacementMask.cs b/osu.Game/Rulesets/Edit/PlacementMask.cs index 36c706db37..381dc5f7f0 100644 --- a/osu.Game/Rulesets/Edit/PlacementMask.cs +++ b/osu.Game/Rulesets/Edit/PlacementMask.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Input.Events; @@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Edit public PlacementMask(HitObject hitObject) { HitObject = hitObject; + + RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] diff --git a/osu.Game/Rulesets/Edit/SelectionMask.cs b/osu.Game/Rulesets/Edit/SelectionMask.cs index 9582c30457..3b78d5aaf6 100644 --- a/osu.Game/Rulesets/Edit/SelectionMask.cs +++ b/osu.Game/Rulesets/Edit/SelectionMask.cs @@ -3,6 +3,7 @@ using System; using osu.Framework; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Input.Events; @@ -52,6 +53,8 @@ namespace osu.Game.Rulesets.Edit { HitObject = hitObject; + RelativeSizeAxes = Axes.Both; + AlwaysPresent = true; Alpha = 0; } @@ -94,6 +97,8 @@ namespace osu.Game.Rulesets.Edit public bool IsSelected => State == SelectionState.Selected; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObject.ReceivePositionalInputAt(screenSpacePos); + private bool selectionRequested; protected override bool OnMouseDown(MouseDownEvent e) @@ -132,11 +137,11 @@ namespace osu.Game.Rulesets.Edit /// /// The screen-space point that causes this to be selected. /// - public virtual Vector2 SelectionPoint => ScreenSpaceDrawQuad.Centre; + public virtual Vector2 SelectionPoint => HitObject.ScreenSpaceDrawQuad.Centre; /// /// The screen-space quad that outlines this for selections. /// - public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; + public virtual Quad SelectionQuad => HitObject.ScreenSpaceDrawQuad; } }