mirror of
https://github.com/ppy/osu
synced 2025-01-28 08:43:05 +00:00
cebd5f6dc2
Another casualty of edc78205d5312e9278f2a22ef156fd34af492595. This particular button was actually *relying* on receiving positional events from its entire bounding box rather than `Content`, in order for the button to be htitable more easily, which broke as other buttons were fixed to behave more in line with expectations. Upon closer inspection this is another case of a weird carried-over construction. The button doesn't really need to inherit `OsuButton` or do any of the arcane stuff that it was doing, so it's now a plain `OsuClickableContainer` with less `Content` hackery.
147 lines
4.6 KiB
C#
147 lines
4.6 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.
|
|
|
|
#nullable disable
|
|
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Extensions.Color4Extensions;
|
|
using osu.Framework.Graphics;
|
|
using osu.Framework.Graphics.Containers;
|
|
using osu.Framework.Graphics.Effects;
|
|
using osu.Framework.Graphics.Shapes;
|
|
using osu.Framework.Graphics.UserInterface;
|
|
using osu.Framework.Input.Events;
|
|
using osu.Framework.Localisation;
|
|
using osu.Game.Graphics;
|
|
using osu.Game.Graphics.Containers;
|
|
using osu.Game.Graphics.UserInterface;
|
|
using osuTK;
|
|
|
|
namespace osu.Game.Overlays
|
|
{
|
|
public partial class RestoreDefaultValueButton<T> : OsuClickableContainer, IHasCurrentValue<T>
|
|
{
|
|
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
|
|
|
|
// this is done to ensure a click on this button doesn't trigger focus on a parent element which contains the button.
|
|
public override bool AcceptsFocus => true;
|
|
|
|
// this is intentionally not using BindableWithCurrent, as it can use the wrong IsDefault implementation when passed a BindableNumber.
|
|
// using GetBoundCopy() ensures that the received bindable is of the exact same type as the source bindable and uses the proper IsDefault implementation.
|
|
private Bindable<T> current;
|
|
|
|
public Bindable<T> Current
|
|
{
|
|
get => current;
|
|
set
|
|
{
|
|
current?.UnbindAll();
|
|
current = value.GetBoundCopy();
|
|
|
|
current.ValueChanged += _ => UpdateState();
|
|
current.DefaultChanged += _ => UpdateState();
|
|
current.DisabledChanged += _ => UpdateState();
|
|
|
|
if (IsLoaded)
|
|
UpdateState();
|
|
}
|
|
}
|
|
|
|
[Resolved]
|
|
private OsuColour colours { get; set; }
|
|
|
|
private const float size = 4;
|
|
|
|
private CircularContainer circle = null!;
|
|
private Box background = null!;
|
|
|
|
public RestoreDefaultValueButton()
|
|
: base(HoverSampleSet.Button)
|
|
{
|
|
}
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load(OsuColour colour)
|
|
{
|
|
// size intentionally much larger than actual drawn content, so that the button is easier to click.
|
|
Size = new Vector2(3 * size);
|
|
|
|
Add(circle = new CircularContainer
|
|
{
|
|
Anchor = Anchor.Centre,
|
|
Origin = Anchor.Centre,
|
|
Size = new Vector2(size),
|
|
Masking = true,
|
|
Child = background = new Box
|
|
{
|
|
RelativeSizeAxes = Axes.Both,
|
|
Colour = colour.Lime1
|
|
}
|
|
});
|
|
|
|
Alpha = 0f;
|
|
|
|
Action += () =>
|
|
{
|
|
if (!current.Disabled)
|
|
current.SetDefault();
|
|
};
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
updateState();
|
|
FinishTransforms(true);
|
|
}
|
|
|
|
public override LocalisableString TooltipText => "revert to default";
|
|
|
|
protected override bool OnHover(HoverEvent e)
|
|
{
|
|
UpdateState();
|
|
return false;
|
|
}
|
|
|
|
protected override void OnHoverLost(HoverLostEvent e)
|
|
{
|
|
UpdateState();
|
|
}
|
|
|
|
public void UpdateState() => Scheduler.AddOnce(updateState);
|
|
|
|
private const double fade_duration = 200;
|
|
|
|
private void updateState()
|
|
{
|
|
if (current == null)
|
|
return;
|
|
|
|
Enabled.Value = !Current.Disabled;
|
|
|
|
if (!Current.Disabled)
|
|
{
|
|
this.FadeTo(Current.IsDefault ? 0 : 1, fade_duration, Easing.OutQuint);
|
|
background.FadeColour(IsHovered ? colours.Lime0 : colours.Lime1, fade_duration, Easing.OutQuint);
|
|
circle.TweenEdgeEffectTo(new EdgeEffectParameters
|
|
{
|
|
Colour = (IsHovered ? colours.Lime1 : colours.Lime3).Opacity(0.4f),
|
|
Radius = IsHovered ? 8 : 4,
|
|
Type = EdgeEffectType.Glow
|
|
}, fade_duration, Easing.OutQuint);
|
|
}
|
|
else
|
|
{
|
|
background.FadeColour(colours.Lime3, fade_duration, Easing.OutQuint);
|
|
circle.TweenEdgeEffectTo(new EdgeEffectParameters
|
|
{
|
|
Colour = colours.Lime3.Opacity(0.1f),
|
|
Radius = 2,
|
|
Type = EdgeEffectType.Glow
|
|
}, fade_duration, Easing.OutQuint);
|
|
}
|
|
}
|
|
}
|
|
}
|