From 075350e12572188f25d5a8b02fedf1a9edf73f83 Mon Sep 17 00:00:00 2001 From: Ibby Date: Sun, 9 May 2021 15:51:17 +1000 Subject: [PATCH 01/33] Adding a reset button to individual keybinds --- .../Settings/TestSceneKeyBindingPanel.cs | 40 +++++++++++++++++++ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 28 +++++++++++++ 2 files changed, 68 insertions(+) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index f495e0fb23..75bbd8f86c 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -104,6 +104,46 @@ namespace osu.Game.Tests.Visual.Settings } } + [Test] + public void TestSingleBindResetButton() + { + KeyBindingRow multiBindingRow = null; + + AddStep("click first row with two bindings", () => + { + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + InputManager.MoveMouseTo(multiBindingRow); + InputManager.Click(MouseButton.Left); + }); + + clickSingleBindResetButton(); + + AddAssert("first binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); + + AddStep("click second binding", () => + { + var target = multiBindingRow.ChildrenOfType().ElementAt(1); + + InputManager.MoveMouseTo(target); + InputManager.Click(MouseButton.Left); + }); + + clickSingleBindResetButton(); + + AddAssert("second binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(1))); + + void clickSingleBindResetButton() + { + AddStep("click reset button for single binding", () => + { + var clearButton = multiBindingRow.ChildrenOfType().Single(); + + InputManager.MoveMouseTo(clearButton); + InputManager.Click(MouseButton.Left); + }); + } + } + [Test] public void TestClickRowSelectsFirstBinding() { diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 300fce962a..1fbaa374d4 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -109,6 +109,7 @@ namespace osu.Game.Overlays.KeyBinding Children = new Drawable[] { new CancelButton { Action = finalise }, + new SingleBindResetButton { Action = singleBindReset }, new ClearButton { Action = clear }, }, } @@ -281,6 +282,15 @@ namespace osu.Game.Overlays.KeyBinding finalise(); } + private void singleBindReset() + { + if (bindTarget == null) + return; + + bindTarget.UpdateKeyCombination(Defaults.ElementAt(buttons.IndexOf(bindTarget))); + finalise(); + } + private void finalise() { if (bindTarget != null) @@ -339,6 +349,24 @@ namespace osu.Game.Overlays.KeyBinding } } + public class SingleBindResetButton : TriangleButton + { + public SingleBindResetButton() + { + Text = "Reset"; + Size = new Vector2(80, 20); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Green; + + Triangles.ColourDark = colours.GreenDark; + Triangles.ColourLight = colours.GreenLight; + } + } + public class ClearButton : TriangleButton { public ClearButton() From 1a465c60ca54ea5f386bab902b62df12f512ac34 Mon Sep 17 00:00:00 2001 From: Swords Date: Sun, 9 May 2021 16:07:18 +1000 Subject: [PATCH 02/33] Rename Tests --- osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 75bbd8f86c..41b65e84b6 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.Settings } [Test] - public void TestSingleBindResetButton() + public void TestResetButtonOnBindings() { KeyBindingRow multiBindingRow = null; From 0725088fdef8cd2aef018e78c8f29f74153a860f Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 01:01:17 +1000 Subject: [PATCH 03/33] Well it works, just pretty ugly looking. --- .../Settings/TestSceneKeyBindingPanel.cs | 69 +++++++--- .../Visual/Settings/TestSceneSettingsItem.cs | 5 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 76 ++++++----- .../KeyBinding/KeyBindingsSubsection.cs | 13 +- .../KeyBinding/SettingsKeyBindingRow.cs | 70 +++++++++++ .../Overlays/RestoreDefaultValueButton.cs | 119 ++++++++++++++++++ osu.Game/Overlays/Settings/SettingsItem.cs | 103 +-------------- 7 files changed, 299 insertions(+), 156 deletions(-) create mode 100644 osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs create mode 100644 osu.Game/Overlays/RestoreDefaultValueButton.cs diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 41b65e84b6..09c8696ee0 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Linq; using NUnit.Framework; +using osu.Framework.Input.Bindings; using osu.Framework.Testing; using osu.Framework.Threading; using osu.Game.Overlays; @@ -31,13 +32,16 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClickTwiceOnClearButton() { + SettingsKeyBindingRow firstSettingRow = null; KeyBindingRow firstRow = null; AddStep("click first row", () => { - firstRow = panel.ChildrenOfType().First(); - InputManager.MoveMouseTo(firstRow); + firstSettingRow = panel.ChildrenOfType().First(); + InputManager.MoveMouseTo(firstSettingRow); InputManager.Click(MouseButton.Left); + + firstRow = firstSettingRow.KeyBindingRow; }); AddStep("schedule button clicks", () => @@ -71,7 +75,7 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).KeyBindingRow; InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); @@ -105,38 +109,67 @@ namespace osu.Game.Tests.Visual.Settings } [Test] - public void TestResetButtonOnBindings() + public void TestSingleBindResetButton() { + SettingsKeyBindingRow multiSettingsBindingRow = null; KeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { + multiSettingsBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); + InputManager.PressKey(Key.P); + InputManager.ReleaseKey(Key.P); }); + AddUntilStep("restore button shown", () => multiSettingsBindingRow.ChildrenOfType>().First().Alpha > 0); + clickSingleBindResetButton(); AddAssert("first binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); - - AddStep("click second binding", () => - { - var target = multiBindingRow.ChildrenOfType().ElementAt(1); - - InputManager.MoveMouseTo(target); - InputManager.Click(MouseButton.Left); - }); - - clickSingleBindResetButton(); - AddAssert("second binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(1))); + AddUntilStep("restore button hidden", () => multiSettingsBindingRow.ChildrenOfType>().First().Alpha == 0); + void clickSingleBindResetButton() { - AddStep("click reset button for single binding", () => + AddStep("click reset button for bindings", () => { - var clearButton = multiBindingRow.ChildrenOfType().Single(); + var clearButton = multiSettingsBindingRow.ChildrenOfType>().Single(); + + InputManager.MoveMouseTo(clearButton); + InputManager.Click(MouseButton.Left); + }); + } + } + + [Test] + public void TestResetAllBindingsButton() + { + SettingsKeyBindingRow multiSettingsBindingRow = null; + KeyBindingRow multiBindingRow = null; + + AddStep("click first row and press p", () => + { + multiSettingsBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(); + InputManager.MoveMouseTo(multiBindingRow); + InputManager.Click(MouseButton.Left); + InputManager.PressKey(Key.P); + InputManager.ReleaseKey(Key.P); + }); + + clickResetAllBindingsButton(); + + AddAssert("bindings cleared", () => multiBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); + + void clickResetAllBindingsButton() + { + AddStep("click reset button for all bindings", () => + { + var clearButton = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(clearButton); InputManager.Click(MouseButton.Left); @@ -176,4 +209,4 @@ namespace osu.Game.Tests.Visual.Settings AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); } } -} +} \ No newline at end of file diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs index 8f1c17ed29..f63145f534 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Overlays.Settings; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Settings { @@ -37,7 +38,7 @@ namespace osu.Game.Tests.Visual.Settings private class TestSettingsTextBox : SettingsTextBox { - public new Drawable RestoreDefaultValueButton => this.ChildrenOfType().Single(); + public Drawable RestoreDefaultValueButton => this.ChildrenOfType>().Single(); } } -} +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 1fbaa374d4..4d2738f244 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -4,12 +4,14 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; 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.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -22,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Overlays.KeyBinding { - public class KeyBindingRow : Container, IFilterable + public class KeyBindingRow : Container, IFilterable, IHasCurrentValue { private readonly object action; private readonly IEnumerable bindings; @@ -51,6 +53,13 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; + private BindableWithCurrent isKeysDefaultValue; + public Bindable Current + { + get => isKeysDefaultValue.Current; + set => isKeysDefaultValue.Current = value; + } + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString()); public KeyBindingRow(object action, IEnumerable bindings) @@ -58,6 +67,11 @@ namespace osu.Game.Overlays.KeyBinding this.action = action; this.bindings = bindings; + isKeysDefaultValue = new BindableWithCurrent() + { + Default = true + }; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -71,6 +85,17 @@ namespace osu.Game.Overlays.KeyBinding [BackgroundDependencyLoader] private void load(OsuColour colours) { + + isKeysDefaultValue.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + isKeysDefaultValue.BindValueChanged(resetButtons => + { + if (resetButtons.NewValue != resetButtons.OldValue && resetButtons.NewValue && !bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults)) + { + RestoreDefaults(); + finalise(); + } + }); + EdgeEffect = new EdgeEffectParameters { Radius = 2, @@ -109,7 +134,6 @@ namespace osu.Game.Overlays.KeyBinding Children = new Drawable[] { new CancelButton { Action = finalise }, - new SingleBindResetButton { Action = singleBindReset }, new ClearButton { Action = clear }, }, } @@ -129,6 +153,8 @@ namespace osu.Game.Overlays.KeyBinding button.UpdateKeyCombination(d); store.Update(button.KeyBinding); } + + isKeysDefaultValue.Value = true; } protected override bool OnHover(HoverEvent e) @@ -282,21 +308,29 @@ namespace osu.Game.Overlays.KeyBinding finalise(); } - private void singleBindReset() - { - if (bindTarget == null) - return; - - bindTarget.UpdateKeyCombination(Defaults.ElementAt(buttons.IndexOf(bindTarget))); - finalise(); - } - private void finalise() { if (bindTarget != null) { store.Update(bindTarget.KeyBinding); + KeyCombination keyDefault = Defaults.ElementAt(buttons.IndexOf(bindTarget)); + if (isKeysDefaultValue.Value) + { + if (!keyDefault.Equals(bindTarget.KeyBinding.KeyCombination)) + { + isKeysDefaultValue.Value = false; + } + } + else + { + if (keyDefault.Equals(bindTarget.KeyBinding.KeyCombination) && + buttons.Select(b => b.KeyBinding.KeyCombination).SequenceEqual(Defaults)) + { + isKeysDefaultValue.Value = true; + } + } + bindTarget.IsBinding = false; Schedule(() => { @@ -349,24 +383,6 @@ namespace osu.Game.Overlays.KeyBinding } } - public class SingleBindResetButton : TriangleButton - { - public SingleBindResetButton() - { - Text = "Reset"; - Size = new Vector2(80, 20); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Green; - - Triangles.ColourDark = colours.GreenDark; - Triangles.ColourLight = colours.GreenLight; - } - } - public class ClearButton : TriangleButton { public ClearButton() @@ -487,4 +503,4 @@ namespace osu.Game.Overlays.KeyBinding } } } -} +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index d784b7aec9..d130a3f536 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -1,17 +1,20 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using osuTK; using osu.Game.Graphics; +using osu.Framework.Input.Bindings; namespace osu.Game.Overlays.KeyBinding { @@ -41,16 +44,12 @@ namespace osu.Game.Overlays.KeyBinding int intKey = (int)defaultGroup.Key; // one row per valid action. - Add(new KeyBindingRow(defaultGroup.Key, bindings.Where(b => ((int)b.Action).Equals(intKey))) - { - AllowMainMouseButtons = Ruleset != null, - Defaults = defaultGroup.Select(d => d.KeyCombination) - }); + Add(new SettingsKeyBindingRow(defaultGroup, bindings, Ruleset)); } Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) }); } } @@ -72,4 +71,4 @@ namespace osu.Game.Overlays.KeyBinding Triangles.ColourLight = colours.Pink; } } -} +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs new file mode 100644 index 0000000000..da8a628b51 --- /dev/null +++ b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs @@ -0,0 +1,70 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.KeyBinding +{ + public class SettingsKeyBindingRow : Container, IFilterable + { + private readonly IGrouping defaultGroup; + private readonly IEnumerable bindings; + public readonly KeyBindingRow KeyBindingRow; + + private bool matchingFilter; + + public bool MatchingFilter + { + get => matchingFilter; + set + { + matchingFilter = value; + this.FadeTo(!matchingFilter ? 0 : 1); + } + } + + public bool FilteringActive { get; set; } + + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(defaultGroup.Key.ToString()); + + public SettingsKeyBindingRow( + IGrouping defaultGroup, + IEnumerable bindings, + RulesetInfo ruleset) + { + this.defaultGroup = defaultGroup; + this.bindings = bindings; + + KeyBindingRow = new KeyBindingRow(defaultGroup.Key, bindings.Where(b => ((int)b.Action).Equals((int)defaultGroup.Key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaultGroup.Select(d => d.KeyCombination) + }; + + + RestoreDefaultValueButton restoreDefaultButton; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; + + InternalChildren = new Drawable[] + { + restoreDefaultButton = new RestoreDefaultValueButton(), + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, + Child = KeyBindingRow + }, + }; + + restoreDefaultButton.Bindable = KeyBindingRow.Current; + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs new file mode 100644 index 0000000000..6d6616a893 --- /dev/null +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -0,0 +1,119 @@ +// 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.Bindables; +using osuTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Overlays +{ + public class RestoreDefaultValueButton : Container, IHasTooltip + { + public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; + + private Bindable bindable; + + public Bindable Bindable + { + get => bindable; + set + { + bindable = value; + bindable.ValueChanged += _ => UpdateState(); + bindable.DisabledChanged += _ => UpdateState(); + bindable.DefaultChanged += _ => UpdateState(); + UpdateState(); + } + } + + private Color4 buttonColour; + + private bool hovering; + + public RestoreDefaultValueButton() + { + RelativeSizeAxes = Axes.Y; + Width = SettingsPanel.CONTENT_MARGINS; + Alpha = 0f; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + buttonColour = colour.Yellow; + + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + CornerRadius = 3, + Masking = true, + Colour = buttonColour, + EdgeEffect = new EdgeEffectParameters + { + Colour = buttonColour.Opacity(0.1f), + Type = EdgeEffectType.Glow, + Radius = 2, + }, + Size = new Vector2(0.33f, 0.8f), + Child = new Box { RelativeSizeAxes = Axes.Both }, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + UpdateState(); + } + + public string TooltipText => "revert to default"; + + protected override bool OnClick(ClickEvent e) + { + if (bindable != null && !bindable.Disabled) + bindable.SetDefault(); + return true; + } + + protected override bool OnHover(HoverEvent e) + { + hovering = true; + UpdateState(); + return false; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hovering = false; + UpdateState(); + } + + public void SetButtonColour(Color4 buttonColour) + { + this.buttonColour = buttonColour; + UpdateState(); + } + + public void UpdateState() => Scheduler.AddOnce(updateState); + + private void updateState() + { + if (bindable == null) + return; + + this.FadeTo(bindable.IsDefault ? 0f : + hovering && !bindable.Disabled ? 1f : 0.65f, 200, Easing.OutQuint); + this.FadeColour(bindable.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 86a836d29b..7677931fde 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -108,7 +108,8 @@ namespace osu.Game.Overlays.Settings protected SettingsItem() { - RestoreDefaultValueButton restoreDefaultButton; + + RestoreDefaultValueButton restoreDefaultButton; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -116,7 +117,7 @@ namespace osu.Game.Overlays.Settings InternalChildren = new Drawable[] { - restoreDefaultButton = new RestoreDefaultValueButton(), + restoreDefaultButton = new RestoreDefaultValueButton(), FlowContent = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -146,101 +147,5 @@ namespace osu.Game.Overlays.Settings if (labelText != null) labelText.Alpha = controlWithCurrent.Current.Disabled ? 0.3f : 1; } - - protected internal class RestoreDefaultValueButton : Container, IHasTooltip - { - public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; - - private Bindable bindable; - - public Bindable Bindable - { - get => bindable; - set - { - bindable = value; - bindable.ValueChanged += _ => UpdateState(); - bindable.DisabledChanged += _ => UpdateState(); - bindable.DefaultChanged += _ => UpdateState(); - UpdateState(); - } - } - - private Color4 buttonColour; - - private bool hovering; - - public RestoreDefaultValueButton() - { - RelativeSizeAxes = Axes.Y; - Width = SettingsPanel.CONTENT_MARGINS; - Padding = new MarginPadding { Vertical = 1.5f }; - Alpha = 0f; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colour) - { - buttonColour = colour.Yellow; - - Child = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - CornerRadius = 3, - Masking = true, - Colour = buttonColour, - EdgeEffect = new EdgeEffectParameters - { - Colour = buttonColour.Opacity(0.1f), - Type = EdgeEffectType.Glow, - Radius = 2, - }, - Width = 0.33f, - Child = new Box { RelativeSizeAxes = Axes.Both }, - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - UpdateState(); - } - - public string TooltipText => "revert to default"; - - protected override bool OnClick(ClickEvent e) - { - if (bindable != null && !bindable.Disabled) - bindable.SetDefault(); - return true; - } - - protected override bool OnHover(HoverEvent e) - { - hovering = true; - UpdateState(); - return false; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hovering = false; - UpdateState(); - } - - public void UpdateState() => Scheduler.AddOnce(updateState); - - private void updateState() - { - if (bindable == null) - return; - - this.FadeTo(bindable.IsDefault ? 0f : - hovering && !bindable.Disabled ? 1f : 0.65f, 200, Easing.OutQuint); - this.FadeColour(bindable.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); - } - } } -} +} \ No newline at end of file From 753bdf208385285eb8ce24213365ddb74299a290 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 01:04:15 +1000 Subject: [PATCH 04/33] Fixed formatting --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 1 - osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs | 1 - osu.Game/Overlays/Settings/SettingsItem.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 4d2738f244..eeb9a5f7ec 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -85,7 +85,6 @@ namespace osu.Game.Overlays.KeyBinding [BackgroundDependencyLoader] private void load(OsuColour colours) { - isKeysDefaultValue.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); isKeysDefaultValue.BindValueChanged(resetButtons => { diff --git a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs index da8a628b51..15392efc9a 100644 --- a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs @@ -45,7 +45,6 @@ namespace osu.Game.Overlays.KeyBinding Defaults = defaultGroup.Select(d => d.KeyCombination) }; - RestoreDefaultValueButton restoreDefaultButton; RelativeSizeAxes = Axes.X; diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 7677931fde..57d1549910 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -108,7 +108,6 @@ namespace osu.Game.Overlays.Settings protected SettingsItem() { - RestoreDefaultValueButton restoreDefaultButton; RelativeSizeAxes = Axes.X; From 1603b92211a478846e8db583747fb66826034ceb Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 01:30:54 +1000 Subject: [PATCH 05/33] Reformatting --- .../Settings/TestSceneKeyBindingPanel.cs | 19 +++++++------------ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 6 ++++-- .../KeyBinding/KeyBindingsSubsection.cs | 5 ----- osu.Game/Overlays/Settings/SettingsItem.cs | 5 ----- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 09c8696ee0..9126808c88 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Linq; using NUnit.Framework; -using osu.Framework.Input.Bindings; using osu.Framework.Testing; using osu.Framework.Threading; using osu.Game.Overlays; @@ -32,16 +31,14 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClickTwiceOnClearButton() { - SettingsKeyBindingRow firstSettingRow = null; KeyBindingRow firstRow = null; AddStep("click first row", () => { - firstSettingRow = panel.ChildrenOfType().First(); - InputManager.MoveMouseTo(firstSettingRow); + InputManager.MoveMouseTo(panel.ChildrenOfType().First()); InputManager.Click(MouseButton.Left); - firstRow = firstSettingRow.KeyBindingRow; + firstRow = panel.ChildrenOfType().First().KeyBindingRow; }); AddStep("schedule button clicks", () => @@ -111,12 +108,10 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindResetButton() { - SettingsKeyBindingRow multiSettingsBindingRow = null; KeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { - multiSettingsBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); @@ -124,20 +119,20 @@ namespace osu.Game.Tests.Visual.Settings InputManager.ReleaseKey(Key.P); }); - AddUntilStep("restore button shown", () => multiSettingsBindingRow.ChildrenOfType>().First().Alpha > 0); + AddUntilStep("restore button shown", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().First().Alpha > 0); clickSingleBindResetButton(); - AddAssert("first binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); - AddAssert("second binding cleared", () => multiBindingRow.ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(1))); + AddAssert("first binding cleared", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); + AddAssert("second binding cleared", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(1))); - AddUntilStep("restore button hidden", () => multiSettingsBindingRow.ChildrenOfType>().First().Alpha == 0); + AddUntilStep("restore button hidden", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().First().Alpha == 0); void clickSingleBindResetButton() { AddStep("click reset button for bindings", () => { - var clearButton = multiSettingsBindingRow.ChildrenOfType>().Single(); + var clearButton = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().Single(); InputManager.MoveMouseTo(clearButton); InputManager.Click(MouseButton.Left); diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index eeb9a5f7ec..3d89028f96 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -53,7 +53,8 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; - private BindableWithCurrent isKeysDefaultValue; + private readonly BindableWithCurrent isKeysDefaultValue; + public Bindable Current { get => isKeysDefaultValue.Current; @@ -67,7 +68,7 @@ namespace osu.Game.Overlays.KeyBinding this.action = action; this.bindings = bindings; - isKeysDefaultValue = new BindableWithCurrent() + isKeysDefaultValue = new BindableWithCurrent { Default = true }; @@ -314,6 +315,7 @@ namespace osu.Game.Overlays.KeyBinding store.Update(bindTarget.KeyBinding); KeyCombination keyDefault = Defaults.ElementAt(buttons.IndexOf(bindTarget)); + if (isKeysDefaultValue.Value) { if (!keyDefault.Equals(bindTarget.KeyBinding.KeyCombination)) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index d130a3f536..84630703bd 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -1,20 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using osuTK; using osu.Game.Graphics; -using osu.Framework.Input.Bindings; namespace osu.Game.Overlays.KeyBinding { @@ -41,8 +38,6 @@ namespace osu.Game.Overlays.KeyBinding foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { - int intKey = (int)defaultGroup.Key; - // one row per valid action. Add(new SettingsKeyBindingRow(defaultGroup, bindings, Ruleset)); } diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 57d1549910..aa5cbf3d4e 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -5,16 +5,11 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osuTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; From 843da30f9d0f3ae60687eef1ddb1180178585f08 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 01:52:16 +1000 Subject: [PATCH 06/33] Reformatting --- osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs | 4 +--- osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 9126808c88..cfef0ecf5a 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -143,13 +143,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestResetAllBindingsButton() { - SettingsKeyBindingRow multiSettingsBindingRow = null; KeyBindingRow multiBindingRow = null; AddStep("click first row and press p", () => { - multiSettingsBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); - multiBindingRow = panel.ChildrenOfType().First(); + multiBindingRow = panel.ChildrenOfType().First().KeyBindingRow; InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); InputManager.PressKey(Key.P); diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 73f4e6c371..e07e5a52c6 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -11,7 +11,6 @@ using osu.Game.Input; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using osuTK; -using osu.Game.Graphics; namespace osu.Game.Overlays.KeyBinding { From 304caf8bdf79aabbd588d07b907e85e32915ba8e Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 11:24:08 +1000 Subject: [PATCH 07/33] Adding Requested changed --- .../Settings/TestSceneKeyBindingPanel.cs | 67 ++++++++----------- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 32 ++------- .../KeyBinding/SettingsKeyBindingRow.cs | 6 +- .../Overlays/RestoreDefaultValueButton.cs | 33 ++++----- osu.Game/Overlays/Settings/SettingsItem.cs | 2 +- 5 files changed, 56 insertions(+), 84 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index cfef0ecf5a..669338d714 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -35,10 +35,10 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click first row", () => { - InputManager.MoveMouseTo(panel.ChildrenOfType().First()); - InputManager.Click(MouseButton.Left); + firstRow = panel.ChildrenOfType().First(); - firstRow = panel.ChildrenOfType().First().KeyBindingRow; + InputManager.MoveMouseTo(firstRow); + InputManager.Click(MouseButton.Left); }); AddStep("schedule button clicks", () => @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).KeyBindingRow; + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); @@ -108,66 +108,55 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindResetButton() { - KeyBindingRow multiBindingRow = null; + SettingsKeyBindingRow settingsKeyBindingRow = null; AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); - InputManager.MoveMouseTo(multiBindingRow); + settingsKeyBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); + InputManager.MoveMouseTo(settingsKeyBindingRow.KeyBindingRow); InputManager.Click(MouseButton.Left); InputManager.PressKey(Key.P); InputManager.ReleaseKey(Key.P); }); - AddUntilStep("restore button shown", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().First().Alpha > 0); + AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha > 0); - clickSingleBindResetButton(); - - AddAssert("first binding cleared", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); - AddAssert("second binding cleared", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(1))); - - AddUntilStep("restore button hidden", () => panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().First().Alpha == 0); - - void clickSingleBindResetButton() + AddStep("click reset button for bindings", () => { - AddStep("click reset button for bindings", () => - { - var clearButton = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1).ChildrenOfType>().Single(); + var clearButton = settingsKeyBindingRow.ChildrenOfType>().Single(); - InputManager.MoveMouseTo(clearButton); - InputManager.Click(MouseButton.Left); - }); - } + InputManager.MoveMouseTo(clearButton); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); + + AddAssert("first binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); + AddAssert("second binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(1))); } [Test] public void TestResetAllBindingsButton() { - KeyBindingRow multiBindingRow = null; + KeyBindingRow keyBindingRow = null; AddStep("click first row and press p", () => { - multiBindingRow = panel.ChildrenOfType().First().KeyBindingRow; - InputManager.MoveMouseTo(multiBindingRow); + keyBindingRow = panel.ChildrenOfType().First(); + InputManager.MoveMouseTo(keyBindingRow); InputManager.Click(MouseButton.Left); InputManager.PressKey(Key.P); InputManager.ReleaseKey(Key.P); }); - - clickResetAllBindingsButton(); - - AddAssert("bindings cleared", () => multiBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(multiBindingRow.Defaults.ElementAt(0))); - - void clickResetAllBindingsButton() + AddStep("click reset button for all bindings", () => { - AddStep("click reset button for all bindings", () => - { - var clearButton = panel.ChildrenOfType().First(); + var clearButton = panel.ChildrenOfType().First(); - InputManager.MoveMouseTo(clearButton); - InputManager.Click(MouseButton.Left); - }); - } + InputManager.MoveMouseTo(clearButton); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("bindings cleared", () => keyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(keyBindingRow.Defaults.ElementAt(0))); } [Test] diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8336dae9ac..6f4c5f1179 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -53,7 +53,11 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; - private readonly BindableWithCurrent isKeysDefaultValue; + private readonly BindableWithCurrent isKeysDefaultValue = new BindableWithCurrent + { + Default = true + }; + public Bindable Current { @@ -67,12 +71,6 @@ namespace osu.Game.Overlays.KeyBinding { this.action = action; this.bindings = bindings; - - isKeysDefaultValue = new BindableWithCurrent - { - Default = true - }; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -89,7 +87,7 @@ namespace osu.Game.Overlays.KeyBinding isKeysDefaultValue.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); isKeysDefaultValue.BindValueChanged(resetButtons => { - if (resetButtons.NewValue != resetButtons.OldValue && resetButtons.NewValue && !bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults)) + if (resetButtons.NewValue && !bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults)) { RestoreDefaults(); finalise(); @@ -314,23 +312,7 @@ namespace osu.Game.Overlays.KeyBinding { store.Update(bindTarget.KeyBinding); - KeyCombination keyDefault = Defaults.ElementAt(buttons.IndexOf(bindTarget)); - - if (isKeysDefaultValue.Value) - { - if (!keyDefault.Equals(bindTarget.KeyBinding.KeyCombination)) - { - isKeysDefaultValue.Value = false; - } - } - else - { - if (keyDefault.Equals(bindTarget.KeyBinding.KeyCombination) && - buttons.Select(b => b.KeyBinding.KeyCombination).SequenceEqual(Defaults)) - { - isKeysDefaultValue.Value = true; - } - } + isKeysDefaultValue.Value = buttons.Select(b => b.KeyBinding.KeyCombination).SequenceEqual(Defaults); bindTarget.IsBinding = false; Schedule(() => diff --git a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs index 15392efc9a..31374a8120 100644 --- a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.KeyBinding public class SettingsKeyBindingRow : Container, IFilterable { private readonly IGrouping defaultGroup; - private readonly IEnumerable bindings; + private readonly ICollection bindings; public readonly KeyBindingRow KeyBindingRow; private bool matchingFilter; @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.KeyBinding public SettingsKeyBindingRow( IGrouping defaultGroup, - IEnumerable bindings, + ICollection bindings, RulesetInfo ruleset) { this.defaultGroup = defaultGroup; @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.KeyBinding }, }; - restoreDefaultButton.Bindable = KeyBindingRow.Current; + restoreDefaultButton.Current = KeyBindingRow.Current; } } } \ No newline at end of file diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 6d6616a893..5d61b76915 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -10,27 +10,27 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; using osuTK; namespace osu.Game.Overlays { - public class RestoreDefaultValueButton : Container, IHasTooltip + public class RestoreDefaultValueButton : Container, IHasTooltip, IHasCurrentValue { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; - private Bindable bindable; + private BindableWithCurrent current = new BindableWithCurrent(); - public Bindable Bindable + public Bindable Current { - get => bindable; - set - { - bindable = value; - bindable.ValueChanged += _ => UpdateState(); - bindable.DisabledChanged += _ => UpdateState(); - bindable.DefaultChanged += _ => UpdateState(); + get => current.Current; + set { + current.Current = value; + current.ValueChanged += _ => UpdateState(); + current.DisabledChanged += _ => UpdateState(); + current.DefaultChanged += _ => UpdateState(); UpdateState(); } } @@ -43,6 +43,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Y; Width = SettingsPanel.CONTENT_MARGINS; + Padding = new MarginPadding { Vertical = 1.5f }; Alpha = 0f; } @@ -80,8 +81,8 @@ namespace osu.Game.Overlays protected override bool OnClick(ClickEvent e) { - if (bindable != null && !bindable.Disabled) - bindable.SetDefault(); + if (current != null && !current.Disabled) + current.SetDefault(); return true; } @@ -108,12 +109,12 @@ namespace osu.Game.Overlays private void updateState() { - if (bindable == null) + if (current == null) return; - this.FadeTo(bindable.IsDefault ? 0f : - hovering && !bindable.Disabled ? 1f : 0.65f, 200, Easing.OutQuint); - this.FadeColour(bindable.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); + this.FadeTo(current.IsDefault ? 0f : + hovering && !current.Disabled ? 1f : 0.65f, 200, Easing.OutQuint); + this.FadeColour(current.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); } } } \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index aa5cbf3d4e..807916e7f6 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.Settings controlWithCurrent.Current.DisabledChanged += _ => updateDisabled(); if (ShowsDefaultIndicator) - restoreDefaultButton.Bindable = controlWithCurrent.Current; + restoreDefaultButton.Current = controlWithCurrent.Current; } } From d85f17159f0e3f5e3cf4b61165ec1f9de5339837 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 11:25:56 +1000 Subject: [PATCH 08/33] Formatting --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 6f4c5f1179..7e81f64458 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -58,7 +58,6 @@ namespace osu.Game.Overlays.KeyBinding Default = true }; - public Bindable Current { get => isKeysDefaultValue.Current; From d988194dd3638749bcf3e53ef6f08ca63928ca52 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 11:40:42 +1000 Subject: [PATCH 09/33] Formatting --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 5d61b76915..e709e874ce 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -21,12 +21,13 @@ namespace osu.Game.Overlays { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; - private BindableWithCurrent current = new BindableWithCurrent(); + private readonly BindableWithCurrent current = new BindableWithCurrent(); public Bindable Current { get => current.Current; - set { + set + { current.Current = value; current.ValueChanged += _ => UpdateState(); current.DisabledChanged += _ => UpdateState(); From 50d5af9662475aba7dadbe7302750ca57f3d9899 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 12:05:22 +1000 Subject: [PATCH 10/33] Removed unused method --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index e709e874ce..5c07eac838 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -100,12 +100,6 @@ namespace osu.Game.Overlays UpdateState(); } - public void SetButtonColour(Color4 buttonColour) - { - this.buttonColour = buttonColour; - UpdateState(); - } - public void UpdateState() => Scheduler.AddOnce(updateState); private void updateState() From c282f0e6035a2388d0360086bceed1d96d04d931 Mon Sep 17 00:00:00 2001 From: Swords Date: Sat, 15 May 2021 19:42:33 +1000 Subject: [PATCH 11/33] Fixing tests For some reason moving the mouse and clicking doesn't work with "dotnet test", but works when you run the osu.Game.Tests project. --- .../Settings/TestSceneKeyBindingPanel.cs | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 669338d714..8053a41de2 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -106,14 +106,15 @@ namespace osu.Game.Tests.Visual.Settings } [Test] - public void TestSingleBindResetButton() + public void TestSingleBindingResetButton() { SettingsKeyBindingRow settingsKeyBindingRow = null; - AddStep("click first row with two bindings", () => + AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(row => row.KeyBindingRow.Defaults.Count() > 1); - InputManager.MoveMouseTo(settingsKeyBindingRow.KeyBindingRow); + settingsKeyBindingRow = panel.ChildrenOfType().First(); + + InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); InputManager.PressKey(Key.P); InputManager.ReleaseKey(Key.P); @@ -123,40 +124,43 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click reset button for bindings", () => { - var clearButton = settingsKeyBindingRow.ChildrenOfType>().Single(); + var resetButton = settingsKeyBindingRow.ChildrenOfType>().First(); - InputManager.MoveMouseTo(clearButton); - InputManager.Click(MouseButton.Left); + resetButton.Click(); }); AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("first binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); - AddAssert("second binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(1).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(1))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestResetAllBindingsButton() { - KeyBindingRow keyBindingRow = null; + SettingsKeyBindingRow settingsKeyBindingRow = null; - AddStep("click first row and press p", () => + AddStep("click first row", () => { - keyBindingRow = panel.ChildrenOfType().First(); - InputManager.MoveMouseTo(keyBindingRow); + settingsKeyBindingRow = panel.ChildrenOfType().First(); + + InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); InputManager.PressKey(Key.P); InputManager.ReleaseKey(Key.P); }); - AddStep("click reset button for all bindings", () => - { - var clearButton = panel.ChildrenOfType().First(); - InputManager.MoveMouseTo(clearButton); - InputManager.Click(MouseButton.Left); + AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha > 0); + + AddStep("click reset button for bindings", () => + { + var resetButton = panel.ChildrenOfType().First(); + + resetButton.Click(); }); - AddUntilStep("bindings cleared", () => keyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(keyBindingRow.Defaults.ElementAt(0))); + AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); + + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); } [Test] From 264d8b9b86c17f09448c78df43aa6d904c492201 Mon Sep 17 00:00:00 2001 From: Swords Date: Sun, 16 May 2021 14:48:00 +1000 Subject: [PATCH 12/33] Finishing requested changes, and tidy up --- .../Settings/TestSceneKeyBindingPanel.cs | 8 +++--- .../KeyBinding/KeyBindingsSubsection.cs | 4 +-- ...ndingRow.cs => RestorableKeyBindingRow.cs} | 28 ++++++++++--------- 3 files changed, 21 insertions(+), 19 deletions(-) rename osu.Game/Overlays/KeyBinding/{SettingsKeyBindingRow.cs => RestorableKeyBindingRow.cs} (74%) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 8053a41de2..3edba2ddd7 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -108,11 +108,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindingResetButton() { - SettingsKeyBindingRow settingsKeyBindingRow = null; + RestorableKeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -137,11 +137,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestResetAllBindingsButton() { - SettingsKeyBindingRow settingsKeyBindingRow = null; + RestorableKeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index e07e5a52c6..dc29f0b4e5 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -38,12 +38,12 @@ namespace osu.Game.Overlays.KeyBinding foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { // one row per valid action. - Add(new SettingsKeyBindingRow(defaultGroup, bindings, Ruleset)); + Add(new RestorableKeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); } Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) }); } } diff --git a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs similarity index 74% rename from osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs rename to osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 31374a8120..0461ae4f35 100644 --- a/osu.Game/Overlays/KeyBinding/SettingsKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -5,13 +5,14 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Bindings; using osu.Game.Rulesets; namespace osu.Game.Overlays.KeyBinding { - public class SettingsKeyBindingRow : Container, IFilterable + public class RestorableKeyBindingRow : Container, IFilterable { - private readonly IGrouping defaultGroup; + private readonly object key; private readonly ICollection bindings; public readonly KeyBindingRow KeyBindingRow; @@ -29,28 +30,29 @@ namespace osu.Game.Overlays.KeyBinding public bool FilteringActive { get; set; } - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(defaultGroup.Key.ToString()); + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - public SettingsKeyBindingRow( - IGrouping defaultGroup, + public RestorableKeyBindingRow( + object key, ICollection bindings, - RulesetInfo ruleset) + RulesetInfo ruleset, + IEnumerable defaults) { - this.defaultGroup = defaultGroup; + this.key = key; this.bindings = bindings; - KeyBindingRow = new KeyBindingRow(defaultGroup.Key, bindings.Where(b => ((int)b.Action).Equals((int)defaultGroup.Key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaultGroup.Select(d => d.KeyCombination) - }; - RestoreDefaultValueButton restoreDefaultButton; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; + KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaults + }; + InternalChildren = new Drawable[] { restoreDefaultButton = new RestoreDefaultValueButton(), From 90f00a76633eb622b72073e32214ff4fc62710e3 Mon Sep 17 00:00:00 2001 From: Swords Date: Sun, 16 May 2021 15:01:19 +1000 Subject: [PATCH 13/33] Fixes ResotreDefaultValue to use the BindableWithCurrent correctly --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 5c07eac838..f390fb1e46 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -29,9 +29,6 @@ namespace osu.Game.Overlays set { current.Current = value; - current.ValueChanged += _ => UpdateState(); - current.DisabledChanged += _ => UpdateState(); - current.DefaultChanged += _ => UpdateState(); UpdateState(); } } @@ -46,6 +43,10 @@ namespace osu.Game.Overlays Width = SettingsPanel.CONTENT_MARGINS; Padding = new MarginPadding { Vertical = 1.5f }; Alpha = 0f; + + Current.ValueChanged += _ => UpdateState(); + Current.DisabledChanged += _ => UpdateState(); + Current.DefaultChanged += _ => UpdateState(); } [BackgroundDependencyLoader] From 33fe843ba9eba9fcdedd8a59969b016a2abde848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 17 May 2021 20:44:47 +0200 Subject: [PATCH 14/33] Move value change bindings to `LoadComplete()` Also removes a redundant one from the setter of `Current`. If the set to current comes with an associated value change, the bind-unbind flow that `BindableWithCurrent` implements will handle that change anyway. --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index f390fb1e46..34ebe270ef 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -26,11 +26,7 @@ namespace osu.Game.Overlays public Bindable Current { get => current.Current; - set - { - current.Current = value; - UpdateState(); - } + set => current.Current = value; } private Color4 buttonColour; @@ -43,10 +39,6 @@ namespace osu.Game.Overlays Width = SettingsPanel.CONTENT_MARGINS; Padding = new MarginPadding { Vertical = 1.5f }; Alpha = 0f; - - Current.ValueChanged += _ => UpdateState(); - Current.DisabledChanged += _ => UpdateState(); - Current.DefaultChanged += _ => UpdateState(); } [BackgroundDependencyLoader] @@ -76,6 +68,11 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); + + Current.ValueChanged += _ => UpdateState(); + Current.DisabledChanged += _ => UpdateState(); + Current.DefaultChanged += _ => UpdateState(); + UpdateState(); } @@ -113,4 +110,4 @@ namespace osu.Game.Overlays this.FadeColour(current.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); } } -} \ No newline at end of file +} From 30d7768971208bf50324aeb32bf103e1851cba30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 17 May 2021 20:47:56 +0200 Subject: [PATCH 15/33] Remove now-redundant null check --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 34ebe270ef..3f4a9785a6 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -80,7 +80,7 @@ namespace osu.Game.Overlays protected override bool OnClick(ClickEvent e) { - if (current != null && !current.Disabled) + if (!current.Disabled) current.SetDefault(); return true; } From ef114f240799be93ef7448e7bf33da9693390dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 17 May 2021 20:57:48 +0200 Subject: [PATCH 16/33] Simplify bindable flow in `KeyBindingRow` --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 45 ++++++++++--------- .../KeyBinding/RestorableKeyBindingRow.cs | 4 +- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 7e81f64458..33f32493ad 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -24,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Overlays.KeyBinding { - public class KeyBindingRow : Container, IFilterable, IHasCurrentValue + public class KeyBindingRow : Container, IFilterable { private readonly object action; private readonly IEnumerable bindings; @@ -53,17 +52,11 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; - private readonly BindableWithCurrent isKeysDefaultValue = new BindableWithCurrent + public Bindable IsDefault { get; } = new BindableBool(true) { Default = true }; - public Bindable Current - { - get => isKeysDefaultValue.Current; - set => isKeysDefaultValue.Current = value; - } - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString()); public KeyBindingRow(object action, IEnumerable bindings) @@ -83,15 +76,7 @@ namespace osu.Game.Overlays.KeyBinding [BackgroundDependencyLoader] private void load(OsuColour colours) { - isKeysDefaultValue.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); - isKeysDefaultValue.BindValueChanged(resetButtons => - { - if (resetButtons.NewValue && !bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults)) - { - RestoreDefaults(); - finalise(); - } - }); + updateIsDefaultValue(); EdgeEffect = new EdgeEffectParameters { @@ -140,6 +125,24 @@ namespace osu.Game.Overlays.KeyBinding buttons.Add(new KeyButton(b)); } + protected override void LoadComplete() + { + base.LoadComplete(); + + IsDefault.BindValueChanged(resetButtons => + { + if (resetButtons.NewValue && !computeIsDefaultValue()) + { + RestoreDefaults(); + finalise(); + } + }); + } + + private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); + + private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + public void RestoreDefaults() { int i = 0; @@ -151,7 +154,7 @@ namespace osu.Game.Overlays.KeyBinding store.Update(button.KeyBinding); } - isKeysDefaultValue.Value = true; + updateIsDefaultValue(); } protected override bool OnHover(HoverEvent e) @@ -311,7 +314,7 @@ namespace osu.Game.Overlays.KeyBinding { store.Update(bindTarget.KeyBinding); - isKeysDefaultValue.Value = buttons.Select(b => b.KeyBinding.KeyCombination).SequenceEqual(Defaults); + updateIsDefaultValue(); bindTarget.IsBinding = false; Schedule(() => @@ -476,4 +479,4 @@ namespace osu.Game.Overlays.KeyBinding } } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 0461ae4f35..b09c21378e 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.KeyBinding }, }; - restoreDefaultButton.Current = KeyBindingRow.Current; + restoreDefaultButton.Current = KeyBindingRow.IsDefault; } } -} \ No newline at end of file +} From 0e91a00a7e3b4084ee3395c1d88d1437740a87f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 17 May 2021 21:18:45 +0200 Subject: [PATCH 17/33] Revert to previous width spec instead of size --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 3f4a9785a6..51fb87da1d 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osuTK; namespace osu.Game.Overlays { @@ -60,7 +59,7 @@ namespace osu.Game.Overlays Type = EdgeEffectType.Glow, Radius = 2, }, - Size = new Vector2(0.33f, 0.8f), + Width = 0.33f, Child = new Box { RelativeSizeAxes = Axes.Both }, }; } From 3a5b21c0f5caafc98e93783f5d014dbc34841f8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 May 2021 13:47:39 +0900 Subject: [PATCH 18/33] Update "reset all bindings" button to better match new key binding row widths --- osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index dc29f0b4e5..737c640b5a 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -55,10 +55,13 @@ namespace osu.Game.Overlays.KeyBinding { Text = "Reset all bindings in section"; RelativeSizeAxes = Axes.X; - Margin = new MarginPadding { Top = 5 }; - Height = 20; + Width = 0.5f; + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + Margin = new MarginPadding { Top = 15 }; + Height = 30; Content.CornerRadius = 5; } } -} \ No newline at end of file +} From 0100b88a8601a693de45531576d4b2ad32900ae0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 May 2021 14:11:26 +0900 Subject: [PATCH 19/33] Move private methods down --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 33f32493ad..959ba36c6a 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -129,9 +129,9 @@ namespace osu.Game.Overlays.KeyBinding { base.LoadComplete(); - IsDefault.BindValueChanged(resetButtons => + IsDefault.BindValueChanged(isDefault => { - if (resetButtons.NewValue && !computeIsDefaultValue()) + if (isDefault.NewValue && !computeIsDefaultValue()) { RestoreDefaults(); finalise(); @@ -139,10 +139,6 @@ namespace osu.Game.Overlays.KeyBinding }); } - private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); - - private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); - public void RestoreDefaults() { int i = 0; @@ -331,6 +327,10 @@ namespace osu.Game.Overlays.KeyBinding cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; } + private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); + + private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + protected override void OnFocus(FocusEvent e) { AutoSizeDuration = 500; From ca1d1c58aba7888cf89bd42f8ced6539a1833d6a Mon Sep 17 00:00:00 2001 From: Swords Date: Mon, 24 May 2021 21:34:47 +1000 Subject: [PATCH 20/33] RestoreDefaultValueButton implements OsuButton --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 +- .../KeyBinding/RestorableKeyBindingRow.cs | 1 + .../Overlays/RestoreDefaultValueButton.cs | 44 +++++++------------ 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 959ba36c6a..8cc03160a2 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -131,9 +131,8 @@ namespace osu.Game.Overlays.KeyBinding IsDefault.BindValueChanged(isDefault => { - if (isDefault.NewValue && !computeIsDefaultValue()) + if (isDefault.NewValue) { - RestoreDefaults(); finalise(); } }); diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index b09c21378e..d07fffe6bc 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -65,6 +65,7 @@ namespace osu.Game.Overlays.KeyBinding }, }; + restoreDefaultButton.Action = () => { KeyBindingRow.RestoreDefaults(); }; restoreDefaultButton.Current = KeyBindingRow.IsDefault; } } diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 51fb87da1d..d75657ea7a 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -6,17 +6,16 @@ using osu.Framework.Bindables; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { - public class RestoreDefaultValueButton : Container, IHasTooltip, IHasCurrentValue + public class RestoreDefaultValueButton : OsuButton, IHasTooltip, IHasCurrentValue { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; @@ -34,34 +33,30 @@ namespace osu.Game.Overlays public RestoreDefaultValueButton() { + Height = 1; + RelativeSizeAxes = Axes.Y; Width = SettingsPanel.CONTENT_MARGINS; - Padding = new MarginPadding { Vertical = 1.5f }; - Alpha = 0f; } [BackgroundDependencyLoader] private void load(OsuColour colour) { + BackgroundColour = colour.Yellow; buttonColour = colour.Yellow; - - Child = new Container + Content.Width = 0.33f; + Content.CornerRadius = 3; + Content.EdgeEffect = new EdgeEffectParameters { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - CornerRadius = 3, - Masking = true, - Colour = buttonColour, - EdgeEffect = new EdgeEffectParameters - { - Colour = buttonColour.Opacity(0.1f), - Type = EdgeEffectType.Glow, - Radius = 2, - }, - Width = 0.33f, - Child = new Box { RelativeSizeAxes = Axes.Both }, + Colour = buttonColour.Opacity(0.1f), + Type = EdgeEffectType.Glow, + Radius = 2, }; + + Padding = new MarginPadding { Vertical = 1.5f }; + Alpha = 0f; + + Action += () => { if (!current.Disabled) current.SetDefault(); }; } protected override void LoadComplete() @@ -77,13 +72,6 @@ namespace osu.Game.Overlays public string TooltipText => "revert to default"; - protected override bool OnClick(ClickEvent e) - { - if (!current.Disabled) - current.SetDefault(); - return true; - } - protected override bool OnHover(HoverEvent e) { hovering = true; From 441e4e7d56fe35088bb2faef2ed741bb3ad82814 Mon Sep 17 00:00:00 2001 From: Swords Date: Mon, 24 May 2021 22:08:34 +1000 Subject: [PATCH 21/33] Formatting --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index d75657ea7a..0fe7b7322f 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -56,7 +56,10 @@ namespace osu.Game.Overlays Padding = new MarginPadding { Vertical = 1.5f }; Alpha = 0f; - Action += () => { if (!current.Disabled) current.SetDefault(); }; + Action += () => + { + if (!current.Disabled) current.SetDefault(); + }; } protected override void LoadComplete() From 518999ffab72b414a5d82bb0ba908d505d7f5187 Mon Sep 17 00:00:00 2001 From: Swords Date: Mon, 24 May 2021 22:49:40 +1000 Subject: [PATCH 22/33] Renaming files --- .../Settings/TestSceneKeyBindingPanel.cs | 42 +- .../Overlays/KeyBinding/BasicKeyBindingRow.cs | 463 +++++++++++++++++ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 465 ++---------------- .../KeyBinding/KeyBindingsSubsection.cs | 4 +- .../KeyBinding/RestorableKeyBindingRow.cs | 72 --- 5 files changed, 514 insertions(+), 532 deletions(-) create mode 100644 osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs delete mode 100644 osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 3edba2ddd7..face2a498d 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -31,11 +31,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClickTwiceOnClearButton() { - KeyBindingRow firstRow = null; + BasicKeyBindingRow firstRow = null; AddStep("click first row", () => { - firstRow = panel.ChildrenOfType().First(); + firstRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(firstRow); InputManager.Click(MouseButton.Left); @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Settings AddStep("schedule button clicks", () => { - var clearButton = firstRow.ChildrenOfType().Single(); + var clearButton = firstRow.ChildrenOfType().Single(); InputManager.MoveMouseTo(clearButton); @@ -68,22 +68,22 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClearButtonOnBindings() { - KeyBindingRow multiBindingRow = null; + BasicKeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); clickClearButton(); - AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().First().Text.Text.ToString())); + AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().First().Text.Text.ToString())); AddStep("click second binding", () => { - var target = multiBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -91,13 +91,13 @@ namespace osu.Game.Tests.Visual.Settings clickClearButton(); - AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().ElementAt(1).Text.Text.ToString())); + AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().ElementAt(1).Text.Text.ToString())); void clickClearButton() { AddStep("click clear button", () => { - var clearButton = multiBindingRow.ChildrenOfType().Single(); + var clearButton = multiBindingRow.ChildrenOfType().Single(); InputManager.MoveMouseTo(clearButton); InputManager.Click(MouseButton.Left); @@ -108,11 +108,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindingResetButton() { - RestorableKeyBindingRow settingsKeyBindingRow = null; + KeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -131,17 +131,17 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestResetAllBindingsButton() { - RestorableKeyBindingRow settingsKeyBindingRow = null; + KeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -160,26 +160,26 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestClickRowSelectsFirstBinding() { - KeyBindingRow multiBindingRow = null; + BasicKeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); AddStep("click second binding", () => { - var target = multiBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -187,12 +187,12 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click back binding row", () => { - multiBindingRow = panel.ChildrenOfType().ElementAt(10); + multiBindingRow = panel.ChildrenOfType().ElementAt(10); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs new file mode 100644 index 0000000000..acdf273622 --- /dev/null +++ b/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs @@ -0,0 +1,463 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions; +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.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Input; +using osuTK; +using osuTK.Graphics; +using osuTK.Input; + +namespace osu.Game.Overlays.KeyBinding +{ + public class BasicKeyBindingRow : Container + { + private readonly object action; + private readonly IEnumerable bindings; + + private const float transition_time = 150; + + private const float height = 20; + + private const float padding = 5; + + private FillFlowContainer cancelAndClearButtons; + private FillFlowContainer buttons; + + public Bindable IsDefault { get; } = new BindableBool(true) + { + Default = true + }; + + public BasicKeyBindingRow(object action, IEnumerable bindings) + { + this.action = action; + this.bindings = bindings; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Masking = true; + CornerRadius = padding; + } + + [Resolved] + private KeyBindingStore store { get; set; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + updateIsDefaultValue(); + + EdgeEffect = new EdgeEffectParameters + { + Radius = 2, + Colour = colours.YellowDark.Opacity(0), + Type = EdgeEffectType.Shadow, + Hollow = true, + }; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.6f, + }, + new OsuSpriteText + { + Text = action.GetDescription(), + Margin = new MarginPadding(padding), + }, + buttons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }, + cancelAndClearButtons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding(padding) { Top = height + padding * 2 }, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Alpha = 0, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new CancelButton { Action = finalise }, + new ClearButton { Action = clear }, + }, + } + }; + foreach (var b in bindings) + buttons.Add(new KeyButton(b)); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + IsDefault.BindValueChanged(isDefault => + { + if (isDefault.NewValue) + { + finalise(); + } + }); + } + + public void RestoreDefaults() + { + int i = 0; + + foreach (var d in Defaults) + { + var button = buttons[i++]; + button.UpdateKeyCombination(d); + store.Update(button.KeyBinding); + } + + updateIsDefaultValue(); + } + + protected override bool OnHover(HoverEvent e) + { + FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + + base.OnHoverLost(e); + } + + public override bool AcceptsFocus => bindTarget == null; + + private KeyButton bindTarget; + + public bool AllowMainMouseButtons; + + public IEnumerable Defaults; + + private bool isModifier(Key k) => k < Key.F1; + + protected override bool OnClick(ClickEvent e) => true; + + protected override bool OnMouseDown(MouseDownEvent e) + { + if (!HasFocus || !bindTarget.IsHovered) + return base.OnMouseDown(e); + + if (!AllowMainMouseButtons) + { + switch (e.Button) + { + case MouseButton.Left: + case MouseButton.Right: + return true; + } + } + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + return true; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + // don't do anything until the last button is released. + if (!HasFocus || e.HasAnyButtonPressed) + { + base.OnMouseUp(e); + return; + } + + if (bindTarget.IsHovered) + finalise(); + // prevent updating bind target before clear button's action + else if (!cancelAndClearButtons.Any(b => b.IsHovered)) + updateBindTarget(); + } + + protected override bool OnScroll(ScrollEvent e) + { + if (HasFocus) + { + if (bindTarget.IsHovered) + { + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta)); + finalise(); + return true; + } + } + + return base.OnScroll(e); + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + if (!isModifier(e.Key)) finalise(); + + return true; + } + + protected override void OnKeyUp(KeyUpEvent e) + { + if (!HasFocus) + { + base.OnKeyUp(e); + return; + } + + finalise(); + } + + protected override bool OnJoystickPress(JoystickPressEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + finalise(); + + return true; + } + + protected override void OnJoystickRelease(JoystickReleaseEvent e) + { + if (!HasFocus) + { + base.OnJoystickRelease(e); + return; + } + + finalise(); + } + + protected override bool OnMidiDown(MidiDownEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + finalise(); + + return true; + } + + protected override void OnMidiUp(MidiUpEvent e) + { + if (!HasFocus) + { + base.OnMidiUp(e); + return; + } + + finalise(); + } + + private void clear() + { + if (bindTarget == null) + return; + + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + } + + private void finalise() + { + if (bindTarget != null) + { + store.Update(bindTarget.KeyBinding); + + updateIsDefaultValue(); + + bindTarget.IsBinding = false; + Schedule(() => + { + // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) + bindTarget = null; + }); + } + + if (HasFocus) + GetContainingInputManager().ChangeFocus(null); + + cancelAndClearButtons.FadeOut(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; + } + + private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); + + private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + + protected override void OnFocus(FocusEvent e) + { + AutoSizeDuration = 500; + AutoSizeEasing = Easing.OutQuint; + + cancelAndClearButtons.FadeIn(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; + + updateBindTarget(); + base.OnFocus(e); + } + + protected override void OnFocusLost(FocusLostEvent e) + { + finalise(); + base.OnFocusLost(e); + } + + /// + /// Updates the bind target to the currently hovered key button or the first if clicked anywhere else. + /// + private void updateBindTarget() + { + if (bindTarget != null) bindTarget.IsBinding = false; + bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); + if (bindTarget != null) bindTarget.IsBinding = true; + } + + private class CancelButton : TriangleButton + { + public CancelButton() + { + Text = "Cancel"; + Size = new Vector2(80, 20); + } + } + + public class ClearButton : DangerousTriangleButton + { + public ClearButton() + { + Text = "Clear"; + Size = new Vector2(80, 20); + } + } + + public class KeyButton : Container + { + public readonly Framework.Input.Bindings.KeyBinding KeyBinding; + + private readonly Box box; + public readonly OsuSpriteText Text; + + private Color4 hoverColour; + + private bool isBinding; + + public bool IsBinding + { + get => isBinding; + set + { + if (value == isBinding) return; + + isBinding = value; + + updateHoverState(); + } + } + + public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) + { + KeyBinding = keyBinding; + + Margin = new MarginPadding(padding); + + // todo: use this in a meaningful way + // var isDefault = keyBinding.Action is Enum; + + Masking = true; + CornerRadius = padding; + + Height = height; + AutoSizeAxes = Axes.X; + + Children = new Drawable[] + { + new Container + { + AlwaysPresent = true, + Width = 80, + Height = height, + }, + box = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + Text = new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 10), + Margin = new MarginPadding(5), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = keyBinding.KeyCombination.ReadableString(), + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverColour = colours.YellowDark; + } + + protected override bool OnHover(HoverEvent e) + { + updateHoverState(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateHoverState(); + base.OnHoverLost(e); + } + + private void updateHoverState() + { + if (isBinding) + { + box.FadeColour(Color4.White, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + } + else + { + box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); + } + } + + public void UpdateKeyCombination(KeyCombination newCombination) + { + KeyBinding.KeyCombination = newCombination; + Text.Text = KeyBinding.KeyCombination.ReadableString(); + } + } + } +} diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8cc03160a2..3221b66bce 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -1,38 +1,20 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions; -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.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Input; -using osuTK; -using osuTK.Graphics; -using osuTK.Input; +using osu.Game.Rulesets; namespace osu.Game.Overlays.KeyBinding { public class KeyBindingRow : Container, IFilterable { - private readonly object action; - private readonly IEnumerable bindings; - - private const float transition_time = 150; - - private const float height = 20; - - private const float padding = 5; + private readonly object key; + private readonly ICollection bindings; + public readonly BasicKeyBindingRow BasicKeyBindingRow; private bool matchingFilter; @@ -48,434 +30,43 @@ namespace osu.Game.Overlays.KeyBinding public bool FilteringActive { get; set; } - private OsuSpriteText text; - private FillFlowContainer cancelAndClearButtons; - private FillFlowContainer buttons; + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - public Bindable IsDefault { get; } = new BindableBool(true) + public KeyBindingRow( + object key, + ICollection bindings, + RulesetInfo ruleset, + IEnumerable defaults) { - Default = true - }; - - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString()); - - public KeyBindingRow(object action, IEnumerable bindings) - { - this.action = action; + this.key = key; this.bindings = bindings; + + RestoreDefaultValueButton restoreDefaultButton; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - Masking = true; - CornerRadius = padding; - } - - [Resolved] - private KeyBindingStore store { get; set; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - updateIsDefaultValue(); - - EdgeEffect = new EdgeEffectParameters + BasicKeyBindingRow = new BasicKeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) { - Radius = 2, - Colour = colours.YellowDark.Opacity(0), - Type = EdgeEffectType.Shadow, - Hollow = true, + AllowMainMouseButtons = ruleset != null, + Defaults = defaults }; - Children = new Drawable[] + InternalChildren = new Drawable[] { - new Box + restoreDefaultButton = new RestoreDefaultValueButton(), + new FillFlowContainer { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.6f, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, + Child = BasicKeyBindingRow }, - text = new OsuSpriteText - { - Text = action.GetDescription(), - Margin = new MarginPadding(padding), - }, - buttons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }, - cancelAndClearButtons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding(padding) { Top = height + padding * 2 }, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Alpha = 0, - Spacing = new Vector2(5), - Children = new Drawable[] - { - new CancelButton { Action = finalise }, - new ClearButton { Action = clear }, - }, - } }; - foreach (var b in bindings) - buttons.Add(new KeyButton(b)); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - IsDefault.BindValueChanged(isDefault => - { - if (isDefault.NewValue) - { - finalise(); - } - }); - } - - public void RestoreDefaults() - { - int i = 0; - - foreach (var d in Defaults) - { - var button = buttons[i++]; - button.UpdateKeyCombination(d); - store.Update(button.KeyBinding); - } - - updateIsDefaultValue(); - } - - protected override bool OnHover(HoverEvent e) - { - FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); - - base.OnHoverLost(e); - } - - public override bool AcceptsFocus => bindTarget == null; - - private KeyButton bindTarget; - - public bool AllowMainMouseButtons; - - public IEnumerable Defaults; - - private bool isModifier(Key k) => k < Key.F1; - - protected override bool OnClick(ClickEvent e) => true; - - protected override bool OnMouseDown(MouseDownEvent e) - { - if (!HasFocus || !bindTarget.IsHovered) - return base.OnMouseDown(e); - - if (!AllowMainMouseButtons) - { - switch (e.Button) - { - case MouseButton.Left: - case MouseButton.Right: - return true; - } - } - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - return true; - } - - protected override void OnMouseUp(MouseUpEvent e) - { - // don't do anything until the last button is released. - if (!HasFocus || e.HasAnyButtonPressed) - { - base.OnMouseUp(e); - return; - } - - if (bindTarget.IsHovered) - finalise(); - // prevent updating bind target before clear button's action - else if (!cancelAndClearButtons.Any(b => b.IsHovered)) - updateBindTarget(); - } - - protected override bool OnScroll(ScrollEvent e) - { - if (HasFocus) - { - if (bindTarget.IsHovered) - { - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta)); - finalise(); - return true; - } - } - - return base.OnScroll(e); - } - - protected override bool OnKeyDown(KeyDownEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - if (!isModifier(e.Key)) finalise(); - - return true; - } - - protected override void OnKeyUp(KeyUpEvent e) - { - if (!HasFocus) - { - base.OnKeyUp(e); - return; - } - - finalise(); - } - - protected override bool OnJoystickPress(JoystickPressEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - finalise(); - - return true; - } - - protected override void OnJoystickRelease(JoystickReleaseEvent e) - { - if (!HasFocus) - { - base.OnJoystickRelease(e); - return; - } - - finalise(); - } - - protected override bool OnMidiDown(MidiDownEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - finalise(); - - return true; - } - - protected override void OnMidiUp(MidiUpEvent e) - { - if (!HasFocus) - { - base.OnMidiUp(e); - return; - } - - finalise(); - } - - private void clear() - { - if (bindTarget == null) - return; - - bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); - } - - private void finalise() - { - if (bindTarget != null) - { - store.Update(bindTarget.KeyBinding); - - updateIsDefaultValue(); - - bindTarget.IsBinding = false; - Schedule(() => - { - // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) - bindTarget = null; - }); - } - - if (HasFocus) - GetContainingInputManager().ChangeFocus(null); - - cancelAndClearButtons.FadeOut(300, Easing.OutQuint); - cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; - } - - private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); - - private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); - - protected override void OnFocus(FocusEvent e) - { - AutoSizeDuration = 500; - AutoSizeEasing = Easing.OutQuint; - - cancelAndClearButtons.FadeIn(300, Easing.OutQuint); - cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; - - updateBindTarget(); - base.OnFocus(e); - } - - protected override void OnFocusLost(FocusLostEvent e) - { - finalise(); - base.OnFocusLost(e); - } - - /// - /// Updates the bind target to the currently hovered key button or the first if clicked anywhere else. - /// - private void updateBindTarget() - { - if (bindTarget != null) bindTarget.IsBinding = false; - bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); - if (bindTarget != null) bindTarget.IsBinding = true; - } - - private class CancelButton : TriangleButton - { - public CancelButton() - { - Text = "Cancel"; - Size = new Vector2(80, 20); - } - } - - public class ClearButton : DangerousTriangleButton - { - public ClearButton() - { - Text = "Clear"; - Size = new Vector2(80, 20); - } - } - - public class KeyButton : Container - { - public readonly Framework.Input.Bindings.KeyBinding KeyBinding; - - private readonly Box box; - public readonly OsuSpriteText Text; - - private Color4 hoverColour; - - private bool isBinding; - - public bool IsBinding - { - get => isBinding; - set - { - if (value == isBinding) return; - - isBinding = value; - - updateHoverState(); - } - } - - public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) - { - KeyBinding = keyBinding; - - Margin = new MarginPadding(padding); - - // todo: use this in a meaningful way - // var isDefault = keyBinding.Action is Enum; - - Masking = true; - CornerRadius = padding; - - Height = height; - AutoSizeAxes = Axes.X; - - Children = new Drawable[] - { - new Container - { - AlwaysPresent = true, - Width = 80, - Height = height, - }, - box = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black - }, - Text = new OsuSpriteText - { - Font = OsuFont.Numeric.With(size: 10), - Margin = new MarginPadding(5), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = keyBinding.KeyCombination.ReadableString(), - }, - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverColour = colours.YellowDark; - } - - protected override bool OnHover(HoverEvent e) - { - updateHoverState(); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - updateHoverState(); - base.OnHoverLost(e); - } - - private void updateHoverState() - { - if (isBinding) - { - box.FadeColour(Color4.White, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - } - else - { - box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); - } - } - - public void UpdateKeyCombination(KeyCombination newCombination) - { - KeyBinding.KeyCombination = newCombination; - Text.Text = KeyBinding.KeyCombination.ReadableString(); - } + restoreDefaultButton.Action = () => { BasicKeyBindingRow.RestoreDefaults(); }; + restoreDefaultButton.Current = BasicKeyBindingRow.IsDefault; } } } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 737c640b5a..b1a5895449 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -38,12 +38,12 @@ namespace osu.Game.Overlays.KeyBinding foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { // one row per valid action. - Add(new RestorableKeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); + Add(new KeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); } Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.BasicKeyBindingRow.RestoreDefaults()) }); } } diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs deleted file mode 100644 index d07fffe6bc..0000000000 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; -using osu.Game.Rulesets; - -namespace osu.Game.Overlays.KeyBinding -{ - public class RestorableKeyBindingRow : Container, IFilterable - { - private readonly object key; - private readonly ICollection bindings; - public readonly KeyBindingRow KeyBindingRow; - - private bool matchingFilter; - - public bool MatchingFilter - { - get => matchingFilter; - set - { - matchingFilter = value; - this.FadeTo(!matchingFilter ? 0 : 1); - } - } - - public bool FilteringActive { get; set; } - - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - - public RestorableKeyBindingRow( - object key, - ICollection bindings, - RulesetInfo ruleset, - IEnumerable defaults) - { - this.key = key; - this.bindings = bindings; - - RestoreDefaultValueButton restoreDefaultButton; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - - KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - }; - - InternalChildren = new Drawable[] - { - restoreDefaultButton = new RestoreDefaultValueButton(), - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = KeyBindingRow - }, - }; - - restoreDefaultButton.Action = () => { KeyBindingRow.RestoreDefaults(); }; - restoreDefaultButton.Current = KeyBindingRow.IsDefault; - } - } -} From ce845a9f8d5748c0ef1ca35edcde6e5469abb076 Mon Sep 17 00:00:00 2001 From: Swords Date: Tue, 25 May 2021 21:00:38 +1000 Subject: [PATCH 23/33] Apply the rest of requested changes --- .../Overlays/KeyBinding/BasicKeyBindingRow.cs | 5 +--- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 30 +++++++------------ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs index acdf273622..91d9aa70bd 100644 --- a/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs @@ -37,10 +37,7 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; - public Bindable IsDefault { get; } = new BindableBool(true) - { - Default = true - }; + public Bindable IsDefault { get; } = new BindableBool(true); public BasicKeyBindingRow(object action, IEnumerable bindings) { diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 3221b66bce..f799b4810f 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -32,41 +32,33 @@ namespace osu.Game.Overlays.KeyBinding public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - public KeyBindingRow( - object key, - ICollection bindings, - RulesetInfo ruleset, - IEnumerable defaults) - { + public KeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) { this.key = key; this.bindings = bindings; - RestoreDefaultValueButton restoreDefaultButton; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - BasicKeyBindingRow = new BasicKeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - }; - InternalChildren = new Drawable[] { - restoreDefaultButton = new RestoreDefaultValueButton(), + new RestoreDefaultValueButton() + { + Current = BasicKeyBindingRow.IsDefault, + Action = () => { BasicKeyBindingRow.RestoreDefaults(); } + }, new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = BasicKeyBindingRow + Child = BasicKeyBindingRow = new BasicKeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaults + } }, }; - - restoreDefaultButton.Action = () => { BasicKeyBindingRow.RestoreDefaults(); }; - restoreDefaultButton.Current = BasicKeyBindingRow.IsDefault; } } } From d9f5b578bf6f81fad7037480cf8ce95ac47eadad Mon Sep 17 00:00:00 2001 From: Swords Date: Tue, 25 May 2021 21:08:40 +1000 Subject: [PATCH 24/33] Restore class names --- .../Settings/TestSceneKeyBindingPanel.cs | 42 +- .../Overlays/KeyBinding/BasicKeyBindingRow.cs | 460 ----------------- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 474 ++++++++++++++++-- .../KeyBinding/KeyBindingsSubsection.cs | 4 +- .../KeyBinding/RestorableKeyBindingRow.cs | 64 +++ 5 files changed, 522 insertions(+), 522 deletions(-) delete mode 100644 osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs create mode 100644 osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index face2a498d..bd3e94dffa 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -31,11 +31,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClickTwiceOnClearButton() { - BasicKeyBindingRow firstRow = null; + KeyBindingRow firstRow = null; AddStep("click first row", () => { - firstRow = panel.ChildrenOfType().First(); + firstRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(firstRow); InputManager.Click(MouseButton.Left); @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Settings AddStep("schedule button clicks", () => { - var clearButton = firstRow.ChildrenOfType().Single(); + var clearButton = firstRow.ChildrenOfType().Single(); InputManager.MoveMouseTo(clearButton); @@ -68,22 +68,22 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestClearButtonOnBindings() { - BasicKeyBindingRow multiBindingRow = null; + KeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); clickClearButton(); - AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().First().Text.Text.ToString())); + AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().First().Text.Text.ToString())); AddStep("click second binding", () => { - var target = multiBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -91,13 +91,13 @@ namespace osu.Game.Tests.Visual.Settings clickClearButton(); - AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().ElementAt(1).Text.Text.ToString())); + AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType().ElementAt(1).Text.Text.ToString())); void clickClearButton() { AddStep("click clear button", () => { - var clearButton = multiBindingRow.ChildrenOfType().Single(); + var clearButton = multiBindingRow.ChildrenOfType().Single(); InputManager.MoveMouseTo(clearButton); InputManager.Click(MouseButton.Left); @@ -108,11 +108,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindingResetButton() { - KeyBindingRow settingsKeyBindingRow = null; + RestorableKeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -131,17 +131,17 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestResetAllBindingsButton() { - KeyBindingRow settingsKeyBindingRow = null; + RestorableKeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -160,26 +160,26 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestClickRowSelectsFirstBinding() { - BasicKeyBindingRow multiBindingRow = null; + KeyBindingRow multiBindingRow = null; AddStep("click first row with two bindings", () => { - multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); + multiBindingRow = panel.ChildrenOfType().First(row => row.Defaults.Count() > 1); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); AddStep("click second binding", () => { - var target = multiBindingRow.ChildrenOfType().ElementAt(1); + var target = multiBindingRow.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(target); InputManager.Click(MouseButton.Left); @@ -187,12 +187,12 @@ namespace osu.Game.Tests.Visual.Settings AddStep("click back binding row", () => { - multiBindingRow = panel.ChildrenOfType().ElementAt(10); + multiBindingRow = panel.ChildrenOfType().ElementAt(10); InputManager.MoveMouseTo(multiBindingRow); InputManager.Click(MouseButton.Left); }); - AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); + AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType().First().IsBinding); } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs deleted file mode 100644 index 91d9aa70bd..0000000000 --- a/osu.Game/Overlays/KeyBinding/BasicKeyBindingRow.cs +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions; -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.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Input; -using osuTK; -using osuTK.Graphics; -using osuTK.Input; - -namespace osu.Game.Overlays.KeyBinding -{ - public class BasicKeyBindingRow : Container - { - private readonly object action; - private readonly IEnumerable bindings; - - private const float transition_time = 150; - - private const float height = 20; - - private const float padding = 5; - - private FillFlowContainer cancelAndClearButtons; - private FillFlowContainer buttons; - - public Bindable IsDefault { get; } = new BindableBool(true); - - public BasicKeyBindingRow(object action, IEnumerable bindings) - { - this.action = action; - this.bindings = bindings; - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - Masking = true; - CornerRadius = padding; - } - - [Resolved] - private KeyBindingStore store { get; set; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - updateIsDefaultValue(); - - EdgeEffect = new EdgeEffectParameters - { - Radius = 2, - Colour = colours.YellowDark.Opacity(0), - Type = EdgeEffectType.Shadow, - Hollow = true, - }; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.6f, - }, - new OsuSpriteText - { - Text = action.GetDescription(), - Margin = new MarginPadding(padding), - }, - buttons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }, - cancelAndClearButtons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding(padding) { Top = height + padding * 2 }, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Alpha = 0, - Spacing = new Vector2(5), - Children = new Drawable[] - { - new CancelButton { Action = finalise }, - new ClearButton { Action = clear }, - }, - } - }; - foreach (var b in bindings) - buttons.Add(new KeyButton(b)); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - IsDefault.BindValueChanged(isDefault => - { - if (isDefault.NewValue) - { - finalise(); - } - }); - } - - public void RestoreDefaults() - { - int i = 0; - - foreach (var d in Defaults) - { - var button = buttons[i++]; - button.UpdateKeyCombination(d); - store.Update(button.KeyBinding); - } - - updateIsDefaultValue(); - } - - protected override bool OnHover(HoverEvent e) - { - FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); - - base.OnHoverLost(e); - } - - public override bool AcceptsFocus => bindTarget == null; - - private KeyButton bindTarget; - - public bool AllowMainMouseButtons; - - public IEnumerable Defaults; - - private bool isModifier(Key k) => k < Key.F1; - - protected override bool OnClick(ClickEvent e) => true; - - protected override bool OnMouseDown(MouseDownEvent e) - { - if (!HasFocus || !bindTarget.IsHovered) - return base.OnMouseDown(e); - - if (!AllowMainMouseButtons) - { - switch (e.Button) - { - case MouseButton.Left: - case MouseButton.Right: - return true; - } - } - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - return true; - } - - protected override void OnMouseUp(MouseUpEvent e) - { - // don't do anything until the last button is released. - if (!HasFocus || e.HasAnyButtonPressed) - { - base.OnMouseUp(e); - return; - } - - if (bindTarget.IsHovered) - finalise(); - // prevent updating bind target before clear button's action - else if (!cancelAndClearButtons.Any(b => b.IsHovered)) - updateBindTarget(); - } - - protected override bool OnScroll(ScrollEvent e) - { - if (HasFocus) - { - if (bindTarget.IsHovered) - { - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta)); - finalise(); - return true; - } - } - - return base.OnScroll(e); - } - - protected override bool OnKeyDown(KeyDownEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - if (!isModifier(e.Key)) finalise(); - - return true; - } - - protected override void OnKeyUp(KeyUpEvent e) - { - if (!HasFocus) - { - base.OnKeyUp(e); - return; - } - - finalise(); - } - - protected override bool OnJoystickPress(JoystickPressEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - finalise(); - - return true; - } - - protected override void OnJoystickRelease(JoystickReleaseEvent e) - { - if (!HasFocus) - { - base.OnJoystickRelease(e); - return; - } - - finalise(); - } - - protected override bool OnMidiDown(MidiDownEvent e) - { - if (!HasFocus) - return false; - - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); - finalise(); - - return true; - } - - protected override void OnMidiUp(MidiUpEvent e) - { - if (!HasFocus) - { - base.OnMidiUp(e); - return; - } - - finalise(); - } - - private void clear() - { - if (bindTarget == null) - return; - - bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); - } - - private void finalise() - { - if (bindTarget != null) - { - store.Update(bindTarget.KeyBinding); - - updateIsDefaultValue(); - - bindTarget.IsBinding = false; - Schedule(() => - { - // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) - bindTarget = null; - }); - } - - if (HasFocus) - GetContainingInputManager().ChangeFocus(null); - - cancelAndClearButtons.FadeOut(300, Easing.OutQuint); - cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; - } - - private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); - - private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); - - protected override void OnFocus(FocusEvent e) - { - AutoSizeDuration = 500; - AutoSizeEasing = Easing.OutQuint; - - cancelAndClearButtons.FadeIn(300, Easing.OutQuint); - cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; - - updateBindTarget(); - base.OnFocus(e); - } - - protected override void OnFocusLost(FocusLostEvent e) - { - finalise(); - base.OnFocusLost(e); - } - - /// - /// Updates the bind target to the currently hovered key button or the first if clicked anywhere else. - /// - private void updateBindTarget() - { - if (bindTarget != null) bindTarget.IsBinding = false; - bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); - if (bindTarget != null) bindTarget.IsBinding = true; - } - - private class CancelButton : TriangleButton - { - public CancelButton() - { - Text = "Cancel"; - Size = new Vector2(80, 20); - } - } - - public class ClearButton : DangerousTriangleButton - { - public ClearButton() - { - Text = "Clear"; - Size = new Vector2(80, 20); - } - } - - public class KeyButton : Container - { - public readonly Framework.Input.Bindings.KeyBinding KeyBinding; - - private readonly Box box; - public readonly OsuSpriteText Text; - - private Color4 hoverColour; - - private bool isBinding; - - public bool IsBinding - { - get => isBinding; - set - { - if (value == isBinding) return; - - isBinding = value; - - updateHoverState(); - } - } - - public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) - { - KeyBinding = keyBinding; - - Margin = new MarginPadding(padding); - - // todo: use this in a meaningful way - // var isDefault = keyBinding.Action is Enum; - - Masking = true; - CornerRadius = padding; - - Height = height; - AutoSizeAxes = Axes.X; - - Children = new Drawable[] - { - new Container - { - AlwaysPresent = true, - Width = 80, - Height = height, - }, - box = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black - }, - Text = new OsuSpriteText - { - Font = OsuFont.Numeric.With(size: 10), - Margin = new MarginPadding(5), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = keyBinding.KeyCombination.ReadableString(), - }, - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverColour = colours.YellowDark; - } - - protected override bool OnHover(HoverEvent e) - { - updateHoverState(); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - updateHoverState(); - base.OnHoverLost(e); - } - - private void updateHoverState() - { - if (isBinding) - { - box.FadeColour(Color4.White, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - } - else - { - box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); - } - } - - public void UpdateKeyCombination(KeyCombination newCombination) - { - KeyBinding.KeyCombination = newCombination; - Text.Text = KeyBinding.KeyCombination.ReadableString(); - } - } - } -} diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index f799b4810f..216eabcf67 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -1,64 +1,460 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions; +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.Input.Bindings; -using osu.Game.Rulesets; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Input; +using osuTK; +using osuTK.Graphics; +using osuTK.Input; namespace osu.Game.Overlays.KeyBinding { - public class KeyBindingRow : Container, IFilterable + public class KeyBindingRow : Container { - private readonly object key; - private readonly ICollection bindings; - public readonly BasicKeyBindingRow BasicKeyBindingRow; + private readonly object action; + private readonly IEnumerable bindings; - private bool matchingFilter; + private const float transition_time = 150; - public bool MatchingFilter + private const float height = 20; + + private const float padding = 5; + + private FillFlowContainer cancelAndClearButtons; + private FillFlowContainer buttons; + + public Bindable IsDefault { get; } = new BindableBool(true); + + public KeyBindingRow(object action, IEnumerable bindings) { - get => matchingFilter; - set + this.action = action; + this.bindings = bindings; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Masking = true; + CornerRadius = padding; + } + + [Resolved] + private KeyBindingStore store { get; set; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + updateIsDefaultValue(); + + EdgeEffect = new EdgeEffectParameters { - matchingFilter = value; - this.FadeTo(!matchingFilter ? 0 : 1); + Radius = 2, + Colour = colours.YellowDark.Opacity(0), + Type = EdgeEffectType.Shadow, + Hollow = true, + }; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.6f, + }, + new OsuSpriteText + { + Text = action.GetDescription(), + Margin = new MarginPadding(padding), + }, + buttons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }, + cancelAndClearButtons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding(padding) { Top = height + padding * 2 }, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Alpha = 0, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new CancelButton { Action = finalise }, + new ClearButton { Action = clear }, + }, + } + }; + foreach (var b in bindings) + buttons.Add(new KeyButton(b)); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + IsDefault.BindValueChanged(isDefault => + { + if (isDefault.NewValue) + { + finalise(); + } + }); + } + + public void RestoreDefaults() + { + int i = 0; + + foreach (var d in Defaults) + { + var button = buttons[i++]; + button.UpdateKeyCombination(d); + store.Update(button.KeyBinding); + } + + updateIsDefaultValue(); + } + + protected override bool OnHover(HoverEvent e) + { + FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + + base.OnHoverLost(e); + } + + public override bool AcceptsFocus => bindTarget == null; + + private KeyButton bindTarget; + + public bool AllowMainMouseButtons; + + public IEnumerable Defaults; + + private bool isModifier(Key k) => k < Key.F1; + + protected override bool OnClick(ClickEvent e) => true; + + protected override bool OnMouseDown(MouseDownEvent e) + { + if (!HasFocus || !bindTarget.IsHovered) + return base.OnMouseDown(e); + + if (!AllowMainMouseButtons) + { + switch (e.Button) + { + case MouseButton.Left: + case MouseButton.Right: + return true; + } + } + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + return true; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + // don't do anything until the last button is released. + if (!HasFocus || e.HasAnyButtonPressed) + { + base.OnMouseUp(e); + return; + } + + if (bindTarget.IsHovered) + finalise(); + // prevent updating bind target before clear button's action + else if (!cancelAndClearButtons.Any(b => b.IsHovered)) + updateBindTarget(); + } + + protected override bool OnScroll(ScrollEvent e) + { + if (HasFocus) + { + if (bindTarget.IsHovered) + { + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta)); + finalise(); + return true; + } + } + + return base.OnScroll(e); + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + if (!isModifier(e.Key)) finalise(); + + return true; + } + + protected override void OnKeyUp(KeyUpEvent e) + { + if (!HasFocus) + { + base.OnKeyUp(e); + return; + } + + finalise(); + } + + protected override bool OnJoystickPress(JoystickPressEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + finalise(); + + return true; + } + + protected override void OnJoystickRelease(JoystickReleaseEvent e) + { + if (!HasFocus) + { + base.OnJoystickRelease(e); + return; + } + + finalise(); + } + + protected override bool OnMidiDown(MidiDownEvent e) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + finalise(); + + return true; + } + + protected override void OnMidiUp(MidiUpEvent e) + { + if (!HasFocus) + { + base.OnMidiUp(e); + return; + } + + finalise(); + } + + private void clear() + { + if (bindTarget == null) + return; + + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + } + + private void finalise() + { + if (bindTarget != null) + { + store.Update(bindTarget.KeyBinding); + + updateIsDefaultValue(); + + bindTarget.IsBinding = false; + Schedule(() => + { + // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) + bindTarget = null; + }); + } + + if (HasFocus) + GetContainingInputManager().ChangeFocus(null); + + cancelAndClearButtons.FadeOut(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; + } + + private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); + + private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + + protected override void OnFocus(FocusEvent e) + { + AutoSizeDuration = 500; + AutoSizeEasing = Easing.OutQuint; + + cancelAndClearButtons.FadeIn(300, Easing.OutQuint); + cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; + + updateBindTarget(); + base.OnFocus(e); + } + + protected override void OnFocusLost(FocusLostEvent e) + { + finalise(); + base.OnFocusLost(e); + } + + /// + /// Updates the bind target to the currently hovered key button or the first if clicked anywhere else. + /// + private void updateBindTarget() + { + if (bindTarget != null) bindTarget.IsBinding = false; + bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); + if (bindTarget != null) bindTarget.IsBinding = true; + } + + private class CancelButton : TriangleButton + { + public CancelButton() + { + Text = "Cancel"; + Size = new Vector2(80, 20); } } - public bool FilteringActive { get; set; } - - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - - public KeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) { - this.key = key; - this.bindings = bindings; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - - InternalChildren = new Drawable[] + public class ClearButton : DangerousTriangleButton + { + public ClearButton() { - new RestoreDefaultValueButton() + Text = "Clear"; + Size = new Vector2(80, 20); + } + } + + public class KeyButton : Container + { + public readonly Framework.Input.Bindings.KeyBinding KeyBinding; + + private readonly Box box; + public readonly OsuSpriteText Text; + + private Color4 hoverColour; + + private bool isBinding; + + public bool IsBinding + { + get => isBinding; + set { - Current = BasicKeyBindingRow.IsDefault, - Action = () => { BasicKeyBindingRow.RestoreDefaults(); } - }, - new FillFlowContainer + if (value == isBinding) return; + + isBinding = value; + + updateHoverState(); + } + } + + public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) + { + KeyBinding = keyBinding; + + Margin = new MarginPadding(padding); + + // todo: use this in a meaningful way + // var isDefault = keyBinding.Action is Enum; + + Masking = true; + CornerRadius = padding; + + Height = height; + AutoSizeAxes = Axes.X; + + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = BasicKeyBindingRow = new BasicKeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + new Container { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - } - }, - }; + AlwaysPresent = true, + Width = 80, + Height = height, + }, + box = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + Text = new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 10), + Margin = new MarginPadding(5), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = keyBinding.KeyCombination.ReadableString(), + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverColour = colours.YellowDark; + } + + protected override bool OnHover(HoverEvent e) + { + updateHoverState(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateHoverState(); + base.OnHoverLost(e); + } + + private void updateHoverState() + { + if (isBinding) + { + box.FadeColour(Color4.White, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + } + else + { + box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); + } + } + + public void UpdateKeyCombination(KeyCombination newCombination) + { + KeyBinding.KeyCombination = newCombination; + Text.Text = KeyBinding.KeyCombination.ReadableString(); + } } } } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index b1a5895449..fc370bd87e 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -38,12 +38,12 @@ namespace osu.Game.Overlays.KeyBinding foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { // one row per valid action. - Add(new KeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); + Add(new RestorableKeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); } Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.BasicKeyBindingRow.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.BasicKeyBindingRow.RestoreDefaults()) }); } } diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs new file mode 100644 index 0000000000..9bfdda727c --- /dev/null +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Bindings; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.KeyBinding +{ + public class RestorableKeyBindingRow : Container, IFilterable + { + private readonly object key; + private readonly ICollection bindings; + public readonly KeyBindingRow BasicKeyBindingRow; + + private bool matchingFilter; + + public bool MatchingFilter + { + get => matchingFilter; + set + { + matchingFilter = value; + this.FadeTo(!matchingFilter ? 0 : 1); + } + } + + public bool FilteringActive { get; set; } + + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); + + public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) { + this.key = key; + this.bindings = bindings; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; + + InternalChildren = new Drawable[] + { + new RestoreDefaultValueButton() + { + Current = BasicKeyBindingRow.IsDefault, + Action = () => { BasicKeyBindingRow.RestoreDefaults(); } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, + Child = BasicKeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaults + } + }, + }; + } + } +} From d5feb8353d874c00f73b2d79623e47e3457871a4 Mon Sep 17 00:00:00 2001 From: Swords Date: Tue, 25 May 2021 21:37:08 +1000 Subject: [PATCH 25/33] Formatting, renaming --- .../Visual/Settings/TestSceneKeyBindingPanel.cs | 4 ++-- osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs | 2 +- .../Overlays/KeyBinding/RestorableKeyBindingRow.cs | 11 ++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index bd3e94dffa..3edba2ddd7 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -131,7 +131,7 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); } [Test] @@ -160,7 +160,7 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.BasicKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); } [Test] diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index fc370bd87e..737c640b5a 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.KeyBinding Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.BasicKeyBindingRow.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) }); } } diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 9bfdda727c..2981c77e15 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.KeyBinding { private readonly object key; private readonly ICollection bindings; - public readonly KeyBindingRow BasicKeyBindingRow; + public readonly KeyBindingRow KeyBindingRow; private bool matchingFilter; @@ -32,7 +32,8 @@ namespace osu.Game.Overlays.KeyBinding public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) { + public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) + { this.key = key; this.bindings = bindings; @@ -44,15 +45,15 @@ namespace osu.Game.Overlays.KeyBinding { new RestoreDefaultValueButton() { - Current = BasicKeyBindingRow.IsDefault, - Action = () => { BasicKeyBindingRow.RestoreDefaults(); } + Current = KeyBindingRow.IsDefault, + Action = () => { KeyBindingRow.RestoreDefaults(); } }, new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = BasicKeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + Child = KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) { AllowMainMouseButtons = ruleset != null, Defaults = defaults From 9c2dca8229b5b956f1715bc67acc5cf42b7460c5 Mon Sep 17 00:00:00 2001 From: Swords Date: Tue, 25 May 2021 21:53:00 +1000 Subject: [PATCH 26/33] Removing redundant argument list --- osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 2981c77e15..62a56ab055 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.KeyBinding InternalChildren = new Drawable[] { - new RestoreDefaultValueButton() + new RestoreDefaultValueButton { Current = KeyBindingRow.IsDefault, Action = () => { KeyBindingRow.RestoreDefaults(); } From 07a24d2747acc4e38d5a88ca67b290617b76de19 Mon Sep 17 00:00:00 2001 From: Swords Date: Tue, 25 May 2021 23:54:13 +1000 Subject: [PATCH 27/33] Fixing errors --- .../Overlays/KeyBinding/RestorableKeyBindingRow.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 62a56ab055..09b2efd7fa 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -41,6 +41,12 @@ namespace osu.Game.Overlays.KeyBinding AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; + KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaults + }; + InternalChildren = new Drawable[] { new RestoreDefaultValueButton @@ -53,11 +59,7 @@ namespace osu.Game.Overlays.KeyBinding RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - } + Child = KeyBindingRow }, }; } From f8a3a3779721ec862d6e920aa5ede5f57ff90f11 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 May 2021 17:34:17 +0900 Subject: [PATCH 28/33] Remove outdated comment --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 546049ea9b..5a2a9baf44 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -386,9 +386,6 @@ namespace osu.Game.Overlays.KeyBinding Margin = new MarginPadding(padding); - // todo: use this in a meaningful way - // var isDefault = keyBinding.Action is Enum; - Masking = true; CornerRadius = padding; From 49b4a6ea67babd011e9f815b04d2ac60884c5c3d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 May 2021 17:07:24 +0900 Subject: [PATCH 29/33] Replace local namespace qualifiers with `using` --- osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 09b2efd7fa..70b4fabd6d 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; using osu.Game.Rulesets; namespace osu.Game.Overlays.KeyBinding @@ -13,7 +14,7 @@ namespace osu.Game.Overlays.KeyBinding public class RestorableKeyBindingRow : Container, IFilterable { private readonly object key; - private readonly ICollection bindings; + private readonly ICollection bindings; public readonly KeyBindingRow KeyBindingRow; private bool matchingFilter; @@ -32,7 +33,7 @@ namespace osu.Game.Overlays.KeyBinding public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) + public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) { this.key = key; this.bindings = bindings; From 17334fd2e6b3ee4280ca5ebcbe0b70a7bb04fd22 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 May 2021 17:12:12 +0900 Subject: [PATCH 30/33] Inline `KeyBindingRow` construction --- .../Overlays/KeyBinding/RestorableKeyBindingRow.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs index 70b4fabd6d..5d1dc6a4d1 100644 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs @@ -42,12 +42,6 @@ namespace osu.Game.Overlays.KeyBinding AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - }; - InternalChildren = new Drawable[] { new RestoreDefaultValueButton @@ -60,7 +54,11 @@ namespace osu.Game.Overlays.KeyBinding RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = KeyBindingRow + Child = KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) + { + AllowMainMouseButtons = ruleset != null, + Defaults = defaults + } }, }; } From 02806fedb06b7c90ac6e32217fe7d41e783ad59f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 May 2021 17:17:02 +0900 Subject: [PATCH 31/33] Add missing newline --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 5a2a9baf44..e8f6a4d065 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -101,6 +101,7 @@ namespace osu.Game.Overlays.KeyBinding }, } }; + foreach (var b in bindings) buttons.Add(new KeyButton(b)); } From 7c9383b586ad2ab0cf73e22c3b3505957f26f0cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 May 2021 18:03:15 +0900 Subject: [PATCH 32/33] Combine `RestorableKeyBindingRow` back into `KeyBindingRow` --- .../Settings/TestSceneKeyBindingPanel.cs | 14 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 132 ++++++++++++------ .../KeyBinding/KeyBindingsSubsection.cs | 10 +- .../KeyBinding/RestorableKeyBindingRow.cs | 66 --------- .../Overlays/RestoreDefaultValueButton.cs | 3 + 5 files changed, 104 insertions(+), 121 deletions(-) delete mode 100644 osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 4d0321b29d..acf9deb3cb 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -142,11 +142,11 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestSingleBindingResetButton() { - RestorableKeyBindingRow settingsKeyBindingRow = null; + KeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -165,17 +165,17 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); } [Test] public void TestResetAllBindingsButton() { - RestorableKeyBindingRow settingsKeyBindingRow = null; + KeyBindingRow settingsKeyBindingRow = null; AddStep("click first row", () => { - settingsKeyBindingRow = panel.ChildrenOfType().First(); + settingsKeyBindingRow = panel.ChildrenOfType().First(); InputManager.MoveMouseTo(settingsKeyBindingRow); InputManager.Click(MouseButton.Left); @@ -194,7 +194,7 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.KeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); } [Test] @@ -261,4 +261,4 @@ namespace osu.Game.Tests.Visual.Settings }); } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index e8f6a4d065..c9ed64cc3f 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Overlays.KeyBinding { - public class KeyBindingRow : Container + public class KeyBindingRow : Container, IFilterable { private readonly object action; private readonly IEnumerable bindings; @@ -35,20 +35,40 @@ namespace osu.Game.Overlays.KeyBinding private const float padding = 5; + private bool matchingFilter; + + public bool MatchingFilter + { + get => matchingFilter; + set + { + matchingFilter = value; + this.FadeTo(!matchingFilter ? 0 : 1); + } + } + + private Container content; + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + content.ReceivePositionalInputAt(screenSpacePos); + + public bool FilteringActive { get; set; } + + private OsuSpriteText text; private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; public Bindable IsDefault { get; } = new BindableBool(true); + public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString()); + public KeyBindingRow(object action, IEnumerable bindings) { this.action = action; this.bindings = bindings; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - - Masking = true; - CornerRadius = padding; } [Resolved] @@ -59,46 +79,65 @@ namespace osu.Game.Overlays.KeyBinding { updateIsDefaultValue(); - EdgeEffect = new EdgeEffectParameters - { - Radius = 2, - Colour = colours.YellowDark.Opacity(0), - Type = EdgeEffectType.Shadow, - Hollow = true, - }; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Horizontal = SettingsPanel.CONTENT_MARGINS }; - Children = new Drawable[] + InternalChildren = new Drawable[] { - new Box + new RestoreDefaultValueButton { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.6f, - }, - new OsuSpriteText - { - Text = action.GetDescription(), - Margin = new MarginPadding(padding), - }, - buttons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }, - cancelAndClearButtons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding(padding) { Top = height + padding * 2 }, - Anchor = Anchor.TopRight, + Current = IsDefault, + Action = RestoreDefaults, Origin = Anchor.TopRight, - Alpha = 0, - Spacing = new Vector2(5), + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Masking = true, + CornerRadius = padding, + EdgeEffect = new EdgeEffectParameters + { + Radius = 2, + Colour = colours.YellowDark.Opacity(0), + Type = EdgeEffectType.Shadow, + Hollow = true, + }, Children = new Drawable[] { - new CancelButton { Action = finalise }, - new ClearButton { Action = clear }, - }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.6f, + }, + text = new OsuSpriteText + { + Text = action.GetDescription(), + Margin = new MarginPadding(padding), + }, + buttons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }, + cancelAndClearButtons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding(padding) { Top = height + padding * 2 }, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Alpha = 0, + Spacing = new Vector2(5), + Children = new Drawable[] + { + new CancelButton { Action = finalise }, + new ClearButton { Action = clear }, + }, + } + } } }; @@ -135,14 +174,14 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnHover(HoverEvent e) { - FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + content.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + content.FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); base.OnHoverLost(e); } @@ -307,14 +346,10 @@ namespace osu.Game.Overlays.KeyBinding cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y; } - private void updateIsDefaultValue() => IsDefault.Value = computeIsDefaultValue(); - - private bool computeIsDefaultValue() => bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); - protected override void OnFocus(FocusEvent e) { - AutoSizeDuration = 500; - AutoSizeEasing = Easing.OutQuint; + content.AutoSizeDuration = 500; + content.AutoSizeEasing = Easing.OutQuint; cancelAndClearButtons.FadeIn(300, Easing.OutQuint); cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y; @@ -339,6 +374,11 @@ namespace osu.Game.Overlays.KeyBinding if (bindTarget != null) bindTarget.IsBinding = true; } + private void updateIsDefaultValue() + { + IsDefault.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + } + private class CancelButton : TriangleButton { public CancelButton() diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 737c640b5a..5e1f9d8f75 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -37,13 +37,19 @@ namespace osu.Game.Overlays.KeyBinding foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { + int intKey = (int)defaultGroup.Key; + // one row per valid action. - Add(new RestorableKeyBindingRow(defaultGroup.Key, bindings, Ruleset, defaultGroup.Select(d => d.KeyCombination))); + Add(new KeyBindingRow(defaultGroup.Key, bindings.Where(b => ((int)b.Action).Equals(intKey))) + { + AllowMainMouseButtons = Ruleset != null, + Defaults = defaultGroup.Select(d => d.KeyCombination) + }); } Add(new ResetButton { - Action = () => Children.OfType().ForEach(k => k.KeyBindingRow.RestoreDefaults()) + Action = () => Children.OfType().ForEach(k => k.RestoreDefaults()) }); } } diff --git a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs deleted file mode 100644 index 5d1dc6a4d1..0000000000 --- a/osu.Game/Overlays/KeyBinding/RestorableKeyBindingRow.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; -using osu.Game.Rulesets; - -namespace osu.Game.Overlays.KeyBinding -{ - public class RestorableKeyBindingRow : Container, IFilterable - { - private readonly object key; - private readonly ICollection bindings; - public readonly KeyBindingRow KeyBindingRow; - - private bool matchingFilter; - - public bool MatchingFilter - { - get => matchingFilter; - set - { - matchingFilter = value; - this.FadeTo(!matchingFilter ? 0 : 1); - } - } - - public bool FilteringActive { get; set; } - - public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(key.ToString()); - - public RestorableKeyBindingRow(object key, ICollection bindings, RulesetInfo ruleset, IEnumerable defaults) - { - this.key = key; - this.bindings = bindings; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS }; - - InternalChildren = new Drawable[] - { - new RestoreDefaultValueButton - { - Current = KeyBindingRow.IsDefault, - Action = () => { KeyBindingRow.RestoreDefaults(); } - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS }, - Child = KeyBindingRow = new KeyBindingRow(key, bindings.Where(b => ((int)b.Action).Equals((int)key))) - { - AllowMainMouseButtons = ruleset != null, - Defaults = defaults - } - }, - }; - } - } -} diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 0fe7b7322f..213ad2ba68 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -21,6 +21,9 @@ namespace osu.Game.Overlays private readonly BindableWithCurrent current = new BindableWithCurrent(); + // this is done to ensure a click on this button doesn't trigger focus on a parent element which contains the button. + public override bool AcceptsFocus => true; + public Bindable Current { get => current.Current; From c05dfee22042f0ccdf305e9474b7b3d0b18de9ec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 May 2021 18:28:00 +0900 Subject: [PATCH 33/33] Simplify default handling flow --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index c9ed64cc3f..0df3359c28 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer cancelAndClearButtons; private FillFlowContainer buttons; - public Bindable IsDefault { get; } = new BindableBool(true); + private Bindable isDefault { get; } = new BindableBool(true); public IEnumerable FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString()); @@ -77,8 +77,6 @@ namespace osu.Game.Overlays.KeyBinding [BackgroundDependencyLoader] private void load(OsuColour colours) { - updateIsDefaultValue(); - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Padding = new MarginPadding { Horizontal = SettingsPanel.CONTENT_MARGINS }; @@ -87,7 +85,7 @@ namespace osu.Game.Overlays.KeyBinding { new RestoreDefaultValueButton { - Current = IsDefault, + Current = isDefault, Action = RestoreDefaults, Origin = Anchor.TopRight, }, @@ -143,19 +141,8 @@ namespace osu.Game.Overlays.KeyBinding foreach (var b in bindings) buttons.Add(new KeyButton(b)); - } - protected override void LoadComplete() - { - base.LoadComplete(); - - IsDefault.BindValueChanged(isDefault => - { - if (isDefault.NewValue) - { - finalise(); - } - }); + updateIsDefaultValue(); } public void RestoreDefaults() @@ -169,7 +156,7 @@ namespace osu.Game.Overlays.KeyBinding store.Update(button.KeyBinding); } - updateIsDefaultValue(); + isDefault.Value = true; } protected override bool OnHover(HoverEvent e) @@ -376,7 +363,7 @@ namespace osu.Game.Overlays.KeyBinding private void updateIsDefaultValue() { - IsDefault.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); + isDefault.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); } private class CancelButton : TriangleButton