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.Drawing;
5using System.Linq;
6using NUnit.Framework;
7using osu.Framework.Allocation;
8using osu.Framework.Bindables;
9using osu.Framework.Configuration;
10using osu.Framework.Extensions.IEnumerableExtensions;
11using osu.Framework.Graphics;
12using osu.Framework.Graphics.Containers;
13using osu.Framework.Graphics.Sprites;
14using osu.Framework.Graphics.UserInterface;
15using osu.Framework.Input;
16using osu.Framework.Logging;
17using osu.Framework.Platform;
18using osuTK;
19
20namespace osu.Framework.Tests.Visual.Platform
21{
22 public class TestSceneFullscreen : FrameworkTestScene
23 {
24 private readonly SpriteText currentActualSize = new SpriteText();
25 private readonly SpriteText currentDisplayMode = new SpriteText();
26 private readonly SpriteText currentWindowMode = new SpriteText();
27 private readonly SpriteText currentWindowState = new SpriteText();
28 private readonly SpriteText supportedWindowModes = new SpriteText();
29 private readonly Dropdown<Display> displaysDropdown;
30
31 private IWindow window;
32 private readonly BindableSize sizeFullscreen = new BindableSize();
33 private readonly Bindable<WindowMode> windowMode = new Bindable<WindowMode>();
34
35 public TestSceneFullscreen()
36 {
37 var currentBindableSize = new SpriteText();
38
39 Child = new FillFlowContainer
40 {
41 Padding = new MarginPadding(10),
42 Spacing = new Vector2(10),
43 Children = new Drawable[]
44 {
45 currentBindableSize,
46 currentActualSize,
47 currentDisplayMode,
48 currentWindowMode,
49 currentWindowState,
50 supportedWindowModes,
51 displaysDropdown = new BasicDropdown<Display> { Width = 600 }
52 },
53 };
54
55 sizeFullscreen.ValueChanged += newSize => currentBindableSize.Text = $"Fullscreen size: {newSize.NewValue}";
56 windowMode.ValueChanged += newMode => currentWindowMode.Text = $"Window Mode: {newMode.NewValue}";
57 }
58
59 [Resolved]
60 private FrameworkConfigManager config { get; set; }
61
62 [BackgroundDependencyLoader]
63 private void load(GameHost host)
64 {
65 window = host.Window;
66 config.BindWith(FrameworkSetting.SizeFullscreen, sizeFullscreen);
67 config.BindWith(FrameworkSetting.WindowMode, windowMode);
68 currentWindowMode.Text = $"Window Mode: {windowMode}";
69
70 if (window == null)
71 return;
72
73 displaysDropdown.Items = window.Displays;
74 displaysDropdown.Current.BindTo(window.CurrentDisplayBindable);
75
76 supportedWindowModes.Text = $"Supported Window Modes: {string.Join(", ", window.SupportedWindowModes)}";
77 }
78
79 [Test]
80 public void TestScreenModeSwitch()
81 {
82 if (window == null)
83 {
84 Assert.Ignore("This test cannot run in headless mode (a window instance is required).");
85 return;
86 }
87
88 // so the test case doesn't change fullscreen size just when you enter it
89 AddStep("nothing", () => { });
90
91 var initialWindowMode = windowMode.Value;
92
93 // if we support windowed mode, switch to it and test resizing the window
94 if (window.SupportedWindowModes.Contains(WindowMode.Windowed))
95 {
96 AddStep("change to windowed", () => windowMode.Value = WindowMode.Windowed);
97 AddStep("change window size", () => config.SetValue(FrameworkSetting.WindowedSize, new Size(640, 640)));
98 }
99
100 // if we support borderless, test that it can be used
101 if (window.SupportedWindowModes.Contains(WindowMode.Borderless))
102 AddStep("change to borderless", () => windowMode.Value = WindowMode.Borderless);
103
104 // if we support fullscreen mode, switch to it and test swapping resolutions
105 if (window.SupportedWindowModes.Contains(WindowMode.Fullscreen))
106 {
107 AddStep("change to fullscreen", () => windowMode.Value = WindowMode.Fullscreen);
108 AddAssert("window position updated", () => ((SDL2DesktopWindow)window).Position == new Point(0, 0));
109 testResolution(1920, 1080);
110 testResolution(1280, 960);
111 testResolution(9999, 9999);
112 }
113
114 // go back to initial window mode
115 AddStep($"revert to {initialWindowMode.ToString()}", () => windowMode.Value = initialWindowMode);
116
117 // show the available displays
118 AddStep("query Window.Displays", () =>
119 {
120 var displaysArray = window.Displays.ToArray();
121 Logger.Log($"Available displays: {displaysArray.Length}");
122 displaysArray.ForEach(display =>
123 {
124 Logger.Log(display.ToString());
125 display.DisplayModes.ForEach(mode => Logger.Log($"-- {mode}"));
126 });
127 });
128
129 AddStep("query Window.CurrentDisplay", () => Logger.Log(window.CurrentDisplayBindable.ToString()));
130
131 AddStep("query Window.CurrentDisplayMode", () => Logger.Log(window.CurrentDisplayMode.ToString()));
132 }
133
134 [Test]
135 public void TestConfineModes()
136 {
137 AddStep("set confined to never", () => config.SetValue(FrameworkSetting.ConfineMouseMode, ConfineMouseMode.Never));
138 AddStep("set confined to fullscreen", () => config.SetValue(FrameworkSetting.ConfineMouseMode, ConfineMouseMode.Fullscreen));
139 AddStep("set confined to always", () => config.SetValue(FrameworkSetting.ConfineMouseMode, ConfineMouseMode.Always));
140 }
141
142 protected override void Update()
143 {
144 base.Update();
145
146 currentActualSize.Text = $"Window size: {window?.ClientSize}";
147 currentDisplayMode.Text = $"Display mode: {window?.CurrentDisplayMode}";
148 currentWindowState.Text = $"Window State: {window?.WindowState}";
149 }
150
151 private void testResolution(int w, int h)
152 {
153 AddStep($"set to {w}x{h}", () => sizeFullscreen.Value = new Size(w, h));
154 }
155 }
156}