A game framework written with osu! in mind.
at master 7.8 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Collections.Generic; 6using NUnit.Framework; 7using osu.Framework.Graphics; 8using osu.Framework.Graphics.UserInterface; 9using osu.Framework.Input.Bindings; 10using osu.Framework.Testing; 11using osuTK; 12using osuTK.Input; 13 14namespace osu.Framework.Tests.Visual.Input 15{ 16 [HeadlessTest] 17 public class TestSceneKeyBindingContainer : ManualInputManagerTestScene 18 { 19 [Test] 20 public void TestTriggerWithNoKeyBindings() 21 { 22 bool pressedReceived = false; 23 bool releasedReceived = false; 24 25 TestKeyBindingContainer keyBindingContainer = null; 26 27 AddStep("add container", () => 28 { 29 pressedReceived = false; 30 releasedReceived = false; 31 32 Child = keyBindingContainer = new TestKeyBindingContainer 33 { 34 Child = new TestKeyBindingReceptor 35 { 36 Pressed = _ => pressedReceived = true, 37 Released = _ => releasedReceived = true 38 } 39 }; 40 }); 41 42 AddStep("trigger press", () => keyBindingContainer.TriggerPressed(TestAction.ActionA)); 43 AddAssert("press received", () => pressedReceived); 44 45 AddStep("trigger release", () => keyBindingContainer.TriggerReleased(TestAction.ActionA)); 46 AddAssert("release received", () => releasedReceived); 47 } 48 49 [Test] 50 public void TestPressKeyBeforeKeyBindingContainerAdded() 51 { 52 List<TestAction> pressedActions = new List<TestAction>(); 53 List<TestAction> releasedActions = new List<TestAction>(); 54 55 AddStep("press key B", () => InputManager.PressKey(Key.B)); 56 57 AddStep("add container", () => 58 { 59 pressedActions.Clear(); 60 releasedActions.Clear(); 61 62 Child = new TestKeyBindingContainer 63 { 64 Child = new TestKeyBindingReceptor 65 { 66 Pressed = a => pressedActions.Add(a), 67 Released = a => releasedActions.Add(a) 68 } 69 }; 70 }); 71 72 AddStep("press key A", () => InputManager.PressKey(Key.A)); 73 AddAssert("only one action triggered", () => pressedActions.Count == 1); 74 AddAssert("ActionA triggered", () => pressedActions[0] == TestAction.ActionA); 75 AddAssert("no actions released", () => releasedActions.Count == 0); 76 77 AddStep("release key A", () => InputManager.ReleaseKey(Key.A)); 78 AddAssert("only one action triggered", () => pressedActions.Count == 1); 79 AddAssert("only one action released", () => releasedActions.Count == 1); 80 AddAssert("ActionA released", () => releasedActions[0] == TestAction.ActionA); 81 } 82 83 [Test] 84 public void TestKeyHandledByOtherDrawableDoesNotTrigger() 85 { 86 List<TestAction> pressedActions = new List<TestAction>(); 87 List<TestAction> releasedActions = new List<TestAction>(); 88 89 TextBox textBox = null; 90 91 AddStep("add children", () => 92 { 93 pressedActions.Clear(); 94 releasedActions.Clear(); 95 96 Child = new TestKeyBindingContainer 97 { 98 Children = new Drawable[] 99 { 100 textBox = new BasicTextBox 101 { 102 Anchor = Anchor.Centre, 103 Origin = Anchor.Centre, 104 Size = new Vector2(200, 30) 105 }, 106 new TestKeyBindingReceptor 107 { 108 Pressed = a => pressedActions.Add(a), 109 Released = a => releasedActions.Add(a) 110 } 111 } 112 }; 113 }); 114 115 AddStep("focus textbox and move mouse away", () => 116 { 117 InputManager.MoveMouseTo(textBox); 118 InputManager.Click(MouseButton.Left); 119 InputManager.MoveMouseTo(textBox, new Vector2(0, 100)); 120 }); 121 122 AddStep("press enter", () => InputManager.PressKey(Key.Enter)); 123 AddStep("press mouse button", () => InputManager.PressButton(MouseButton.Left)); 124 125 AddStep("release enter", () => InputManager.ReleaseKey(Key.Enter)); 126 AddStep("release mouse button", () => InputManager.ReleaseButton(MouseButton.Left)); 127 128 AddAssert("no pressed actions", () => pressedActions.Count == 0); 129 AddAssert("no released actions", () => releasedActions.Count == 0); 130 } 131 132 [Test] 133 public void TestReleasingSpecificModifierDoesNotReleaseCommonBindingIfOtherKeyIsActive() 134 { 135 bool pressedReceived = false; 136 bool releasedReceived = false; 137 138 AddStep("add container", () => 139 { 140 pressedReceived = false; 141 releasedReceived = false; 142 143 Child = new TestKeyBindingContainer 144 { 145 Child = new TestKeyBindingReceptor 146 { 147 Pressed = _ => pressedReceived = true, 148 Released = _ => releasedReceived = true 149 } 150 }; 151 }); 152 153 AddStep("press lctrl", () => InputManager.PressKey(Key.LControl)); 154 AddAssert("press received", () => pressedReceived); 155 156 AddStep("reset variables", () => 157 { 158 pressedReceived = false; 159 releasedReceived = false; 160 }); 161 162 AddStep("press rctrl", () => InputManager.PressKey(Key.RControl)); 163 AddAssert("press not received", () => !pressedReceived); 164 AddAssert("release not received", () => !releasedReceived); 165 166 AddStep("release rctrl", () => InputManager.ReleaseKey(Key.RControl)); 167 AddAssert("release not received", () => !releasedReceived); 168 169 AddStep("release lctrl", () => InputManager.ReleaseKey(Key.LControl)); 170 AddAssert("release received", () => releasedReceived); 171 } 172 173 private class TestKeyBindingReceptor : Drawable, IKeyBindingHandler<TestAction> 174 { 175 public Action<TestAction> Pressed; 176 public Action<TestAction> Released; 177 178 public TestKeyBindingReceptor() 179 { 180 RelativeSizeAxes = Axes.Both; 181 } 182 183 public bool OnPressed(TestAction action) 184 { 185 Pressed?.Invoke(action); 186 return true; 187 } 188 189 public void OnReleased(TestAction action) 190 { 191 Released?.Invoke(action); 192 } 193 } 194 195 private class TestKeyBindingContainer : KeyBindingContainer<TestAction> 196 { 197 public override IEnumerable<IKeyBinding> DefaultKeyBindings => new IKeyBinding[] 198 { 199 new KeyBinding(InputKey.A, TestAction.ActionA), 200 new KeyBinding(new KeyCombination(InputKey.A, InputKey.B), TestAction.ActionAB), 201 new KeyBinding(InputKey.Enter, TestAction.ActionEnter), 202 new KeyBinding(InputKey.Control, TestAction.ActionControl) 203 }; 204 } 205 206 private enum TestAction 207 { 208 ActionA, 209 ActionAB, 210 ActionEnter, 211 ActionControl 212 } 213 } 214}