mirror of
https://github.com/ppy/osu.git
synced 2026-06-05 02:23:38 +08:00
199bcd7fdb
This is in response to feedback in https://osu.ppy.sh/community/forums/topics/2056547?n=1. Upon examining the button further, there was indeed some rather weird... almost hysteresis in how the button behaved with respect to the area on the screen that activated it. Because of the following scourge of a method that continues to haunt us to this day: https://github.com/ppy/osu/blob/31487545d0d17c4337d4b4cc5d4afb3ba1dae838/osu.Game/Graphics/Containers/OsuClickableContainer.cs#L24-L25 the button would effectively only be activated by 80% of its drawable area when it was not hovered, because of the scale applied to the `content` container which `Container.Content` redirected to. This is resolved here by various rearrangements of paddings and sizes such that the clickable area of any of the buttons of the card is always the full top or bottom half of the button area. Also included are some cosmetic touch-ups which happened to be convenient like folding the loading spinner into the base `BeatmapCardIconButton`, adding loading support for the favourite button, using BDL more, and resolving some "virtual member call in constructor" inspections.
131 lines
4.0 KiB
C#
131 lines
4.0 KiB
C#
// 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 osu.Framework.Allocation;
|
|
using osu.Framework.Extensions.Color4Extensions;
|
|
using osu.Framework.Graphics;
|
|
using osu.Framework.Graphics.Containers;
|
|
using osu.Framework.Graphics.Shapes;
|
|
using osu.Framework.Graphics.Sprites;
|
|
using osu.Framework.Input.Events;
|
|
using osu.Game.Graphics.Containers;
|
|
using osu.Game.Graphics.UserInterface;
|
|
using osu.Game.Overlays;
|
|
using osuTK;
|
|
using osuTK.Graphics;
|
|
|
|
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
|
|
{
|
|
public abstract partial class BeatmapCardIconButton : OsuClickableContainer
|
|
{
|
|
private Colour4 idleColour;
|
|
|
|
public Colour4 IdleColour
|
|
{
|
|
get => idleColour;
|
|
set
|
|
{
|
|
idleColour = value;
|
|
if (IsLoaded)
|
|
updateState();
|
|
}
|
|
}
|
|
|
|
private Colour4 hoverColour;
|
|
|
|
public Colour4 HoverColour
|
|
{
|
|
get => hoverColour;
|
|
set
|
|
{
|
|
hoverColour = value;
|
|
if (IsLoaded)
|
|
updateState();
|
|
}
|
|
}
|
|
|
|
protected SpriteIcon Icon { get; private set; } = null!;
|
|
|
|
private Container content = null!;
|
|
private Container hover = null!;
|
|
private LoadingSpinner spinner = null!;
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load(OverlayColourProvider colourProvider)
|
|
{
|
|
RelativeSizeAxes = Axes.Both;
|
|
|
|
Add(content = new Container
|
|
{
|
|
RelativeSizeAxes = Axes.Both,
|
|
Masking = true,
|
|
Scale = new Vector2(0.8f),
|
|
Origin = Anchor.Centre,
|
|
Anchor = Anchor.Centre,
|
|
Children = new Drawable[]
|
|
{
|
|
hover = new Container
|
|
{
|
|
RelativeSizeAxes = Axes.Both,
|
|
CornerRadius = BeatmapCard.CORNER_RADIUS,
|
|
Masking = true,
|
|
Colour = Color4.White.Opacity(0.1f),
|
|
Blending = BlendingParameters.Additive,
|
|
Child = new Box { RelativeSizeAxes = Axes.Both, }
|
|
},
|
|
Icon = new SpriteIcon
|
|
{
|
|
Origin = Anchor.Centre,
|
|
Anchor = Anchor.Centre,
|
|
Size = new Vector2(14),
|
|
},
|
|
spinner = new LoadingSpinner
|
|
{
|
|
Size = new Vector2(14),
|
|
},
|
|
}
|
|
});
|
|
|
|
IdleColour = colourProvider.Light1;
|
|
HoverColour = colourProvider.Content1;
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
Enabled.BindValueChanged(_ => updateState(), true);
|
|
FinishTransforms(true);
|
|
}
|
|
|
|
protected override bool OnHover(HoverEvent e)
|
|
{
|
|
updateState();
|
|
return base.OnHover(e);
|
|
}
|
|
|
|
protected override void OnHoverLost(HoverLostEvent e)
|
|
{
|
|
base.OnHoverLost(e);
|
|
updateState();
|
|
}
|
|
|
|
private void updateState()
|
|
{
|
|
bool isHovered = IsHovered && Enabled.Value;
|
|
|
|
hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint);
|
|
content.ScaleTo(isHovered ? 0.9f : 0.8f, 500, Easing.OutQuint);
|
|
Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
|
|
spinner.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
|
|
}
|
|
|
|
protected void SetLoading(bool isLoading)
|
|
{
|
|
Icon.Alpha = isLoading ? 0 : 1;
|
|
spinner.Alpha = isLoading ? 1 : 0;
|
|
Enabled.Value = !isLoading;
|
|
}
|
|
}
|
|
}
|