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 @@
+