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 NUnit.Framework;
5using osu.Framework.Graphics;
6using osu.Framework.Graphics.Containers;
7using osu.Framework.Graphics.Shapes;
8using osu.Framework.Input.Events;
9using osu.Framework.Testing;
10using osuTK;
11using osuTK.Graphics;
12using osuTK.Input;
13
14namespace osu.Framework.Tests.Visual.UserInterface
15{
16 public class TestSceneFocusedOverlayContainer : ManualInputManagerTestScene
17 {
18 private TestFocusedOverlayContainer overlayContainer;
19
20 private ParentContainer parentContainer;
21
22 [Test]
23 public void TestClickDismiss()
24 {
25 AddStep("create container", () => { Child = overlayContainer = new TestFocusedOverlayContainer(); });
26
27 AddStep("show", () => overlayContainer.Show());
28 AddAssert("has focus", () => overlayContainer.HasFocus);
29
30 AddStep("click inside", () =>
31 {
32 InputManager.MoveMouseTo(overlayContainer.ScreenSpaceDrawQuad.Centre);
33 InputManager.PressButton(MouseButton.Left);
34 InputManager.ReleaseButton(MouseButton.Left);
35 });
36
37 AddAssert("still has focus", () => overlayContainer.HasFocus);
38
39 AddStep("click outside", () =>
40 {
41 InputManager.MoveMouseTo(overlayContainer.ScreenSpaceDrawQuad.TopLeft - new Vector2(20));
42 InputManager.PressButton(MouseButton.Left);
43 InputManager.ReleaseButton(MouseButton.Left);
44 });
45
46 AddAssert("lost focus", () => !overlayContainer.HasFocus);
47 AddAssert("not visible", () => overlayContainer.State.Value == Visibility.Hidden);
48 }
49
50 [TestCase(true)]
51 [TestCase(false)]
52 public void TestScrollBlocking(bool isBlocking)
53 {
54 AddStep("create container", () =>
55 {
56 Child = parentContainer = new ParentContainer
57 {
58 RelativeSizeAxes = Axes.Both,
59 Children = new Drawable[]
60 {
61 overlayContainer = new TestFocusedOverlayContainer(blockScrollInput: isBlocking)
62 }
63 };
64 });
65
66 AddStep("show", () => overlayContainer.Show());
67
68 AddAssert("has focus", () => overlayContainer.HasFocus);
69
70 int initialScrollCount = 0;
71
72 AddStep("scroll inside", () =>
73 {
74 initialScrollCount = parentContainer.ScrollReceived;
75 InputManager.MoveMouseTo(overlayContainer.ScreenSpaceDrawQuad.Centre);
76 InputManager.ScrollVerticalBy(1);
77 });
78
79 if (isBlocking)
80 AddAssert("scroll not received by parent", () => parentContainer.ScrollReceived == initialScrollCount);
81 else
82 AddAssert("scroll received by parent", () => parentContainer.ScrollReceived == ++initialScrollCount);
83
84 AddStep("scroll outside", () =>
85 {
86 InputManager.MoveMouseTo(overlayContainer.ScreenSpaceDrawQuad.TopLeft - new Vector2(20));
87 InputManager.ScrollVerticalBy(1);
88 });
89
90 AddAssert("scroll received by parent", () => parentContainer.ScrollReceived == ++initialScrollCount);
91 }
92
93 private class TestFocusedOverlayContainer : FocusedOverlayContainer
94 {
95 protected override bool StartHidden { get; }
96
97 protected override bool BlockPositionalInput => true;
98
99 protected override bool BlockNonPositionalInput => false;
100
101 protected override bool BlockScrollInput { get; }
102
103 public TestFocusedOverlayContainer(bool startHidden = true, bool blockScrollInput = true)
104 {
105 BlockScrollInput = blockScrollInput;
106
107 StartHidden = startHidden;
108
109 Size = new Vector2(0.5f);
110 RelativeSizeAxes = Axes.Both;
111
112 Anchor = Anchor.Centre;
113 Origin = Anchor.Centre;
114
115 Children = new Drawable[]
116 {
117 new Box
118 {
119 Colour = Color4.Cyan,
120 RelativeSizeAxes = Axes.Both,
121 },
122 };
123
124 State.ValueChanged += e => FireCount++;
125 }
126
127 public int FireCount { get; private set; }
128
129 public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
130
131 protected override bool OnClick(ClickEvent e)
132 {
133 if (!base.ReceivePositionalInputAt(e.ScreenSpaceMousePosition))
134 {
135 Hide();
136 return true;
137 }
138
139 return true;
140 }
141
142 protected override bool OnMouseDown(MouseDownEvent e)
143 {
144 base.OnMouseDown(e);
145 return true;
146 }
147
148 protected override void PopIn()
149 {
150 this.FadeIn(1000, Easing.OutQuint);
151 this.ScaleTo(1, 1000, Easing.OutElastic);
152
153 base.PopIn();
154 }
155
156 protected override void PopOut()
157 {
158 this.FadeOut(1000, Easing.OutQuint);
159 this.ScaleTo(0.4f, 1000, Easing.OutQuint);
160
161 base.PopOut();
162 }
163 }
164 }
165
166 public class ParentContainer : Container
167 {
168 public int ScrollReceived;
169
170 protected override bool OnScroll(ScrollEvent e)
171 {
172 ScrollReceived++;
173 return base.OnScroll(e);
174 }
175 }
176}