1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-21 08:52:54 +08:00

Extract base class for beatmap cards

This commit is contained in:
Bartłomiej Dach 2021-12-17 13:27:11 +01:00
parent f052b47d87
commit d6f6039934
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
12 changed files with 168 additions and 167 deletions

View File

@ -5,18 +5,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Beatmaps.Drawables.Cards.Statistics; using osu.Game.Beatmaps.Drawables.Cards.Statistics;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet;
@ -25,21 +21,14 @@ using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Beatmaps.Drawables.Cards namespace osu.Game.Beatmaps.Drawables.Cards
{ {
public class BeatmapCard : OsuClickableContainer public class BeatmapCard : BeatmapCardBase
{ {
public const float TRANSITION_DURATION = 400; protected override Drawable IdleContent => idleBottomContent;
public const float CORNER_RADIUS = 10; protected override Drawable DownloadInProgressContent => downloadProgressBar;
public IBindable<bool> Expanded { get; }
private const float width = 408; private const float width = 408;
private const float height = 100; private const float height = 100;
private readonly APIBeatmapSet beatmapSet;
private readonly Bindable<BeatmapSetFavouriteState> favouriteState;
private readonly BeatmapDownloadTracker downloadTracker;
[Cached] [Cached]
private readonly BeatmapCardContent content; private readonly BeatmapCardContent content;
@ -55,18 +44,13 @@ namespace osu.Game.Beatmaps.Drawables.Cards
private OverlayColourProvider colourProvider { get; set; } = null!; private OverlayColourProvider colourProvider { get; set; } = null!;
public BeatmapCard(APIBeatmapSet beatmapSet, bool allowExpansion = true) public BeatmapCard(APIBeatmapSet beatmapSet, bool allowExpansion = true)
: base(HoverSampleSet.Submit) : base(beatmapSet, allowExpansion)
{ {
Expanded = new BindableBool { Disabled = !allowExpansion };
this.beatmapSet = beatmapSet;
favouriteState = new Bindable<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
downloadTracker = new BeatmapDownloadTracker(beatmapSet);
content = new BeatmapCardContent(height); content = new BeatmapCardContent(height);
} }
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader]
private void load(BeatmapSetOverlay? beatmapSetOverlay) private void load()
{ {
Width = width; Width = width;
Height = height; Height = height;
@ -75,15 +59,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards
GridContainer titleContainer = null!; GridContainer titleContainer = null!;
GridContainer artistContainer = null!; GridContainer artistContainer = null!;
InternalChild = content.With(c => Child = content.With(c =>
{ {
c.MainContent = new Container c.MainContent = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
downloadTracker, thumbnail = new BeatmapCardThumbnail(BeatmapSet)
thumbnail = new BeatmapCardThumbnail(beatmapSet)
{ {
Name = @"Left (icon) area", Name = @"Left (icon) area",
Size = new Vector2(height), Size = new Vector2(height),
@ -96,11 +79,11 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Spacing = new Vector2(1) Spacing = new Vector2(1)
} }
}, },
buttonContainer = new CollapsibleButtonContainer(beatmapSet) buttonContainer = new CollapsibleButtonContainer(BeatmapSet)
{ {
X = height - CORNER_RADIUS, X = height - CORNER_RADIUS,
Width = width - height + CORNER_RADIUS, Width = width - height + CORNER_RADIUS,
FavouriteState = { BindTarget = favouriteState }, FavouriteState = { BindTarget = FavouriteState },
ButtonsCollapsedWidth = CORNER_RADIUS, ButtonsCollapsedWidth = CORNER_RADIUS,
ButtonsExpandedWidth = 30, ButtonsExpandedWidth = 30,
ButtonsPadding = new MarginPadding { Vertical = 17.5f }, ButtonsPadding = new MarginPadding { Vertical = 17.5f },
@ -131,7 +114,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
new OsuSpriteText new OsuSpriteText
{ {
Text = new RomanisableString(beatmapSet.TitleUnicode, beatmapSet.Title), Text = new RomanisableString(BeatmapSet.TitleUnicode, BeatmapSet.Title),
Font = OsuFont.Default.With(size: 22.5f, weight: FontWeight.SemiBold), Font = OsuFont.Default.With(size: 22.5f, weight: FontWeight.SemiBold),
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Truncate = true Truncate = true
@ -177,7 +160,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
d.AutoSizeAxes = Axes.Both; d.AutoSizeAxes = Axes.Both;
d.Margin = new MarginPadding { Top = 2 }; d.Margin = new MarginPadding { Top = 2 };
d.AddText("mapped by ", t => t.Colour = colourProvider.Content2); d.AddText("mapped by ", t => t.Colour = colourProvider.Content2);
d.AddUserLink(beatmapSet.Author); d.AddUserLink(BeatmapSet.Author);
}), }),
} }
}, },
@ -209,7 +192,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
AlwaysPresent = true, AlwaysPresent = true,
ChildrenEnumerable = createStatistics() ChildrenEnumerable = createStatistics()
}, },
new BeatmapCardExtraInfoRow(beatmapSet) new BeatmapCardExtraInfoRow(BeatmapSet)
} }
}, },
downloadProgressBar = new BeatmapCardDownloadProgressBar downloadProgressBar = new BeatmapCardDownloadProgressBar
@ -218,8 +201,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Height = 6, Height = 6,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
State = { BindTarget = downloadTracker.State }, State = { BindTarget = DownloadTracker.State },
Progress = { BindTarget = downloadTracker.Progress } Progress = { BindTarget = DownloadTracker.Progress }
} }
} }
} }
@ -232,18 +215,18 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = 10, Vertical = 13 }, Padding = new MarginPadding { Horizontal = 10, Vertical = 13 },
Child = new BeatmapCardDifficultyList(beatmapSet) Child = new BeatmapCardDifficultyList(BeatmapSet)
}; };
c.Expanded.BindTarget = Expanded; c.Expanded.BindTarget = Expanded;
}); });
if (beatmapSet.HasVideo) if (BeatmapSet.HasVideo)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) }); leftIconArea.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) });
if (beatmapSet.HasStoryboard) if (BeatmapSet.HasStoryboard)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) }); leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) });
if (beatmapSet.HasExplicitContent) if (BeatmapSet.HasExplicitContent)
{ {
titleContainer.Content[0][1] = new ExplicitContentBeatmapPill titleContainer.Content[0][1] = new ExplicitContentBeatmapPill
{ {
@ -253,7 +236,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
}; };
} }
if (beatmapSet.TrackId != null) if (BeatmapSet.TrackId != null)
{ {
artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill
{ {
@ -262,57 +245,36 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Margin = new MarginPadding { Left = 5 } Margin = new MarginPadding { Left = 5 }
}; };
} }
Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapSet.OnlineID);
}
protected override void LoadComplete()
{
base.LoadComplete();
downloadTracker.State.BindValueChanged(_ => updateState());
Expanded.BindValueChanged(_ => updateState(), true);
FinishTransforms(true);
}
protected override bool OnHover(HoverEvent e)
{
updateState();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateState();
base.OnHoverLost(e);
} }
private LocalisableString createArtistText() private LocalisableString createArtistText()
{ {
var romanisableArtist = new RomanisableString(beatmapSet.ArtistUnicode, beatmapSet.Artist); var romanisableArtist = new RomanisableString(BeatmapSet.ArtistUnicode, BeatmapSet.Artist);
return BeatmapsetsStrings.ShowDetailsByArtist(romanisableArtist); return BeatmapsetsStrings.ShowDetailsByArtist(romanisableArtist);
} }
private IEnumerable<BeatmapCardStatistic> createStatistics() private IEnumerable<BeatmapCardStatistic> createStatistics()
{ {
var hypesStatistic = HypesStatistic.CreateFor(beatmapSet); var hypesStatistic = HypesStatistic.CreateFor(BeatmapSet);
if (hypesStatistic != null) if (hypesStatistic != null)
yield return hypesStatistic; yield return hypesStatistic;
var nominationsStatistic = NominationsStatistic.CreateFor(beatmapSet); var nominationsStatistic = NominationsStatistic.CreateFor(BeatmapSet);
if (nominationsStatistic != null) if (nominationsStatistic != null)
yield return nominationsStatistic; yield return nominationsStatistic;
yield return new FavouritesStatistic(beatmapSet) { Current = favouriteState }; yield return new FavouritesStatistic(BeatmapSet) { Current = FavouriteState };
yield return new PlayCountStatistic(beatmapSet); yield return new PlayCountStatistic(BeatmapSet);
var dateStatistic = BeatmapCardDateStatistic.CreateFor(beatmapSet); var dateStatistic = BeatmapCardDateStatistic.CreateFor(BeatmapSet);
if (dateStatistic != null) if (dateStatistic != null)
yield return dateStatistic; yield return dateStatistic;
} }
private void updateState() protected override void UpdateState()
{ {
base.UpdateState();
bool showDetails = IsHovered || Expanded.Value; bool showDetails = IsHovered || Expanded.Value;
buttonContainer.ShowDetails.Value = showDetails; buttonContainer.ShowDetails.Value = showDetails;
@ -323,11 +285,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
content.ScaleTo(Expanded.Value ? 1.03f : 1, 500, Easing.OutQuint); content.ScaleTo(Expanded.Value ? 1.03f : 1, 500, Easing.OutQuint);
statisticsContainer.FadeTo(showDetails ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint); statisticsContainer.FadeTo(showDetails ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint);
bool showProgress = downloadTracker.State.Value == DownloadState.Downloading || downloadTracker.State.Value == DownloadState.Importing;
idleBottomContent.FadeTo(showProgress ? 0 : 1, TRANSITION_DURATION, Easing.OutQuint);
downloadProgressBar.FadeTo(showProgress ? 1 : 0, TRANSITION_DURATION, Easing.OutQuint);
} }
} }
} }

View File

@ -0,0 +1,80 @@
// 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.
#nullable enable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
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;
namespace osu.Game.Beatmaps.Drawables.Cards
{
public abstract class BeatmapCardBase : OsuClickableContainer
{
public const float TRANSITION_DURATION = 400;
public const float CORNER_RADIUS = 10;
public IBindable<bool> Expanded { get; }
protected readonly APIBeatmapSet BeatmapSet;
protected readonly Bindable<BeatmapSetFavouriteState> FavouriteState;
protected abstract Drawable IdleContent { get; }
protected abstract Drawable DownloadInProgressContent { get; }
protected readonly BeatmapDownloadTracker DownloadTracker;
protected BeatmapCardBase(APIBeatmapSet beatmapSet, bool allowExpansion = true)
: base(HoverSampleSet.Submit)
{
Expanded = new BindableBool { Disabled = !allowExpansion };
BeatmapSet = beatmapSet;
FavouriteState = new Bindable<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
DownloadTracker = new BeatmapDownloadTracker(beatmapSet);
}
[BackgroundDependencyLoader(true)]
private void load(BeatmapSetOverlay? beatmapSetOverlay)
{
Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(BeatmapSet.OnlineID);
AddInternal(DownloadTracker);
}
protected override void LoadComplete()
{
base.LoadComplete();
DownloadTracker.State.BindValueChanged(_ => UpdateState());
Expanded.BindValueChanged(_ => UpdateState(), true);
FinishTransforms(true);
}
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);
}
}
}

View File

@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
CornerRadius = BeatmapCard.CORNER_RADIUS, CornerRadius = BeatmapCardBase.CORNER_RADIUS,
Masking = true, Masking = true,
Unhovered = _ => updateFromHoverChange(), Unhovered = _ => updateFromHoverChange(),
Children = new Drawable[] Children = new Drawable[]
@ -67,7 +67,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Height = height, Height = height,
CornerRadius = BeatmapCard.CORNER_RADIUS, CornerRadius = BeatmapCardBase.CORNER_RADIUS,
Masking = true, Masking = true,
}, },
dropdownContent = new HoverHandlingContainer dropdownContent = new HoverHandlingContainer
@ -91,7 +91,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
borderContainer = new Container borderContainer = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
CornerRadius = BeatmapCard.CORNER_RADIUS, CornerRadius = BeatmapCardBase.CORNER_RADIUS,
Masking = true, Masking = true,
BorderThickness = 3, BorderThickness = 3,
Child = new Box Child = new Box
@ -139,9 +139,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards
private void updateState() private void updateState()
{ {
background.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); background.FadeTo(Expanded.Value ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
dropdownContent.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); dropdownContent.FadeTo(Expanded.Value ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
borderContainer.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); borderContainer.FadeTo(Expanded.Value ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
content.TweenEdgeEffectTo(new EdgeEffectParameters content.TweenEdgeEffectTo(new EdgeEffectParameters
{ {
@ -150,7 +150,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Radius = 10, Radius = 10,
Colour = Colour4.Black.Opacity(Expanded.Value ? 0.3f : 0f), Colour = Colour4.Black.Opacity(Expanded.Value ? 0.3f : 0f),
Hollow = true, Hollow = true,
}, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); }, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
} }
private class ExpandedContentScrollContainer : OsuScrollContainer private class ExpandedContentScrollContainer : OsuScrollContainer

View File

@ -62,10 +62,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards
private void updateState() => Schedule(() => private void updateState() => Schedule(() =>
{ {
background.FadeColour(Dimmed.Value ? colourProvider.Background4 : colourProvider.Background2, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); background.FadeColour(Dimmed.Value ? colourProvider.Background4 : colourProvider.Background2, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
var gradient = ColourInfo.GradientHorizontal(Colour4.White.Opacity(0), Colour4.White.Opacity(0.2f)); var gradient = ColourInfo.GradientHorizontal(Colour4.White.Opacity(0), Colour4.White.Opacity(0.2f));
cover.FadeColour(gradient, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); cover.FadeColour(gradient, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
}); });
} }
} }

View File

@ -82,14 +82,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards
break; break;
case DownloadState.Importing: case DownloadState.Importing:
foregroundFill.FadeColour(colours.Yellow, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); foregroundFill.FadeColour(colours.Yellow, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
break; break;
} }
} }
private void progressChanged() private void progressChanged()
{ {
foreground.ResizeWidthTo((float)progress.Value, progress.Value > 0 ? BeatmapCard.TRANSITION_DURATION : 0, Easing.OutQuint); foreground.ResizeWidthTo((float)progress.Value, progress.Value > 0 ? BeatmapCardBase.TRANSITION_DURATION : 0, Easing.OutQuint);
} }
} }
} }

View File

@ -4,18 +4,14 @@
#nullable enable #nullable enable
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Beatmaps.Drawables.Cards.Statistics; using osu.Game.Beatmaps.Drawables.Cards.Statistics;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapSet; using osu.Game.Overlays.BeatmapSet;
@ -24,18 +20,14 @@ using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Beatmaps.Drawables.Cards namespace osu.Game.Beatmaps.Drawables.Cards
{ {
public class BeatmapCardExtra : OsuClickableContainer public class BeatmapCardExtra : BeatmapCardBase
{ {
protected override Drawable IdleContent => idleBottomContent;
protected override Drawable DownloadInProgressContent => downloadProgressBar;
private const float width = 475; private const float width = 475;
private const float height = 140; private const float height = 140;
public Bindable<bool> Expanded { get; } = new BindableBool();
private readonly APIBeatmapSet beatmapSet;
private readonly Bindable<BeatmapSetFavouriteState> favouriteState;
private readonly BeatmapDownloadTracker downloadTracker;
[Cached] [Cached]
private readonly BeatmapCardContent content; private readonly BeatmapCardContent content;
@ -50,12 +42,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards
[Resolved] [Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!; private OverlayColourProvider colourProvider { get; set; } = null!;
public BeatmapCardExtra(APIBeatmapSet beatmapSet) public BeatmapCardExtra(APIBeatmapSet beatmapSet, bool allowExpansion = true)
: base(HoverSampleSet.Submit) : base(beatmapSet, allowExpansion)
{ {
this.beatmapSet = beatmapSet;
favouriteState = new Bindable<BeatmapSetFavouriteState>(new BeatmapSetFavouriteState(beatmapSet.HasFavourited, beatmapSet.FavouriteCount));
downloadTracker = new BeatmapDownloadTracker(beatmapSet);
content = new BeatmapCardContent(height); content = new BeatmapCardContent(height);
} }
@ -69,19 +58,18 @@ namespace osu.Game.Beatmaps.Drawables.Cards
GridContainer titleContainer = null!; GridContainer titleContainer = null!;
GridContainer artistContainer = null!; GridContainer artistContainer = null!;
InternalChild = content.With(c => Child = content.With(c =>
{ {
c.MainContent = new Container c.MainContent = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Drawable[] Children = new Drawable[]
{ {
downloadTracker, thumbnail = new BeatmapCardThumbnail(BeatmapSet)
thumbnail = new BeatmapCardThumbnail(beatmapSet)
{ {
Name = @"Left (icon) area", Name = @"Left (icon) area",
Size = new Vector2(height), Size = new Vector2(height),
Padding = new MarginPadding { Right = BeatmapCard.CORNER_RADIUS }, Padding = new MarginPadding { Right = CORNER_RADIUS },
Child = leftIconArea = new FillFlowContainer Child = leftIconArea = new FillFlowContainer
{ {
Margin = new MarginPadding(5), Margin = new MarginPadding(5),
@ -90,12 +78,12 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Spacing = new Vector2(1) Spacing = new Vector2(1)
} }
}, },
buttonContainer = new CollapsibleButtonContainer(beatmapSet) buttonContainer = new CollapsibleButtonContainer(BeatmapSet)
{ {
X = height - BeatmapCard.CORNER_RADIUS, X = height - CORNER_RADIUS,
Width = width - height + BeatmapCard.CORNER_RADIUS, Width = width - height + CORNER_RADIUS,
FavouriteState = { BindTarget = favouriteState }, FavouriteState = { BindTarget = FavouriteState },
ButtonsCollapsedWidth = BeatmapCard.CORNER_RADIUS, ButtonsCollapsedWidth = CORNER_RADIUS,
ButtonsExpandedWidth = 30, ButtonsExpandedWidth = 30,
ButtonsPadding = new MarginPadding { Vertical = 35 }, ButtonsPadding = new MarginPadding { Vertical = 35 },
Children = new Drawable[] Children = new Drawable[]
@ -125,7 +113,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
new OsuSpriteText new OsuSpriteText
{ {
Text = new RomanisableString(beatmapSet.TitleUnicode, beatmapSet.Title), Text = new RomanisableString(BeatmapSet.TitleUnicode, BeatmapSet.Title),
Font = OsuFont.Default.With(size: 22.5f, weight: FontWeight.SemiBold), Font = OsuFont.Default.With(size: 22.5f, weight: FontWeight.SemiBold),
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Truncate = true Truncate = true
@ -166,7 +154,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
Truncate = true, Truncate = true,
Text = beatmapSet.Source, Text = BeatmapSet.Source,
Shadow = false, Shadow = false,
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold),
Colour = colourProvider.Content2 Colour = colourProvider.Content2
@ -200,7 +188,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
d.AutoSizeAxes = Axes.Both; d.AutoSizeAxes = Axes.Both;
d.Margin = new MarginPadding { Top = 2 }; d.Margin = new MarginPadding { Top = 2 };
d.AddText("mapped by ", t => t.Colour = colourProvider.Content2); d.AddText("mapped by ", t => t.Colour = colourProvider.Content2);
d.AddUserLink(beatmapSet.Author); d.AddUserLink(BeatmapSet.Author);
}), }),
statisticsContainer = new GridContainer statisticsContainer = new GridContainer
{ {
@ -223,7 +211,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
new Drawable[3] new Drawable[3]
} }
}, },
new BeatmapCardExtraInfoRow(beatmapSet) new BeatmapCardExtraInfoRow(BeatmapSet)
} }
}, },
downloadProgressBar = new BeatmapCardDownloadProgressBar downloadProgressBar = new BeatmapCardDownloadProgressBar
@ -232,8 +220,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Height = 6, Height = 6,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
State = { BindTarget = downloadTracker.State }, State = { BindTarget = DownloadTracker.State },
Progress = { BindTarget = downloadTracker.Progress } Progress = { BindTarget = DownloadTracker.Progress }
} }
} }
} }
@ -246,18 +234,18 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = 10, Vertical = 13 }, Padding = new MarginPadding { Horizontal = 10, Vertical = 13 },
Child = new BeatmapCardDifficultyList(beatmapSet) Child = new BeatmapCardDifficultyList(BeatmapSet)
}; };
c.Expanded.BindTarget = Expanded; c.Expanded.BindTarget = Expanded;
}); });
if (beatmapSet.HasVideo) if (BeatmapSet.HasVideo)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) }); leftIconArea.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) });
if (beatmapSet.HasStoryboard) if (BeatmapSet.HasStoryboard)
leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) }); leftIconArea.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) });
if (beatmapSet.HasExplicitContent) if (BeatmapSet.HasExplicitContent)
{ {
titleContainer.Content[0][1] = new ExplicitContentBeatmapPill titleContainer.Content[0][1] = new ExplicitContentBeatmapPill
{ {
@ -267,7 +255,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
}; };
} }
if (beatmapSet.TrackId != null) if (BeatmapSet.TrackId != null)
{ {
artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill artistContainer.Content[0][1] = new FeaturedArtistBeatmapPill
{ {
@ -279,33 +267,12 @@ namespace osu.Game.Beatmaps.Drawables.Cards
createStatistics(); createStatistics();
Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapSet.OnlineID); Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(BeatmapSet.OnlineID);
}
protected override void LoadComplete()
{
base.LoadComplete();
downloadTracker.State.BindValueChanged(_ => updateState());
Expanded.BindValueChanged(_ => updateState(), true);
FinishTransforms(true);
}
protected override bool OnHover(HoverEvent e)
{
updateState();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateState();
base.OnHoverLost(e);
} }
private LocalisableString createArtistText() private LocalisableString createArtistText()
{ {
var romanisableArtist = new RomanisableString(beatmapSet.ArtistUnicode, beatmapSet.Artist); var romanisableArtist = new RomanisableString(BeatmapSet.ArtistUnicode, BeatmapSet.Artist);
return BeatmapsetsStrings.ShowDetailsByArtist(romanisableArtist); return BeatmapsetsStrings.ShowDetailsByArtist(romanisableArtist);
} }
@ -317,28 +284,30 @@ namespace osu.Game.Beatmaps.Drawables.Cards
return original; return original;
} }
statisticsContainer.Content[0][0] = withMargin(new FavouritesStatistic(beatmapSet) statisticsContainer.Content[0][0] = withMargin(new FavouritesStatistic(BeatmapSet)
{ {
Current = favouriteState, Current = FavouriteState,
}); });
statisticsContainer.Content[1][0] = withMargin(new PlayCountStatistic(beatmapSet)); statisticsContainer.Content[1][0] = withMargin(new PlayCountStatistic(BeatmapSet));
var hypesStatistic = HypesStatistic.CreateFor(beatmapSet); var hypesStatistic = HypesStatistic.CreateFor(BeatmapSet);
if (hypesStatistic != null) if (hypesStatistic != null)
statisticsContainer.Content[0][1] = withMargin(hypesStatistic); statisticsContainer.Content[0][1] = withMargin(hypesStatistic);
var nominationsStatistic = NominationsStatistic.CreateFor(beatmapSet); var nominationsStatistic = NominationsStatistic.CreateFor(BeatmapSet);
if (nominationsStatistic != null) if (nominationsStatistic != null)
statisticsContainer.Content[1][1] = withMargin(nominationsStatistic); statisticsContainer.Content[1][1] = withMargin(nominationsStatistic);
var dateStatistic = BeatmapCardDateStatistic.CreateFor(beatmapSet); var dateStatistic = BeatmapCardDateStatistic.CreateFor(BeatmapSet);
if (dateStatistic != null) if (dateStatistic != null)
statisticsContainer.Content[0][2] = withMargin(dateStatistic); statisticsContainer.Content[0][2] = withMargin(dateStatistic);
} }
private void updateState() protected override void UpdateState()
{ {
base.UpdateState();
bool showDetails = IsHovered || Expanded.Value; bool showDetails = IsHovered || Expanded.Value;
buttonContainer.ShowDetails.Value = showDetails; buttonContainer.ShowDetails.Value = showDetails;
@ -347,11 +316,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
// Scale value is intentionally chosen to fit in the spacing of listing displays, as to not overlap horizontally with adjacent cards. // Scale value is intentionally chosen to fit in the spacing of listing displays, as to not overlap horizontally with adjacent cards.
// This avoids depth issues where a hovered (scaled) card to the right of another card would be beneath the card to the left. // This avoids depth issues where a hovered (scaled) card to the right of another card would be beneath the card to the left.
content.ScaleTo(Expanded.Value ? 1.03f : 1, 500, Easing.OutQuint); content.ScaleTo(Expanded.Value ? 1.03f : 1, 500, Easing.OutQuint);
bool showProgress = downloadTracker.State.Value == DownloadState.Downloading || downloadTracker.State.Value == DownloadState.Importing;
idleBottomContent.FadeTo(showProgress ? 0 : 1, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
downloadProgressBar.FadeTo(showProgress ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
} }
} }
} }

View File

@ -88,8 +88,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
bool shouldDim = Dimmed.Value || playButton.Playing.Value; bool shouldDim = Dimmed.Value || playButton.Playing.Value;
playButton.FadeTo(shouldDim ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); playButton.FadeTo(shouldDim ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
cover.FadeColour(shouldDim ? OsuColour.Gray(0.2f) : Color4.White, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); cover.FadeColour(shouldDim ? OsuColour.Gray(0.2f) : Color4.White, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
} }
} }
} }

View File

@ -115,7 +115,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
bool isHovered = IsHovered && Enabled.Value; bool isHovered = IsHovered && Enabled.Value;
content.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); content.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint);
content.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); content.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
} }
} }
} }

View File

@ -69,7 +69,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
case DownloadState.LocallyAvailable: case DownloadState.LocallyAvailable:
Action = null; Action = null;
TooltipText = string.Empty; TooltipText = string.Empty;
this.FadeOut(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); this.FadeOut(BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
break; break;
case DownloadState.NotDownloaded: case DownloadState.NotDownloaded:
@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
} }
Action = () => beatmaps.Download(beatmapSet, preferNoVideo.Value); Action = () => beatmaps.Download(beatmapSet, preferNoVideo.Value);
this.FadeIn(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); this.FadeIn(BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
spinner.Hide(); spinner.Hide();
Icon.Show(); Icon.Show();

View File

@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
private void updateState() private void updateState()
{ {
this.FadeTo(state.Value == DownloadState.LocallyAvailable ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); this.FadeTo(state.Value == DownloadState.LocallyAvailable ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
} }
} }
} }

View File

@ -141,7 +141,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
private void toggleLoading(bool loading) private void toggleLoading(bool loading)
{ {
Enabled.Value = !loading; Enabled.Value = !loading;
icon.FadeTo(loading ? 0 : 1, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); icon.FadeTo(loading ? 0 : 1, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
loadingSpinner.State.Value = loading ? Visibility.Visible : Visibility.Hidden; loadingSpinner.State.Value = loading ? Visibility.Visible : Visibility.Hidden;
} }
} }

View File

@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
Masking = true; Masking = true;
CornerRadius = BeatmapCard.CORNER_RADIUS; CornerRadius = BeatmapCardBase.CORNER_RADIUS;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
@ -133,7 +133,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
Name = @"Main content", Name = @"Main content",
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
CornerRadius = BeatmapCard.CORNER_RADIUS, CornerRadius = BeatmapCardBase.CORNER_RADIUS,
Masking = true, Masking = true,
Children = new Drawable[] Children = new Drawable[]
{ {
@ -169,10 +169,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards
{ {
float targetWidth = Width - (ShowDetails.Value ? ButtonsExpandedWidth : ButtonsCollapsedWidth); float targetWidth = Width - (ShowDetails.Value ? ButtonsExpandedWidth : ButtonsCollapsedWidth);
mainArea.ResizeWidthTo(targetWidth, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); mainArea.ResizeWidthTo(targetWidth, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
background.FadeColour(downloadTracker.State.Value == DownloadState.LocallyAvailable ? colours.Lime0 : colourProvider.Background3, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); background.FadeColour(downloadTracker.State.Value == DownloadState.LocallyAvailable ? colours.Lime0 : colourProvider.Background3, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
buttons.FadeTo(ShowDetails.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); buttons.FadeTo(ShowDetails.Value ? 1 : 0, BeatmapCardBase.TRANSITION_DURATION, Easing.OutQuint);
foreach (var button in buttons) foreach (var button in buttons)
{ {