From 66fa84a451e0b3afdbfd95fc0e1d87448cefe6be Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Aug 2017 22:21:22 +0900 Subject: [PATCH 01/34] Make settings more modular --- .../Visual/TestCaseKeyConfiguration.cs | 44 +++++++++++++++++++ osu.Desktop.Tests/Visual/TestCaseSettings.cs | 2 +- osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/MainSettings.cs | 29 ++++++++++++ osu.Game/Overlays/Settings/SettingsHeader.cs | 13 +++++- osu.Game/Overlays/SettingsOverlay.cs | 30 ++++++------- osu.Game/osu.Game.csproj | 1 + 8 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs create mode 100644 osu.Game/Overlays/MainSettings.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs new file mode 100644 index 0000000000..10a15d0a96 --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Overlays; +using osu.Game.Overlays.Settings; +using System.Collections.Generic; +using osu.Game.Graphics; + +namespace osu.Desktop.Tests.Visual +{ + public class TestCaseKeyConfiguration : OsuTestCase + { + private readonly KeyConfiguration configuration; + + public override string Description => @"Key configuration"; + + public TestCaseKeyConfiguration() + { + Child = configuration = new KeyConfiguration(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + configuration.Show(); + } + } + + public class KeyConfiguration : SettingsOverlay + { + protected override IEnumerable CreateSections() => new[] + { + new BindingsSection(), + new BindingsSection() + }; + } + + public class BindingsSection : SettingsSection + { + public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; + public override string Header => "Header"; + } +} diff --git a/osu.Desktop.Tests/Visual/TestCaseSettings.cs b/osu.Desktop.Tests/Visual/TestCaseSettings.cs index 7b35009aef..1f4b88e9e3 100644 --- a/osu.Desktop.Tests/Visual/TestCaseSettings.cs +++ b/osu.Desktop.Tests/Visual/TestCaseSettings.cs @@ -13,7 +13,7 @@ namespace osu.Desktop.Tests.Visual public TestCaseSettings() { - Children = new[] { settings = new SettingsOverlay() }; + Children = new[] { settings = new MainSettings() }; } protected override void LoadComplete() diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 3111088ff6..24d112a45c 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -81,6 +81,7 @@ + diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f54fba4a0b..0d1e8396e4 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -182,7 +182,7 @@ namespace osu.Game LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add); LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add); LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add); - LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add); + LoadComponentAsync(settings = new MainSettings { Depth = -1 }, overlayContent.Add); LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add); LoadComponentAsync(musicController = new MusicController { diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs new file mode 100644 index 0000000000..86a1262a11 --- /dev/null +++ b/osu.Game/Overlays/MainSettings.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Overlays.Settings; +using osu.Game.Overlays.Settings.Sections; + +namespace osu.Game.Overlays +{ + public class MainSettings : SettingsOverlay + { + protected override IEnumerable CreateSections() => new SettingsSection[] + { + new GeneralSection(), + new GraphicsSection(), + new GameplaySection(), + new AudioSection(), + new SkinSection(), + new InputSection(), + new OnlineSection(), + new MaintenanceSection(), + new DebugSection(), + }; + + protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves"); + protected override Drawable CreateFooter() => new SettingsFooter(); + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/SettingsHeader.cs b/osu.Game/Overlays/Settings/SettingsHeader.cs index c554b54a87..80d60b6e5d 100644 --- a/osu.Game/Overlays/Settings/SettingsHeader.cs +++ b/osu.Game/Overlays/Settings/SettingsHeader.cs @@ -11,6 +11,15 @@ namespace osu.Game.Overlays.Settings { public class SettingsHeader : Container { + private readonly string heading; + private readonly string subheading; + + public SettingsHeader(string heading, string subheading) + { + this.heading = heading; + this.subheading = subheading; + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -28,7 +37,7 @@ namespace osu.Game.Overlays.Settings { new OsuSpriteText { - Text = "settings", + Text = heading, TextSize = 40, Margin = new MarginPadding { @@ -39,7 +48,7 @@ namespace osu.Game.Overlays.Settings new OsuSpriteText { Colour = colours.Pink, - Text = "Change the way osu! behaves", + Text = subheading, TextSize = 18, Margin = new MarginPadding { diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 1dcabbfa15..c4971fd4ac 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -12,11 +13,10 @@ using osu.Framework.Input; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; -using osu.Game.Overlays.Settings.Sections; namespace osu.Game.Overlays { - public class SettingsOverlay : OsuFocusedOverlayContainer + public abstract class SettingsOverlay : OsuFocusedOverlayContainer { internal const float CONTENT_MARGINS = 10; @@ -38,27 +38,19 @@ namespace osu.Game.Overlays private Func getToolbarHeight; - public SettingsOverlay() + protected SettingsOverlay() { RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; } + protected abstract IEnumerable CreateSections(); + [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuGame game) { - var sections = new SettingsSection[] - { - new GeneralSection(), - new GraphicsSection(), - new GameplaySection(), - new AudioSection(), - new SkinSection(), - new InputSection(), - new OnlineSection(), - new MaintenanceSection(), - new DebugSection(), - }; + var sections = CreateSections().ToList(); + Children = new Drawable[] { new Box @@ -72,7 +64,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Y, Width = width, Margin = new MarginPadding { Left = SIDEBAR_WIDTH }, - ExpandableHeader = new SettingsHeader(), + ExpandableHeader = CreateHeader(), FixedHeader = searchTextBox = new SearchTextBox { RelativeSizeAxes = Axes.X, @@ -87,7 +79,7 @@ namespace osu.Game.Overlays Exit = Hide, }, Children = sections, - Footer = new SettingsFooter() + Footer = CreateFooter() }, sidebar = new Sidebar { @@ -121,6 +113,10 @@ namespace osu.Game.Overlays getToolbarHeight = () => game?.ToolbarOffset ?? 0; } + protected virtual Drawable CreateHeader() => new Container(); + + protected virtual Drawable CreateFooter() => new Container(); + protected override void PopIn() { base.PopIn(); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7690a56378..13c4938850 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -102,6 +102,7 @@ + From dccefe1c0e1c926bdf424a8b2eef5ebe62813250 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Aug 2017 14:40:48 +0900 Subject: [PATCH 02/34] Make the settings sidebar optional Also removes an unnecessary secondary list of SidebarButtons by using generic containers. --- osu.Game/Overlays/MainSettings.cs | 4 + osu.Game/Overlays/Settings/SettingsSection.cs | 52 ++++++------ osu.Game/Overlays/Settings/Sidebar.cs | 8 +- osu.Game/Overlays/SettingsOverlay.cs | 79 +++++++++++-------- 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index 86a1262a11..44c4d4ccdb 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -25,5 +25,9 @@ namespace osu.Game.Overlays protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves"); protected override Drawable CreateFooter() => new SettingsFooter(); + + public MainSettings() : base(true) + { + } } } \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index 68ebde6b28..f091192d27 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using System.Collections.Generic; @@ -25,25 +24,38 @@ namespace osu.Game.Overlays.Settings public IEnumerable FilterableChildren => Children.OfType(); public string[] FilterTerms => new[] { Header }; + + private const int header_size = 26; + private const int header_margin = 25; + private const int border_size = 2; + public bool MatchingFilter { - set - { - this.FadeTo(value ? 1 : 0); - } + set { this.FadeTo(value ? 1 : 0); } } - private readonly SpriteText headerLabel; - protected SettingsSection() { Margin = new MarginPadding { Top = 20 }; AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - const int header_size = 26; - const int header_margin = 25; - const int border_size = 2; + FlowContent = new FillFlowContainer + { + Margin = new MarginPadding + { + Top = header_size + header_margin + }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 30), + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { AddRangeInternal(new Drawable[] { new Box @@ -65,28 +77,16 @@ namespace osu.Game.Overlays.Settings AutoSizeAxes = Axes.Y, Children = new[] { - headerLabel = new OsuSpriteText + new OsuSpriteText { TextSize = header_size, Text = Header, + Colour = colours.Yellow }, - FlowContent = new FillFlowContainer - { - Margin = new MarginPadding { Top = header_size + header_margin }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 30), - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - }, + FlowContent } }, }); } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - headerLabel.Colour = colours.Yellow; - } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 6eafc65d12..706e7ecc25 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -14,12 +14,12 @@ using osu.Game.Overlays.Toolbar; namespace osu.Game.Overlays.Settings { - public class Sidebar : Container, IStateful + public class Sidebar : Container, IStateful { - private readonly FillFlowContainer content; + private readonly FillFlowContainer content; internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH; internal const int EXPANDED_WIDTH = 200; - protected override Container Content => content; + protected override Container Content => content; public Sidebar() { @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Settings { Children = new[] { - content = new FillFlowContainer + content = new FillFlowContainer { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index c4971fd4ac..dfbcedd479 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -29,7 +30,6 @@ namespace osu.Game.Overlays private const float sidebar_padding = 10; private Sidebar sidebar; - private SidebarButton[] sidebarButtons; private SidebarButton selectedSidebarButton; private SettingsSectionsContainer sectionsContainer; @@ -38,19 +38,20 @@ namespace osu.Game.Overlays private Func getToolbarHeight; - protected SettingsOverlay() + private readonly bool showSidebar; + + protected SettingsOverlay(bool showSidebar) { + this.showSidebar = showSidebar; RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; } - protected abstract IEnumerable CreateSections(); + protected virtual IEnumerable CreateSections() => null; [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuGame game) { - var sections = CreateSections().ToList(); - Children = new Drawable[] { new Box @@ -78,39 +79,53 @@ namespace osu.Game.Overlays }, Exit = Hide, }, - Children = sections, Footer = CreateFooter() - }, - sidebar = new Sidebar - { - Width = SIDEBAR_WIDTH, - Children = sidebarButtons = sections.Select(section => - new SidebarButton - { - Section = section, - Action = s => - { - sectionsContainer.ScrollTo(s); - sidebar.State = ExpandedState.Contracted; - }, - } - ).ToArray() } }; - selectedSidebarButton = sidebarButtons[0]; - selectedSidebarButton.Selected = true; - - sectionsContainer.SelectedSection.ValueChanged += section => + if (showSidebar) { - selectedSidebarButton.Selected = false; - selectedSidebarButton = sidebarButtons.Single(b => b.Section == section); - selectedSidebarButton.Selected = true; - }; + Add(sidebar = new Sidebar { Width = SIDEBAR_WIDTH }); + + sectionsContainer.SelectedSection.ValueChanged += section => + { + selectedSidebarButton.Selected = false; + selectedSidebarButton = sidebar.Children.Single(b => b.Section == section); + selectedSidebarButton.Selected = true; + }; + } searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue; getToolbarHeight = () => game?.ToolbarOffset ?? 0; + + CreateSections()?.ForEach(AddSection); + } + + protected void AddSection(SettingsSection section) + { + sectionsContainer.Add(section); + + if (sidebar != null) + { + var button = new SidebarButton + { + Section = section, + Action = s => + { + sectionsContainer.ScrollTo(s); + sidebar.State = ExpandedState.Contracted; + }, + }; + + sidebar.Add(button); + + if (selectedSidebarButton == null) + { + selectedSidebarButton = sidebar.Children.First(); + selectedSidebarButton.Selected = true; + } + } } protected virtual Drawable CreateHeader() => new Container(); @@ -122,7 +137,7 @@ namespace osu.Game.Overlays base.PopIn(); sectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); - sidebar.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); + sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH / 2); searchTextBox.HoldFocus = true; @@ -133,7 +148,7 @@ namespace osu.Game.Overlays base.PopOut(); sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint); - sidebar.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint); + sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(0, TRANSITION_LENGTH / 2); searchTextBox.HoldFocus = false; @@ -155,7 +170,7 @@ namespace osu.Game.Overlays { base.UpdateAfterChildren(); - sectionsContainer.Margin = new MarginPadding { Left = sidebar.DrawWidth }; + sectionsContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 }; sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() }; } From 7c9d6c9c83a4f070d205527cc5d0bb852a030862 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Aug 2017 20:19:25 +0900 Subject: [PATCH 03/34] Initial refactoring of key binding logic --- osu.Game.Rulesets.Catch/CatchInputManager.cs | 12 ---------- osu.Game.Rulesets.Catch/CatchRuleset.cs | 11 ++++++++++ .../UI/CatchRulesetContainer.cs | 2 +- osu.Game.Rulesets.Osu/OsuInputManager.cs | 12 +++------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 11 +++++++++- .../UI/OsuRulesetContainer.cs | 2 +- .../Input/Bindings/DatabasedKeyBinding.cs | 2 +- .../DatabasedKeyBindingInputManager.cs | 22 +++++++------------ .../Bindings/GlobalBindingInputManager.cs | 2 +- .../{BindingStore.cs => KeyBindingStore.cs} | 19 +++++++++++++--- osu.Game/OsuGameBase.cs | 10 ++++++--- osu.Game/Rulesets/Ruleset.cs | 13 +++++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++-- osu.Game/osu.Game.csproj | 2 +- 14 files changed, 75 insertions(+), 49 deletions(-) rename osu.Game/Input/{BindingStore.cs => KeyBindingStore.cs} (61%) diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index 446f9b2787..683724b7b8 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -1,11 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using System.ComponentModel; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; -using OpenTK.Input; namespace osu.Game.Rulesets.Catch { @@ -15,16 +13,6 @@ namespace osu.Game.Rulesets.Catch : base(ruleset, simultaneousMode: SimultaneousBindingMode.Unique) { } - - protected override IEnumerable CreateDefaultMappings() => new[] - { - new KeyBinding(Key.Z, CatchAction.MoveLeft), - new KeyBinding(Key.Left, CatchAction.MoveLeft), - new KeyBinding(Key.X, CatchAction.MoveRight), - new KeyBinding(Key.Right, CatchAction.MoveRight), - new KeyBinding(Key.LShift, CatchAction.Dash), - new KeyBinding(Key.RShift, CatchAction.Dash), - }; } public enum CatchAction diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8d45ea8fa2..b486566b7d 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Scoring; +using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Catch { @@ -20,6 +21,16 @@ namespace osu.Game.Rulesets.Catch { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] + { + new KeyBinding(Key.Z, CatchAction.MoveLeft), + new KeyBinding(Key.Left, CatchAction.MoveLeft), + new KeyBinding(Key.X, CatchAction.MoveRight), + new KeyBinding(Key.Right, CatchAction.MoveRight), + new KeyBinding(Key.LShift, CatchAction.Dash), + new KeyBinding(Key.RShift, CatchAction.Dash), + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 8469be24dd..1d037deaef 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override Playfield CreatePlayfield() => new CatchPlayfield(); - protected override PassThroughInputManager CreateActionMappingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo); + public override PassThroughInputManager CreateKeyBindingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo); protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index c1ee19d8c5..06836994d2 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using osu.Framework.Input; using osu.Framework.Input.Bindings; @@ -33,19 +33,13 @@ namespace osu.Game.Rulesets.Osu keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 2 }); } } - - protected override IEnumerable CreateDefaultMappings() => new[] - { - new KeyBinding(Key.Z, OsuAction.LeftButton), - new KeyBinding(Key.X, OsuAction.RightButton), - new KeyBinding(Key.LastKey + 1, OsuAction.LeftButton), - new KeyBinding(Key.LastKey + 2, OsuAction.RightButton), - }; } public enum OsuAction { + [Description("Left Button")] LeftButton, + [Description("Right Button")] RightButton } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 212c634aaf..75b7be01a4 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; +using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Osu { @@ -24,8 +25,16 @@ namespace osu.Game.Rulesets.Osu { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { + new KeyBinding(Key.Z, OsuAction.LeftButton), + new KeyBinding(Key.X, OsuAction.RightButton), + new KeyBinding(Key.LastKey + 1, OsuAction.LeftButton), + new KeyBinding(Key.LastKey + 2, OsuAction.RightButton), + }; + + public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] + { new BeatmapStatistic { Name = @"Circle count", diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 538b94603c..917322de44 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override Playfield CreatePlayfield() => new OsuPlayfield(); - protected override PassThroughInputManager CreateActionMappingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo); + public override PassThroughInputManager CreateKeyBindingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo); protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h) { diff --git a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs index 278033899c..3870cc5b04 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs @@ -27,7 +27,7 @@ namespace osu.Game.Input.Bindings [Column("Action")] public new int Action { - get { return base.Action; } + get { return (int)base.Action; } private set { base.Action = value; } } } diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs index 5c62f1ddc8..52e5af152c 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Input.Bindings; using osu.Game.Rulesets; @@ -18,7 +19,9 @@ namespace osu.Game.Input.Bindings private readonly int? variant; - private BindingStore store; + private KeyBindingStore store; + + public override IEnumerable DefaultMappings => ruleset.CreateInstance().GetDefaultKeyBindings(); /// /// Create a new instance. @@ -34,24 +37,15 @@ namespace osu.Game.Input.Bindings } [BackgroundDependencyLoader] - private void load(BindingStore bindings) + private void load(KeyBindingStore keyBindings) { - store = bindings; + store = keyBindings; } protected override void ReloadMappings() { - // load defaults - base.ReloadMappings(); - - var rulesetId = ruleset?.ID; - - // load from database if present. - if (store != null) - { - foreach (var b in store.Query(b => b.RulesetID == rulesetId && b.Variant == variant)) - KeyBindings.Add(b); - } + KeyBindings.Clear(); + KeyBindings.AddRange(store.GetProcessedList(DefaultMappings, ruleset?.ID, variant)); } } } \ No newline at end of file diff --git a/osu.Game/Input/Bindings/GlobalBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalBindingInputManager.cs index 60a4faa8cd..d00ed588ae 100644 --- a/osu.Game/Input/Bindings/GlobalBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalBindingInputManager.cs @@ -21,7 +21,7 @@ namespace osu.Game.Input.Bindings handler = game; } - protected override IEnumerable CreateDefaultMappings() => new[] + public override IEnumerable DefaultMappings => new[] { new KeyBinding(Key.F8, GlobalAction.ToggleChat), new KeyBinding(Key.F9, GlobalAction.ToggleSocial), diff --git a/osu.Game/Input/BindingStore.cs b/osu.Game/Input/KeyBindingStore.cs similarity index 61% rename from osu.Game/Input/BindingStore.cs rename to osu.Game/Input/KeyBindingStore.cs index 25a997e29d..e26942a06c 100644 --- a/osu.Game/Input/BindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -2,6 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Input.Bindings; @@ -9,9 +11,9 @@ using SQLite.Net; namespace osu.Game.Input { - public class BindingStore : DatabaseBackedStore + public class KeyBindingStore : DatabaseBackedStore { - public BindingStore(SQLiteConnection connection, Storage storage = null) + public KeyBindingStore(SQLiteConnection connection, Storage storage = null) : base(connection, storage) { } @@ -44,5 +46,16 @@ namespace osu.Game.Input typeof(DatabasedKeyBinding) }; + public List GetProcessedList(IEnumerable defaults, int? rulesetId, int? variant) + { + //todo: cache and share reference + List bindings = new List(defaults); + + // load from database if present. + foreach (var b in Query(b => b.RulesetID == rulesetId && b.Variant == variant)) + bindings.Add(b); + + return bindings; + } } -} \ No newline at end of file +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 344b23cca4..d72716b5d6 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -39,7 +39,7 @@ namespace osu.Game protected ScoreStore ScoreStore; - protected BindingStore BindingStore; + protected KeyBindingStore KeyBindingStore; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -108,7 +108,7 @@ namespace osu.Game dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager)); - dependencies.Cache(BindingStore = new BindingStore(connection)); + dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. @@ -183,12 +183,14 @@ namespace osu.Game { base.LoadComplete(); + GlobalBindingInputManager globalBinding; + base.Content.Add(new RatioAdjust { Children = new Drawable[] { Cursor = new MenuCursor(), - new GlobalBindingInputManager(this) + globalBinding = new GlobalBindingInputManager(this) { RelativeSizeAxes = Axes.Both, Child = new OsuTooltipContainer(Cursor) @@ -200,6 +202,8 @@ namespace osu.Game } }); + dependencies.Cache(globalBinding); + // TODO: This is temporary until we reimplement the local FPS display. // It's just to allow end-users to access the framework FPS display without knowing the shortcut key. fpsDisplayVisible = LocalConfig.GetBindable(OsuSetting.ShowFpsDisplay); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ba040403ba..e5fa7117f3 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; using System.Collections.Generic; using osu.Framework.Graphics; +using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; @@ -53,5 +54,17 @@ namespace osu.Game.Rulesets /// Do not override this unless you are a legacy mode. /// public virtual int LegacyID => -1; + + /// + /// A list of available variant ids. + /// + public virtual IEnumerable AvailableVariants => new[] { 0 }; + + /// + /// Get a list of default keys for the specified variant. + /// + /// A variant. + /// A list of valid s. + public virtual IEnumerable GetDefaultKeyBindings(int variant = 0) => new KeyBinding[] { }; } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 387fa15191..8512d4b5e1 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; - KeyConversionInputManager = CreateActionMappingInputManager(); + KeyConversionInputManager = CreateKeyBindingInputManager(); KeyConversionInputManager.RelativeSizeAxes = Axes.Both; } @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.UI /// Creates a key conversion input manager. /// /// The input manager. - protected virtual PassThroughInputManager CreateActionMappingInputManager() => new PassThroughInputManager(); + public virtual PassThroughInputManager CreateKeyBindingInputManager() => new PassThroughInputManager(); protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 13c4938850..b324fb9f92 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -94,7 +94,7 @@ - + From 46bfa4db29da2bb501a98a97c4cd39ba74d1c355 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Aug 2017 22:31:23 +0900 Subject: [PATCH 04/34] Load defaults, pass around live IEnumerable, add PK for updating --- .../Input/Bindings/DatabasedKeyBinding.cs | 5 +- .../DatabasedKeyBindingInputManager.cs | 3 +- osu.Game/Input/KeyBindingStore.cs | 50 +++++++++++++++---- osu.Game/OsuGameBase.cs | 2 +- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs index 3870cc5b04..73896b5ffe 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs @@ -11,6 +11,9 @@ namespace osu.Game.Input.Bindings [Table("KeyBinding")] public class DatabasedKeyBinding : KeyBinding { + [PrimaryKey, AutoIncrement] + public int ID { get; set; } + [ForeignKey(typeof(RulesetInfo))] public int? RulesetID { get; set; } @@ -28,7 +31,7 @@ namespace osu.Game.Input.Bindings public new int Action { get { return (int)base.Action; } - private set { base.Action = value; } + set { base.Action = value; } } } } \ No newline at end of file diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs index 52e5af152c..a02dd00a77 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs @@ -44,8 +44,7 @@ namespace osu.Game.Input.Bindings protected override void ReloadMappings() { - KeyBindings.Clear(); - KeyBindings.AddRange(store.GetProcessedList(DefaultMappings, ruleset?.ID, variant)); + KeyBindings = store.GetProcessedList(DefaultMappings, ruleset?.ID, variant); } } } \ No newline at end of file diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index e26942a06c..0cd556289f 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -3,22 +3,35 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Input.Bindings; +using osu.Game.Rulesets; using SQLite.Net; namespace osu.Game.Input { public class KeyBindingStore : DatabaseBackedStore { - public KeyBindingStore(SQLiteConnection connection, Storage storage = null) + public KeyBindingStore(SQLiteConnection connection, RulesetStore rulesets, Storage storage = null) : base(connection, storage) { + foreach (var info in rulesets.Query()) + { + var ruleset = info.CreateInstance(); + foreach (var variant in ruleset.AvailableVariants) + GetProcessedList(ruleset.GetDefaultKeyBindings(), info.ID, variant); + } } - protected override int StoreVersion => 2; + public void Register(KeyBindingInputManager manager) + { + GetProcessedList(manager.DefaultMappings); + } + + protected override int StoreVersion => 3; protected override void PerformMigration(int currentVersion, int targetVersion) { @@ -29,6 +42,8 @@ namespace osu.Game.Input switch (currentVersion) { case 1: + case 2: + case 3: // cannot migrate; breaking underlying changes. Reset(); break; @@ -38,6 +53,11 @@ namespace osu.Game.Input protected override void Prepare(bool reset = false) { + if (reset) + { + Connection.DropTable(); + } + Connection.CreateTable(); } @@ -46,16 +66,28 @@ namespace osu.Game.Input typeof(DatabasedKeyBinding) }; - public List GetProcessedList(IEnumerable defaults, int? rulesetId, int? variant) + public IEnumerable GetProcessedList(IEnumerable defaults, int? rulesetId = null, int? variant = null) { - //todo: cache and share reference - List bindings = new List(defaults); + var databaseEntries = Query(b => b.RulesetID == rulesetId && b.Variant == variant); - // load from database if present. - foreach (var b in Query(b => b.RulesetID == rulesetId && b.Variant == variant)) - bindings.Add(b); + if (!databaseEntries.Any()) + { + // if there are no entries for this category in the database, we should populate our defaults. + Connection.InsertAll(defaults.Select(k => new DatabasedKeyBinding + { + KeyCombination = k.KeyCombination, + Action = (int)k.Action, + RulesetID = rulesetId, + Variant = variant + })); + } - return bindings; + return databaseEntries; + } + + public void Update(KeyBinding keyBinding) + { + Connection.Update(keyBinding); } } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index d72716b5d6..54b091d7d9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -108,7 +108,7 @@ namespace osu.Game dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager)); - dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection)); + dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. From 4da76cd98e8164155a21f7a0ab88954e8a1ffaaa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Aug 2017 22:31:35 +0900 Subject: [PATCH 05/34] Initial key configuration UI implementation --- .../Visual/TestCaseKeyConfiguration.cs | 355 +++++++++++++++++- 1 file changed, 348 insertions(+), 7 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs index 10a15d0a96..077417577a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -1,10 +1,27 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; +using System.Linq; using osu.Game.Overlays; using osu.Game.Overlays.Settings; -using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input; +using osu.Game.Rulesets; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Input; +using OpenTK.Input; namespace osu.Desktop.Tests.Visual { @@ -29,16 +46,340 @@ namespace osu.Desktop.Tests.Visual public class KeyConfiguration : SettingsOverlay { - protected override IEnumerable CreateSections() => new[] + protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); + + [BackgroundDependencyLoader(permitNulls: true)] + private void load(RulesetStore rulesets, GlobalBindingInputManager global) { - new BindingsSection(), - new BindingsSection() - }; + AddSection(new GlobalBindingsSection(global, "Global")); + + foreach (var ruleset in rulesets.Query()) + AddSection(new RulesetBindingsSection(ruleset)); + } + + public KeyConfiguration() + : base(false) + { + } } - public class BindingsSection : SettingsSection + public class GlobalBindingsSection : KeyBindingsSection + { + private readonly string name; + + public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; + public override string Header => name; + + public GlobalBindingsSection(KeyBindingInputManager manager, string name) + { + this.name = name; + + Defaults = manager.DefaultMappings; + } + } + + public class RulesetBindingsSection : KeyBindingsSection { public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; - public override string Header => "Header"; + public override string Header => Ruleset.Name; + + public RulesetBindingsSection(RulesetInfo ruleset) + { + Ruleset = ruleset; + + Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(); + } + } + + public abstract class KeyBindingsSection : SettingsSection + { + protected IEnumerable Defaults; + + protected RulesetInfo Ruleset; + + protected KeyBindingsSection() + { + FlowContent.Spacing = new Vector2(0, 1); + } + + [BackgroundDependencyLoader] + private void load(KeyBindingStore store) + { + var firstDefault = Defaults?.FirstOrDefault(); + + if (firstDefault == null) return; + + var actionType = firstDefault.Action.GetType(); + + var bindings = store.GetProcessedList(Defaults, Ruleset?.ID); + + foreach (Enum v in Enum.GetValues(actionType)) + { + Add(new KeyBindingRow(v, bindings.Where(b => (int)b.Action == (int)(object)v))); + } + } + } + + internal class KeyBindingRow : Container, IFilterable + { + private readonly Enum action; + private readonly IEnumerable bindings; + + private const float transition_time = 150; + + private const float height = 20; + + private const float padding = 5; + + private bool matchingFilter; + + public bool MatchingFilter + { + get { return matchingFilter; } + set + { + matchingFilter = value; + this.FadeTo(!matchingFilter ? 0 : 1); + } + } + + private OsuSpriteText text; + private OsuSpriteText pressAKey; + + private FillFlowContainer buttons; + + public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); + + public KeyBindingRow(Enum action, IEnumerable bindings) + { + this.action = action; + this.bindings = bindings; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Masking = true; + CornerRadius = padding; + } + + private KeyBindingStore store; + + [BackgroundDependencyLoader] + private void load(OsuColour colours, KeyBindingStore store) + { + this.store = store; + + 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, + }, + text = new OsuSpriteText + { + Text = action.GetDescription(), + Margin = new MarginPadding(padding), + }, + buttons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }, + pressAKey = new OsuSpriteText + { + Text = "Press a key to change the binding, or ESC to cancel.", + Y = height, + Margin = new MarginPadding(padding), + Alpha = 0, + Colour = colours.YellowDark + } + }; + + reloadBindings(); + } + + private void reloadBindings() + { + buttons.Clear(); + foreach (var b in bindings) + buttons.Add(new KeyButton(b)); + } + + protected override bool OnHover(InputState state) + { + this.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + this.FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + + public override bool AcceptsFocus => true; + + private KeyButton bindTarget; + + protected override void OnFocus(InputState state) + { + AutoSizeDuration = 500; + AutoSizeEasing = Easing.OutQuint; + + pressAKey.FadeIn(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding(); + + base.OnFocus(state); + } + + private bool isModifier(Key k) => k < Key.F1; + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (HasFocus) + { + if (!isModifier(args.Key)) + { + bindTarget.KeyBinding.KeyCombination = new KeyCombination(state.Keyboard.Keys); + store.Update(bindTarget.KeyBinding); + GetContainingInputManager().ChangeFocus(null); + } + return true; + } + + return base.OnKeyDown(state, args); + } + + protected override void OnFocusLost(InputState state) + { + bindTarget.IsBinding = false; + bindTarget = null; + reloadBindings(); + + pressAKey.FadeOut(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; + base.OnFocusLost(state); + } + + protected override bool OnClick(InputState state) + { + bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); + if (bindTarget != null) bindTarget.IsBinding = true; + + return bindTarget != null; + } + + private class KeyButton : Container + { + public readonly KeyBinding KeyBinding; + + private readonly Box box; + public readonly OsuSpriteText Text; + + private Color4 hoverColour; + + private bool isBinding; + + public bool IsBinding + { + get { return isBinding; } + set + { + isBinding = value; + + if (value) + { + box.FadeColour(Color4.White, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + + } + else + { + box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); + } + } + } + + public KeyButton(KeyBinding keyBinding) + { + KeyBinding = keyBinding; + + Margin = new MarginPadding(padding); + + 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 = "Venera", + TextSize = 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(InputState state) + { + if (isBinding) + return false; + + box.FadeColour(hoverColour, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if (isBinding) + return; + + box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + } } } From 97ac8e1a64b2bacf8697423ad124965ede65dbc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Aug 2017 11:03:03 +0900 Subject: [PATCH 06/34] Update usages of IsAlive/IsLoaded in line with framework changes --- osu.Desktop.Tests/Visual/TestCaseNotificationOverlay.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs | 2 +- osu.Game/Screens/BackgroundScreen.cs | 2 +- osu.Game/Screens/Play/KeyCounterCollection.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseNotificationOverlay.cs b/osu.Desktop.Tests/Visual/TestCaseNotificationOverlay.cs index b9e492593f..1e46fbda35 100644 --- a/osu.Desktop.Tests/Visual/TestCaseNotificationOverlay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseNotificationOverlay.cs @@ -68,7 +68,7 @@ namespace osu.Desktop.Tests.Visual while (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3) { - var p = progressingNotifications.FirstOrDefault(n => n.IsLoaded && n.State == ProgressNotificationState.Queued); + var p = progressingNotifications.FirstOrDefault(n => n.IsAlive && n.State == ProgressNotificationState.Queued); if (p == null) break; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index 8b9441ea65..680f987274 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces return; accentColour = value; - if (LoadState == LoadState.Loaded) + if (LoadState == LoadState.Ready) Schedule(reloadTexture); } } diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index c5bbf04075..5b07ca6020 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens } // Make sure the in-progress loading is complete before pushing the screen. - while (screen.LoadState < LoadState.Loaded) + while (screen.LoadState < LoadState.Ready) Thread.Sleep(1); base.Push(screen); diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 01e20fdbd7..63c29a8f78 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play } } - public override bool HandleInput => receptor?.IsAlive != true; + public override bool HandleInput => receptor == null; private Receptor receptor; From a74ebdfe568bfd94a20756ac880981279e2a159e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Aug 2017 14:30:25 +0900 Subject: [PATCH 07/34] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 2a56eb0619..4a213a02aa 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2a56eb0619adf654ed4927af1a4b227596c87494 +Subproject commit 4a213a02aa09b0fd8bd119eb391549ca1fa00f95 From 6ded194c5317cc6bdae056c377433bb394c8f05e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Aug 2017 14:30:50 +0900 Subject: [PATCH 08/34] Remove all usage of DI to retrieve InputManager Uses GetContainingInputManager instead, as per framework changes. --- osu.Game/Graphics/Containers/ParallaxContainer.cs | 9 +++++++-- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 10 +--------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 6 ++---- .../Settings/Sections/General/LoginSettings.cs | 15 +++++---------- osu.Game/Screens/Select/FilterControl.cs | 8 ++------ osu.Game/Screens/Select/SongSelect.cs | 8 ++++---- 6 files changed, 21 insertions(+), 35 deletions(-) diff --git a/osu.Game/Graphics/Containers/ParallaxContainer.cs b/osu.Game/Graphics/Containers/ParallaxContainer.cs index ec9d30f244..3e0ed4b059 100644 --- a/osu.Game/Graphics/Containers/ParallaxContainer.cs +++ b/osu.Game/Graphics/Containers/ParallaxContainer.cs @@ -34,9 +34,8 @@ namespace osu.Game.Graphics.Containers protected override Container Content => content; [BackgroundDependencyLoader] - private void load(UserInputManager input, OsuConfigManager config) + private void load(OsuConfigManager config) { - this.input = input; parallaxEnabled = config.GetBindable(OsuSetting.MenuParallax); parallaxEnabled.ValueChanged += delegate { @@ -48,6 +47,12 @@ namespace osu.Game.Graphics.Containers }; } + protected override void LoadComplete() + { + base.LoadComplete(); + input = GetContainingInputManager(); + } + private bool firstUpdate = true; protected override void Update() diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 447daca75e..4817212f7a 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -28,18 +28,10 @@ namespace osu.Game.Graphics.UserInterface { focus = value; if (!focus && HasFocus) - inputManager.ChangeFocus(null); + GetContainingInputManager().ChangeFocus(null); } } - private InputManager inputManager; - - [BackgroundDependencyLoader] - private void load(UserInputManager inputManager) - { - this.inputManager = inputManager; - } - protected override void OnFocus(InputState state) { base.OnFocus(state); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 942633b35e..2681c8bbb8 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -31,12 +31,10 @@ namespace osu.Game.Overlays.Music private readonly Bindable beatmapBacking = new Bindable(); public IEnumerable BeatmapSets; - private InputManager inputManager; [BackgroundDependencyLoader] - private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, UserInputManager inputManager) + private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours) { - this.inputManager = inputManager; this.beatmaps = beatmaps; Children = new Drawable[] @@ -102,7 +100,7 @@ namespace osu.Game.Overlays.Music protected override void PopIn() { filter.Search.HoldFocus = true; - Schedule(() => inputManager.ChangeFocus(filter.Search)); + Schedule(() => GetContainingInputManager().ChangeFocus(filter.Search)); this.ResizeTo(new Vector2(1, playlist_height), transition_duration, Easing.OutQuint); this.FadeIn(transition_duration, Easing.OutQuint); diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index d07f156673..3f8b6186c4 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -57,12 +57,9 @@ namespace osu.Game.Overlays.Settings.Sections.General Spacing = new Vector2(0f, 5f); } - private InputManager inputManager; - [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, APIAccess api, UserInputManager inputManager) + private void load(OsuColour colours, APIAccess api) { - this.inputManager = inputManager; this.colours = colours; api?.Register(this); @@ -174,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections.General break; } - if (form != null) inputManager.ChangeFocus(form); + if (form != null) GetContainingInputManager().ChangeFocus(form); } public override bool AcceptsFocus => true; @@ -183,7 +180,7 @@ namespace osu.Game.Overlays.Settings.Sections.General protected override void OnFocus(InputState state) { - if (form != null) inputManager.ChangeFocus(form); + if (form != null) GetContainingInputManager().ChangeFocus(form); base.OnFocus(state); } @@ -192,7 +189,6 @@ namespace osu.Game.Overlays.Settings.Sections.General private TextBox username; private TextBox password; private APIAccess api; - private InputManager inputManager; private void performLogin() { @@ -201,9 +197,8 @@ namespace osu.Game.Overlays.Settings.Sections.General } [BackgroundDependencyLoader(permitNulls: true)] - private void load(APIAccess api, OsuConfigManager config, UserInputManager inputManager) + private void load(APIAccess api, OsuConfigManager config) { - this.inputManager = inputManager; this.api = api; Direction = FillDirection.Vertical; Spacing = new Vector2(0, 5); @@ -256,7 +251,7 @@ namespace osu.Game.Overlays.Settings.Sections.General protected override void OnFocus(InputState state) { - Schedule(() => { inputManager.ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); }); + Schedule(() => { GetContainingInputManager().ChangeFocus(string.IsNullOrEmpty(username.Text) ? username : password); }); } } diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 838e6f7123..e83613125b 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -153,7 +153,7 @@ namespace osu.Game.Screens.Select { searchTextBox.HoldFocus = false; if (searchTextBox.HasFocus) - inputManager.ChangeFocus(searchTextBox); + GetContainingInputManager().ChangeFocus(searchTextBox); } public void Activate() @@ -163,13 +163,9 @@ namespace osu.Game.Screens.Select private readonly Bindable ruleset = new Bindable(); - private InputManager inputManager; - [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, OsuGame osu, UserInputManager inputManager) + private void load(OsuColour colours, OsuGame osu) { - this.inputManager = inputManager; - sortTabs.AccentColour = colours.GreenLight; if (osu != null) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8f545240c8..afab9e8746 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -156,11 +156,11 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, UserInputManager input) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) { if (Footer != null) { - Footer.AddButton(@"random", colours.Green, () => triggerRandom(input), Key.F2); + Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3); BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, promptDelete, Key.Number4, float.MaxValue); @@ -267,9 +267,9 @@ namespace osu.Game.Screens.Select } } - private void triggerRandom(UserInputManager input) + private void triggerRandom() { - if (input.CurrentState.Keyboard.ShiftPressed) + if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed) carousel.SelectPreviousRandom(); else carousel.SelectNextRandom(); From 143ff695efd03e163c558f5bebbbeb70cb0d81b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Aug 2017 17:44:04 +0900 Subject: [PATCH 09/34] Remove unused using statements --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 1 - osu.Game/Overlays/Music/PlaylistOverlay.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 4817212f7a..dbbb069f7c 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -3,7 +3,6 @@ using OpenTK.Graphics; using OpenTK.Input; -using osu.Framework.Allocation; using osu.Framework.Input; using System; using System.Linq; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 2681c8bbb8..83e92c5554 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Input; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 3bee36f6a2faf447cb863984b562013e93436a01 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Aug 2017 23:59:06 +0900 Subject: [PATCH 10/34] Add index to Action column Is used for default assignment --- osu.Game/Input/Bindings/DatabasedKeyBinding.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs index 73896b5ffe..c0197ce3dc 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs @@ -27,6 +27,7 @@ namespace osu.Game.Input.Bindings private set { KeyCombination = value; } } + [Indexed] [Column("Action")] public new int Action { From 2bd098173818718c533166d7da9805f86e4625b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Aug 2017 23:59:58 +0900 Subject: [PATCH 11/34] Improve default key binding logic Defaults will be added to the database as long as the database has unbalanced counts for any actions. --- .../DatabasedKeyBindingInputManager.cs | 2 +- osu.Game/Input/KeyBindingStore.cs | 51 ++++++++++--------- osu.Game/OsuGameBase.cs | 1 + 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs index a02dd00a77..e565c13b31 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs @@ -44,7 +44,7 @@ namespace osu.Game.Input.Bindings protected override void ReloadMappings() { - KeyBindings = store.GetProcessedList(DefaultMappings, ruleset?.ID, variant); + KeyBindings = store.Query(ruleset?.ID, variant); } } } \ No newline at end of file diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index 0cd556289f..057fa4d4e7 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -22,14 +22,11 @@ namespace osu.Game.Input { var ruleset = info.CreateInstance(); foreach (var variant in ruleset.AvailableVariants) - GetProcessedList(ruleset.GetDefaultKeyBindings(), info.ID, variant); + insertDefaults(ruleset.GetDefaultKeyBindings(), info.ID, variant); } } - public void Register(KeyBindingInputManager manager) - { - GetProcessedList(manager.DefaultMappings); - } + public void Register(KeyBindingInputManager manager) => insertDefaults(manager.DefaultMappings); protected override int StoreVersion => 3; @@ -61,29 +58,37 @@ namespace osu.Game.Input Connection.CreateTable(); } + private void insertDefaults(IEnumerable defaults, int? rulesetId = null, int? variant = null) + { + var query = Query(rulesetId, variant); + + // compare counts in database vs defaults + foreach (var group in defaults.GroupBy(k => k.Action)) + { + int count; + while (group.Count() > (count = query.Count(k => (int)k.Action == (int)group.Key))) + { + var insertable = group.Skip(count).First(); + + // insert any defaults which are missing. + Connection.Insert(new DatabasedKeyBinding + { + KeyCombination = insertable.KeyCombination, + Action = (int)insertable.Action, + RulesetID = rulesetId, + Variant = variant + }); + } + } + } + protected override Type[] ValidTypes => new[] { typeof(DatabasedKeyBinding) }; - public IEnumerable GetProcessedList(IEnumerable defaults, int? rulesetId = null, int? variant = null) - { - var databaseEntries = Query(b => b.RulesetID == rulesetId && b.Variant == variant); - - if (!databaseEntries.Any()) - { - // if there are no entries for this category in the database, we should populate our defaults. - Connection.InsertAll(defaults.Select(k => new DatabasedKeyBinding - { - KeyCombination = k.KeyCombination, - Action = (int)k.Action, - RulesetID = rulesetId, - Variant = variant - })); - } - - return databaseEntries; - } + public IEnumerable Query(int? rulesetId = null, int? variant = null) => + Query(b => b.RulesetID == rulesetId && b.Variant == variant); public void Update(KeyBinding keyBinding) { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 54b091d7d9..571c75022e 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -202,6 +202,7 @@ namespace osu.Game } }); + KeyBindingStore.Register(globalBinding); dependencies.Cache(globalBinding); // TODO: This is temporary until we reimplement the local FPS display. From 9c75df884fe67c41b0d77b21bbe480119f88746b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 00:08:59 +0900 Subject: [PATCH 12/34] Add initial implementation of KeyConfiguration overlay --- .../Visual/TestCaseKeyConfiguration.cs | 362 +----------------- .../KeyConfiguration/GlobalBindingsSection.cs | 23 ++ .../KeyConfiguration/KeyBindingRow.cs | 284 ++++++++++++++ .../KeyConfiguration/KeyBindingsSection.cs | 51 +++ .../KeyConfiguration/KeyConfiguration.cs | 30 ++ .../RulesetBindingsSection.cs | 21 + osu.Game/osu.Game.csproj | 5 + 7 files changed, 415 insertions(+), 361 deletions(-) create mode 100644 osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs create mode 100644 osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs create mode 100644 osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs create mode 100644 osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs create mode 100644 osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs index 077417577a..69489c51a1 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -1,27 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; -using System.Linq; -using osu.Game.Overlays; -using osu.Game.Overlays.Settings; -using osu.Framework.Allocation; -using osu.Framework.Extensions; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Input; -using osu.Game.Rulesets; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Input; -using OpenTK.Input; +using osu.Game.Overlays.KeyConfiguration; namespace osu.Desktop.Tests.Visual { @@ -39,347 +19,7 @@ namespace osu.Desktop.Tests.Visual protected override void LoadComplete() { base.LoadComplete(); - configuration.Show(); } } - - public class KeyConfiguration : SettingsOverlay - { - protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); - - [BackgroundDependencyLoader(permitNulls: true)] - private void load(RulesetStore rulesets, GlobalBindingInputManager global) - { - AddSection(new GlobalBindingsSection(global, "Global")); - - foreach (var ruleset in rulesets.Query()) - AddSection(new RulesetBindingsSection(ruleset)); - } - - public KeyConfiguration() - : base(false) - { - } - } - - public class GlobalBindingsSection : KeyBindingsSection - { - private readonly string name; - - public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; - public override string Header => name; - - public GlobalBindingsSection(KeyBindingInputManager manager, string name) - { - this.name = name; - - Defaults = manager.DefaultMappings; - } - } - - public class RulesetBindingsSection : KeyBindingsSection - { - public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; - public override string Header => Ruleset.Name; - - public RulesetBindingsSection(RulesetInfo ruleset) - { - Ruleset = ruleset; - - Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(); - } - } - - public abstract class KeyBindingsSection : SettingsSection - { - protected IEnumerable Defaults; - - protected RulesetInfo Ruleset; - - protected KeyBindingsSection() - { - FlowContent.Spacing = new Vector2(0, 1); - } - - [BackgroundDependencyLoader] - private void load(KeyBindingStore store) - { - var firstDefault = Defaults?.FirstOrDefault(); - - if (firstDefault == null) return; - - var actionType = firstDefault.Action.GetType(); - - var bindings = store.GetProcessedList(Defaults, Ruleset?.ID); - - foreach (Enum v in Enum.GetValues(actionType)) - { - Add(new KeyBindingRow(v, bindings.Where(b => (int)b.Action == (int)(object)v))); - } - } - } - - internal class KeyBindingRow : Container, IFilterable - { - private readonly Enum action; - private readonly IEnumerable bindings; - - private const float transition_time = 150; - - private const float height = 20; - - private const float padding = 5; - - private bool matchingFilter; - - public bool MatchingFilter - { - get { return matchingFilter; } - set - { - matchingFilter = value; - this.FadeTo(!matchingFilter ? 0 : 1); - } - } - - private OsuSpriteText text; - private OsuSpriteText pressAKey; - - private FillFlowContainer buttons; - - public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); - - public KeyBindingRow(Enum action, IEnumerable bindings) - { - this.action = action; - this.bindings = bindings; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - Masking = true; - CornerRadius = padding; - } - - private KeyBindingStore store; - - [BackgroundDependencyLoader] - private void load(OsuColour colours, KeyBindingStore store) - { - this.store = store; - - 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, - }, - text = new OsuSpriteText - { - Text = action.GetDescription(), - Margin = new MarginPadding(padding), - }, - buttons = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }, - pressAKey = new OsuSpriteText - { - Text = "Press a key to change the binding, or ESC to cancel.", - Y = height, - Margin = new MarginPadding(padding), - Alpha = 0, - Colour = colours.YellowDark - } - }; - - reloadBindings(); - } - - private void reloadBindings() - { - buttons.Clear(); - foreach (var b in bindings) - buttons.Add(new KeyButton(b)); - } - - protected override bool OnHover(InputState state) - { - this.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); - - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - this.FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); - - base.OnHoverLost(state); - } - - public override bool AcceptsFocus => true; - - private KeyButton bindTarget; - - protected override void OnFocus(InputState state) - { - AutoSizeDuration = 500; - AutoSizeEasing = Easing.OutQuint; - - pressAKey.FadeIn(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding(); - - base.OnFocus(state); - } - - private bool isModifier(Key k) => k < Key.F1; - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - if (HasFocus) - { - if (!isModifier(args.Key)) - { - bindTarget.KeyBinding.KeyCombination = new KeyCombination(state.Keyboard.Keys); - store.Update(bindTarget.KeyBinding); - GetContainingInputManager().ChangeFocus(null); - } - return true; - } - - return base.OnKeyDown(state, args); - } - - protected override void OnFocusLost(InputState state) - { - bindTarget.IsBinding = false; - bindTarget = null; - reloadBindings(); - - pressAKey.FadeOut(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; - base.OnFocusLost(state); - } - - protected override bool OnClick(InputState state) - { - bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); - if (bindTarget != null) bindTarget.IsBinding = true; - - return bindTarget != null; - } - - private class KeyButton : Container - { - public readonly KeyBinding KeyBinding; - - private readonly Box box; - public readonly OsuSpriteText Text; - - private Color4 hoverColour; - - private bool isBinding; - - public bool IsBinding - { - get { return isBinding; } - set - { - isBinding = value; - - if (value) - { - box.FadeColour(Color4.White, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - - } - else - { - box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); - } - } - } - - public KeyButton(KeyBinding keyBinding) - { - KeyBinding = keyBinding; - - Margin = new MarginPadding(padding); - - 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 = "Venera", - TextSize = 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(InputState state) - { - if (isBinding) - return false; - - box.FadeColour(hoverColour, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - if (isBinding) - return; - - box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); - - base.OnHoverLost(state); - } - } - } } diff --git a/osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs b/osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs new file mode 100644 index 0000000000..9d68b41045 --- /dev/null +++ b/osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Input.Bindings; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.KeyConfiguration +{ + public class GlobalBindingsSection : KeyBindingsSection + { + private readonly string name; + + public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; + public override string Header => name; + + public GlobalBindingsSection(KeyBindingInputManager manager, string name) + { + this.name = name; + + Defaults = manager.DefaultMappings; + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs b/osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs new file mode 100644 index 0000000000..a9ef10eae6 --- /dev/null +++ b/osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs @@ -0,0 +1,284 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input; +using OpenTK.Graphics; +using OpenTK.Input; + +namespace osu.Game.Overlays.KeyConfiguration +{ + internal class KeyBindingRow : Container, IFilterable + { + private readonly Enum action; + private readonly IEnumerable bindings; + + private const float transition_time = 150; + + private const float height = 20; + + private const float padding = 5; + + private bool matchingFilter; + + public bool MatchingFilter + { + get { return matchingFilter; } + set + { + matchingFilter = value; + this.FadeTo(!matchingFilter ? 0 : 1); + } + } + + private OsuSpriteText text; + private OsuSpriteText pressAKey; + + private FillFlowContainer buttons; + + public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); + + public KeyBindingRow(Enum action, IEnumerable bindings) + { + this.action = action; + this.bindings = bindings; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Masking = true; + CornerRadius = padding; + } + + private KeyBindingStore store; + + [BackgroundDependencyLoader] + private void load(OsuColour colours, KeyBindingStore store) + { + this.store = store; + + 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, + }, + text = new OsuSpriteText + { + Text = action.GetDescription(), + Margin = new MarginPadding(padding), + }, + buttons = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }, + pressAKey = new OsuSpriteText + { + Text = "Press a key to change binding, DEL to delete, ESC to cancel.", + Y = height, + Margin = new MarginPadding(padding), + Alpha = 0, + Colour = colours.YellowDark + } + }; + + reloadBindings(); + } + + private void reloadBindings() + { + buttons.Clear(); + foreach (var b in bindings) + buttons.Add(new KeyButton(b)); + } + + protected override bool OnHover(InputState state) + { + this.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + this.FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + + public override bool AcceptsFocus => true; + + private KeyButton bindTarget; + + protected override void OnFocus(InputState state) + { + AutoSizeDuration = 500; + AutoSizeEasing = Easing.OutQuint; + + pressAKey.FadeIn(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding(); + + base.OnFocus(state); + } + + private bool isModifier(Key k) => k < Key.F1; + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (HasFocus && !isModifier(args.Key)) + { + bindTarget.KeyBinding.KeyCombination = args.Key == Key.Delete ? Key.Unknown : new KeyCombination(state.Keyboard.Keys); + + store.Update(bindTarget.KeyBinding); + GetContainingInputManager().ChangeFocus(null); + return true; + } + + return base.OnKeyDown(state, args); + } + + protected override void OnFocusLost(InputState state) + { + bindTarget.IsBinding = false; + bindTarget = null; + reloadBindings(); + + pressAKey.FadeOut(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; + base.OnFocusLost(state); + } + + protected override bool OnClick(InputState state) + { + if (bindTarget != null) bindTarget.IsBinding = false; + bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); + if (bindTarget != null) bindTarget.IsBinding = true; + + return bindTarget != null; + } + + private class KeyButton : Container + { + public readonly KeyBinding KeyBinding; + + private readonly Box box; + public readonly OsuSpriteText Text; + + private Color4 hoverColour; + + private bool isBinding; + + public bool IsBinding + { + get { return isBinding; } + set + { + isBinding = value; + + if (value) + { + box.FadeColour(Color4.White, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + + } + else + { + box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); + } + } + } + + public KeyButton(KeyBinding keyBinding) + { + KeyBinding = keyBinding; + + Margin = new MarginPadding(padding); + + //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 = "Venera", + TextSize = 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(InputState state) + { + if (isBinding) + return false; + + box.FadeColour(hoverColour, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + if (isBinding) + return; + + box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs new file mode 100644 index 0000000000..1e574d5e55 --- /dev/null +++ b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Input.Bindings; +using osu.Game.Input; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets; +using OpenTK; + +namespace osu.Game.Overlays.KeyConfiguration +{ + public abstract class KeyBindingsSection : SettingsSection + { + protected IEnumerable Defaults; + + protected RulesetInfo Ruleset; + + protected KeyBindingsSection() + { + FlowContent.Spacing = new Vector2(0, 1); + } + + [BackgroundDependencyLoader] + private void load(KeyBindingStore store) + { + var firstDefault = Defaults?.FirstOrDefault(); + + if (firstDefault == null) return; + + var actionType = firstDefault.Action.GetType(); + + int? variant = null; + + // for now let's just assume a variant of zero. + // this will need to be implemented in a better way in the future. + if (Ruleset != null) + variant = 0; + + var bindings = store.Query(Ruleset?.ID, variant); + + foreach (Enum v in Enum.GetValues(actionType)) + { + Add(new KeyBindingRow(v, bindings.Where(b => (int)b.Action == (int)(object)v))); + } + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs b/osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs new file mode 100644 index 0000000000..416f828495 --- /dev/null +++ b/osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Input.Bindings; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.KeyConfiguration +{ + public class KeyConfiguration : SettingsOverlay + { + protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); + + [BackgroundDependencyLoader(permitNulls: true)] + private void load(RulesetStore rulesets, GlobalBindingInputManager global) + { + AddSection(new GlobalBindingsSection(global, "Global")); + + foreach (var ruleset in rulesets.Query()) + AddSection(new RulesetBindingsSection(ruleset)); + } + + public KeyConfiguration() + : base(false) + { + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs b/osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs new file mode 100644 index 0000000000..038df5e122 --- /dev/null +++ b/osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.KeyConfiguration +{ + public class RulesetBindingsSection : KeyBindingsSection + { + public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; + public override string Header => Ruleset.Name; + + public RulesetBindingsSection(RulesetInfo ruleset) + { + Ruleset = ruleset; + + Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(); + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b324fb9f92..6eb0ece6ed 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -102,6 +102,11 @@ + + + + + From 72eb082f916b849ad58041ecf27fa89e6da2251b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 01:14:37 +0900 Subject: [PATCH 13/34] Use .Equals --- osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs index 1e574d5e55..b7b07ab2f8 100644 --- a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.KeyConfiguration foreach (Enum v in Enum.GetValues(actionType)) { - Add(new KeyBindingRow(v, bindings.Where(b => (int)b.Action == (int)(object)v))); + Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v)))); } } } From c221472d6ee7e01c59bde8a085371c760a216ca2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 01:19:21 +0900 Subject: [PATCH 14/34] Code tidy-ups --- .../KeyConfiguration/KeyBindingsSection.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs index b7b07ab2f8..fe72c64edb 100644 --- a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs @@ -27,25 +27,21 @@ namespace osu.Game.Overlays.KeyConfiguration [BackgroundDependencyLoader] private void load(KeyBindingStore store) { - var firstDefault = Defaults?.FirstOrDefault(); + var enumType = Defaults?.FirstOrDefault()?.Action?.GetType(); - if (firstDefault == null) return; - - var actionType = firstDefault.Action.GetType(); - - int? variant = null; + if (enumType == null) return; // for now let's just assume a variant of zero. // this will need to be implemented in a better way in the future. + int? variant = null; if (Ruleset != null) variant = 0; var bindings = store.Query(Ruleset?.ID, variant); - foreach (Enum v in Enum.GetValues(actionType)) - { + foreach (Enum v in Enum.GetValues(enumType)) + // one row per valid action. Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v)))); - } } } } \ No newline at end of file From 6ee4716ec53e378da4e91a394dd7d1b0878cd61c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 12:39:18 +0900 Subject: [PATCH 15/34] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 2a56eb0619..e5b0f1c9d0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2a56eb0619adf654ed4927af1a4b227596c87494 +Subproject commit e5b0f1c9d0c98ee89563042071e516d5304a6d06 From a5007fc64fa3c661f29b5f7b4978af932252db9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 13:07:18 +0900 Subject: [PATCH 16/34] Fix some remaining usage of local InputManager instances --- osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs | 2 +- osu.Game/Overlays/ChatOverlay.cs | 2 +- osu.Game/Overlays/LoginOverlay.cs | 2 +- osu.Game/Overlays/SearchableList/SearchableListOverlay.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs b/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs index 368d3cc5ef..4362b3f787 100644 --- a/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs +++ b/osu.Game/Overlays/Chat/ChannelSelectionOverlay.cs @@ -152,7 +152,7 @@ namespace osu.Game.Overlays.Chat protected override void OnFocus(InputState state) { - InputManager.ChangeFocus(search); + GetContainingInputManager().ChangeFocus(search); base.OnFocus(state); } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 29b7548ada..e7a4c1c0ab 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -243,7 +243,7 @@ namespace osu.Game.Overlays protected override void OnFocus(InputState state) { //this is necessary as inputTextBox is masked away and therefore can't get focus :( - InputManager.ChangeFocus(inputTextBox); + GetContainingInputManager().ChangeFocus(inputTextBox); base.OnFocus(state); } diff --git a/osu.Game/Overlays/LoginOverlay.cs b/osu.Game/Overlays/LoginOverlay.cs index 95e0fef9aa..1bce31c789 100644 --- a/osu.Game/Overlays/LoginOverlay.cs +++ b/osu.Game/Overlays/LoginOverlay.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays settingsSection.Bounding = true; this.FadeIn(transition_time, Easing.OutQuint); - InputManager.ChangeFocus(settingsSection); + GetContainingInputManager().ChangeFocus(settingsSection); } protected override void PopOut() diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index c5b8b0cf85..d1d40388e1 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.SearchableList protected override void OnFocus(InputState state) { - InputManager.ChangeFocus(Filter.Search); + GetContainingInputManager().ChangeFocus(Filter.Search); } protected override void PopIn() diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index dfbcedd479..bd2212785a 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -153,7 +153,7 @@ namespace osu.Game.Overlays searchTextBox.HoldFocus = false; if (searchTextBox.HasFocus) - InputManager.ChangeFocus(null); + GetContainingInputManager().ChangeFocus(null); } public override bool AcceptsFocus => true; @@ -162,7 +162,7 @@ namespace osu.Game.Overlays protected override void OnFocus(InputState state) { - InputManager.ChangeFocus(searchTextBox); + GetContainingInputManager().ChangeFocus(searchTextBox); base.OnFocus(state); } From 7d00365154592294e2bb3be3ec6953e63df5bed3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 12:12:25 +0900 Subject: [PATCH 17/34] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 4a213a02aa..fc13a4c2f1 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4a213a02aa09b0fd8bd119eb391549ca1fa00f95 +Subproject commit fc13a4c2f1eff443ffe7d5ff3ca5caa17b98ffbf From 25a3835c3c25ab89baed02a88a9bf104b5696920 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 16:59:16 +0900 Subject: [PATCH 18/34] Cancel pending sidebar expansion when a button is clicked --- osu.Game/Overlays/Settings/Sidebar.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index 6eafc65d12..bfb3b96cb7 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -87,6 +87,8 @@ namespace osu.Game.Overlays.Settings get { return state; } set { + expandEvent?.Cancel(); + if (state == value) return; state = value; From dc82a88bb8ee6fa2983512bb1e532dd7e1965a26 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 17:19:27 +0900 Subject: [PATCH 19/34] Improve namespaces of key bindings --- .../Visual/TestCaseKeyConfiguration.cs | 6 ++--- .../GlobalBindingsSection.cs | 2 +- .../KeyBindingRow.cs | 10 ++++---- .../KeyBindingsSection.cs | 5 ++-- .../RulesetBindingsSection.cs | 2 +- ...yConfiguration.cs => KeyBindingOverlay.cs} | 7 +++--- osu.Game/Overlays/SettingsOverlay.cs | 24 +++++++++---------- osu.Game/osu.Game.csproj | 10 ++++---- 8 files changed, 32 insertions(+), 34 deletions(-) rename osu.Game/Overlays/{KeyConfiguration => KeyBinding}/GlobalBindingsSection.cs (90%) rename osu.Game/Overlays/{KeyConfiguration => KeyBinding}/KeyBindingRow.cs (92%) rename osu.Game/Overlays/{KeyConfiguration => KeyBinding}/KeyBindingsSection.cs (87%) rename osu.Game/Overlays/{KeyConfiguration => KeyBinding}/RulesetBindingsSection.cs (89%) rename osu.Game/Overlays/{KeyConfiguration/KeyConfiguration.cs => KeyBindingOverlay.cs} (81%) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs index 69489c51a1..77db6e7b91 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -1,19 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Overlays.KeyConfiguration; - namespace osu.Desktop.Tests.Visual { public class TestCaseKeyConfiguration : OsuTestCase { - private readonly KeyConfiguration configuration; + private readonly KeyConfigurationOverlay configuration; public override string Description => @"Key configuration"; public TestCaseKeyConfiguration() { - Child = configuration = new KeyConfiguration(); + Child = configuration = new KeyConfigurationOverlay(); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs similarity index 90% rename from osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs rename to osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs index 9d68b41045..943fc4a416 100644 --- a/osu.Game/Overlays/KeyConfiguration/GlobalBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs @@ -4,7 +4,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Graphics; -namespace osu.Game.Overlays.KeyConfiguration +namespace osu.Game.Overlays.KeyBinding { public class GlobalBindingsSection : KeyBindingsSection { diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs similarity index 92% rename from osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs rename to osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a9ef10eae6..4cc179aaf1 100644 --- a/osu.Game/Overlays/KeyConfiguration/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -18,12 +18,12 @@ using osu.Game.Input; using OpenTK.Graphics; using OpenTK.Input; -namespace osu.Game.Overlays.KeyConfiguration +namespace osu.Game.Overlays.KeyBinding { internal class KeyBindingRow : Container, IFilterable { private readonly Enum action; - private readonly IEnumerable bindings; + private readonly IEnumerable bindings; private const float transition_time = 150; @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.KeyConfiguration public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); - public KeyBindingRow(Enum action, IEnumerable bindings) + public KeyBindingRow(Enum action, IEnumerable bindings) { this.action = action; this.bindings = bindings; @@ -183,7 +183,7 @@ namespace osu.Game.Overlays.KeyConfiguration private class KeyButton : Container { - public readonly KeyBinding KeyBinding; + public readonly Framework.Input.Bindings.KeyBinding KeyBinding; private readonly Box box; public readonly OsuSpriteText Text; @@ -213,7 +213,7 @@ namespace osu.Game.Overlays.KeyConfiguration } } - public KeyButton(KeyBinding keyBinding) + public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) { KeyBinding = keyBinding; diff --git a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs similarity index 87% rename from osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs rename to osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs index fe72c64edb..19baeca771 100644 --- a/osu.Game/Overlays/KeyConfiguration/KeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs @@ -5,17 +5,16 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Input.Bindings; using osu.Game.Input; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using OpenTK; -namespace osu.Game.Overlays.KeyConfiguration +namespace osu.Game.Overlays.KeyBinding { public abstract class KeyBindingsSection : SettingsSection { - protected IEnumerable Defaults; + protected IEnumerable Defaults; protected RulesetInfo Ruleset; diff --git a/osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs b/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs similarity index 89% rename from osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs rename to osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs index 038df5e122..20941115e3 100644 --- a/osu.Game/Overlays/KeyConfiguration/RulesetBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs @@ -4,7 +4,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets; -namespace osu.Game.Overlays.KeyConfiguration +namespace osu.Game.Overlays.KeyBinding { public class RulesetBindingsSection : KeyBindingsSection { diff --git a/osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs b/osu.Game/Overlays/KeyBindingOverlay.cs similarity index 81% rename from osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs rename to osu.Game/Overlays/KeyBindingOverlay.cs index 416f828495..e5061def77 100644 --- a/osu.Game/Overlays/KeyConfiguration/KeyConfiguration.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -4,12 +4,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Overlays.KeyBinding; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; -namespace osu.Game.Overlays.KeyConfiguration +namespace osu.Game.Overlays { - public class KeyConfiguration : SettingsOverlay + public class KeyConfigurationOverlay : SettingsOverlay { protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); @@ -22,7 +23,7 @@ namespace osu.Game.Overlays.KeyConfiguration AddSection(new RulesetBindingsSection(ruleset)); } - public KeyConfiguration() + public KeyConfigurationOverlay() : base(false) { } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index bd2212785a..76f9ef3326 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays private Sidebar sidebar; private SidebarButton selectedSidebarButton; - private SettingsSectionsContainer sectionsContainer; + protected SettingsSectionsContainer SectionsContainer; private SearchTextBox searchTextBox; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays Colour = Color4.Black, Alpha = 0.6f, }, - sectionsContainer = new SettingsSectionsContainer + SectionsContainer = new SettingsSectionsContainer { RelativeSizeAxes = Axes.Y, Width = width, @@ -80,14 +80,14 @@ namespace osu.Game.Overlays Exit = Hide, }, Footer = CreateFooter() - } + }, }; if (showSidebar) { Add(sidebar = new Sidebar { Width = SIDEBAR_WIDTH }); - sectionsContainer.SelectedSection.ValueChanged += section => + SectionsContainer.SelectedSection.ValueChanged += section => { selectedSidebarButton.Selected = false; selectedSidebarButton = sidebar.Children.Single(b => b.Section == section); @@ -95,7 +95,7 @@ namespace osu.Game.Overlays }; } - searchTextBox.Current.ValueChanged += newValue => sectionsContainer.SearchContainer.SearchTerm = newValue; + searchTextBox.Current.ValueChanged += newValue => SectionsContainer.SearchContainer.SearchTerm = newValue; getToolbarHeight = () => game?.ToolbarOffset ?? 0; @@ -104,7 +104,7 @@ namespace osu.Game.Overlays protected void AddSection(SettingsSection section) { - sectionsContainer.Add(section); + SectionsContainer.Add(section); if (sidebar != null) { @@ -113,7 +113,7 @@ namespace osu.Game.Overlays Section = section, Action = s => { - sectionsContainer.ScrollTo(s); + SectionsContainer.ScrollTo(s); sidebar.State = ExpandedState.Contracted; }, }; @@ -136,7 +136,7 @@ namespace osu.Game.Overlays { base.PopIn(); - sectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); + SectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH / 2); @@ -147,7 +147,7 @@ namespace osu.Game.Overlays { base.PopOut(); - sectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint); + SectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint); sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(0, TRANSITION_LENGTH / 2); @@ -170,11 +170,11 @@ namespace osu.Game.Overlays { base.UpdateAfterChildren(); - sectionsContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 }; - sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() }; + SectionsContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 }; + SectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() }; } - private class SettingsSectionsContainer : SectionsContainer + protected class SettingsSectionsContainer : SectionsContainer { public SearchContainer SearchContainer; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6eb0ece6ed..f21ce528ca 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -102,11 +102,11 @@ - - - - - + + + + + From 54698f2d8ff37071ec706d919add0010cf4b3845 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 17:27:09 +0900 Subject: [PATCH 20/34] Use IntAction instead of new --- osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs | 2 ++ osu.Game/Input/Bindings/DatabasedKeyBinding.cs | 6 +++--- osu.Game/Input/KeyBindingStore.cs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs index 77db6e7b91..41e0c25507 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Overlays; + namespace osu.Desktop.Tests.Visual { public class TestCaseKeyConfiguration : OsuTestCase diff --git a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs index c0197ce3dc..cbf74d6984 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBinding.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBinding.cs @@ -29,10 +29,10 @@ namespace osu.Game.Input.Bindings [Indexed] [Column("Action")] - public new int Action + public int IntAction { - get { return (int)base.Action; } - set { base.Action = value; } + get { return (int)Action; } + set { Action = value; } } } } \ No newline at end of file diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index 057fa4d4e7..95fdaba339 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -74,7 +74,7 @@ namespace osu.Game.Input Connection.Insert(new DatabasedKeyBinding { KeyCombination = insertable.KeyCombination, - Action = (int)insertable.Action, + Action = insertable.Action, RulesetID = rulesetId, Variant = variant }); From 3df51540e19a39b0c8010d00153058ecf4ee0625 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 17:34:49 +0900 Subject: [PATCH 21/34] Code review fixes --- osu-framework | 2 +- .../Input/Bindings/DatabasedKeyBindingInputManager.cs | 2 +- ...ngInputManager.cs => GlobalKeyBindingInputManager.cs} | 6 +++--- osu.Game/Input/KeyBindingStore.cs | 9 ++------- osu.Game/OsuGameBase.cs | 4 ++-- ...balBindingsSection.cs => GlobalKeyBindingsSection.cs} | 6 +++--- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 3 ++- osu.Game/Overlays/KeyBindingOverlay.cs | 4 ++-- osu.Game/osu.Game.csproj | 4 ++-- 9 files changed, 18 insertions(+), 22 deletions(-) rename osu.Game/Input/Bindings/{GlobalBindingInputManager.cs => GlobalKeyBindingInputManager.cs} (88%) rename osu.Game/Overlays/KeyBinding/{GlobalBindingsSection.cs => GlobalKeyBindingsSection.cs} (68%) diff --git a/osu-framework b/osu-framework index fc13a4c2f1..acb9bfb084 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fc13a4c2f1eff443ffe7d5ff3ca5caa17b98ffbf +Subproject commit acb9bfb084b5607ff31c6269cb7942fa02624b75 diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs index e565c13b31..89aee7ca4d 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingInputManager.cs @@ -21,7 +21,7 @@ namespace osu.Game.Input.Bindings private KeyBindingStore store; - public override IEnumerable DefaultMappings => ruleset.CreateInstance().GetDefaultKeyBindings(); + public override IEnumerable DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(); /// /// Create a new instance. diff --git a/osu.Game/Input/Bindings/GlobalBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs similarity index 88% rename from osu.Game/Input/Bindings/GlobalBindingInputManager.cs rename to osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index d00ed588ae..4dff25d509 100644 --- a/osu.Game/Input/Bindings/GlobalBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -11,17 +11,17 @@ using osu.Framework.Input.Bindings; namespace osu.Game.Input.Bindings { - public class GlobalBindingInputManager : DatabasedKeyBindingInputManager + public class GlobalKeyBindingInputManager : DatabasedKeyBindingInputManager { private readonly Drawable handler; - public GlobalBindingInputManager(OsuGameBase game) + public GlobalKeyBindingInputManager(OsuGameBase game) { if (game is IKeyBindingHandler) handler = game; } - public override IEnumerable DefaultMappings => new[] + public override IEnumerable DefaultKeyBindings => new[] { new KeyBinding(Key.F8, GlobalAction.ToggleChat), new KeyBinding(Key.F9, GlobalAction.ToggleSocial), diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index 95fdaba339..f50acb4802 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -26,7 +26,7 @@ namespace osu.Game.Input } } - public void Register(KeyBindingInputManager manager) => insertDefaults(manager.DefaultMappings); + public void Register(KeyBindingInputManager manager) => insertDefaults(manager.DefaultKeyBindings); protected override int StoreVersion => 3; @@ -51,9 +51,7 @@ namespace osu.Game.Input protected override void Prepare(bool reset = false) { if (reset) - { Connection.DropTable(); - } Connection.CreateTable(); } @@ -90,9 +88,6 @@ namespace osu.Game.Input public IEnumerable Query(int? rulesetId = null, int? variant = null) => Query(b => b.RulesetID == rulesetId && b.Variant == variant); - public void Update(KeyBinding keyBinding) - { - Connection.Update(keyBinding); - } + public void Update(KeyBinding keyBinding) => Connection.Update(keyBinding); } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 571c75022e..a5600d1ef7 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -183,14 +183,14 @@ namespace osu.Game { base.LoadComplete(); - GlobalBindingInputManager globalBinding; + GlobalKeyBindingInputManager globalBinding; base.Content.Add(new RatioAdjust { Children = new Drawable[] { Cursor = new MenuCursor(), - globalBinding = new GlobalBindingInputManager(this) + globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, Child = new OsuTooltipContainer(Cursor) diff --git a/osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs similarity index 68% rename from osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs rename to osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 943fc4a416..7dd9919e5d 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -6,18 +6,18 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.KeyBinding { - public class GlobalBindingsSection : KeyBindingsSection + public class GlobalKeyBindingsSection : KeyBindingsSection { private readonly string name; public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; public override string Header => name; - public GlobalBindingsSection(KeyBindingInputManager manager, string name) + public GlobalKeyBindingsSection(KeyBindingInputManager manager, string name) { this.name = name; - Defaults = manager.DefaultMappings; + Defaults = manager.DefaultKeyBindings; } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 4cc179aaf1..082e1c0eec 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -219,7 +219,8 @@ namespace osu.Game.Overlays.KeyBinding Margin = new MarginPadding(padding); - //var isDefault = keyBinding.Action is Enum; + // todo: use this in a meaningful way + // var isDefault = keyBinding.Action is Enum; Masking = true; CornerRadius = padding; diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index e5061def77..ba45b3c812 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -15,9 +15,9 @@ namespace osu.Game.Overlays protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); [BackgroundDependencyLoader(permitNulls: true)] - private void load(RulesetStore rulesets, GlobalBindingInputManager global) + private void load(RulesetStore rulesets, GlobalKeyBindingInputManager global) { - AddSection(new GlobalBindingsSection(global, "Global")); + AddSection(new GlobalKeyBindingsSection(global, "Global")); foreach (var ruleset in rulesets.Query()) AddSection(new RulesetBindingsSection(ruleset)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f21ce528ca..07ab58bffc 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -95,14 +95,14 @@ - + - + From 7e1fc47b76d0fc6252549f0c65d51555b7d400ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 17:43:01 +0900 Subject: [PATCH 22/34] Fix forgotten rename --- osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs | 6 +++--- osu.Game/Overlays/KeyBindingOverlay.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs index 41e0c25507..cab285c72e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyConfiguration.cs @@ -7,19 +7,19 @@ namespace osu.Desktop.Tests.Visual { public class TestCaseKeyConfiguration : OsuTestCase { - private readonly KeyConfigurationOverlay configuration; + private readonly KeyBindingOverlay overlay; public override string Description => @"Key configuration"; public TestCaseKeyConfiguration() { - Child = configuration = new KeyConfigurationOverlay(); + Child = overlay = new KeyBindingOverlay(); } protected override void LoadComplete() { base.LoadComplete(); - configuration.Show(); + overlay.Show(); } } } diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index ba45b3c812..7d6ef7ffa6 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays { - public class KeyConfigurationOverlay : SettingsOverlay + public class KeyBindingOverlay : SettingsOverlay { protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); @@ -23,7 +23,7 @@ namespace osu.Game.Overlays AddSection(new RulesetBindingsSection(ruleset)); } - public KeyConfigurationOverlay() + public KeyBindingOverlay() : base(false) { } From 7e21ddb5eb5ab0fbdc466fe1209bad805fe999b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 19:17:29 +0900 Subject: [PATCH 23/34] Remove usage of HideOnEscape --- osu.Desktop/Overlays/VersionManager.cs | 2 -- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 9 +++++---- osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs | 2 -- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 -- osu.Game/Screens/Play/MenuOverlay.cs | 5 ++--- osu.Game/Screens/Play/SongProgress.cs | 2 -- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 -- 7 files changed, 7 insertions(+), 17 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 18fa43ab5c..b445340f50 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -27,8 +27,6 @@ namespace osu.Desktop.Overlays private UpdateManager updateManager; private NotificationOverlay notificationOverlay; - protected override bool HideOnEscape => false; - public override bool HandleInput => false; [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index dbbb069f7c..fe060f70f0 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -5,7 +5,6 @@ using OpenTK.Graphics; using OpenTK.Input; using osu.Framework.Input; using System; -using System.Linq; namespace osu.Game.Graphics.UserInterface { @@ -37,16 +36,18 @@ namespace osu.Game.Graphics.UserInterface BorderThickness = 0; } - protected override void OnFocusLost(InputState state) + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (state.Keyboard.Keys.Any(key => key == Key.Escape)) + if (args.Key == Key.Escape) { if (Text.Length > 0) Text = string.Empty; else Exit?.Invoke(); + return true; } - base.OnFocusLost(state); + + return base.OnKeyDown(state, args); } public override bool RequestsFocus => HoldFocus; diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index fa192b0825..cd77fb9f5b 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -15,8 +15,6 @@ namespace osu.Game.Graphics.UserInterface.Volume { private readonly VolumeMeter volumeMeterMaster; - protected override bool HideOnEscape => false; - private void volumeChanged(double newVolume) { Show(); diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 1ecfe90aa1..f9821782a7 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -22,8 +22,6 @@ namespace osu.Game.Overlays.Toolbar private readonly ToolbarUserArea userArea; - protected override bool HideOnEscape => false; - protected override bool BlockPassThroughMouse => false; private const double transition_time = 500; diff --git a/osu.Game/Screens/Play/MenuOverlay.cs b/osu.Game/Screens/Play/MenuOverlay.cs index a0f867d248..0a8e172e57 100644 --- a/osu.Game/Screens/Play/MenuOverlay.cs +++ b/osu.Game/Screens/Play/MenuOverlay.cs @@ -22,8 +22,6 @@ namespace osu.Game.Screens.Play private const int button_height = 70; private const float background_alpha = 0.75f; - protected override bool HideOnEscape => false; - protected override bool BlockPassThroughKeyboard => true; public Action OnRetry; @@ -95,7 +93,8 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Height = button_height, - Action = delegate { + Action = delegate + { action?.Invoke(); Hide(); } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index c513daf3d9..68f0cb3661 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -18,8 +18,6 @@ namespace osu.Game.Screens.Play { private const int bottom_bar_height = 5; - protected override bool HideOnEscape => false; - private static readonly Vector2 handle_size = new Vector2(14, 25); private const float transition_duration = 200; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 1fb9c707f0..872f7483b6 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -50,8 +50,6 @@ namespace osu.Game.Screens.Select AlwaysPresent = true; } - protected override bool HideOnEscape => false; - protected override bool BlockPassThroughMouse => false; protected override void PopIn() From 5ebec53970a8e6a3b24ec401a65a9028ba928eab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 19:17:42 +0900 Subject: [PATCH 24/34] Integrate key binding config with main settings --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 75 ++++++++++++------- osu.Game/Overlays/MainSettings.cs | 51 ++++++++++++- .../Sections/Input/KeyboardSettings.cs | 5 +- .../Settings/Sections/InputSection.cs | 4 +- osu.Game/Overlays/SettingsOverlay.cs | 69 +++++++++-------- 5 files changed, 139 insertions(+), 65 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 082e1c0eec..3415c22972 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.Shapes; using osu.Framework.Input; -using osu.Framework.Input.Bindings; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input; @@ -106,12 +105,6 @@ namespace osu.Game.Overlays.KeyBinding } }; - reloadBindings(); - } - - private void reloadBindings() - { - buttons.Clear(); foreach (var b in bindings) buttons.Add(new KeyButton(b)); } @@ -149,23 +142,46 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (HasFocus && !isModifier(args.Key)) + if (args.Key == Key.Delete) { - bindTarget.KeyBinding.KeyCombination = args.Key == Key.Delete ? Key.Unknown : new KeyCombination(state.Keyboard.Keys); - + bindTarget.UpdateKeyCombination(Key.Unknown); store.Update(bindTarget.KeyBinding); GetContainingInputManager().ChangeFocus(null); return true; } + if (HasFocus) + { + bindTarget.UpdateKeyCombination(state.Keyboard.Keys.ToArray()); + if (!isModifier(args.Key)) + finalise(); + return true; + } + return base.OnKeyDown(state, args); } + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + { + if (HasFocus) + { + finalise(); + return true; + } + + return base.OnKeyUp(state, args); + } + + private void finalise() + { + store.Update(bindTarget.KeyBinding); + GetContainingInputManager().ChangeFocus(null); + } + protected override void OnFocusLost(InputState state) { bindTarget.IsBinding = false; bindTarget = null; - reloadBindings(); pressAKey.FadeOut(300, Easing.OutQuint); pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; @@ -197,19 +213,16 @@ namespace osu.Game.Overlays.KeyBinding get { return isBinding; } set { + if (value == isBinding) return; isBinding = value; - if (value) + if (isBinding) { box.FadeColour(Color4.White, transition_time, Easing.OutQuint); Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - } else - { - box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); - } + updateHoverState(); } } @@ -261,25 +274,29 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnHover(InputState state) { - if (isBinding) - return false; - - box.FadeColour(hoverColour, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - + if (!isBinding) + updateHoverState(); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - if (isBinding) - return; - - box.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.White, transition_time, Easing.OutQuint); - + if (!isBinding) + updateHoverState(); base.OnHoverLost(state); } + + private void updateHoverState() + { + box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); + Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); + } + + public void UpdateKeyCombination(params Key[] newCombination) + { + KeyBinding.KeyCombination = newCombination; + Text.Text = KeyBinding.KeyCombination.ReadableString(); + } } } } \ No newline at end of file diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index 44c4d4ccdb..b040f5043b 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -2,7 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections; @@ -10,6 +12,8 @@ namespace osu.Game.Overlays { public class MainSettings : SettingsOverlay { + private readonly KeyBindingOverlay keyBindingOverlay; + protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), @@ -17,7 +21,7 @@ namespace osu.Game.Overlays new GameplaySection(), new AudioSection(), new SkinSection(), - new InputSection(), + new InputSection(keyBindingOverlay), new OnlineSection(), new MaintenanceSection(), new DebugSection(), @@ -26,8 +30,51 @@ namespace osu.Game.Overlays protected override Drawable CreateHeader() => new SettingsHeader("settings", "Change the way osu! behaves"); protected override Drawable CreateFooter() => new SettingsFooter(); - public MainSettings() : base(true) + public MainSettings() + : base(true) { + keyBindingOverlay = new KeyBindingOverlay { Depth = 1 }; + keyBindingOverlay.StateChanged += keyBindingOverlay_StateChanged; + } + + public override bool AcceptsFocus => keyBindingOverlay.State != Visibility.Visible; + + private void keyBindingOverlay_StateChanged(VisibilityContainer container, Visibility visibility) + { + const float hidden_width = 120; + + switch (visibility) + { + case Visibility.Visible: + Background.FadeTo(0.9f, 500, Easing.OutQuint); + SectionsContainer.FadeOut(100); + ContentContainer.MoveToX(hidden_width - ContentContainer.DrawWidth, 500, Easing.OutQuint); + break; + case Visibility.Hidden: + Background.FadeTo(0.6f, 500, Easing.OutQuint); + SectionsContainer.FadeIn(500, Easing.OutQuint); + ContentContainer.MoveToX(0, 500, Easing.OutQuint); + break; + } + } + + protected override void PopOut() + { + base.PopOut(); + keyBindingOverlay.State = Visibility.Hidden; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(keyBindingOverlay); + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + keyBindingOverlay.Margin = new MarginPadding { Left = ContentContainer.Margin.Left + ContentContainer.DrawWidth + ContentContainer.X }; } } } \ No newline at end of file diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs index 9ead4ca7a4..01e73d0168 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs @@ -10,14 +10,15 @@ namespace osu.Game.Overlays.Settings.Sections.Input { protected override string Header => "Keyboard"; - public KeyboardSettings() + public KeyboardSettings(KeyBindingOverlay keyConfig) { Children = new Drawable[] { new OsuButton { RelativeSizeAxes = Axes.X, - Text = "Key Configuration" + Text = "Key Configuration", + Action = () => keyConfig.ToggleVisibility() }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index 65df3746b3..5ece8aad77 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -12,12 +12,12 @@ namespace osu.Game.Overlays.Settings.Sections public override string Header => "Input"; public override FontAwesome Icon => FontAwesome.fa_keyboard_o; - public InputSection() + public InputSection(KeyBindingOverlay keyConfig) { Children = new Drawable[] { new MouseSettings(), - new KeyboardSettings(), + new KeyboardSettings(keyConfig), }; } } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 76f9ef3326..f62087ee71 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -29,6 +29,10 @@ namespace osu.Game.Overlays private const float sidebar_padding = 10; + protected Container ContentContainer; + + protected override Container Content => ContentContainer; + private Sidebar sidebar; private SidebarButton selectedSidebarButton; @@ -40,6 +44,8 @@ namespace osu.Game.Overlays private readonly bool showSidebar; + protected Box Background; + protected SettingsOverlay(bool showSidebar) { this.showSidebar = showSidebar; @@ -52,40 +58,43 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuGame game) { - Children = new Drawable[] + InternalChild = ContentContainer = new Container { - new Box + Width = width, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.6f, - }, - SectionsContainer = new SettingsSectionsContainer - { - RelativeSizeAxes = Axes.Y, - Width = width, - Margin = new MarginPadding { Left = SIDEBAR_WIDTH }, - ExpandableHeader = CreateHeader(), - FixedHeader = searchTextBox = new SearchTextBox + Background = new Box { - RelativeSizeAxes = Axes.X, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 0.95f, - Margin = new MarginPadding - { - Top = 20, - Bottom = 20 - }, - Exit = Hide, + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.6f, }, - Footer = CreateFooter() - }, + SectionsContainer = new SettingsSectionsContainer + { + RelativeSizeAxes = Axes.Both, + ExpandableHeader = CreateHeader(), + FixedHeader = searchTextBox = new SearchTextBox + { + RelativeSizeAxes = Axes.X, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 0.95f, + Margin = new MarginPadding + { + Top = 20, + Bottom = 20 + }, + Exit = Hide, + }, + Footer = CreateFooter() + }, + } }; if (showSidebar) { - Add(sidebar = new Sidebar { Width = SIDEBAR_WIDTH }); + AddInternal(sidebar = new Sidebar { Width = SIDEBAR_WIDTH }); SectionsContainer.SelectedSection.ValueChanged += section => { @@ -136,7 +145,7 @@ namespace osu.Game.Overlays { base.PopIn(); - SectionsContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); + ContentContainer.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH / 2); @@ -147,7 +156,7 @@ namespace osu.Game.Overlays { base.PopOut(); - SectionsContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint); + ContentContainer.MoveToX(-width, TRANSITION_LENGTH, Easing.OutQuint); sidebar?.MoveToX(-SIDEBAR_WIDTH, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(0, TRANSITION_LENGTH / 2); @@ -170,8 +179,8 @@ namespace osu.Game.Overlays { base.UpdateAfterChildren(); - SectionsContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 }; - SectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() }; + ContentContainer.Margin = new MarginPadding { Left = sidebar?.DrawWidth ?? 0 }; + ContentContainer.Padding = new MarginPadding { Top = getToolbarHeight() }; } protected class SettingsSectionsContainer : SectionsContainer From 71f83dbdfa606541b163d9cc17130bffb884560e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 20:16:40 +0900 Subject: [PATCH 25/34] Add null check for safety --- .../Settings/Sections/Audio/AudioDevicesSettings.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 47f7abf571..9b1c5e5e49 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -26,8 +26,11 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { base.Dispose(isDisposing); - audio.OnNewDevice -= onDeviceChanged; - audio.OnLostDevice -= onDeviceChanged; + if (audio != null) + { + audio.OnNewDevice -= onDeviceChanged; + audio.OnLostDevice -= onDeviceChanged; + } } private void updateItems() From c41ba7b7042eee8ac1d66839bbb5c6f0c6393451 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 22:55:13 +0900 Subject: [PATCH 26/34] Update with latest framework changes --- .../Bindings/GlobalKeyBindingInputManager.cs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index 4dff25d509..e9eab49c32 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Framework.Input.Bindings; namespace osu.Game.Input.Bindings @@ -31,23 +30,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { Key.LControl, Key.D }, GlobalAction.ToggleDirect), }; - protected override bool PropagateKeyDown(IEnumerable drawables, InputState state, KeyDownEventArgs args) - { - if (handler != null) - drawables = new[] { handler }.Concat(drawables); - - // always handle ourselves before all children. - return base.PropagateKeyDown(drawables, state, args); - } - - protected override bool PropagateKeyUp(IEnumerable drawables, InputState state, KeyUpEventArgs args) - { - if (handler != null) - drawables = new[] { handler }.Concat(drawables); - - // always handle ourselves before all children. - return base.PropagateKeyUp(drawables, state, args); - } + protected override IEnumerable GetKeyboardInputQueue() => new[] { handler }.Concat(base.GetKeyboardInputQueue()); } public enum GlobalAction From e64f455ff74d14fcf31f417d8406cc0f86e24241 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 23:01:10 +0900 Subject: [PATCH 27/34] Escape to cancel, again --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 3415c22972..274619991c 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -142,12 +142,16 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (args.Key == Key.Delete) + switch (args.Key) { - bindTarget.UpdateKeyCombination(Key.Unknown); - store.Update(bindTarget.KeyBinding); - GetContainingInputManager().ChangeFocus(null); - return true; + case Key.Escape: + GetContainingInputManager().ChangeFocus(null); + return true; + case Key.Delete: + bindTarget.UpdateKeyCombination(Key.Unknown); + store.Update(bindTarget.KeyBinding); + GetContainingInputManager().ChangeFocus(null); + return true; } if (HasFocus) From 09089a31260122e1385aa58acbdcbc6bb781731d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 23:20:08 +0900 Subject: [PATCH 28/34] Fix potential nullref --- osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index e9eab49c32..31be2e6adc 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -30,7 +30,8 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { Key.LControl, Key.D }, GlobalAction.ToggleDirect), }; - protected override IEnumerable GetKeyboardInputQueue() => new[] { handler }.Concat(base.GetKeyboardInputQueue()); + protected override IEnumerable GetKeyboardInputQueue() => + handler == null ? base.GetKeyboardInputQueue() : new[] { handler }.Concat(base.GetKeyboardInputQueue()); } public enum GlobalAction From 0c19202b9aff2371e5daef1f7d3d3e6236902b8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 23:20:18 +0900 Subject: [PATCH 29/34] Add basic back button --- osu.Game/Overlays/MainSettings.cs | 94 +++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index b040f5043b..6302c56018 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -5,14 +5,21 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections; +using osu.Game.Screens.Ranking; +using OpenTK; namespace osu.Game.Overlays { public class MainSettings : SettingsOverlay { private readonly KeyBindingOverlay keyBindingOverlay; + private BackButton backButton; protected override IEnumerable CreateSections() => new SettingsSection[] { @@ -49,11 +56,15 @@ namespace osu.Game.Overlays Background.FadeTo(0.9f, 500, Easing.OutQuint); SectionsContainer.FadeOut(100); ContentContainer.MoveToX(hidden_width - ContentContainer.DrawWidth, 500, Easing.OutQuint); + + backButton.Delay(100).FadeIn(100); break; case Visibility.Hidden: Background.FadeTo(0.6f, 500, Easing.OutQuint); SectionsContainer.FadeIn(500, Easing.OutQuint); ContentContainer.MoveToX(0, 500, Easing.OutQuint); + + backButton.FadeOut(100); break; } } @@ -68,6 +79,14 @@ namespace osu.Game.Overlays private void load() { AddInternal(keyBindingOverlay); + AddInternal(backButton = new BackButton + { + Alpha = 0, + Height = 150, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Action = () => keyBindingOverlay.Hide() + }); } protected override void UpdateAfterChildren() @@ -75,6 +94,81 @@ namespace osu.Game.Overlays base.UpdateAfterChildren(); keyBindingOverlay.Margin = new MarginPadding { Left = ContentContainer.Margin.Left + ContentContainer.DrawWidth + ContentContainer.X }; + + backButton.Margin = new MarginPadding { Left = ContentContainer.Margin.Left }; + backButton.Width = ContentContainer.DrawWidth + ContentContainer.X; + } + + private class BackButton : OsuClickableContainer + { + private FillFlowContainer flow; + private AspectContainer aspect; + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + aspect = new AspectContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + flow = new FillFlowContainer + { + Anchor = Anchor.TopCentre, + RelativePositionAxes = Axes.Y, + Y = 0.4f, + AutoSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + Children = new[] + { + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_left }, + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_left }, + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.fa_chevron_left }, + } + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + RelativePositionAxes = Axes.Y, + Y = 0.7f, + TextSize = 12, + Font = @"Exo2.0-Bold", + Origin = Anchor.Centre, + Text = @"back", + }, + } + } + }; + } + + protected override bool OnHover(InputState state) + { + flow.TransformSpacingTo(new Vector2(5), 500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + flow.TransformSpacingTo(new Vector2(0), 500, Easing.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + aspect.ScaleTo(0.75f, 2000, Easing.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + aspect.ScaleTo(1, 1000, Easing.OutElastic); + return base.OnMouseUp(state, args); + } } } } \ No newline at end of file From c6c9c5431fe19c4638d24877bb3c7cbced88b7c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Aug 2017 23:22:12 +0900 Subject: [PATCH 30/34] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index acb9bfb084..68e461df82 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit acb9bfb084b5607ff31c6269cb7942fa02624b75 +Subproject commit 68e461df82a608d5748e758101f99f9d3081f8b6 From 8c05a40fbfd5decac27b45ecea116d6ce4c23dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 16 Aug 2017 01:10:09 +0900 Subject: [PATCH 31/34] Use SliderStep instead of TestCaseSliderBar This greatly simplifies TestCaseKeyCounter and TestCaseHitObject and allows more future automation. --- .../Visual/TestCaseHitObjects.cs | 27 ++----------------- .../Visual/TestCaseKeyCounter.cs | 27 +++---------------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs index df5f9f65b8..8dfaa7ea3d 100644 --- a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs @@ -27,35 +27,13 @@ namespace osu.Desktop.Tests.Visual { var rateAdjustClock = new StopwatchClock(true); framedClock = new FramedClock(rateAdjustClock); - playbackSpeed.ValueChanged += delegate { rateAdjustClock.Rate = playbackSpeed.Value; }; - - playbackSpeed.TriggerChange(); AddStep(@"circles", () => loadHitobjects(HitObjectType.Circle)); AddStep(@"slider", () => loadHitobjects(HitObjectType.Slider)); AddStep(@"spinner", () => loadHitobjects(HitObjectType.Spinner)); - AddToggleStep(@"auto", state => { auto = state; loadHitobjects(mode); }); - - BasicSliderBar sliderBar; - Add(new Container - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new SpriteText { Text = "Playback Speed" }, - sliderBar = new BasicSliderBar - { - Width = 150, - Height = 10, - SelectionColor = Color4.Orange, - } - } - }); - - sliderBar.Current.BindTo(playbackSpeed); + AddToggleStep("Auto", state => { auto = state; loadHitobjects(mode); }); + AddSliderStep("Playback speed", 0.0, 2.0, 0.5, v => rateAdjustClock.Rate = v); framedClock.ProcessFrame(); @@ -75,7 +53,6 @@ namespace osu.Desktop.Tests.Visual private HitObjectType mode = HitObjectType.Slider; - private readonly BindableNumber playbackSpeed = new BindableDouble(0.5) { MinValue = 0, MaxValue = 1 }; private readonly Container playfieldContainer; private readonly Container approachContainer; diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs index efb662d3b9..f0c77659eb 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs @@ -34,34 +34,13 @@ namespace osu.Desktop.Tests.Visual new KeyCounterMouse(MouseButton.Right), }, }; - BindableInt bindable = new BindableInt { MinValue = 0, MaxValue = 200, Default = 50 }; - bindable.ValueChanged += delegate { kc.FadeTime = bindable.Value; }; - AddStep("Add Random", () => + + AddStep("Add random", () => { Key key = (Key)((int)Key.A + RNG.Next(26)); kc.Add(new KeyCounterKeyboard(key)); }); - - TestSliderBar sliderBar; - - Add(new Container - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new SpriteText { Text = "FadeTime" }, - sliderBar = new TestSliderBar - { - Width = 150, - Height = 10, - SelectionColor = Color4.Orange, - } - } - }); - - sliderBar.Current.BindTo(bindable); + AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v); Add(kc); } From 55b159b976208e72c422d5353639ae8f7fb3628a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 16 Aug 2017 13:02:11 +0900 Subject: [PATCH 32/34] Remove unnecessary usings --- osu.Desktop.Tests/Visual/TestCaseHitObjects.cs | 4 ---- osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs | 3 --- 2 files changed, 7 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs index 8dfaa7ea3d..75e1a656de 100644 --- a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs @@ -2,18 +2,14 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Timing; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using OpenTK; -using OpenTK.Graphics; namespace osu.Desktop.Tests.Visual { diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs index f0c77659eb..1861a77a3a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs @@ -1,11 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.MathUtils; using osu.Game.Screens.Play; From 118d0f09704483c7d8ba03735d1085891d1c3e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 17 Aug 2017 07:28:07 +0900 Subject: [PATCH 33/34] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index acb9bfb084..5c22092e59 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit acb9bfb084b5607ff31c6269cb7942fa02624b75 +Subproject commit 5c22092e590d589927962b8d0173dae5f9b1405c From 4ef1be308037af1d4775b9c0d8a491d5ab2aae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 17 Aug 2017 08:43:45 +0900 Subject: [PATCH 34/34] More localised key binding hover colour logic --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 274619991c..44aee0e666 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -220,13 +220,7 @@ namespace osu.Game.Overlays.KeyBinding if (value == isBinding) return; isBinding = value; - if (isBinding) - { - box.FadeColour(Color4.White, transition_time, Easing.OutQuint); - Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint); - } - else - updateHoverState(); + updateHoverState(); } } @@ -278,22 +272,28 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnHover(InputState state) { - if (!isBinding) - updateHoverState(); + updateHoverState(); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - if (!isBinding) - updateHoverState(); + updateHoverState(); base.OnHoverLost(state); } private void updateHoverState() { - box.FadeColour(IsHovered ? hoverColour : Color4.Black, transition_time, Easing.OutQuint); - Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint); + 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(params Key[] newCombination)