mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 15:27:30 +08:00
Make BreakPeriod
a struct
This commit is contained in:
parent
6a6ccbc09f
commit
1f692f5fc7
@ -1,11 +1,12 @@
|
||||
// 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 System;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Beatmaps.Timing
|
||||
{
|
||||
public class BreakPeriod
|
||||
public readonly struct BreakPeriod : IEquatable<BreakPeriod>
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum duration required for a break to have any effect.
|
||||
@ -15,12 +16,12 @@ namespace osu.Game.Beatmaps.Timing
|
||||
/// <summary>
|
||||
/// The break start time.
|
||||
/// </summary>
|
||||
public double StartTime;
|
||||
public double StartTime { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The break end time.
|
||||
/// </summary>
|
||||
public double EndTime;
|
||||
public double EndTime { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The break duration.
|
||||
@ -49,5 +50,9 @@ namespace osu.Game.Beatmaps.Timing
|
||||
/// <param name="time">The time to check in milliseconds.</param>
|
||||
/// <returns>Whether the time falls within this <see cref="BreakPeriod"/>.</returns>
|
||||
public bool Contains(double time) => time >= StartTime && time <= EndTime - BreakOverlay.BREAK_FADE_DURATION;
|
||||
|
||||
public bool Equals(BreakPeriod other) => StartTime.Equals(other.StartTime) && EndTime.Equals(other.EndTime);
|
||||
public override bool Equals(object? obj) => obj is BreakPeriod other && Equals(other);
|
||||
public override int GetHashCode() => HashCode.Combine(StartTime, EndTime);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -20,11 +21,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
{
|
||||
public partial class TimelineBreak : CompositeDrawable
|
||||
{
|
||||
public BreakPeriod Break { get; }
|
||||
public Bindable<BreakPeriod> Break { get; } = new Bindable<BreakPeriod>();
|
||||
|
||||
public TimelineBreak(BreakPeriod b)
|
||||
{
|
||||
Break = b;
|
||||
Break.Value = b;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -48,40 +49,46 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
Alpha = 0.4f,
|
||||
},
|
||||
},
|
||||
new DragHandle(Break, isStartHandle: true)
|
||||
new DragHandle(isStartHandle: true)
|
||||
{
|
||||
Break = { BindTarget = Break },
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Action = (time, breakPeriod) => breakPeriod.StartTime = time,
|
||||
Action = (time, breakPeriod) => breakPeriod with { StartTime = time },
|
||||
},
|
||||
new DragHandle(Break, isStartHandle: false)
|
||||
new DragHandle(isStartHandle: false)
|
||||
{
|
||||
Break = { BindTarget = Break },
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Action = (time, breakPeriod) => breakPeriod.EndTime = time,
|
||||
Action = (time, breakPeriod) => breakPeriod with { EndTime = time },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.Update();
|
||||
base.LoadComplete();
|
||||
|
||||
X = (float)Break.StartTime;
|
||||
Width = (float)Break.Duration;
|
||||
Break.BindValueChanged(_ =>
|
||||
{
|
||||
X = (float)Break.Value.StartTime;
|
||||
Width = (float)Break.Value.Duration;
|
||||
}, true);
|
||||
}
|
||||
|
||||
private partial class DragHandle : FillFlowContainer
|
||||
{
|
||||
public Bindable<BreakPeriod> Break { get; } = new Bindable<BreakPeriod>();
|
||||
|
||||
public new Anchor Anchor
|
||||
{
|
||||
get => base.Anchor;
|
||||
init => base.Anchor = value;
|
||||
}
|
||||
|
||||
public Action<double, BreakPeriod>? Action { get; init; }
|
||||
public Func<double, BreakPeriod, BreakPeriod>? Action { get; init; }
|
||||
|
||||
private readonly BreakPeriod breakPeriod;
|
||||
private readonly bool isStartHandle;
|
||||
|
||||
private Container handle = null!;
|
||||
@ -99,9 +106,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
|
||||
public DragHandle(BreakPeriod breakPeriod, bool isStartHandle)
|
||||
public DragHandle(bool isStartHandle)
|
||||
{
|
||||
this.breakPeriod = breakPeriod;
|
||||
this.isStartHandle = isStartHandle;
|
||||
}
|
||||
|
||||
@ -164,13 +170,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
changeHandler?.BeginChange();
|
||||
updateState();
|
||||
|
||||
double min = beatmap.HitObjects.Last(ho => ho.GetEndTime() <= breakPeriod.StartTime).GetEndTime();
|
||||
double max = beatmap.HitObjects.First(ho => ho.StartTime >= breakPeriod.EndTime).StartTime;
|
||||
double min = beatmap.HitObjects.Last(ho => ho.GetEndTime() <= Break.Value.StartTime).GetEndTime();
|
||||
double max = beatmap.HitObjects.First(ho => ho.StartTime >= Break.Value.EndTime).StartTime;
|
||||
|
||||
if (isStartHandle)
|
||||
max = Math.Min(max, breakPeriod.EndTime - BreakPeriod.MIN_BREAK_DURATION);
|
||||
max = Math.Min(max, Break.Value.EndTime - BreakPeriod.MIN_BREAK_DURATION);
|
||||
else
|
||||
min = Math.Max(min, breakPeriod.StartTime + BreakPeriod.MIN_BREAK_DURATION);
|
||||
min = Math.Max(min, Break.Value.StartTime + BreakPeriod.MIN_BREAK_DURATION);
|
||||
|
||||
allowedDragRange = (min, max);
|
||||
|
||||
@ -183,11 +189,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
Debug.Assert(allowedDragRange != null);
|
||||
|
||||
if (timeline.FindSnappedPositionAndTime(e.ScreenSpaceMousePosition).Time is double time
|
||||
if (Action != null
|
||||
&& timeline.FindSnappedPositionAndTime(e.ScreenSpaceMousePosition).Time is double time
|
||||
&& time > allowedDragRange.Value.min
|
||||
&& time < allowedDragRange.Value.max)
|
||||
{
|
||||
Action?.Invoke(time, breakPeriod);
|
||||
int index = beatmap.Breaks.IndexOf(Break.Value);
|
||||
beatmap.Breaks[index] = Break.Value = Action.Invoke(time, Break.Value);
|
||||
}
|
||||
|
||||
updateState();
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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 System.Collections.Specialized;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
@ -29,7 +30,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
breaks.UnbindAll();
|
||||
breaks.BindTo(beatmap.Breaks);
|
||||
breaks.BindCollectionChanged((_, _) => breakCache.Invalidate());
|
||||
breaks.BindCollectionChanged((_, e) =>
|
||||
{
|
||||
if (e.Action != NotifyCollectionChangedAction.Replace)
|
||||
breakCache.Invalidate();
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -57,14 +62,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
private void recreateBreaks()
|
||||
{
|
||||
// Remove groups outside the visible range
|
||||
foreach (TimelineBreak drawableBreak in this)
|
||||
{
|
||||
if (!shouldBeVisible(drawableBreak.Break))
|
||||
drawableBreak.Expire();
|
||||
}
|
||||
Clear();
|
||||
|
||||
// Add remaining ones
|
||||
for (int i = 0; i < breaks.Count; i++)
|
||||
{
|
||||
var breakPeriod = breaks[i];
|
||||
@ -72,20 +71,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
if (!shouldBeVisible(breakPeriod))
|
||||
continue;
|
||||
|
||||
bool alreadyVisible = false;
|
||||
|
||||
foreach (var b in this)
|
||||
{
|
||||
if (ReferenceEquals(b.Break, breakPeriod))
|
||||
{
|
||||
alreadyVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyVisible)
|
||||
continue;
|
||||
|
||||
Add(new TimelineBreak(breakPeriod));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user