diff --git a/fluXis.Game/Graphics/Gamepad/GamepadTooltipBar.cs b/fluXis.Game/Graphics/Gamepad/GamepadTooltipBar.cs index 0e1540b4..9de7a251 100644 --- a/fluXis.Game/Graphics/Gamepad/GamepadTooltipBar.cs +++ b/fluXis.Game/Graphics/Gamepad/GamepadTooltipBar.cs @@ -16,8 +16,7 @@ public partial class GamepadTooltipBar : Container [BackgroundDependencyLoader] private void load() { - RelativeSizeAxes = Axes.X; - Height = 50; + RelativeSizeAxes = Axes.Both; Anchor = Origin = Anchor.BottomCentre; if (ShowBackground) diff --git a/fluXis.Game/Screens/Select/Footer/FooterCornerButton.cs b/fluXis.Game/Screens/Select/Footer/FooterCornerButton.cs new file mode 100644 index 00000000..12261f3e --- /dev/null +++ b/fluXis.Game/Screens/Select/Footer/FooterCornerButton.cs @@ -0,0 +1,132 @@ +using System; +using fluXis.Game.Graphics; +using osu.Framework.Allocation; +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.Input.Events; +using osuTK; +using osuTK.Graphics; + +namespace fluXis.Game.Screens.Select.Footer; + +public partial class FooterCornerButton : Container +{ + private const int corner_radius = 20; + + public Action Action { get; set; } + + protected virtual string ButtonText => "Button"; + protected virtual IconUsage Icon => FontAwesome.Solid.Question; + protected virtual Colour4 ButtonColor => FluXisColors.Background4; + + private Box hover; + private Box flash; + + [BackgroundDependencyLoader] + private void load() + { + bool isRight = Anchor == Anchor.BottomRight; + + Width = 250 + corner_radius; + Height = 80 + corner_radius; + Position = new Vector2(isRight ? 200 : -200, corner_radius); + Shear = new Vector2(isRight ? .1f : -.1f, 0); + CornerRadius = corner_radius; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(.25f), + Radius = 10 + }; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ButtonColor + }, + hover = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0 + }, + flash = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0 + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Shear = new Vector2(isRight ? -.1f : .1f, 0), + Padding = new MarginPadding + { + Left = isRight ? 0 : corner_radius, + Right = isRight ? corner_radius : 0, + Bottom = corner_radius + }, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Spacing = new Vector2(10), + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = Icon, + Size = new Vector2(24) + }, + new FluXisSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + FontSize = 24, + Text = ButtonText + } + } + } + } + }; + } + + protected override bool OnClick(ClickEvent e) + { + flash.FadeOutFromOne(500); + Action?.Invoke(); + return true; + } + + protected override bool OnHover(HoverEvent e) + { + hover.FadeTo(.2f, 200); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hover.FadeOut(200); + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + this.ScaleTo(.9f, 1000, Easing.OutQuint); + return true; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + this.ScaleTo(1, 1000, Easing.OutElastic); + } +} + diff --git a/fluXis.Game/Screens/Select/Footer/SelectFooter.cs b/fluXis.Game/Screens/Select/Footer/SelectFooter.cs index b1f05846..a767bef4 100644 --- a/fluXis.Game/Screens/Select/Footer/SelectFooter.cs +++ b/fluXis.Game/Screens/Select/Footer/SelectFooter.cs @@ -1,12 +1,18 @@ +using fluXis.Game.Graphics; using fluXis.Game.Graphics.Gamepad; using fluXis.Game.Input; using fluXis.Game.Overlay.Notification; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.IEnumerableExtensions; 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.Input.Events; using osu.Framework.Screens; +using osuTK.Graphics; namespace fluXis.Game.Screens.Select.Footer; @@ -16,24 +22,39 @@ public partial class SelectFooter : Container public NotificationOverlay Notifications { get; private set; } public SelectScreen Screen { get; init; } + public Container ButtonContainer { get; private set; } + private Container backgroundContainer; private Container keyboardContainer; private GamepadTooltipBar gamepadContainer; + private FooterCornerButton backButton; + private FooterCornerButton playButton; [BackgroundDependencyLoader] private void load() { RelativeSizeAxes = Axes.X; - Height = 50; + Height = 60; Anchor = Origin = Anchor.BottomLeft; Children = new Drawable[] { - new Box + backgroundContainer = new Container { RelativeSizeAxes = Axes.Both, - Colour = Colour4.Black, - Alpha = .5f + Masking = true, + Y = 80, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(.25f), + Radius = 10 + }, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = FluXisColors.Background2 + } }, keyboardContainer = new Container { @@ -42,55 +63,49 @@ private void load() Alpha = GamepadHandler.GamepadConnected ? 0 : 1, Children = new Drawable[] { - new FillFlowContainer + backButton = new SelectFooterBackButton { Action = Screen.Exit }, + ButtonContainer = new Container { - Direction = FillDirection.Horizontal, RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, + Y = 100, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Children = new Drawable[] + Padding = new MarginPadding { Left = 300 }, + Children = new[] { - new SelectFooterButton + /*new SelectModsButton { - Text = "Back", - Action = Screen.Exit - }, - new Container + ModSelector = Screen.ModSelector + },*/ + new SelectFooterButton { - RelativeSizeAxes = Axes.Y, - Width = 100, - Name = "Spacer" + Text = "Mods", + Icon = FontAwesome.Solid.LayerGroup, + AccentColor = Colour4.FromHex("#edbb98"), + Action = openModSelector }, - new SelectModsButton { ModSelector = Screen.ModSelector }, new SelectFooterButton { Text = "Random", - Action = randomMap + Icon = FontAwesome.Solid.Random, + AccentColor = Colour4.FromHex("#ed98a7"), + Action = randomMap, + Index = 1, + Margin = new MarginPadding { Left = 160 } }, new SelectFooterButton { Text = "Options", - Action = OpenSettings + Icon = FontAwesome.Solid.Cog, + AccentColor = Colour4.FromHex("#98cbed"), + Action = OpenSettings, + Index = 2, + Margin = new MarginPadding { Left = 320 } } } }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Children = new Drawable[] - { - new SelectFooterButton - { - Text = "Play", - Action = Screen.Accept - } - } - } + playButton = new SelectFooterPlayButton { Action = Screen.Accept } } }, gamepadContainer = new GamepadTooltipBar @@ -156,20 +171,26 @@ protected override void Dispose(bool isDisposing) GamepadHandler.OnGamepadStatusChanged -= updateGamepadStatus; } - private void openModSelector() + public override void Show() { - Screen.ModSelector.IsOpen.Value = true; + backButton.MoveToX(-20, 500, Easing.OutQuint); + playButton.MoveToX(20, 500, Easing.OutQuint); + backgroundContainer.MoveToY(0, 500, Easing.OutQuint); + ButtonContainer.MoveToY(0); + ButtonContainer.ForEach(b => b.Show()); } - private void randomMap() + public override void Hide() { - Screen.RandomMap(); + backButton.MoveToX(-200, 500, Easing.OutQuint); + playButton.MoveToX(200, 500, Easing.OutQuint); + backgroundContainer.MoveToY(80, 500, Easing.OutQuint); + ButtonContainer.MoveToY(100, 500, Easing.OutQuint); } - public void OpenSettings() - { - Notifications.Post("This is still in development\nCome back later!"); - } + private void openModSelector() => Screen.ModSelector.IsOpen.Toggle(); + private void randomMap() => Screen.RandomMap(); + public void OpenSettings() => Notifications.Post("This is still in development\nCome back later!"); protected override bool OnClick(ClickEvent e) => true; // Prevents the click from going through to the map list } diff --git a/fluXis.Game/Screens/Select/Footer/SelectFooterBackButton.cs b/fluXis.Game/Screens/Select/Footer/SelectFooterBackButton.cs new file mode 100644 index 00000000..6095c5c3 --- /dev/null +++ b/fluXis.Game/Screens/Select/Footer/SelectFooterBackButton.cs @@ -0,0 +1,16 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; + +namespace fluXis.Game.Screens.Select.Footer; + +public partial class SelectFooterBackButton : FooterCornerButton +{ + protected override string ButtonText => "Back"; + protected override IconUsage Icon => FontAwesome.Solid.ChevronLeft; + + public SelectFooterBackButton() + { + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; + } +} diff --git a/fluXis.Game/Screens/Select/Footer/SelectFooterButton.cs b/fluXis.Game/Screens/Select/Footer/SelectFooterButton.cs index 651a7670..c6c1e740 100644 --- a/fluXis.Game/Screens/Select/Footer/SelectFooterButton.cs +++ b/fluXis.Game/Screens/Select/Footer/SelectFooterButton.cs @@ -1,62 +1,120 @@ using System; using fluXis.Game.Graphics; using osu.Framework.Allocation; +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.Input.Events; +using osuTK; +using osuTK.Graphics; namespace fluXis.Game.Screens.Select.Footer; public partial class SelectFooterButton : Container { public string Text { get; init; } = string.Empty; + public IconUsage Icon { get; init; } = FontAwesome.Solid.Question; public Action Action { get; set; } + public Colour4 AccentColor { get; init; } = Color4.White; + public int Index { get; init; } - private Box hoverBox; + private Box hover; + private Box flash; [BackgroundDependencyLoader] private void load() { - AutoSizeAxes = Axes.X; - RelativeSizeAxes = Axes.Y; - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; + Width = 150; + Height = 90; + Y = 20; + Anchor = Origin = Anchor.BottomLeft; + CornerRadius = 10; + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(.25f), + Radius = 10 + }; InternalChildren = new Drawable[] { - hoverBox = new Box + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = FluXisColors.Background3 + }, + hover = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0 }, - new FluXisSpriteText + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Bottom = 10 }, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Size = new Vector2(24), + Icon = Icon, + Shadow = true, + Colour = AccentColor + }, + new FluXisSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = Text, + Shadow = true + } + } + } + }, + flash = new Box { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Margin = new MarginPadding { Horizontal = 20 }, - FontSize = 24, - Text = Text + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Colour = AccentColor } }; } + public override void Show() + { + this.MoveToY(100).Delay(100 * Index).MoveToY(20, 500, Easing.OutQuint); + } + protected override bool OnClick(ClickEvent e) { - hoverBox.FadeTo(.4f).FadeTo(.2f, 200); + flash.FadeOutFromOne(1000, Easing.OutQuint); Action?.Invoke(); return true; } protected override bool OnHover(HoverEvent e) { - hoverBox.FadeTo(.2f, 50); + hover.FadeTo(.2f, 50); + this.MoveToY(10, 200, Easing.OutQuint); return true; } protected override void OnHoverLost(HoverLostEvent e) { - hoverBox.FadeTo(0, 200); - base.OnHoverLost(e); + hover.FadeTo(0, 200); + this.MoveToY(20, 400, Easing.OutQuint); } } diff --git a/fluXis.Game/Screens/Select/Footer/SelectFooterPlayButton.cs b/fluXis.Game/Screens/Select/Footer/SelectFooterPlayButton.cs new file mode 100644 index 00000000..956cbf23 --- /dev/null +++ b/fluXis.Game/Screens/Select/Footer/SelectFooterPlayButton.cs @@ -0,0 +1,18 @@ +using fluXis.Game.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; + +namespace fluXis.Game.Screens.Select.Footer; + +public partial class SelectFooterPlayButton : FooterCornerButton +{ + protected override string ButtonText => "Play"; + protected override IconUsage Icon => FontAwesome.Solid.Play; + protected override Colour4 ButtonColor => FluXisColors.Accent2; + + public SelectFooterPlayButton() + { + Anchor = Anchor.BottomRight; + Origin = Anchor.BottomRight; + } +} diff --git a/fluXis.Game/Screens/Select/SelectScreen.cs b/fluXis.Game/Screens/Select/SelectScreen.cs index e4562054..d6b44e98 100644 --- a/fluXis.Game/Screens/Select/SelectScreen.cs +++ b/fluXis.Game/Screens/Select/SelectScreen.cs @@ -423,7 +423,7 @@ public override void OnSuspending(ScreenTransitionEvent e) mapList.MoveToX(-200, 500, Easing.OutQuint); searchBar.MoveToY(-200, 500, Easing.OutQuint); selectMapInfo.MoveToX(200, 500, Easing.OutQuint); - footer.MoveToY(50, 500, Easing.OutQuint); + footer.Hide(); } public override void OnResuming(ScreenTransitionEvent e) @@ -435,7 +435,7 @@ public override void OnResuming(ScreenTransitionEvent e) mapList.MoveToX(0, 500, Easing.OutQuint); searchBar.MoveToY(0, 500, Easing.OutQuint); selectMapInfo.MoveToX(0, 500, Easing.OutQuint); - footer.MoveToY(0, 500, Easing.OutQuint); + footer.Show(); activity.Update("Selecting a map", "", "songselect"); @@ -464,8 +464,7 @@ public override void OnEntering(ScreenTransitionEvent e) selectMapInfo.MoveToX(200) .MoveToX(0, 500, Easing.OutQuint); - footer.MoveToY(50) - .MoveToY(0, 500, Easing.OutQuint); + footer.Show(); activity.Update("Selecting a map", "", "songselect"); @@ -477,11 +476,12 @@ public override bool OnExiting(ScreenExitEvent e) { this.FadeOut(200); clock.Looping = false; + menuBack.Play(); mapList.MoveToX(-200, 500, Easing.OutQuint); searchBar.MoveToY(-200, 500, Easing.OutQuint); selectMapInfo.MoveToX(200, 500, Easing.OutQuint); - footer.MoveToY(50, 500, Easing.OutQuint); + footer.Hide(); mapStore.MapSetAdded -= addMapSet; mapStore.MapSetUpdated -= replaceMapSet; @@ -522,7 +522,6 @@ public bool OnPressed(KeyBindingPressEvent e) return true; } - menuBack.Play(); this.Exit(); return true; } @@ -536,16 +535,12 @@ protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) { - case Key.F1: - ModSelector.IsOpen.Toggle(); - return true; + case >= Key.F1 and <= Key.F12: + var index = (int)e.Key - (int)Key.F1; - case Key.F2: - RandomMap(); - return true; + if (index < footer.ButtonContainer.Count) + footer.ButtonContainer[index].TriggerClick(); - case Key.F3: - footer.OpenSettings(); return true; case Key.PageUp: