A game framework written with osu! in mind.
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 NUnit.Framework;
6using osu.Framework.Graphics;
7using osu.Framework.Graphics.Shapes;
8using osu.Framework.Input.Events;
9using osu.Framework.Testing;
10using osuTK;
11using osuTK.Input;
12
13namespace osu.Framework.Tests.Input
14{
15 [HeadlessTest]
16 public class MouseInputTest : ManualInputManagerTestScene
17 {
18 /// <summary>
19 /// Tests that a drawable that is removed from the hierarchy (or is otherwise removed from the input queues) does not receive an OnClick() event on mouse up.
20 /// </summary>
21 [Test]
22 public void TestNoLongerValidDrawableDoesNotReceiveClick()
23 {
24 var receptors = new InputReceptor[2];
25
26 AddStep("create hierarchy", () =>
27 {
28 Children = new Drawable[]
29 {
30 receptors[0] = new InputReceptor { Size = new Vector2(100) },
31 receptors[1] = new InputReceptor { Size = new Vector2(100) }
32 };
33 });
34
35 AddStep("move mouse to receptors", () => InputManager.MoveMouseTo(receptors[0]));
36 AddStep("press button", () => InputManager.PressButton(MouseButton.Left));
37
38 AddStep("remove receptor 0", () => Remove(receptors[0]));
39
40 AddStep("release button", () => InputManager.ReleaseButton(MouseButton.Left));
41 AddAssert("receptor 0 did not receive click", () => !receptors[0].ClickReceived);
42 }
43
44 /// <summary>
45 /// Tests that a drawable that is removed and re-added to the hierarchy still receives an OnClick() event.
46 /// </summary>
47 [Test]
48 public void TestReValidatedDrawableReceivesClick()
49 {
50 var receptors = new InputReceptor[2];
51
52 AddStep("create hierarchy", () =>
53 {
54 Children = new Drawable[]
55 {
56 receptors[0] = new InputReceptor { Size = new Vector2(100) },
57 receptors[1] = new InputReceptor { Size = new Vector2(100) }
58 };
59 });
60
61 AddStep("move mouse to receptors", () => InputManager.MoveMouseTo(receptors[0]));
62 AddStep("press button", () => InputManager.PressButton(MouseButton.Left));
63
64 AddStep("remove receptor 0", () => Remove(receptors[0]));
65 AddStep("add back receptor 0", () => Add(receptors[0]));
66
67 AddStep("release button", () => InputManager.ReleaseButton(MouseButton.Left));
68 AddAssert("receptor 0 received click", () => receptors[0].ClickReceived);
69 }
70
71 /// <summary>
72 /// Tests that a drawable that is removed from the hierarchy (or is otherwise removed from the input queues) does not receive an OnDoubleClick() event.
73 /// </summary>
74 [Test]
75 public void TestNoLongerValidDrawableDoesNotReceiveDoubleClick()
76 {
77 InputReceptor receptor = null;
78
79 AddStep("create hierarchy", () =>
80 {
81 Child = receptor = new InputReceptor
82 {
83 Size = new Vector2(100),
84 Click = () => true
85 };
86 });
87
88 AddStep("move mouse to receptor", () => InputManager.MoveMouseTo(receptor));
89 AddStep("click", () => InputManager.Click(MouseButton.Left));
90
91 AddStep("remove receptor and double click", () =>
92 {
93 Remove(receptor); // Test correctness can be asserted by removing this line and ensuring the test fails
94 InputManager.Click(MouseButton.Left); // Done immediately after due to double clicks being frame-dependent (timing)
95 });
96
97 AddAssert("receptor did not receive double click", () => !receptor.DoubleClickReceived);
98 }
99
100 private class InputReceptor : Box
101 {
102 public bool ClickReceived { get; set; }
103 public bool DoubleClickReceived { get; set; }
104
105 public new Func<bool> Click;
106
107 protected override bool OnClick(ClickEvent e)
108 {
109 ClickReceived = true;
110 return Click?.Invoke() ?? false;
111 }
112
113 protected override bool OnDoubleClick(DoubleClickEvent e)
114 {
115 DoubleClickReceived = true;
116 return true;
117 }
118 }
119 }
120}