// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Footer; namespace osu.Game.Overlays.Mods { /// /// A sheared overlay which provides a header and basic animations. /// Exposes and as valid targets for content. /// public abstract partial class ShearedOverlayContainer : OsuFocusedOverlayContainer { public const float PADDING = 14; [Cached] public readonly OverlayColourProvider ColourProvider; /// /// The overlay's header. /// protected ShearedOverlayHeader Header { get; private set; } = null!; /// /// The overlay's footer. /// protected Container Footer { get; private set; } = null!; [Resolved] private ScreenFooter? footer { get; set; } // todo: very temporary property that will be removed once ModSelectOverlay and FirstRunSetupOverlay are updated to use new footer. public virtual bool UseNewFooter => false; /// /// A container containing all content, including the header and footer. /// May be used for overlay-wide animations. /// protected Container TopLevelContent { get; private set; } = null!; /// /// A container for content that is to be displayed between the header and footer. /// protected Container MainAreaContent { get; private set; } = null!; /// /// A container for content that is to be displayed inside the footer. /// protected Container FooterContent { get; private set; } = null!; protected override bool StartHidden => true; protected override bool BlockNonPositionalInput => true; protected ShearedOverlayContainer(OverlayColourScheme colourScheme) { RelativeSizeAxes = Axes.Both; ColourProvider = new OverlayColourProvider(colourScheme); } [BackgroundDependencyLoader] private void load() { const float footer_height = ScreenFooter.HEIGHT; Child = TopLevelContent = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] { Header = new ShearedOverlayHeader { Anchor = Anchor.TopCentre, Depth = float.MinValue, Origin = Anchor.TopCentre, Close = Hide }, MainAreaContent = new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = ShearedOverlayHeader.HEIGHT, Bottom = footer_height + PADDING, } }, Footer = new InputBlockingContainer { RelativeSizeAxes = Axes.X, Depth = float.MinValue, Height = footer_height, Margin = new MarginPadding { Top = PADDING }, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = ColourProvider.Background5 }, FooterContent = new Container { RelativeSizeAxes = Axes.Both, }, } } } }; } /// /// Creates content to be displayed on the game-wide footer. /// public virtual Drawable CreateFooterContent() => Empty(); /// /// Invoked when the back button in the footer is pressed. /// /// Whether the back button should not close the overlay. public virtual bool OnBackButton() => false; protected override bool OnClick(ClickEvent e) { if (State.Value == Visibility.Visible) { Hide(); return true; } return base.OnClick(e); } private bool hideFooterOnPopOut; protected override void PopIn() { const double fade_in_duration = 400; this.FadeIn(fade_in_duration, Easing.OutQuint); Header.MoveToY(0, fade_in_duration, Easing.OutQuint); if (UseNewFooter && footer != null) { footer.SetActiveOverlayContainer(this); if (footer.State.Value == Visibility.Hidden) { footer.Show(); hideFooterOnPopOut = true; } } else Footer.MoveToY(0, fade_in_duration, Easing.OutQuint); } protected override void PopOut() { const double fade_out_duration = 500; base.PopOut(); this.FadeOut(fade_out_duration, Easing.OutQuint); Header.MoveToY(-Header.DrawHeight, fade_out_duration, Easing.OutQuint); if (UseNewFooter && footer != null) { footer.ClearActiveOverlayContainer(); if (hideFooterOnPopOut) { footer.Hide(); hideFooterOnPopOut = false; } } else Footer.MoveToY(Footer.DrawHeight, fade_out_duration, Easing.OutQuint); } } }