diff --git a/osu.Game/Overlays/Options/OptionsSidebar.cs b/osu.Game/Overlays/Options/OptionsSidebar.cs index 6f1cb4a48c..d4b64a5d60 100644 --- a/osu.Game/Overlays/Options/OptionsSidebar.cs +++ b/osu.Game/Overlays/Options/OptionsSidebar.cs @@ -71,79 +71,5 @@ namespace osu.Game.Overlays.Options Content.Origin = Anchor.CentreLeft; } } - - public class SidebarButton : Container - { - private TextAwesome drawableIcon; - private SpriteText headerText; - private Box backgroundBox; - public Action Action; - - public FontAwesome Icon - { - get { return drawableIcon.Icon; } - set { drawableIcon.Icon = value; } - } - - public string Header - { - get { return headerText.Text; } - set { headerText.Text = value; } - } - - public SidebarButton() - { - Height = default_width; - RelativeSizeAxes = Axes.X; - Children = new Drawable[] - { - backgroundBox = new Box - { - RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, - Colour = new Color4(60, 60, 60, 255), - Alpha = 0, - }, - new Container - { - Width = default_width, - RelativeSizeAxes = Axes.Y, - Children = new[] - { - drawableIcon = new TextAwesome - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - } - }, - headerText = new SpriteText - { - Position = new Vector2(default_width + 10, 0), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - } - }; - } - - protected override bool OnClick(InputState state) - { - Action?.Invoke(); - backgroundBox.FlashColour(Color4.White, 400); - return true; - } - - protected override bool OnHover(InputState state) - { - backgroundBox.FadeTo(0.4f, 200); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - backgroundBox.FadeTo(0, 200); - base.OnHoverLost(state); - } - } } } \ No newline at end of file diff --git a/osu.Game/Overlays/Options/SidebarButton.cs b/osu.Game/Overlays/Options/SidebarButton.cs new file mode 100644 index 0000000000..5174ecfa27 --- /dev/null +++ b/osu.Game/Overlays/Options/SidebarButton.cs @@ -0,0 +1,112 @@ +using System; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Options +{ + public class SidebarButton : Container + { + private TextAwesome drawableIcon; + private SpriteText headerText; + private Box backgroundBox; + private Box selectionIndicator; + public Action Action; + + private OptionsSection section; + public OptionsSection Section + { + get + { + return section; + } + set + { + section = value; + headerText.Text = value.Header; + drawableIcon.Icon = value.Icon; + } + } + + private bool selected; + public bool Selected + { + get { return selected; } + set + { + selected = value; + if (selected) + selectionIndicator.FadeIn(50); + else + selectionIndicator.FadeOut(50); + } + } + + public SidebarButton() + { + Height = OptionsSidebar.default_width; + RelativeSizeAxes = Axes.X; + Children = new Drawable[] + { + backgroundBox = new Box + { + RelativeSizeAxes = Axes.Both, + BlendingMode = BlendingMode.Additive, + Colour = new Color4(60, 60, 60, 255), + Alpha = 0, + }, + new Container + { + Width = OptionsSidebar.default_width, + RelativeSizeAxes = Axes.Y, + Children = new[] + { + drawableIcon = new TextAwesome + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + } + }, + headerText = new SpriteText + { + Position = new Vector2(OptionsSidebar.default_width + 10, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + selectionIndicator = new Box + { + Alpha = 0, + RelativeSizeAxes = Axes.Y, + Width = 5, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Colour = new Color4(233, 103, 161, 255) + } + }; + } + + protected override bool OnClick(InputState state) + { + Action?.Invoke(); + backgroundBox.FlashColour(Color4.White, 400); + return true; + } + + protected override bool OnHover(InputState state) + { + backgroundBox.FadeTo(0.4f, 200); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + backgroundBox.FadeTo(0, 200); + base.OnHoverLost(state); + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/OptionsOverlay.cs b/osu.Game/Overlays/OptionsOverlay.cs index b2d6aef448..3ad894e102 100644 --- a/osu.Game/Overlays/OptionsOverlay.cs +++ b/osu.Game/Overlays/OptionsOverlay.cs @@ -35,10 +35,13 @@ namespace osu.Game.Overlays private ScrollContainer scrollContainer; private OptionsSidebar sidebar; + private SidebarButton[] sidebarButtons; + private OptionsSection[] sections; + private float lastKnownScroll; public OptionsOverlay() { - var sections = new OptionsSection[] + sections = new OptionsSection[] { new GeneralSection(), new GraphicsSection(), @@ -106,14 +109,15 @@ namespace osu.Game.Overlays sidebar = new OptionsSidebar { Width = sidebar_width, - Children = sections.Select(section => - new OptionsSidebar.SidebarButton + Children = sidebarButtons = sections.Select(section => + new SidebarButton { - Icon = section.Icon, - Header = section.Header, - Action = () => scrollContainer.ScrollIntoView(section), + Selected = sections[0] == section, + Section = section, + Action = () => scrollContainer.ScrollTo( + scrollContainer.GetChildYInContent(section) - scrollContainer.DrawSize.Y / 2), } - ) + ).ToArray() } }; } @@ -124,6 +128,30 @@ namespace osu.Game.Overlays scrollContainer.Padding = new MarginPadding { Top = game?.Toolbar.DrawHeight ?? 0 }; } + protected override void Update() + { + base.Update(); + if (scrollContainer.Current != lastKnownScroll) + { + for (int i = sections.Length - 1; i >= 0; i--) + { + var section = sections[i]; + float y = scrollContainer.GetChildYInContent(section) - scrollContainer.Current; + if (y <= scrollContainer.DrawSize.Y / 2 + 25) + { + var previous = sidebarButtons.SingleOrDefault(sb => sb.Selected); + var next = sidebarButtons.SingleOrDefault(sb => sb.Section == section); + if (next != null) + { + previous.Selected = false; + next.Selected = true; + } + break; + } + } + } + } + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true; protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b8113853d6..09e19ef4e5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,6 +239,7 @@ +