1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00

Merge pull request #32577 from bdach/improve-card-button-input-handling

Improve input handling in beatmap card buttons
This commit is contained in:
Dean Herbert
2025-03-27 20:03:37 +09:00
committed by GitHub
Unverified
6 changed files with 33 additions and 57 deletions
@@ -91,6 +91,6 @@ namespace osu.Game.Tests.Visual.Beatmaps
} }
private void assertCorrectIcon(bool favourited) => AddAssert("icon correct", private void assertCorrectIcon(bool favourited) => AddAssert("icon correct",
() => this.ChildrenOfType<SpriteIcon>().Single().Icon.Equals(favourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart)); () => this.ChildrenOfType<SpriteIcon>().First().Icon.Equals(favourited ? FontAwesome.Solid.Heart : FontAwesome.Regular.Heart));
} }
} }
@@ -43,61 +43,43 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
} }
} }
private float iconSize; protected SpriteIcon Icon { get; private set; } = null!;
public float IconSize private Container content = null!;
private Container hover = null!;
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{ {
get => iconSize; RelativeSizeAxes = Axes.Both;
set
{
iconSize = value;
Icon.Size = new Vector2(iconSize);
}
}
protected readonly SpriteIcon Icon; Add(content = new Container
protected override Container<Drawable> Content => content;
private readonly Container content;
private readonly Box hover;
protected BeatmapCardIconButton()
{
Origin = Anchor.Centre;
Anchor = Anchor.Centre;
base.Content.Add(content = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Masking = true, Masking = true,
CornerRadius = BeatmapCard.CORNER_RADIUS,
Scale = new Vector2(0.8f), Scale = new Vector2(0.8f),
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Children = new Drawable[] Children = new Drawable[]
{ {
hover = new Box hover = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
CornerRadius = BeatmapCard.CORNER_RADIUS,
Masking = true,
Colour = Color4.White.Opacity(0.1f), Colour = Color4.White.Opacity(0.1f),
Blending = BlendingParameters.Additive, Blending = BlendingParameters.Additive,
Child = new Box { RelativeSizeAxes = Axes.Both, }
}, },
Icon = new SpriteIcon Icon = new SpriteIcon
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Scale = new Vector2(1.2f), Size = new Vector2(14),
}, },
} }
}); });
IconSize = 12;
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
IdleColour = colourProvider.Light1; IdleColour = colourProvider.Light1;
HoverColour = colourProvider.Content1; HoverColour = colourProvider.Content1;
} }
@@ -127,8 +109,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
bool isHovered = IsHovered && Enabled.Value; bool isHovered = IsHovered && Enabled.Value;
hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint); hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint);
content.ScaleTo(isHovered ? 1 : 0.8f, 500, Easing.OutQuint); content.ScaleTo(isHovered ? 0.9f : 0.8f, 500, Easing.OutQuint);
Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
} }
protected void SetLoading(bool isLoading)
{
Icon.FadeTo(isLoading ? 0.2f : 1, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
Enabled.Value = !isLoading;
}
} }
} }
@@ -8,10 +8,8 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online; using osu.Game.Online;
using osu.Game.Resources.Localisation.Web; using osu.Game.Resources.Localisation.Web;
using osuTK;
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
{ {
@@ -23,17 +21,11 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
private Bindable<bool> preferNoVideo = null!; private Bindable<bool> preferNoVideo = null!;
private readonly LoadingSpinner spinner;
[Resolved] [Resolved]
private BeatmapModelDownloader beatmaps { get; set; } = null!; private BeatmapModelDownloader beatmaps { get; set; } = null!;
public DownloadButton(APIBeatmapSet beatmapSet) public DownloadButton(APIBeatmapSet beatmapSet)
{ {
Icon.Icon = FontAwesome.Solid.Download;
Content.Add(spinner = new LoadingSpinner { Size = new Vector2(IconSize) });
this.beatmapSet = beatmapSet; this.beatmapSet = beatmapSet;
} }
@@ -41,6 +33,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
preferNoVideo = config.GetBindable<bool>(OsuSetting.PreferNoVideo); preferNoVideo = config.GetBindable<bool>(OsuSetting.PreferNoVideo);
Icon.Icon = FontAwesome.Solid.Download;
} }
protected override void LoadComplete() protected override void LoadComplete()
@@ -64,8 +57,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
case DownloadState.Importing: case DownloadState.Importing:
Action = null; Action = null;
TooltipText = string.Empty; TooltipText = string.Empty;
spinner.Show(); SetLoading(true);
Icon.Hide();
break; break;
case DownloadState.LocallyAvailable: case DownloadState.LocallyAvailable:
@@ -84,8 +76,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(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
spinner.Hide(); SetLoading(false);
Icon.Show();
if (!beatmapSet.HasVideo) if (!beatmapSet.HasVideo)
TooltipText = BeatmapsetsStrings.PanelDownloadAll; TooltipText = BeatmapsetsStrings.PanelDownloadAll;
@@ -53,19 +53,20 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
favouriteRequest?.Cancel(); favouriteRequest?.Cancel();
favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType); favouriteRequest = new PostBeatmapFavouriteRequest(beatmapSet.OnlineID, actionType);
Enabled.Value = false; SetLoading(true);
favouriteRequest.Success += () => favouriteRequest.Success += () =>
{ {
bool favourited = actionType == BeatmapFavouriteAction.Favourite; bool favourited = actionType == BeatmapFavouriteAction.Favourite;
current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1)); current.Value = new BeatmapSetFavouriteState(favourited, current.Value.FavouriteCount + (favourited ? 1 : -1));
Enabled.Value = true; SetLoading(false);
}; };
favouriteRequest.Failure += e => favouriteRequest.Failure += e =>
{ {
Logger.Error(e, $"Failed to {actionType.ToString().ToLowerInvariant()} beatmap: {e.Message}"); Logger.Error(e, $"Failed to {actionType.ToString().ToLowerInvariant()} beatmap: {e.Message}");
Enabled.Value = true; SetLoading(false);
}; };
api.Queue(favouriteRequest); api.Queue(favouriteRequest);
@@ -20,15 +20,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
public GoToBeatmapButton(APIBeatmapSet beatmapSet) public GoToBeatmapButton(APIBeatmapSet beatmapSet)
{ {
this.beatmapSet = beatmapSet; this.beatmapSet = beatmapSet;
Icon.Icon = FontAwesome.Solid.AngleDoubleRight;
TooltipText = "Go to beatmap";
} }
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuGame? game) private void load(OsuGame? game)
{ {
Action = () => game?.PresentBeatmap(beatmapSet); Action = () => game?.PresentBeatmap(beatmapSet);
Icon.Icon = FontAwesome.Solid.AngleDoubleRight;
TooltipText = "Go to beatmap";
} }
protected override void LoadComplete() protected override void LoadComplete()
@@ -95,9 +95,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Child = buttons = new Container<BeatmapCardIconButton> Child = buttons = new Container<BeatmapCardIconButton>
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
// Padding of 4 avoids touching the card borders when in the expanded (ie. showing difficulties) state.
// Left override allows the buttons to visually be wider and look better.
Padding = new MarginPadding(4) { Left = 2 },
Children = new BeatmapCardIconButton[] Children = new BeatmapCardIconButton[]
{ {
new FavouriteButton(beatmapSet) new FavouriteButton(beatmapSet)
@@ -106,7 +103,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.48f, Height = 0.5f,
}, },
new DownloadButton(beatmapSet) new DownloadButton(beatmapSet)
{ {
@@ -114,7 +111,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
State = { BindTarget = downloadTracker.State }, State = { BindTarget = downloadTracker.State },
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.48f, Height = 0.5f,
}, },
new GoToBeatmapButton(beatmapSet) new GoToBeatmapButton(beatmapSet)
{ {
@@ -122,7 +119,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Origin = Anchor.BottomCentre, Origin = Anchor.BottomCentre,
State = { BindTarget = downloadTracker.State }, State = { BindTarget = downloadTracker.State },
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Height = 0.48f, Height = 0.5f,
} }
} }
} }