// Copyright (c) ppy Pty Ltd . 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.Graphics; using osu.Framework.Graphics.Containers; namespace osu.Game.Beatmaps.Drawables { /// /// Display a beatmap background from a local source, but fallback to online source if not available. /// public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { public readonly Bindable Beatmap = new Bindable(); [Resolved] private BeatmapManager beatmaps { get; set; } private readonly BeatmapSetCoverType beatmapSetCoverType; public UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) { Beatmap.BindValueChanged(b => Model = b.NewValue); this.beatmapSetCoverType = beatmapSetCoverType; } /// /// Delay before the background is unloaded while off-screen. /// protected virtual double UnloadDelay => 10000; private BeatmapInfo lastModel; private bool firstLoad = true; protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Drawable content, double timeBeforeLoad) { return new DelayedLoadUnloadWrapper(() => { // If DelayedLoadUnloadWrapper is attempting to RELOAD the same content (Beatmap), that means that it was // previously UNLOADED and thus its children have been disposed of, so we need to recreate them here. if (!firstLoad && lastModel == Beatmap.Value) return CreateDrawable(Beatmap.Value); // If the model has changed since the previous unload (or if there was no load), then we can safely use the given content lastModel = Beatmap.Value; firstLoad = false; return content; }, timeBeforeLoad, UnloadDelay); } protected override Drawable CreateDrawable(BeatmapInfo model) { Drawable drawable = getDrawableForModel(model); drawable.RelativeSizeAxes = Axes.Both; drawable.Anchor = Anchor.Centre; drawable.Origin = Anchor.Centre; drawable.FillMode = FillMode.Fill; drawable.OnLoadComplete += d => d.FadeInFromZero(400); return drawable; } private Drawable getDrawableForModel(BeatmapInfo model) { // prefer online cover where available. if (model?.BeatmapSet?.OnlineInfo != null) return new BeatmapSetCover(model.BeatmapSet, beatmapSetCoverType); return model?.ID > 0 ? new BeatmapBackgroundSprite(beatmaps.GetWorkingBeatmap(model)) : new BeatmapBackgroundSprite(beatmaps.DefaultBeatmap); } } }