diff --git a/osu.Framework.Tests/Visual/UserInterface/TestSceneSliderBar.cs b/osu.Framework.Tests/Visual/UserInterface/TestSceneSliderBar.cs index d41832481c..9cf6f699c3 100644 --- a/osu.Framework.Tests/Visual/UserInterface/TestSceneSliderBar.cs +++ b/osu.Framework.Tests/Visual/UserInterface/TestSceneSliderBar.cs @@ -59,6 +59,7 @@ public TestSceneSliderBar() Size = new Vector2(200, 50), BackgroundColour = Color4.White, SelectionColour = Color4.Pink, + FocusColour = Color4.OrangeRed, KeyboardStep = 1, Current = sliderBarValue }, @@ -72,6 +73,7 @@ public TestSceneSliderBar() RangePadding = 20, BackgroundColour = Color4.White, SelectionColour = Color4.Pink, + FocusColour = Color4.OrangeRed, KeyboardStep = 1, Current = sliderBarValue }, @@ -85,6 +87,7 @@ public TestSceneSliderBar() Size = new Vector2(200, 10), BackgroundColour = Color4.White, SelectionColour = Color4.Pink, + FocusColour = Color4.OrangeRed, KeyboardStep = 1, Current = sliderBarValue }, @@ -97,6 +100,7 @@ public TestSceneSliderBar() Size = new Vector2(200, 10), BackgroundColour = Color4.White, SelectionColour = Color4.Pink, + FocusColour = Color4.OrangeRed, KeyboardStep = 1, Current = sliderBarValue }, @@ -109,6 +113,8 @@ public TestSceneSliderBar() { sliderBar.Current.Disabled = false; sliderBar.Current.Value = 0; + sliderBar.GetContainingFocusManager()!.ChangeFocus(null); + sliderBarWithNub.GetContainingFocusManager()!.ChangeFocus(null); }); [Test] @@ -122,6 +128,7 @@ public void TestVerticalDragHasNoEffect() () => { InputManager.MoveMouseTo(sliderBar.ToScreenSpace(sliderBar.DrawSize * new Vector2(0.75f, 1f))); }); AddStep("Release Click", () => { InputManager.ReleaseButton(MouseButton.Left); }); checkValue(0); + AddAssert("Slider has no focus", () => !sliderBar.HasFocus); } [Test] @@ -136,6 +143,7 @@ public void TestDragOutReleaseInHasNoEffect() AddStep("Drag Up", () => { InputManager.MoveMouseTo(sliderBar.ToScreenSpace(sliderBar.DrawSize * new Vector2(0.25f, 0.5f))); }); AddStep("Release Click", () => { InputManager.ReleaseButton(MouseButton.Left); }); checkValue(0); + AddAssert("Slider has focus", () => sliderBar.HasFocus); } [Test] @@ -160,6 +168,23 @@ public void TestKeyboardInput() InputManager.ReleaseKey(Key.Right); }); checkValue(1); + + AddStep("Click slider", () => InputManager.Click(MouseButton.Left)); + checkValue(-5); + + AddAssert("Slider has focus", () => sliderBar.HasFocus); + + AddStep("move mouse outside", () => + { + InputManager.MoveMouseTo(sliderBar.ToScreenSpace(sliderBar.DrawSize * new Vector2(2f, 0.5f))); + }); + + AddStep("Press right arrow key", () => + { + InputManager.PressKey(Key.Right); + InputManager.ReleaseKey(Key.Right); + }); + checkValue(-4); } [TestCase(false)] @@ -246,6 +271,7 @@ public void TestAbsoluteDrag() () => { InputManager.MoveMouseTo(sliderBarWithNub.ToScreenSpace(sliderBarWithNub.DrawSize * new Vector2(0.4f, 1f))); }); AddStep("Release Click", () => { InputManager.ReleaseButton(MouseButton.Left); }); checkValue(-2); + AddAssert("Slider has focus", () => sliderBarWithNub.HasFocus); } [Test] @@ -259,6 +285,7 @@ public void TestRelativeDrag() () => { InputManager.MoveMouseTo(sliderBarWithNub.ToScreenSpace(sliderBarWithNub.DrawSize * new Vector2(0.75f, 1f))); }); AddStep("Release Click", () => { InputManager.ReleaseButton(MouseButton.Left); }); checkValue(3); + AddAssert("Slider has focus", () => sliderBarWithNub.HasFocus); } [Test] diff --git a/osu.Framework/Graphics/UserInterface/BasicSliderBar.cs b/osu.Framework/Graphics/UserInterface/BasicSliderBar.cs index 17b932cee9..9b6697d13d 100644 --- a/osu.Framework/Graphics/UserInterface/BasicSliderBar.cs +++ b/osu.Framework/Graphics/UserInterface/BasicSliderBar.cs @@ -4,6 +4,7 @@ using System.Numerics; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using Vector2 = osuTK.Vector2; namespace osu.Framework.Graphics.UserInterface @@ -23,6 +24,18 @@ public Color4 SelectionColour set => SelectionBox.Colour = value; } + private Color4 focusColour = FrameworkColour.YellowGreen; + + public Color4 FocusColour + { + get => focusColour; + set + { + focusColour = value; + updateFocus(); + } + } + protected readonly Box SelectionBox; protected readonly Box Box; @@ -37,10 +50,37 @@ public BasicSliderBar() }, SelectionBox = new Box { - RelativeSizeAxes = Axes.Both, Colour = FrameworkColour.Yellow, + RelativeSizeAxes = Axes.Both, } }; + + Masking = true; + } + + protected override void OnFocus(FocusEvent e) + { + updateFocus(); + base.OnFocus(e); + } + + protected override void OnFocusLost(FocusLostEvent e) + { + updateFocus(); + base.OnFocusLost(e); + } + + private void updateFocus() + { + if (HasFocus) + { + BorderThickness = 3; + BorderColour = FocusColour; + } + else + { + BorderThickness = 0; + } } protected override void UpdateValue(float value) diff --git a/osu.Framework/Graphics/UserInterface/SliderBar.cs b/osu.Framework/Graphics/UserInterface/SliderBar.cs index d1232baea4..20fe6a18b7 100644 --- a/osu.Framework/Graphics/UserInterface/SliderBar.cs +++ b/osu.Framework/Graphics/UserInterface/SliderBar.cs @@ -166,18 +166,21 @@ protected override bool OnDragStart(DragStartEvent e) return false; } + GetContainingFocusManager()?.ChangeFocus(this); handleMouseInput(e); return true; } protected override void OnDragEnd(DragEndEvent e) => Commit(); + public override bool AcceptsFocus => true; + protected override bool OnKeyDown(KeyDownEvent e) { if (currentNumberInstantaneous.Disabled) return false; - if (!IsHovered) + if (!IsHovered && !HasFocus) return false; float step = KeyboardStep != 0 ? KeyboardStep : (Convert.ToSingle(currentNumberInstantaneous.MaxValue) - Convert.ToSingle(currentNumberInstantaneous.MinValue)) / 20;