1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-20 11:03:05 +08:00

Display storyboard in editor background

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.
This commit is contained in:
Bartłomiej Dach 2024-12-31 13:57:50 +01:00
parent 73083e1337
commit 21dba621f0
No known key found for this signature in database
4 changed files with 135 additions and 11 deletions

View File

@ -218,6 +218,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.AlwaysShowHoldForMenuButton, false);
SetDefault(OsuSetting.AlwaysRequireHoldingForPause, false);
SetDefault(OsuSetting.EditorShowStoryboard, true);
}
protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup)
@ -452,5 +453,6 @@ namespace osu.Game.Configuration
AlwaysRequireHoldingForPause,
MultiplayerShowInProgressFilter,
BeatmapListingFeaturedArtistFilter,
EditorShowStoryboard,
}
}

View File

@ -0,0 +1,117 @@
// 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;
}
}
}

View File

@ -45,6 +45,7 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Edit.Components.Menus;
using osu.Game.Screens.Edit.Compose;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
@ -54,7 +55,6 @@ using osu.Game.Screens.Edit.Setup;
using osu.Game.Screens.Edit.Timing;
using osu.Game.Screens.Edit.Verify;
using osu.Game.Screens.OnlinePlay;
using osu.Game.Screens.Play;
using osu.Game.Users;
using osuTK.Input;
using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings;
@ -63,7 +63,7 @@ namespace osu.Game.Screens.Edit
{
[Cached(typeof(IBeatSnapProvider))]
[Cached]
public partial class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>, IKeyBindingHandler<PlatformAction>, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider
public partial class Editor : OsuScreen, IKeyBindingHandler<GlobalAction>, IKeyBindingHandler<PlatformAction>, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider
{
/// <summary>
/// An offset applied to waveform visuals to align them with expectations.
@ -210,6 +210,7 @@ namespace osu.Game.Screens.Edit
private OnScreenDisplay onScreenDisplay { get; set; }
private Bindable<float> editorBackgroundDim;
private Bindable<bool> editorShowStoryboard;
private Bindable<bool> editorHitMarkers;
private Bindable<bool> editorAutoSeekOnPlacement;
private Bindable<bool> editorLimitedDistanceSnap;
@ -320,6 +321,7 @@ namespace osu.Game.Screens.Edit
OsuMenuItem redoMenuItem;
editorBackgroundDim = config.GetBindable<float>(OsuSetting.EditorDim);
editorShowStoryboard = config.GetBindable<bool>(OsuSetting.EditorShowStoryboard);
editorHitMarkers = config.GetBindable<bool>(OsuSetting.EditorShowHitMarkers);
editorAutoSeekOnPlacement = config.GetBindable<bool>(OsuSetting.EditorAutoSeekOnPlacement);
editorLimitedDistanceSnap = config.GetBindable<bool>(OsuSetting.EditorLimitedDistanceSnap);
@ -398,7 +400,13 @@ namespace osu.Game.Screens.Edit
},
]
},
new OsuMenuItemSpacer(),
new BackgroundDimMenuItem(editorBackgroundDim),
new ToggleMenuItem("Show storyboard")
{
State = { BindTarget = editorShowStoryboard },
},
new OsuMenuItemSpacer(),
new ToggleMenuItem(EditorStrings.ShowHitMarkers)
{
State = { BindTarget = editorHitMarkers },
@ -472,6 +480,8 @@ namespace osu.Game.Screens.Edit
[Resolved]
private MusicController musicController { get; set; }
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen(Beatmap.Value);
protected override void LoadComplete()
{
base.LoadComplete();
@ -867,9 +877,8 @@ namespace osu.Game.Screens.Edit
{
ApplyToBackground(b =>
{
b.IgnoreUserSettings.Value = true;
b.DimWhenUserSettingsIgnored.Value = editorBackgroundDim.Value;
b.BlurAmount.Value = 0;
var editorBackground = (EditorBackgroundScreen)b;
editorBackground.ChangeClockSource(clock);
});
}
@ -908,11 +917,6 @@ namespace osu.Game.Screens.Edit
beatmap.EditorTimestamp = clock.CurrentTime;
});
ApplyToBackground(b =>
{
b.DimWhenUserSettingsIgnored.Value = 0;
});
resetTrack();
refetchBeatmap();

View File

@ -12,6 +12,7 @@ using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Localisation;
using osu.Game.Models;
using osu.Game.Screens.Backgrounds;
using osu.Game.Utils;
namespace osu.Game.Screens.Edit.Setup
@ -87,7 +88,7 @@ namespace osu.Game.Screens.Edit.Setup
(metadata, name) => metadata.BackgroundFile = name);
headerBackground.UpdateBackground();
editor?.ApplyToBackground(bg => bg.RefreshBackground());
editor?.ApplyToBackground(bg => ((EditorBackgroundScreen)bg).RefreshBackground());
return true;
}