mirror of
https://github.com/ppy/osu.git
synced 2025-02-08 07:02:54 +08:00
21dba621f0
Fixes the main part of https://github.com/ppy/osu/issues/31144. Support for selecting a video will come later. Making this work was an absolutely awful time full of dealing with delightfully kooky issues, and yielded in a very weird-shaped contraption. There is at least one issue remaining wherein storyboard videos do not actually display until the track is started in editor, but that is 99% a framework issue and I do not currently have the mental fortitude to diagnose further.
118 lines
4.5 KiB
C#
118 lines
4.5 KiB
C#
// 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.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics;
|
|
using osu.Framework.Graphics.Containers;
|
|
using osu.Framework.Timing;
|
|
using osu.Game.Beatmaps;
|
|
using osu.Game.Configuration;
|
|
using osu.Game.Graphics;
|
|
using osu.Game.Graphics.Backgrounds;
|
|
using osu.Game.Storyboards.Drawables;
|
|
|
|
namespace osu.Game.Screens.Backgrounds
|
|
{
|
|
public partial class EditorBackgroundScreen : BackgroundScreen
|
|
{
|
|
private readonly WorkingBeatmap beatmap;
|
|
private readonly Container dimContainer;
|
|
|
|
private CancellationTokenSource? cancellationTokenSource;
|
|
private Bindable<float> dimLevel = null!;
|
|
private Bindable<bool> showStoryboard = null!;
|
|
|
|
private BeatmapBackground background = null!;
|
|
private Container storyboardContainer = null!;
|
|
|
|
private IFrameBasedClock? clockSource;
|
|
|
|
public EditorBackgroundScreen(WorkingBeatmap beatmap)
|
|
{
|
|
this.beatmap = beatmap;
|
|
|
|
InternalChild = dimContainer = new Container
|
|
{
|
|
RelativeSizeAxes = Axes.Both,
|
|
};
|
|
}
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load(OsuConfigManager config)
|
|
{
|
|
dimContainer.AddRange(createContent());
|
|
background = dimContainer.OfType<BeatmapBackground>().Single();
|
|
storyboardContainer = dimContainer.OfType<Container>().Single();
|
|
|
|
dimLevel = config.GetBindable<float>(OsuSetting.EditorDim);
|
|
showStoryboard = config.GetBindable<bool>(OsuSetting.EditorShowStoryboard);
|
|
}
|
|
|
|
private IEnumerable<Drawable> createContent() =>
|
|
[
|
|
new BeatmapBackground(beatmap) { RelativeSizeAxes = Axes.Both, },
|
|
// this kooky container nesting is here because the storyboard needs a custom clock
|
|
// but also needs it on an isolated-enough level that doesn't break screen stack expiry logic (which happens if the clock was put on `this`),
|
|
// or doesn't make it literally impossible to fade the storyboard in/out in real time (which happens if the fade transforms were to be applied directly to the storyboard).
|
|
new Container
|
|
{
|
|
RelativeSizeAxes = Axes.Both,
|
|
Child = new DrawableStoryboard(beatmap.Storyboard)
|
|
{
|
|
Clock = clockSource ?? Clock,
|
|
}
|
|
}
|
|
];
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
dimLevel.BindValueChanged(_ => dimContainer.FadeColour(OsuColour.Gray(1 - dimLevel.Value), 500, Easing.OutQuint), true);
|
|
showStoryboard.BindValueChanged(_ => updateState());
|
|
updateState(0);
|
|
}
|
|
|
|
private void updateState(double duration = 500)
|
|
{
|
|
storyboardContainer.FadeTo(showStoryboard.Value ? 1 : 0, duration, Easing.OutQuint);
|
|
// yes, this causes overdraw, but is also a (crude) fix for bad-looking transitions on screen entry
|
|
// caused by the previous background on the background stack poking out from under this one and then instantly fading out
|
|
background.FadeColour(beatmap.Storyboard.ReplacesBackground && showStoryboard.Value ? Colour4.Black : Colour4.White, duration, Easing.OutQuint);
|
|
}
|
|
|
|
public void ChangeClockSource(IFrameBasedClock frameBasedClock)
|
|
{
|
|
clockSource = frameBasedClock;
|
|
if (IsLoaded)
|
|
storyboardContainer.Child.Clock = frameBasedClock;
|
|
}
|
|
|
|
public void RefreshBackground()
|
|
{
|
|
cancellationTokenSource?.Cancel();
|
|
LoadComponentsAsync(createContent(), loaded =>
|
|
{
|
|
dimContainer.Clear();
|
|
dimContainer.AddRange(loaded);
|
|
|
|
background = dimContainer.OfType<BeatmapBackground>().Single();
|
|
storyboardContainer = dimContainer.OfType<Container>().Single();
|
|
updateState(0);
|
|
}, (cancellationTokenSource ??= new CancellationTokenSource()).Token);
|
|
}
|
|
|
|
public override bool Equals(BackgroundScreen? other)
|
|
{
|
|
if (other is not EditorBackgroundScreen otherBeatmapBackground)
|
|
return false;
|
|
|
|
return base.Equals(other) && beatmap == otherBeatmapBackground.beatmap;
|
|
}
|
|
}
|
|
}
|