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

Add break display to editor timeline

This commit is contained in:
Bartłomiej Dach 2024-06-18 14:55:59 +02:00
parent 316125d47a
commit a9e662a2b6
No known key found for this signature in database
3 changed files with 190 additions and 1 deletions

View File

@ -0,0 +1,87 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.Timing;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
public partial class TimelineBreak : CompositeDrawable
{
public BreakPeriod Break { get; }
public TimelineBreak(BreakPeriod b)
{
Break = b;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
RelativePositionAxes = Axes.X;
RelativeSizeAxes = Axes.Both;
Origin = Anchor.TopLeft;
X = (float)Break.StartTime;
Width = (float)Break.Duration;
CornerRadius = 10;
Masking = true;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colours.GreyCarmineLight,
Alpha = 0.4f,
},
new Circle
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y,
Width = 10,
CornerRadius = 5,
Colour = colours.GreyCarmineLighter,
},
new OsuSpriteText
{
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
Text = "Break",
Margin = new MarginPadding
{
Left = 16,
Top = 3,
},
Colour = colours.GreyCarmineLighter,
},
new Circle
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Y,
Width = 10,
CornerRadius = 5,
Colour = colours.GreyCarmineLighter,
},
new OsuSpriteText
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Text = "Break",
Margin = new MarginPadding
{
Right = 16,
Top = 3,
},
Colour = colours.GreyCarmineLighter,
},
};
}
}
}

View File

@ -0,0 +1,94 @@
// 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.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Game.Beatmaps.Timing;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
public partial class TimelineBreakDisplay : TimelinePart<TimelineBreak>
{
[Resolved]
private Timeline timeline { get; set; } = null!;
/// <summary>
/// The visible time/position range of the timeline.
/// </summary>
private (float min, float max) visibleRange = (float.MinValue, float.MaxValue);
private readonly Cached breakCache = new Cached();
private readonly BindableList<BreakPeriod> breaks = new BindableList<BreakPeriod>();
protected override void LoadBeatmap(EditorBeatmap beatmap)
{
base.LoadBeatmap(beatmap);
// TODO: this will have to be mutable soon enough
breaks.AddRange(beatmap.Breaks);
}
protected override void Update()
{
base.Update();
if (DrawWidth <= 0) return;
(float, float) newRange = (
(ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopLeft).X) / DrawWidth * Content.RelativeChildSize.X,
(ToLocalSpace(timeline.ScreenSpaceDrawQuad.TopRight).X) / DrawWidth * Content.RelativeChildSize.X);
if (visibleRange != newRange)
{
visibleRange = newRange;
breakCache.Invalidate();
}
if (!breakCache.IsValid)
{
recreateBreaks();
breakCache.Validate();
}
}
private void recreateBreaks()
{
// Remove groups outside the visible range
foreach (TimelineBreak drawableBreak in this)
{
if (!shouldBeVisible(drawableBreak.Break))
drawableBreak.Expire();
}
// Add remaining ones
for (int i = 0; i < breaks.Count; i++)
{
var breakPeriod = breaks[i];
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));
}
}
private bool shouldBeVisible(BreakPeriod breakPeriod) => breakPeriod.EndTime >= visibleRange.min && breakPeriod.StartTime <= visibleRange.max;
}
}

View File

@ -69,7 +69,15 @@ namespace osu.Game.Screens.Edit.Compose
if (ruleset == null || composer == null)
return base.CreateTimelineContent();
return wrapSkinnableContent(new TimelineBlueprintContainer(composer));
return wrapSkinnableContent(new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new TimelineBreakDisplay { RelativeSizeAxes = Axes.Both, },
new TimelineBlueprintContainer(composer)
}
});
}
private Drawable wrapSkinnableContent(Drawable content)