// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; 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.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays { /// /// which provides . Mostly used in . /// public class OverlayScrollContainer : OsuScrollContainer { /// /// Scroll position at which the will be shown. /// private const int button_scroll_position = 200; public ScrollToTopButton Button { get; } private float currentTarget; public OverlayScrollContainer() { AddInternal(Button = new ScrollToTopButton { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, Margin = new MarginPadding(20), Action = () => { ScrollToStart(); currentTarget = Target; Button.Current.Value = Visibility.Hidden; } }); } protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); if (ScrollContent.DrawHeight + button_scroll_position < DrawHeight) { Button.Current.Value = Visibility.Hidden; return; } if (Target == currentTarget) return; currentTarget = Target; Button.Current.Value = Current > button_scroll_position ? Visibility.Visible : Visibility.Hidden; } public class ScrollToTopButton : OsuHoverContainer, IHasCurrentValue { private const int fade_duration = 500; private readonly BindableWithCurrent current = new BindableWithCurrent(); public Bindable Current { get => current.Current; set => current.Current = value; } protected override IEnumerable EffectTargets => new[] { background }; private Color4 flashColour; private readonly Container content; private readonly Box background; public ScrollToTopButton() { Size = new Vector2(50); Alpha = 0; Add(content = new CircularContainer { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, Masking = true, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Offset = new Vector2(0f, 1f), Radius = 3f, Colour = Color4.Black.Opacity(0.25f), }, Children = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both }, new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(15), Icon = FontAwesome.Solid.ChevronUp } } }); TooltipText = "Scroll to top"; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { IdleColour = colourProvider.Background6; HoverColour = colourProvider.Background5; flashColour = colourProvider.Light1; } protected override void LoadComplete() { base.LoadComplete(); Current.BindValueChanged(visibility => { Enabled.Value = visibility.NewValue == Visibility.Visible; this.FadeTo(visibility.NewValue == Visibility.Visible ? 1 : 0, fade_duration, Easing.OutQuint); }, true); } protected override bool OnClick(ClickEvent e) { background.FlashColour(flashColour, 800, Easing.OutQuint); return base.OnClick(e); } protected override bool OnMouseDown(MouseDownEvent e) { content.ScaleTo(0.75f, 2000, Easing.OutQuint); return true; } protected override void OnMouseUp(MouseUpEvent e) { content.ScaleTo(1, 1000, Easing.OutElastic); base.OnMouseUp(e); } } } }