1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 17:27:24 +08:00

Merge pull request #12782 from smoogipoo/rework-hitobject-blueprints

Rename hitobject blueprints and tie them to HitObjects
This commit is contained in:
Dean Herbert 2021-05-18 16:30:58 +09:00 committed by GitHub
commit a96603f025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 115 additions and 122 deletions

View File

@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
} }
}; };
AddBlueprint(new HoldNoteSelectionBlueprint(drawableObject)); AddBlueprint(new HoldNoteSelectionBlueprint(holdNote), drawableObject);
} }
protected override void Update() protected override void Update()

View File

@ -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("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("tail note positioned correctly", () => Precision.AlmostEquals(holdNote.ScreenSpaceDrawQuad.TopLeft, holdNote.Tail.ScreenSpaceDrawQuad.BottomLeft));
AddAssert("head blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteSelectionBlueprint>().ElementAt(0).DrawPosition == holdNote.Head.DrawPosition); AddAssert("head blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteOverlay>().ElementAt(0).DrawPosition == holdNote.Head.DrawPosition);
AddAssert("tail blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteSelectionBlueprint>().ElementAt(1).DrawPosition == holdNote.Tail.DrawPosition); AddAssert("tail blueprint positioned correctly", () => this.ChildrenOfType<HoldNoteNoteOverlay>().ElementAt(1).DrawPosition == holdNote.Tail.DrawPosition);
} }
private void setScrollStep(ScrollingDirection direction) private void setScrollStep(ScrollingDirection direction)

View File

@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
Child = drawableObject = new DrawableNote(note) Child = drawableObject = new DrawableNote(note)
}; };
AddBlueprint(new NoteSelectionBlueprint(drawableObject)); AddBlueprint(new NoteSelectionBlueprint(note), drawableObject);
} }
} }
} }

View File

@ -2,34 +2,35 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components; using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class HoldNoteNoteSelectionBlueprint : ManiaSelectionBlueprint public class HoldNoteNoteOverlay : CompositeDrawable
{ {
protected new DrawableHoldNote DrawableObject => (DrawableHoldNote)base.DrawableObject; private readonly HoldNoteSelectionBlueprint holdNoteBlueprint;
private readonly HoldNotePosition position; private readonly HoldNotePosition position;
public HoldNoteNoteSelectionBlueprint(DrawableHoldNote holdNote, HoldNotePosition position) public HoldNoteNoteOverlay(HoldNoteSelectionBlueprint holdNoteBlueprint, HoldNotePosition position)
: base(holdNote)
{ {
this.holdNoteBlueprint = holdNoteBlueprint;
this.position = position; this.position = position;
InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
Select(); InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
} }
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
var drawableObject = holdNoteBlueprint.DrawableObject;
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly. // Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
if (DrawableObject.IsLoaded) if (drawableObject.IsLoaded)
{ {
DrawableNote note = position == HoldNotePosition.Start ? (DrawableNote)DrawableObject.Head : DrawableObject.Tail; DrawableNote note = position == HoldNotePosition.Start ? (DrawableNote)drawableObject.Head : drawableObject.Tail;
Anchor = note.Anchor; Anchor = note.Anchor;
Origin = note.Origin; Origin = note.Origin;
@ -38,8 +39,5 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
Position = note.DrawPosition; Position = note.DrawPosition;
} }
} }
// Todo: This is temporary, since the note masks don't do anything special yet. In the future they will handle input.
public override bool HandlePositionalInput => false;
} }
} }

View File

@ -8,13 +8,14 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint<HoldNote>
{ {
public new DrawableHoldNote DrawableObject => (DrawableHoldNote)base.DrawableObject; public new DrawableHoldNote DrawableObject => (DrawableHoldNote)base.DrawableObject;
@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved] [Resolved]
private OsuColour colours { get; set; } private OsuColour colours { get; set; }
public HoldNoteSelectionBlueprint(DrawableHoldNote hold) public HoldNoteSelectionBlueprint(HoldNote hold)
: base(hold) : base(hold)
{ {
} }
@ -32,16 +33,11 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
private void load(IScrollingInfo scrollingInfo) private void load(IScrollingInfo scrollingInfo)
{ {
direction.BindTo(scrollingInfo.Direction); direction.BindTo(scrollingInfo.Direction);
}
protected override void LoadComplete()
{
base.LoadComplete();
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new HoldNoteNoteSelectionBlueprint(DrawableObject, HoldNotePosition.Start), new HoldNoteNoteOverlay(this, HoldNotePosition.Start),
new HoldNoteNoteSelectionBlueprint(DrawableObject, HoldNotePosition.End), new HoldNoteNoteOverlay(this, HoldNotePosition.End),
new Container new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,

View File

@ -4,22 +4,23 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public abstract class ManiaSelectionBlueprint : OverlaySelectionBlueprint public abstract class ManiaSelectionBlueprint<T> : HitObjectSelectionBlueprint<T>
where T : ManiaHitObject
{ {
public new DrawableManiaHitObject DrawableObject => (DrawableManiaHitObject)base.DrawableObject; public new DrawableManiaHitObject DrawableObject => (DrawableManiaHitObject)base.DrawableObject;
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
protected ManiaSelectionBlueprint(DrawableHitObject drawableObject) protected ManiaSelectionBlueprint(T hitObject)
: base(drawableObject) : base(hitObject)
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
} }

View File

@ -3,13 +3,13 @@
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components; using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class NoteSelectionBlueprint : ManiaSelectionBlueprint public class NoteSelectionBlueprint : ManiaSelectionBlueprint<Note>
{ {
public NoteSelectionBlueprint(DrawableNote note) public NoteSelectionBlueprint(Note note)
: base(note) : base(note)
{ {
AddInternal(new EditNotePiece { RelativeSizeAxes = Axes.X }); AddInternal(new EditNotePiece { RelativeSizeAxes = Axes.X });

View File

@ -3,9 +3,8 @@
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
namespace osu.Game.Rulesets.Mania.Edit namespace osu.Game.Rulesets.Mania.Edit
@ -17,18 +16,18 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
} }
public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject)
{ {
switch (hitObject) switch (hitObject)
{ {
case DrawableNote note: case Note note:
return new NoteSelectionBlueprint(note); return new NoteSelectionBlueprint(note);
case DrawableHoldNote holdNote: case HoldNote holdNote:
return new HoldNoteSelectionBlueprint(holdNote); return new HoldNoteSelectionBlueprint(holdNote);
} }
return base.CreateBlueprintFor(hitObject); return base.CreateHitObjectBlueprintFor(hitObject);
} }
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new ManiaSelectionHandler(); protected override SelectionHandler<HitObject> CreateSelectionHandler() => new ManiaSelectionHandler();

View File

@ -5,7 +5,6 @@ using System;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
@ -23,8 +22,8 @@ namespace osu.Game.Rulesets.Mania.Edit
public override bool HandleMovement(MoveSelectionEvent<HitObject> moveEvent) public override bool HandleMovement(MoveSelectionEvent<HitObject> moveEvent)
{ {
var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint; var hitObjectBlueprint = (HitObjectSelectionBlueprint)moveEvent.Blueprint;
int lastColumn = maniaBlueprint.DrawableObject.HitObject.Column; int lastColumn = ((ManiaHitObject)hitObjectBlueprint.Item).Column;
performColumnMovement(lastColumn, moveEvent); performColumnMovement(lastColumn, moveEvent);

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 }); hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });
Add(drawableObject = new DrawableHitCircle(hitCircle)); Add(drawableObject = new DrawableHitCircle(hitCircle));
AddBlueprint(blueprint = new TestBlueprint(drawableObject)); AddBlueprint(blueprint = new TestBlueprint(hitCircle), drawableObject);
}); });
[Test] [Test]
@ -63,8 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{ {
public new HitCirclePiece CirclePiece => base.CirclePiece; public new HitCirclePiece CirclePiece => base.CirclePiece;
public TestBlueprint(DrawableHitCircle drawableCircle) public TestBlueprint(HitCircle circle)
: base(drawableCircle) : base(circle)
{ {
} }
} }

View File

@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 }); slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });
Add(drawableObject = new DrawableSlider(slider)); Add(drawableObject = new DrawableSlider(slider));
AddBlueprint(new TestSliderBlueprint(drawableObject)); AddBlueprint(new TestSliderBlueprint(slider), drawableObject);
}); });
[Test] [Test]
@ -150,23 +150,23 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
private class TestSliderBlueprint : SliderSelectionBlueprint private class TestSliderBlueprint : SliderSelectionBlueprint
{ {
public new SliderBodyPiece BodyPiece => base.BodyPiece; public new SliderBodyPiece BodyPiece => base.BodyPiece;
public new TestSliderCircleBlueprint HeadBlueprint => (TestSliderCircleBlueprint)base.HeadBlueprint; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay;
public new TestSliderCircleBlueprint TailBlueprint => (TestSliderCircleBlueprint)base.TailBlueprint; public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay;
public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser;
public TestSliderBlueprint(DrawableSlider slider) public TestSliderBlueprint(Slider slider)
: base(slider) : base(slider)
{ {
} }
protected override SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new TestSliderCircleBlueprint(slider, position); protected override SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new TestSliderCircleOverlay(slider, position);
} }
private class TestSliderCircleBlueprint : SliderCircleSelectionBlueprint private class TestSliderCircleOverlay : SliderCircleOverlay
{ {
public new HitCirclePiece CirclePiece => base.CirclePiece; public new HitCirclePiece CirclePiece => base.CirclePiece;
public TestSliderCircleBlueprint(DrawableSlider slider, SliderPosition position) public TestSliderCircleOverlay(Slider slider, SliderPosition position)
: base(slider, position) : base(slider, position)
{ {
} }

View File

@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 }); slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });
Add(drawableObject = new DrawableSlider(slider)); Add(drawableObject = new DrawableSlider(slider));
AddBlueprint(blueprint = new TestSliderBlueprint(drawableObject)); AddBlueprint(blueprint = new TestSliderBlueprint(slider), drawableObject);
}); });
[Test] [Test]
@ -174,10 +174,10 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
AddAssert("body positioned correctly", () => blueprint.BodyPiece.Position == slider.StackedPosition); AddAssert("body positioned correctly", () => blueprint.BodyPiece.Position == slider.StackedPosition);
AddAssert("head positioned correctly", AddAssert("head positioned correctly",
() => Precision.AlmostEquals(blueprint.HeadBlueprint.CirclePiece.ScreenSpaceDrawQuad.Centre, drawableObject.HeadCircle.ScreenSpaceDrawQuad.Centre)); () => Precision.AlmostEquals(blueprint.HeadOverlay.CirclePiece.ScreenSpaceDrawQuad.Centre, drawableObject.HeadCircle.ScreenSpaceDrawQuad.Centre));
AddAssert("tail positioned correctly", AddAssert("tail positioned correctly",
() => Precision.AlmostEquals(blueprint.TailBlueprint.CirclePiece.ScreenSpaceDrawQuad.Centre, drawableObject.TailCircle.ScreenSpaceDrawQuad.Centre)); () => Precision.AlmostEquals(blueprint.TailOverlay.CirclePiece.ScreenSpaceDrawQuad.Centre, drawableObject.TailCircle.ScreenSpaceDrawQuad.Centre));
} }
private void moveMouseToControlPoint(int index) private void moveMouseToControlPoint(int index)
@ -195,23 +195,23 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
private class TestSliderBlueprint : SliderSelectionBlueprint private class TestSliderBlueprint : SliderSelectionBlueprint
{ {
public new SliderBodyPiece BodyPiece => base.BodyPiece; public new SliderBodyPiece BodyPiece => base.BodyPiece;
public new TestSliderCircleBlueprint HeadBlueprint => (TestSliderCircleBlueprint)base.HeadBlueprint; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay;
public new TestSliderCircleBlueprint TailBlueprint => (TestSliderCircleBlueprint)base.TailBlueprint; public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay;
public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser;
public TestSliderBlueprint(DrawableSlider slider) public TestSliderBlueprint(Slider slider)
: base(slider) : base(slider)
{ {
} }
protected override SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new TestSliderCircleBlueprint(slider, position); protected override SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new TestSliderCircleOverlay(slider, position);
} }
private class TestSliderCircleBlueprint : SliderCircleSelectionBlueprint private class TestSliderCircleOverlay : SliderCircleOverlay
{ {
public new HitCirclePiece CirclePiece => base.CirclePiece; public new HitCirclePiece CirclePiece => base.CirclePiece;
public TestSliderCircleBlueprint(DrawableSlider slider, SliderPosition position) public TestSliderCircleOverlay(Slider slider, SliderPosition position)
: base(slider, position) : base(slider, position)
{ {
} }

View File

@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
Child = drawableSpinner = new DrawableSpinner(spinner) Child = drawableSpinner = new DrawableSpinner(spinner)
}); });
AddBlueprint(new SpinnerSelectionBlueprint(drawableSpinner) { Size = new Vector2(0.5f) }); AddBlueprint(new SpinnerSelectionBlueprint(spinner) { Size = new Vector2(0.5f) }, drawableSpinner);
} }
} }
} }

View File

@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
protected readonly HitCirclePiece CirclePiece; protected readonly HitCirclePiece CirclePiece;
public HitCircleSelectionBlueprint(DrawableHitCircle drawableCircle) public HitCircleSelectionBlueprint(HitCircle circle)
: base(drawableCircle) : base(circle)
{ {
InternalChild = CirclePiece = new HitCirclePiece(); InternalChild = CirclePiece = new HitCirclePiece();
} }

View File

@ -2,20 +2,20 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints namespace osu.Game.Rulesets.Osu.Edit.Blueprints
{ {
public abstract class OsuSelectionBlueprint<T> : OverlaySelectionBlueprint public abstract class OsuSelectionBlueprint<T> : HitObjectSelectionBlueprint<T>
where T : OsuHitObject where T : OsuHitObject
{ {
protected T HitObject => (T)DrawableObject.HitObject; protected new DrawableOsuHitObject DrawableObject => (DrawableOsuHitObject)base.DrawableObject;
protected override bool AlwaysShowWhenSelected => true; protected override bool AlwaysShowWhenSelected => true;
protected OsuSelectionBlueprint(DrawableHitObject drawableObject) protected OsuSelectionBlueprint(T hitObject)
: base(drawableObject) : base(hitObject)
{ {
} }
} }

View File

@ -1,36 +1,32 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
{ {
public class SliderCircleSelectionBlueprint : OsuSelectionBlueprint<Slider> public class SliderCircleOverlay : CompositeDrawable
{ {
protected readonly HitCirclePiece CirclePiece; protected readonly HitCirclePiece CirclePiece;
private readonly Slider slider;
private readonly SliderPosition position; private readonly SliderPosition position;
public SliderCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) public SliderCircleOverlay(Slider slider, SliderPosition position)
: base(slider)
{ {
this.slider = slider;
this.position = position; this.position = position;
InternalChild = CirclePiece = new HitCirclePiece(); InternalChild = CirclePiece = new HitCirclePiece();
Select();
} }
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
CirclePiece.UpdateFrom(position == SliderPosition.Start ? (HitCircle)HitObject.HeadCircle : HitObject.TailCircle); CirclePiece.UpdateFrom(position == SliderPosition.Start ? (HitCircle)slider.HeadCircle : slider.TailCircle);
} }
// 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;
} }
} }

View File

@ -16,7 +16,6 @@ using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose;
using osuTK; using osuTK;
@ -27,14 +26,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
public class SliderSelectionBlueprint : OsuSelectionBlueprint<Slider> public class SliderSelectionBlueprint : OsuSelectionBlueprint<Slider>
{ {
protected SliderBodyPiece BodyPiece { get; private set; } protected SliderBodyPiece BodyPiece { get; private set; }
protected SliderCircleSelectionBlueprint HeadBlueprint { get; private set; } protected SliderCircleOverlay HeadOverlay { get; private set; }
protected SliderCircleSelectionBlueprint TailBlueprint { get; private set; } protected SliderCircleOverlay TailOverlay { get; private set; }
[CanBeNull] [CanBeNull]
protected PathControlPointVisualiser ControlPointVisualiser { get; private set; } protected PathControlPointVisualiser ControlPointVisualiser { get; private set; }
private readonly DrawableSlider slider;
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private HitObjectComposer composer { get; set; } private HitObjectComposer composer { get; set; }
@ -52,10 +49,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private readonly BindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>(); private readonly BindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>();
private readonly IBindable<int> pathVersion = new Bindable<int>(); private readonly IBindable<int> pathVersion = new Bindable<int>();
public SliderSelectionBlueprint(DrawableSlider slider) public SliderSelectionBlueprint(Slider slider)
: base(slider) : base(slider)
{ {
this.slider = slider;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -64,8 +60,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
BodyPiece = new SliderBodyPiece(), BodyPiece = new SliderBodyPiece(),
HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start), HeadOverlay = CreateCircleOverlay(HitObject, SliderPosition.Start),
TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End), TailOverlay = CreateCircleOverlay(HitObject, SliderPosition.End),
}; };
} }
@ -103,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
protected override void OnSelected() protected override void OnSelected()
{ {
AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(slider.HitObject, true) AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(HitObject, true)
{ {
RemoveControlPointsRequested = removeControlPoints RemoveControlPointsRequested = removeControlPoints
}); });
@ -215,7 +211,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
} }
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted // If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
if (controlPoints.Count <= 1 || !slider.HitObject.Path.HasValidLength) if (controlPoints.Count <= 1 || !HitObject.Path.HasValidLength)
{ {
placementHandler?.Delete(HitObject); placementHandler?.Delete(HitObject);
return; return;
@ -245,6 +241,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true;
protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); protected virtual SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new SliderCircleOverlay(slider, position);
} }
} }

View File

@ -3,7 +3,6 @@
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components; using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
{ {
private readonly SpinnerPiece piece; private readonly SpinnerPiece piece;
public SpinnerSelectionBlueprint(DrawableSpinner spinner) public SpinnerSelectionBlueprint(Spinner spinner)
: base(spinner) : base(spinner)
{ {
InternalChild = piece = new SpinnerPiece(); InternalChild = piece = new SpinnerPiece();

View File

@ -3,11 +3,10 @@
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners; using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
namespace osu.Game.Rulesets.Osu.Edit namespace osu.Game.Rulesets.Osu.Edit
@ -21,21 +20,21 @@ namespace osu.Game.Rulesets.Osu.Edit
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new OsuSelectionHandler(); protected override SelectionHandler<HitObject> CreateSelectionHandler() => new OsuSelectionHandler();
public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject)
{ {
switch (hitObject) switch (hitObject)
{ {
case DrawableHitCircle circle: case HitCircle circle:
return new HitCircleSelectionBlueprint(circle); return new HitCircleSelectionBlueprint(circle);
case DrawableSlider slider: case Slider slider:
return new SliderSelectionBlueprint(slider); return new SliderSelectionBlueprint(slider);
case DrawableSpinner spinner: case Spinner spinner:
return new SpinnerSelectionBlueprint(spinner); return new SpinnerSelectionBlueprint(spinner);
} }
return base.CreateBlueprintFor(hitObject); return base.CreateHitObjectBlueprintFor(hitObject);
} }
} }
} }

View File

@ -3,14 +3,14 @@
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Taiko.Edit.Blueprints namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
{ {
public class TaikoSelectionBlueprint : OverlaySelectionBlueprint public class TaikoSelectionBlueprint : HitObjectSelectionBlueprint
{ {
public TaikoSelectionBlueprint(DrawableHitObject hitObject) public TaikoSelectionBlueprint(HitObject hitObject)
: base(hitObject) : base(hitObject)
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;

View File

@ -3,7 +3,6 @@
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Edit.Blueprints; using osu.Game.Rulesets.Taiko.Edit.Blueprints;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
@ -18,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Edit
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new TaikoSelectionHandler(); protected override SelectionHandler<HitObject> CreateSelectionHandler() => new TaikoSelectionHandler();
public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) =>
new TaikoSelectionBlueprint(hitObject); new TaikoSelectionBlueprint(hitObject);
} }
} }

View File

@ -9,12 +9,12 @@ using osuTK;
namespace osu.Game.Rulesets.Edit namespace osu.Game.Rulesets.Edit
{ {
public abstract class OverlaySelectionBlueprint : SelectionBlueprint<HitObject> public abstract class HitObjectSelectionBlueprint : SelectionBlueprint<HitObject>
{ {
/// <summary> /// <summary>
/// The <see cref="DrawableHitObject"/> which this <see cref="OverlaySelectionBlueprint"/> applies to. /// The <see cref="DrawableHitObject"/> which this <see cref="HitObjectSelectionBlueprint"/> applies to.
/// </summary> /// </summary>
public readonly DrawableHitObject DrawableObject; public DrawableHitObject DrawableObject { get; internal set; }
/// <summary> /// <summary>
/// Whether the blueprint should be shown even when the <see cref="DrawableObject"/> is not alive. /// Whether the blueprint should be shown even when the <see cref="DrawableObject"/> is not alive.
@ -23,10 +23,9 @@ namespace osu.Game.Rulesets.Edit
protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected); protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected);
protected OverlaySelectionBlueprint(DrawableHitObject drawableObject) protected HitObjectSelectionBlueprint(HitObject hitObject)
: base(drawableObject.HitObject) : base(hitObject)
{ {
DrawableObject = drawableObject;
} }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
@ -35,4 +34,15 @@ namespace osu.Game.Rulesets.Edit
public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad;
} }
public abstract class HitObjectSelectionBlueprint<T> : HitObjectSelectionBlueprint
where T : HitObject
{
public T HitObject => (T)Item;
protected HitObjectSelectionBlueprint(T item)
: base(item)
{
}
}
} }

View File

@ -105,34 +105,34 @@ namespace osu.Game.Rulesets.Edit
protected override bool ShouldBeConsideredForInput(Drawable child) => State == SelectionState.Selected; protected override bool ShouldBeConsideredForInput(Drawable child) => State == SelectionState.Selected;
/// <summary> /// <summary>
/// Selects this <see cref="OverlaySelectionBlueprint"/>, causing it to become visible. /// Selects this <see cref="SelectionBlueprint{T}"/>, causing it to become visible.
/// </summary> /// </summary>
public void Select() => State = SelectionState.Selected; public void Select() => State = SelectionState.Selected;
/// <summary> /// <summary>
/// Deselects this <see cref="OverlaySelectionBlueprint"/>, causing it to become invisible. /// Deselects this <see cref="HitObjectSelectionBlueprint"/>, causing it to become invisible.
/// </summary> /// </summary>
public void Deselect() => State = SelectionState.NotSelected; public void Deselect() => State = SelectionState.NotSelected;
/// <summary> /// <summary>
/// Toggles the selection state of this <see cref="OverlaySelectionBlueprint"/>. /// Toggles the selection state of this <see cref="HitObjectSelectionBlueprint"/>.
/// </summary> /// </summary>
public void ToggleSelection() => State = IsSelected ? SelectionState.NotSelected : SelectionState.Selected; public void ToggleSelection() => State = IsSelected ? SelectionState.NotSelected : SelectionState.Selected;
public bool IsSelected => State == SelectionState.Selected; public bool IsSelected => State == SelectionState.Selected;
/// <summary> /// <summary>
/// The <see cref="MenuItem"/>s to be displayed in the context menu for this <see cref="OverlaySelectionBlueprint"/>. /// The <see cref="MenuItem"/>s to be displayed in the context menu for this <see cref="HitObjectSelectionBlueprint"/>.
/// </summary> /// </summary>
public virtual MenuItem[] ContextMenuItems => Array.Empty<MenuItem>(); public virtual MenuItem[] ContextMenuItems => Array.Empty<MenuItem>();
/// <summary> /// <summary>
/// The screen-space point that causes this <see cref="OverlaySelectionBlueprint"/> to be selected via a drag. /// The screen-space point that causes this <see cref="HitObjectSelectionBlueprint"/> to be selected via a drag.
/// </summary> /// </summary>
public virtual Vector2 ScreenSpaceSelectionPoint => ScreenSpaceDrawQuad.Centre; public virtual Vector2 ScreenSpaceSelectionPoint => ScreenSpaceDrawQuad.Centre;
/// <summary> /// <summary>
/// The screen-space quad that outlines this <see cref="OverlaySelectionBlueprint"/> for selections. /// The screen-space quad that outlines this <see cref="HitObjectSelectionBlueprint"/> for selections.
/// </summary> /// </summary>
public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; public virtual Quad SelectionQuad => ScreenSpaceDrawQuad;

View File

@ -16,7 +16,6 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Components.TernaryButtons;
using osuTK; using osuTK;
@ -246,10 +245,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (drawable == null) if (drawable == null)
return null; return null;
return CreateBlueprintFor(drawable); return CreateHitObjectBlueprintFor(item).With(b => b.DrawableObject = drawable);
} }
public virtual OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; public virtual HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) => null;
protected override void OnBlueprintAdded(HitObject item) protected override void OnBlueprintAdded(HitObject item)
{ {

View File

@ -7,7 +7,7 @@ using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components namespace osu.Game.Screens.Edit.Compose.Components
{ {
/// <summary> /// <summary>
/// An event which occurs when a <see cref="OverlaySelectionBlueprint"/> is moved. /// An event which occurs when a <see cref="SelectionBlueprint{T}"/> is moved.
/// </summary> /// </summary>
public class MoveSelectionEvent<T> public class MoveSelectionEvent<T>
{ {

View File

@ -5,6 +5,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
@ -22,10 +23,11 @@ namespace osu.Game.Tests.Visual
}); });
} }
protected void AddBlueprint(OverlaySelectionBlueprint blueprint) protected void AddBlueprint(HitObjectSelectionBlueprint blueprint, DrawableHitObject drawableObject)
{ {
Add(blueprint.With(d => Add(blueprint.With(d =>
{ {
d.DrawableObject = drawableObject;
d.Depth = float.MinValue; d.Depth = float.MinValue;
d.Select(); d.Select();
})); }));