1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 18:07:23 +08:00

Use HitObject instead of DHO for mania selection blueprint layout

- Fix moving selected hold note between columns will cause a crash
This commit is contained in:
ekrctb 2021-06-15 13:20:33 +09:00
parent bbf0022689
commit d0e57f7dd9
6 changed files with 24 additions and 103 deletions

View File

@ -12,7 +12,7 @@ using osu.Framework.Utils;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Skinning.Default;
@ -184,8 +184,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
AddAssert("head note positioned correctly", () => Precision.AlmostEquals(holdNote.ScreenSpaceDrawQuad.BottomLeft, holdNote.Head.ScreenSpaceDrawQuad.BottomLeft));
AddAssert("tail note positioned correctly", () => Precision.AlmostEquals(holdNote.ScreenSpaceDrawQuad.TopLeft, holdNote.Tail.ScreenSpaceDrawQuad.BottomLeft));
AddAssert("head blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteOverlay>().ElementAt(0).DrawPosition == holdNote.Head.DrawPosition);
AddAssert("tail blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteOverlay>().ElementAt(1).DrawPosition == holdNote.Tail.DrawPosition);
AddAssert("head blueprint positioned correctly", () => this.ChildrenOfType<EditNotePiece>().ElementAt(0).DrawPosition == holdNote.Head.DrawPosition);
AddAssert("tail blueprint positioned correctly", () => this.ChildrenOfType<EditNotePiece>().ElementAt(1).DrawPosition == holdNote.Tail.DrawPosition);
}
private void setScrollStep(ScrollingDirection direction)

View File

@ -1,43 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
public class HoldNoteNoteOverlay : CompositeDrawable
{
private readonly HoldNoteSelectionBlueprint holdNoteBlueprint;
private readonly HoldNotePosition position;
public HoldNoteNoteOverlay(HoldNoteSelectionBlueprint holdNoteBlueprint, HoldNotePosition position)
{
this.holdNoteBlueprint = holdNoteBlueprint;
this.position = position;
InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
}
protected override void Update()
{
base.Update();
var drawableObject = holdNoteBlueprint.DrawableObject;
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
if (drawableObject.IsLoaded)
{
DrawableNote note = position == HoldNotePosition.Start ? (DrawableNote)drawableObject.Head : drawableObject.Tail;
Anchor = note.Anchor;
Origin = note.Origin;
Size = note.DrawSize;
Position = note.DrawPosition;
}
}
}
}

View File

@ -1,11 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
public enum HoldNotePosition
{
Start,
End
}
}

View File

@ -2,14 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
@ -17,13 +16,12 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint<HoldNote>
{
public new DrawableHoldNote DrawableObject => (DrawableHoldNote)base.DrawableObject;
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
[Resolved]
private OsuColour colours { get; set; }
private EditNotePiece head;
private EditNotePiece tail;
public HoldNoteSelectionBlueprint(HoldNote hold)
: base(hold)
{
@ -32,12 +30,10 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[BackgroundDependencyLoader]
private void load(IScrollingInfo scrollingInfo)
{
direction.BindTo(scrollingInfo.Direction);
InternalChildren = new Drawable[]
{
new HoldNoteNoteOverlay(this, HoldNotePosition.Start),
new HoldNoteNoteOverlay(this, HoldNotePosition.End),
head = new EditNotePiece { RelativeSizeAxes = Axes.X },
tail = new EditNotePiece { RelativeSizeAxes = Axes.X },
new Container
{
RelativeSizeAxes = Axes.Both,
@ -58,21 +54,13 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
base.Update();
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
if (DrawableObject.IsLoaded)
{
Size = DrawableObject.DrawSize + new Vector2(0, DrawableObject.Tail.DrawHeight);
// This is a side-effect of not matching the hitobject's anchors/origins, which is kinda hard to do
// When scrolling upwards our origin is already at the top of the head note (which is the intended location),
// but when scrolling downwards our origin is at the _bottom_ of the tail note (where we need to be at the _top_ of the tail note)
if (direction.Value == ScrollingDirection.Down)
Y -= DrawableObject.Tail.DrawHeight;
}
head.Y = HitObjectContainer.PositionAtTime(HitObject.Head.StartTime, HitObject.StartTime);
tail.Y = HitObjectContainer.PositionAtTime(HitObject.Tail.StartTime, HitObject.StartTime);
Height = HitObjectContainer.LengthAtTime(HitObject.StartTime, HitObject.EndTime) + tail.DrawHeight;
}
public override Quad SelectionQuad => ScreenSpaceDrawQuad;
public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.Head.ScreenSpaceDrawQuad.Centre;
public override Vector2 ScreenSpaceSelectionPoint => head.ScreenSpaceDrawQuad.Centre;
}
}

View File

@ -5,20 +5,22 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
public abstract class ManiaSelectionBlueprint<T> : HitObjectSelectionBlueprint<T>
where T : ManiaHitObject
{
public new DrawableManiaHitObject DrawableObject => (DrawableManiaHitObject)base.DrawableObject;
[Resolved]
private HitObjectComposer composer { get; set; }
[Resolved]
private IScrollingInfo scrollingInfo { get; set; }
protected ScrollingHitObjectContainer HitObjectContainer => ((ManiaPlayfield)composer.Playfield).GetColumn(HitObject.Column).HitObjectContainer;
protected ManiaSelectionBlueprint(T hitObject)
: base(hitObject)
{
@ -29,19 +31,13 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
base.Update();
Position = Parent.ToLocalSpace(DrawableObject.ToScreenSpace(Vector2.Zero));
}
var anchor = scrollingInfo.Direction.Value == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
Anchor = Origin = anchor;
foreach (var child in InternalChildren)
child.Anchor = child.Origin = anchor;
public override void Show()
{
DrawableObject.AlwaysAlive = true;
base.Show();
}
public override void Hide()
{
DrawableObject.AlwaysAlive = false;
base.Hide();
Position = Parent.ToLocalSpace(HitObjectContainer.ScreenSpacePositionAtTime(HitObject.StartTime)) - AnchorPosition;
Width = HitObjectContainer.DrawWidth;
}
}
}

View File

@ -14,14 +14,5 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{
AddInternal(new EditNotePiece { RelativeSizeAxes = Axes.X });
}
protected override void Update()
{
base.Update();
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
if (DrawableObject.IsLoaded)
Size = DrawableObject.DrawSize;
}
}
}