// Copyright (c) ppy Pty Ltd . 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.Containers; using osu.Game.Configuration; namespace osu.Game.Graphics.Containers { public abstract class HoldToConfirmContainer : Container { public const double DANGEROUS_HOLD_ACTIVATION_DELAY = 500; /// /// Whether the associated action is considered dangerous, warranting a longer hold. /// public bool IsDangerousAction { get; } public Action Action; private const int fadeout_delay = 200; /// /// Whether currently in a fired state (and the confirm has been sent). /// public bool Fired { get; private set; } private bool confirming; /// /// Whether the overlay should be allowed to return from a fired state. /// protected virtual bool AllowMultipleFires => false; /// /// The current activation delay for this control. /// protected IBindable HoldActivationDelay => holdActivationDelay; public Bindable Progress = new BindableDouble(); private Bindable holdActivationDelay; [Resolved] private OsuConfigManager config { get; set; } protected HoldToConfirmContainer(bool isDangerousAction = false) { IsDangerousAction = isDangerousAction; } protected override void LoadComplete() { base.LoadComplete(); if (IsDangerousAction) { holdActivationDelay.Value = DANGEROUS_HOLD_ACTIVATION_DELAY; } else { holdActivationDelay = HoldActivationDelay != null ? new Bindable(HoldActivationDelay.Value) : config.GetBindable(OsuSetting.UIHoldActivationDelay); } } protected void BeginConfirm() { if (confirming || (!AllowMultipleFires && Fired)) return; confirming = true; this.TransformBindableTo(Progress, 1, holdActivationDelay.Value * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm()); } protected virtual void Confirm() { Action?.Invoke(); Fired = true; } protected void AbortConfirm() { if (!AllowMultipleFires && Fired) return; confirming = false; Fired = false; this .TransformBindableTo(Progress, Progress.Value) .Delay(200) .TransformBindableTo(Progress, 0, fadeout_delay, Easing.InSine); } } }