Path: blob/master/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
4493 views
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Localisation; namespace osu.Game.Beatmaps.Drawables.Cards { public abstract partial class BeatmapCard : OsuClickableContainer, IHasContextMenu { public const float TRANSITION_DURATION = 340; public const float CORNER_RADIUS = 8; public const float WIDTH = 345; public IBindable<bool> Expanded { get; } public readonly APIBeatmapSet BeatmapSet; protected readonly Bindable<BeatmapSetFavouriteState> FavouriteState; protected abstract Drawable IdleContent { get; } protected abstract Drawable DownloadInProgressContent { get; } protected readonly BeatmapDownloadTracker DownloadTracker; private readonly Bindable<bool> preferNoVideo = new BindableBool(); private InputManager? containingInputManager; [Resolved] private BeatmapSetOverlay? beatmapSetOverlay { get; set; } [Resolved] private BeatmapModelDownloader? beatmaps { get; set; } [Resolved] private OsuGame? game { get; set; } protected BeatmapCard(APIBeatmapSet beatmapSet, bool allowExpansion = true) : base(HoverSampleSet.Button) { Expanded = new BindableBool { Disabled = !allowExpansion }; BeatmapSet = beatmapSet; FavouriteState = new Bindable<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount)); DownloadTracker = new BeatmapDownloadTracker(beatmapSet); } [BackgroundDependencyLoader] private void load(OsuConfigManager configManager) { configManager.BindWith(OsuSetting.PreferNoVideo, preferNoVideo); AddInternal(DownloadTracker); } protected override void LoadComplete() { base.LoadComplete(); DownloadTracker.State.BindValueChanged(_ => UpdateState()); Expanded.BindValueChanged(_ => UpdateState(), true); FinishTransforms(true); containingInputManager = GetContainingInputManager(); if (Action == null) throw new InvalidOperationException($"An action should be assigned to this {nameof(BeatmapCard)}. To use the default, assign {nameof(DefaultAction)}."); } protected void DefaultAction() { if (containingInputManager?.CurrentState.Keyboard.ShiftPressed == true) { switch (DownloadTracker.State.Value) { case DownloadState.NotDownloaded: if (!BeatmapSet.Availability.DownloadDisabled) beatmaps?.Download(BeatmapSet, preferNoVideo.Value); break; case DownloadState.LocallyAvailable: game?.PresentBeatmap(BeatmapSet); break; } } else beatmapSetOverlay?.FetchAndShowBeatmapSet(BeatmapSet.OnlineID); } protected override bool OnHover(HoverEvent e) { UpdateState(); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { UpdateState(); base.OnHoverLost(e); } protected virtual void UpdateState() { bool showProgress = DownloadTracker.State.Value == DownloadState.Downloading || DownloadTracker.State.Value == DownloadState.Importing; IdleContent.FadeTo(showProgress ? 0 : 1, TRANSITION_DURATION, Easing.OutQuint); DownloadInProgressContent.FadeTo(showProgress ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint); } /// <summary> /// Creates a beatmap card of the given <paramref name="size"/> for the supplied <paramref name="beatmapSet"/>. /// </summary> public static BeatmapCard Create(APIBeatmapSet beatmapSet, BeatmapCardSize size, bool allowExpansion = true) { switch (size) { case BeatmapCardSize.Nano: return new BeatmapCardNano(beatmapSet); case BeatmapCardSize.Normal: return new BeatmapCardNormal(beatmapSet, allowExpansion); case BeatmapCardSize.Extra: return new BeatmapCardExtra(beatmapSet, allowExpansion); default: throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size"); } } public virtual MenuItem[] ContextMenuItems => new MenuItem[] { new OsuMenuItem(ContextMenuStrings.ViewBeatmap, MenuItemType.Highlighted, Action), }; } }