From 5e5ad9a8999dcb80969cb53beed10c0e63098097 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2017 12:53:50 +0900 Subject: [PATCH 1/2] Add basic on-screen display --- .../Tests/TestCaseOnScreenDisplay.cs | 47 ++++ .../osu.Desktop.VisualTests.csproj | 1 + osu.Game/OsuGame.cs | 1 + osu.Game/Overlays/OnScreenDisplay.cs | 262 ++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 5 files changed, 312 insertions(+) create mode 100644 osu.Desktop.VisualTests/Tests/TestCaseOnScreenDisplay.cs create mode 100644 osu.Game/Overlays/OnScreenDisplay.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCaseOnScreenDisplay.cs b/osu.Desktop.VisualTests/Tests/TestCaseOnScreenDisplay.cs new file mode 100644 index 0000000000..3cefb8a3d2 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCaseOnScreenDisplay.cs @@ -0,0 +1,47 @@ +// 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.Configuration; +using osu.Framework.Testing; +using osu.Game.Overlays; + +namespace osu.Desktop.VisualTests.Tests +{ + internal class TestCaseOnScreenDisplay : TestCase + { + private FrameworkConfigManager config; + private Bindable frameSyncMode; + + public override string Description => @"Make it easier to see setting changes"; + + public override void Reset() + { + base.Reset(); + + Add(new OnScreenDisplay()); + + frameSyncMode = config.GetBindable(FrameworkSetting.FrameSync); + + FrameSync initial = frameSyncMode.Value; + + AddRepeatStep(@"Change frame limiter", setNextMode, 3); + + AddStep(@"Restore frame limiter", () => frameSyncMode.Value = initial); + } + + private void setNextMode() + { + var nextMode = frameSyncMode.Value + 1; + if (nextMode > FrameSync.Unlimited) + nextMode = FrameSync.VSync; + frameSyncMode.Value = nextMode; + } + + [BackgroundDependencyLoader] + private void load(FrameworkConfigManager config) + { + this.config = config; + } + } +} diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 9b07ebf90b..dbb1750b72 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -195,6 +195,7 @@ + diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9ce725661b..dfa94b2bfe 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -146,6 +146,7 @@ namespace osu.Game }, volume = new VolumeControl(), overlayContent = new Container{ RelativeSizeAxes = Axes.Both }, + new OnScreenDisplay(), new GlobalHotkeys //exists because UserInputManager is at a level below us. { Handler = globalHotkeyPressed diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs new file mode 100644 index 0000000000..1c837eb602 --- /dev/null +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -0,0 +1,262 @@ +// 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.Configuration; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; + +namespace osu.Game.Overlays +{ + public class OnScreenDisplay : Container + { + private readonly Container box; + + public override bool HandleInput => false; + + private readonly SpriteText textLine1; + private readonly SpriteText textLine2; + private readonly SpriteText textLine3; + + private const float height = 110; + private const float height_contracted = height * 0.9f; + + private readonly FillFlowContainer optionLights; + + public OnScreenDisplay() + { + RelativeSizeAxes = Axes.Both; + + Children = new Drawable[] + { + box = new Container + { + Origin = Anchor.Centre, + RelativePositionAxes = Axes.Both, + Position = new Vector2(0.5f, 0.75f), + Masking = true, + AutoSizeAxes = Axes.X, + Height = height_contracted, + Alpha = 0, + CornerRadius = 20, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.7f, + }, + new Container // purely to add a minimum width + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 240, + RelativeSizeAxes = Axes.Y, + }, + textLine1 = new SpriteText + { + Padding = new MarginPadding(10), + Font = @"Exo2.0-Black", + Spacing = new Vector2(1, 0), + TextSize = 14, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }, + textLine2 = new SpriteText + { + TextSize = 24, + Font = @"Exo2.0-Light", + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + }, + new FillFlowContainer + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + optionLights = new FillFlowContainer + { + Padding = new MarginPadding { Top = 20, Bottom = 5 }, + Spacing = new Vector2(5, 0), + Direction = FillDirection.Horizontal, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.Both + }, + textLine3 = new SpriteText + { + Padding = new MarginPadding { Bottom = 15 }, + Font = @"Exo2.0-Bold", + TextSize = 12, + Alpha = 0.3f, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }, + } + } + } + }, + }; + } + + [BackgroundDependencyLoader] + private void load(FrameworkConfigManager frameworkConfig) + { + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.FrameSync), v => display(v, "Frame Limiter", v.GetDescription(), "Ctrl+F7")); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", v, v)); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay), v => display(v, "Debug Logs", v ? "visible" : "hidden", "Ctrl+F10")); + + Action displayResolution = delegate { display(null, "Screen Resolution", frameworkConfig.Get(FrameworkSetting.Width) + "x" + frameworkConfig.Get(FrameworkSetting.Height)); }; + + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Width), v => displayResolution()); + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Height), v => displayResolution()); + + trackSetting(frameworkConfig.GetBindable(FrameworkSetting.WindowMode), v => display(v, "Screen Mode", v.ToString(), "Alt+Enter")); + } + + private readonly List references = new List(); + + private void trackSetting(Bindable bindable, Bindable.BindableValueChanged action) + { + // we need to keep references as we bind + references.Add(bindable); + + bindable.ValueChanged += action; + } + + private void display(object rawValue, string settingName, string settingValue, string shortcut = @"") + { + Schedule(() => + { + textLine1.Text = settingName.ToUpper(); + textLine2.Text = settingValue; + textLine3.Text = shortcut.ToUpper(); + + box.FadeIn(500, EasingTypes.OutQuint); + box.ResizeHeightTo(height, 500, EasingTypes.OutQuint); + + using (box.BeginDelayedSequence(500)) + { + box.FadeOutFromOne(1500, EasingTypes.InQuint); + box.ResizeHeightTo(height_contracted, 1500, EasingTypes.InQuint); + } + + int optionCount = 0; + int selectedOption = -1; + + if (rawValue is bool) + { + optionCount = 1; + if ((bool)rawValue) selectedOption = 0; + } + else if (rawValue is Enum) + { + var values = Enum.GetValues(rawValue.GetType()); + optionCount = values.Length; + selectedOption = Convert.ToInt32(rawValue); + } + + textLine2.Origin = optionCount > 0 ? Anchor.BottomCentre : Anchor.Centre; + textLine2.Y = optionCount > 0 ? 0 : 5; + + if (optionLights.Children.Count() != optionCount) + { + optionLights.Clear(); + for (int i = 0; i < optionCount; i++) + optionLights.Add(new OptionLight()); + } + + for (int i = 0; i < optionCount; i++) + optionLights.Children.Skip(i).First().Glowing = i == selectedOption; + }); + } + + private class OptionLight : Container + { + private Color4 glowingColour, idleColour; + + private const float transition_speed = 300; + + private const float glow_strength = 0.4f; + + private readonly Box fill; + + public OptionLight() + { + Children = new[] + { + fill = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 1, + }, + }; + } + + private bool glowing; + + public bool Glowing + { + set + { + glowing = value; + if (!IsLoaded) return; + + updateGlow(); + } + } + + private void updateGlow() + { + if (glowing) + { + fill.FadeColour(glowingColour, transition_speed, EasingTypes.OutQuint); + FadeEdgeEffectTo(glow_strength, transition_speed, EasingTypes.OutQuint); + } + else + { + FadeEdgeEffectTo(0, transition_speed, EasingTypes.OutQuint); + fill.FadeColour(idleColour, transition_speed, EasingTypes.OutQuint); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + fill.Colour = idleColour = Color4.White.Opacity(0.4f); + glowingColour = Color4.White; + + Size = new Vector2(25, 5); + + Masking = true; + CornerRadius = 3; + + EdgeEffect = new EdgeEffect + { + Colour = colours.BlueDark.Opacity(glow_strength), + Type = EdgeEffectType.Glow, + Radius = 8, + }; + + FadeEdgeEffectTo(0); + + updateGlow(); + Flush(true); + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1f866f0e17..2e94b3d658 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -79,6 +79,7 @@ + From 694b85c4b0399801c288ce9ab71c07819850c880 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2017 16:29:18 +0900 Subject: [PATCH 2/2] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 7146c07159..30cd231fc6 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 7146c07159d2cf3d07a8d371fa50ef8b200ba038 +Subproject commit 30cd231fc6b3e971c70456433dbcf03591141f28