1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 15:05:34 +08:00

Begin refactoring SelectionBlueprint to handle non-drawable HitObjects

This commit is contained in:
Dean Herbert 2020-01-21 00:53:59 +09:00
parent 1becbb072e
commit bd96cf94a6
15 changed files with 102 additions and 107 deletions

View File

@ -13,7 +13,7 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class ManiaSelectionBlueprint : SelectionBlueprint public class ManiaSelectionBlueprint : OverlaySelectionBlueprint
{ {
public Vector2 ScreenSpaceDragPosition { get; private set; } public Vector2 ScreenSpaceDragPosition { get; private set; }
public Vector2 DragPosition { get; private set; } public Vector2 DragPosition { get; private set; }

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{ {
} }
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
{ {
switch (hitObject) switch (hitObject)
{ {

View File

@ -5,6 +5,7 @@ using System;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Timing; using osu.Framework.Timing;
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; using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
@ -72,8 +73,10 @@ namespace osu.Game.Rulesets.Mania.Edit
if (scrollingInfo.Direction.Value == ScrollingDirection.Down) if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight; delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight;
foreach (var b in SelectedBlueprints) foreach (var selectionBlueprint in SelectedBlueprints)
{ {
var b = (OverlaySelectionBlueprint)selectionBlueprint;
var hitObject = b.DrawableObject; var hitObject = b.DrawableObject;
var objectParent = (HitObjectContainer)hitObject.Parent; var objectParent = (HitObjectContainer)hitObject.Parent;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Edit.Masks namespace osu.Game.Rulesets.Mania.Edit.Masks
{ {
public abstract class ManiaSelectionBlueprint : SelectionBlueprint public abstract class ManiaSelectionBlueprint : OverlaySelectionBlueprint
{ {
protected ManiaSelectionBlueprint(DrawableHitObject drawableObject) protected ManiaSelectionBlueprint(DrawableHitObject drawableObject)
: base(drawableObject) : base(drawableObject)

View File

@ -7,10 +7,10 @@ using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints namespace osu.Game.Rulesets.Osu.Edit.Blueprints
{ {
public abstract class OsuSelectionBlueprint<T> : SelectionBlueprint public abstract class OsuSelectionBlueprint<T> : OverlaySelectionBlueprint
where T : OsuHitObject where T : OsuHitObject
{ {
protected T HitObject => (T)DrawableObject.HitObject; protected new T HitObject => (T)DrawableObject.HitObject;
protected OsuSelectionBlueprint(DrawableHitObject drawableObject) protected OsuSelectionBlueprint(DrawableHitObject drawableObject)
: base(drawableObject) : base(drawableObject)

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Edit
protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler();
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
{ {
switch (hitObject) switch (hitObject)
{ {

View File

@ -0,0 +1,32 @@
// 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.Primitives;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
namespace osu.Game.Rulesets.Edit
{
public abstract class OverlaySelectionBlueprint : SelectionBlueprint
{
/// <summary>
/// The <see cref="DrawableHitObject"/> which this <see cref="OverlaySelectionBlueprint"/> applies to.
/// </summary>
public readonly DrawableHitObject DrawableObject;
protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected;
protected OverlaySelectionBlueprint(DrawableHitObject drawableObject)
: base(drawableObject.HitObject)
{
DrawableObject = drawableObject;
}
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
public override Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre;
public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad;
}
}

View File

@ -1,4 +1,4 @@
// 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 System; using System;
@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public abstract class SelectionBlueprint : CompositeDrawable, IStateful<SelectionState> public abstract class SelectionBlueprint : CompositeDrawable, IStateful<SelectionState>
{ {
public readonly HitObject HitObject;
/// <summary> /// <summary>
/// Invoked when this <see cref="SelectionBlueprint"/> has been selected. /// Invoked when this <see cref="SelectionBlueprint"/> has been selected.
/// </summary> /// </summary>
@ -30,22 +32,15 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public event Action<SelectionBlueprint> Deselected; public event Action<SelectionBlueprint> Deselected;
/// <summary>
/// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to.
/// </summary>
public readonly DrawableHitObject DrawableObject;
protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected;
public override bool HandlePositionalInput => ShouldBeAlive; public override bool HandlePositionalInput => ShouldBeAlive;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private HitObjectComposer composer { get; set; } private HitObjectComposer composer { get; set; }
protected SelectionBlueprint(DrawableHitObject drawableObject) protected SelectionBlueprint(HitObject hitObject)
{ {
DrawableObject = drawableObject; this.HitObject = hitObject;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
AlwaysPresent = true; AlwaysPresent = true;
@ -87,37 +82,35 @@ 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="SelectionBlueprint"/>, causing it to become visible. /// Selects this <see cref="OverlaySelectionBlueprint"/>, 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="SelectionBlueprint"/>, causing it to become invisible. /// Deselects this <see cref="OverlaySelectionBlueprint"/>, causing it to become invisible.
/// </summary> /// </summary>
public void Deselect() => State = SelectionState.NotSelected; public void Deselect() => State = SelectionState.NotSelected;
public bool IsSelected => State == SelectionState.Selected; public bool IsSelected => State == SelectionState.Selected;
/// <summary> /// <summary>
/// Updates the <see cref="HitObject"/>, invoking <see cref="HitObject.ApplyDefaults"/> and re-processing the beatmap. /// Updates the <see cref="Objects.HitObject"/>, invoking <see cref="Objects.HitObject.ApplyDefaults"/> and re-processing the beatmap.
/// </summary> /// </summary>
protected void UpdateHitObject() => composer?.UpdateHitObject(DrawableObject.HitObject); protected void UpdateHitObject() => composer?.UpdateHitObject(HitObject);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
/// <summary> /// <summary>
/// The <see cref="MenuItem"/>s to be displayed in the context menu for this <see cref="SelectionBlueprint"/>. /// The <see cref="MenuItem"/>s to be displayed in the context menu for this <see cref="OverlaySelectionBlueprint"/>.
/// </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="SelectionBlueprint"/> to be selected. /// The screen-space point that causes this <see cref="OverlaySelectionBlueprint"/> to be selected.
/// </summary> /// </summary>
public virtual Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; public virtual Vector2 SelectionPoint => ScreenSpaceDrawQuad.Centre;
/// <summary> /// <summary>
/// The screen-space quad that outlines this <see cref="SelectionBlueprint"/> for selections. /// The screen-space quad that outlines this <see cref="OverlaySelectionBlueprint"/> for selections.
/// </summary> /// </summary>
public virtual Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; public virtual Quad SelectionQuad => ScreenSpaceDrawQuad;
} }
} }

View File

@ -11,20 +11,24 @@ using osu.Game.Beatmaps;
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
{ {
public class TimelinePart : TimelinePart<Drawable>
{
}
/// <summary> /// <summary>
/// Represents a part of the summary timeline.. /// Represents a part of the summary timeline..
/// </summary> /// </summary>
public class TimelinePart : Container public class TimelinePart<T> : Container<T> where T : Drawable
{ {
protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>(); protected readonly IBindable<WorkingBeatmap> Beatmap = new Bindable<WorkingBeatmap>();
private readonly Container timeline; private readonly Container<T> content;
protected override Container<Drawable> Content => timeline; protected override Container<T> Content => content;
public TimelinePart() public TimelinePart(Container<T> content = null)
{ {
AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); AddInternal(this.content = content ?? new Container<T> { RelativeSizeAxes = Axes.Both });
Beatmap.ValueChanged += b => Beatmap.ValueChanged += b =>
{ {
@ -44,17 +48,17 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
// the track may not be loaded completely (only has a length once it is). // the track may not be loaded completely (only has a length once it is).
if (!Beatmap.Value.Track.IsLoaded) if (!Beatmap.Value.Track.IsLoaded)
{ {
timeline.RelativeChildSize = Vector2.One; content.RelativeChildSize = Vector2.One;
Schedule(updateRelativeChildSize); Schedule(updateRelativeChildSize);
return; return;
} }
timeline.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1);
} }
protected virtual void LoadBeatmap(WorkingBeatmap beatmap) protected virtual void LoadBeatmap(WorkingBeatmap beatmap)
{ {
timeline.Clear(); content.Clear();
} }
} }
} }

View File

@ -59,7 +59,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
DragBox = CreateDragBox(select), DragBox = CreateDragBox(select),
selectionHandler, selectionHandler,
selectionBlueprints = new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }, selectionBlueprints = CreateSelectionBlueprintContainer(),
DragBox.CreateProxy().With(p => p.Depth = float.MinValue) DragBox.CreateProxy().With(p => p.Depth = float.MinValue)
}); });
@ -67,6 +67,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
AddBlueprintFor(obj); AddBlueprintFor(obj);
} }
protected virtual SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both };
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
@ -118,7 +120,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (clickedBlueprint == null) if (clickedBlueprint == null)
return false; return false;
adjustableClock?.Seek(clickedBlueprint.DrawableObject.HitObject.StartTime); adjustableClock?.Seek(clickedBlueprint.HitObject.StartTime);
return true; return true;
} }
@ -208,7 +210,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void removeBlueprintFor(HitObject hitObject) private void removeBlueprintFor(HitObject hitObject)
{ {
var blueprint = selectionBlueprints.SingleOrDefault(m => m.DrawableObject.HitObject == hitObject); var blueprint = selectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject);
if (blueprint == null) if (blueprint == null)
return; return;
@ -346,8 +348,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
return false; return false;
// Movement is tracked from the blueprint of the earliest hitobject, since it only makes sense to distance snap from that hitobject // Movement is tracked from the blueprint of the earliest hitobject, since it only makes sense to distance snap from that hitobject
movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.DrawableObject.HitObject.StartTime).First(); movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.HitObject.StartTime).First();
screenSpaceMovementStartPosition = movementBlueprint.DrawableObject.ToScreenSpace(movementBlueprint.DrawableObject.OriginPosition); screenSpaceMovementStartPosition = movementBlueprint.SelectionPoint; // todo: unsure if correct
return true; return true;
} }
@ -365,14 +367,14 @@ namespace osu.Game.Screens.Edit.Compose.Components
Debug.Assert(screenSpaceMovementStartPosition != null); Debug.Assert(screenSpaceMovementStartPosition != null);
Vector2 startPosition = screenSpaceMovementStartPosition.Value; Vector2 startPosition = screenSpaceMovementStartPosition.Value;
HitObject draggedObject = movementBlueprint.DrawableObject.HitObject; HitObject draggedObject = movementBlueprint.HitObject;
// The final movement position, relative to screenSpaceMovementStartPosition // The final movement position, relative to screenSpaceMovementStartPosition
Vector2 movePosition = startPosition + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; Vector2 movePosition = startPosition + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition;
(Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime);
// Move the hitobjects // Move the hitobjects
if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) if (!selectionHandler.HandleMovement(new MoveSelectionEvent((OverlaySelectionBlueprint)movementBlueprint, startPosition, ToScreenSpace(snappedPosition))))
return true; return true;
// Apply the start time at the newly snapped-to position // Apply the start time at the newly snapped-to position
@ -411,29 +413,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
} }
} }
private class SelectionBlueprintContainer : Container<SelectionBlueprint> protected class SelectionBlueprintContainer : Container<SelectionBlueprint>
{ {
public IEnumerable<SelectionBlueprint> AliveBlueprints => AliveInternalChildren.Cast<SelectionBlueprint>(); public IEnumerable<SelectionBlueprint> AliveBlueprints => AliveInternalChildren.Cast<SelectionBlueprint>();
protected override int Compare(Drawable x, Drawable y)
{
if (!(x is SelectionBlueprint xBlueprint) || !(y is SelectionBlueprint yBlueprint))
return base.Compare(x, y);
return Compare(xBlueprint, yBlueprint);
}
public int Compare(SelectionBlueprint x, SelectionBlueprint y)
{
// dpeth is used to denote selected status (we always want selected blueprints to handle input first).
int d = x.Depth.CompareTo(y.Depth);
if (d != 0)
return d;
// Put earlier hitobjects towards the end of the list, so they handle input first
int i = y.DrawableObject.HitObject.StartTime.CompareTo(x.DrawableObject.HitObject.StartTime);
return i == 0 ? CompareReverseChildID(x, y) : i;
}
} }
} }
} }

View File

@ -119,7 +119,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
return CreateBlueprintFor(drawable); return CreateBlueprintFor(drawable);
} }
public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; public virtual OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null;
protected override void AddBlueprintFor(HitObject hitObject) protected override void AddBlueprintFor(HitObject hitObject)
{ {

View File

@ -7,14 +7,14 @@ 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="SelectionBlueprint"/> is moved. /// An event which occurs when a <see cref="OverlaySelectionBlueprint"/> is moved.
/// </summary> /// </summary>
public class MoveSelectionEvent public class MoveSelectionEvent
{ {
/// <summary> /// <summary>
/// The <see cref="SelectionBlueprint"/> that triggered this <see cref="MoveSelectionEvent"/>. /// The <see cref="OverlaySelectionBlueprint"/> that triggered this <see cref="MoveSelectionEvent"/>.
/// </summary> /// </summary>
public readonly SelectionBlueprint Blueprint; public readonly OverlaySelectionBlueprint Blueprint;
/// <summary> /// <summary>
/// The starting screen-space position of the hitobject. /// The starting screen-space position of the hitobject.
@ -34,7 +34,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// </remarks> /// </remarks>
public readonly Vector2 InstantDelta; public readonly Vector2 InstantDelta;
public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) public MoveSelectionEvent(OverlaySelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition)
{ {
Blueprint = blueprint; Blueprint = blueprint;
ScreenSpaceStartPosition = screenSpaceStartPosition; ScreenSpaceStartPosition = screenSpaceStartPosition;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
public IEnumerable<SelectionBlueprint> SelectedBlueprints => selectedBlueprints; public IEnumerable<SelectionBlueprint> SelectedBlueprints => selectedBlueprints;
private readonly List<SelectionBlueprint> selectedBlueprints; private readonly List<SelectionBlueprint> selectedBlueprints;
public IEnumerable<HitObject> SelectedHitObjects => selectedBlueprints.Select(b => b.DrawableObject.HitObject); public IEnumerable<HitObject> SelectedHitObjects => selectedBlueprints.Select(b => b.HitObject);
private Drawable outline; private Drawable outline;
@ -146,7 +146,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void deleteSelected() private void deleteSelected()
{ {
foreach (var h in selectedBlueprints.ToList()) foreach (var h in selectedBlueprints.ToList())
placementHandler.Delete(h.DrawableObject.HitObject); placementHandler.Delete(h.HitObject);
} }
#endregion #endregion

View File

@ -2,13 +2,12 @@
// 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 System; using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; 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.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
@ -19,32 +18,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
internal class TimelineHitObjectDisplay : BlueprintContainer internal class TimelineHitObjectDisplay : BlueprintContainer
{ {
private EditorBeatmap beatmap { get; }
private readonly TimelinePart content;
public TimelineHitObjectDisplay(EditorBeatmap beatmap) public TimelineHitObjectDisplay(EditorBeatmap beatmap)
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
this.beatmap = beatmap;
AddInternal(content = new TimelinePart { RelativeSizeAxes = Axes.Both });
} }
[BackgroundDependencyLoader] protected override SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both };
private void load()
{
foreach (var h in beatmap.HitObjects)
add(h);
beatmap.HitObjectAdded += add; protected class TimelineSelectionBlueprintContainer : SelectionBlueprintContainer
beatmap.HitObjectRemoved += remove; {
beatmap.StartTimeChanged += h => protected override Container<SelectionBlueprint> Content { get; }
public TimelineSelectionBlueprintContainer()
{ {
remove(h); AddInternal(new TimelinePart<SelectionBlueprint>(Content = new Container<SelectionBlueprint> { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both });
add(h); }
};
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -53,24 +41,19 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
DragBox.Alpha = 0; DragBox.Alpha = 0;
} }
private void remove(HitObject h) protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject)
{ {
foreach (var d in content.OfType<TimelineHitObjectRepresentation>().Where(c => c.HitObject == h)) //var yOffset = content.Count(d => d.X == h.StartTime);
d.Expire(); var yOffset = 0;
}
private void add(HitObject h) return new TimelineHitObjectRepresentation(hitObject) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS };
{
var yOffset = content.Count(d => d.X == h.StartTime);
content.Add(new TimelineHitObjectRepresentation(h) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS });
} }
protected override bool OnMouseDown(MouseDownEvent e) protected override bool OnMouseDown(MouseDownEvent e)
{ {
base.OnMouseDown(e); base.OnMouseDown(e);
return false; // tempoerary until we correctly handle selections. return false; // temporary until we correctly handle selections.
} }
protected override DragBox CreateDragBox(Action<RectangleF> performSelect) => new NoDragDragBox(performSelect); protected override DragBox CreateDragBox(Action<RectangleF> performSelect) => new NoDragDragBox(performSelect);
@ -85,15 +68,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public override bool UpdateDrag(MouseButtonEvent e) => false; public override bool UpdateDrag(MouseButtonEvent e) => false;
} }
private class TimelineHitObjectRepresentation : CompositeDrawable private class TimelineHitObjectRepresentation : SelectionBlueprint
{ {
public const float THICKNESS = 3; public const float THICKNESS = 3;
public readonly HitObject HitObject;
public TimelineHitObjectRepresentation(HitObject hitObject) public TimelineHitObjectRepresentation(HitObject hitObject)
: base(hitObject)
{ {
HitObject = hitObject;
Anchor = Anchor.CentreLeft; Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft; Origin = Anchor.CentreLeft;

View File

@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual
}); });
} }
protected void AddBlueprint(SelectionBlueprint blueprint) protected void AddBlueprint(OverlaySelectionBlueprint blueprint)
{ {
Add(blueprint.With(d => Add(blueprint.With(d =>
{ {