mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 07:33:20 +08:00
Merge pull request #7168 from peppy/improve-hud-hiding
Improve HUD hiding
This commit is contained in:
commit
267d832ecc
81
osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
Normal file
81
osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneHUDOverlay : ManualInputManagerTestScene
|
||||
{
|
||||
private HUDOverlay hudOverlay;
|
||||
|
||||
private Drawable hideTarget => hudOverlay.KeyCounter; // best way of checking hideTargets without exposing.
|
||||
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; }
|
||||
|
||||
[Test]
|
||||
public void TestShownByDefault()
|
||||
{
|
||||
createNew();
|
||||
|
||||
AddAssert("showhud is set", () => hudOverlay.ShowHud.Value);
|
||||
|
||||
AddAssert("hidetarget is visible", () => hideTarget.IsPresent);
|
||||
AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFadesInOnLoadComplete()
|
||||
{
|
||||
float? initialAlpha = null;
|
||||
|
||||
createNew(h => h.OnLoadComplete += _ => initialAlpha = hideTarget.Alpha);
|
||||
AddUntilStep("wait for load", () => hudOverlay.IsAlive);
|
||||
AddAssert("initial alpha was less than 1", () => initialAlpha != null && initialAlpha < 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHideExternally()
|
||||
{
|
||||
createNew();
|
||||
|
||||
AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
|
||||
|
||||
AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent);
|
||||
AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExternalHideDoesntAffectConfig()
|
||||
{
|
||||
bool originalConfigValue = false;
|
||||
|
||||
createNew();
|
||||
|
||||
AddStep("get original config value", () => originalConfigValue = config.Get<bool>(OsuSetting.ShowInterface));
|
||||
|
||||
AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
|
||||
AddAssert("config unchanged", () => originalConfigValue == config.Get<bool>(OsuSetting.ShowInterface));
|
||||
|
||||
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
||||
AddAssert("config unchanged", () => originalConfigValue == config.Get<bool>(OsuSetting.ShowInterface));
|
||||
}
|
||||
|
||||
private void createNew(Action<HUDOverlay> action = null)
|
||||
{
|
||||
AddStep("create overlay", () =>
|
||||
{
|
||||
Child = hudOverlay = new HUDOverlay(null, null, Array.Empty<Mod>());
|
||||
|
||||
action?.Invoke(hudOverlay);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,8 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
processor.NewJudgement += onNewJudgement;
|
||||
if (processor != null)
|
||||
processor.NewJudgement += onNewJudgement;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -96,7 +97,9 @@ namespace osu.Game.Screens.Play.HUD
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
processor.NewJudgement -= onNewJudgement;
|
||||
|
||||
if (processor != null)
|
||||
processor.NewJudgement -= onNewJudgement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
@ -23,8 +24,8 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
public class HUDOverlay : Container
|
||||
{
|
||||
private const int duration = 250;
|
||||
private const Easing easing = Easing.OutQuint;
|
||||
private const float fade_duration = 400;
|
||||
private const Easing fade_easing = Easing.Out;
|
||||
|
||||
public readonly KeyCounterDisplay KeyCounter;
|
||||
public readonly RollingCounter<int> ComboCounter;
|
||||
@ -43,8 +44,15 @@ namespace osu.Game.Screens.Play
|
||||
private readonly DrawableRuleset drawableRuleset;
|
||||
private readonly IReadOnlyList<Mod> mods;
|
||||
|
||||
private Bindable<bool> showHud;
|
||||
/// <summary>
|
||||
/// Whether the elements that can optionally be hidden should be visible.
|
||||
/// </summary>
|
||||
public Bindable<bool> ShowHud { get; } = new BindableBool();
|
||||
|
||||
private Bindable<bool> configShowHud;
|
||||
|
||||
private readonly Container visibilityContainer;
|
||||
|
||||
private readonly BindableBool replayLoaded = new BindableBool();
|
||||
|
||||
private static bool hasShownNotificationOnce;
|
||||
@ -53,6 +61,8 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private readonly Container topScoreContainer;
|
||||
|
||||
private IEnumerable<Drawable> hideTargets => new Drawable[] { visibilityContainer, KeyCounter };
|
||||
|
||||
public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
this.scoreProcessor = scoreProcessor;
|
||||
@ -68,13 +78,12 @@ namespace osu.Game.Screens.Play
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
HealthDisplay = CreateHealthDisplay(),
|
||||
topScoreContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
AutoSizeDuration = 200,
|
||||
AutoSizeEasing = Easing.Out,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
AccuracyCounter = CreateAccuracyCounter(),
|
||||
@ -82,19 +91,20 @@ namespace osu.Game.Screens.Play
|
||||
ComboCounter = CreateComboCounter(),
|
||||
},
|
||||
},
|
||||
HealthDisplay = CreateHealthDisplay(),
|
||||
Progress = CreateProgress(),
|
||||
ModDisplay = CreateModsContainer(),
|
||||
HitErrorDisplay = CreateHitErrorDisplayOverlay(),
|
||||
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
|
||||
}
|
||||
},
|
||||
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Position = -new Vector2(5, TwoLayerButton.SIZE_RETRACTED.Y),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
LayoutDuration = fade_duration / 2,
|
||||
LayoutEasing = fade_easing,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -108,34 +118,24 @@ namespace osu.Game.Screens.Play
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
||||
{
|
||||
BindProcessor(scoreProcessor);
|
||||
BindDrawableRuleset(drawableRuleset);
|
||||
if (scoreProcessor != null)
|
||||
BindProcessor(scoreProcessor);
|
||||
|
||||
Progress.Objects = drawableRuleset.Objects;
|
||||
Progress.AllowSeeking = drawableRuleset.HasReplayLoaded.Value;
|
||||
Progress.RequestSeek = time => RequestSeek(time);
|
||||
Progress.ReferenceClock = drawableRuleset.FrameStableClock;
|
||||
if (drawableRuleset != null)
|
||||
{
|
||||
BindDrawableRuleset(drawableRuleset);
|
||||
|
||||
Progress.Objects = drawableRuleset.Objects;
|
||||
Progress.AllowSeeking = drawableRuleset.HasReplayLoaded.Value;
|
||||
Progress.RequestSeek = time => RequestSeek(time);
|
||||
Progress.ReferenceClock = drawableRuleset.FrameStableClock;
|
||||
}
|
||||
|
||||
ModDisplay.Current.Value = mods;
|
||||
|
||||
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
||||
showHud.BindValueChanged(visible => visibilityContainer.FadeTo(visible.NewValue ? 1 : 0, duration, easing), true);
|
||||
configShowHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
||||
|
||||
ShowHealthbar.BindValueChanged(healthBar =>
|
||||
{
|
||||
if (healthBar.NewValue)
|
||||
{
|
||||
HealthDisplay.FadeIn(duration, easing);
|
||||
topScoreContainer.MoveToY(30, duration, easing);
|
||||
}
|
||||
else
|
||||
{
|
||||
HealthDisplay.FadeOut(duration, easing);
|
||||
topScoreContainer.MoveToY(0, duration, easing);
|
||||
}
|
||||
}, true);
|
||||
|
||||
if (!showHud.Value && !hasShownNotificationOnce)
|
||||
if (!configShowHud.Value && !hasShownNotificationOnce)
|
||||
{
|
||||
hasShownNotificationOnce = true;
|
||||
|
||||
@ -144,12 +144,39 @@ namespace osu.Game.Screens.Play
|
||||
Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab."
|
||||
});
|
||||
}
|
||||
|
||||
// start all elements hidden
|
||||
hideTargets.ForEach(d => d.Hide());
|
||||
}
|
||||
|
||||
public override void Hide() => throw new InvalidOperationException($"{nameof(HUDOverlay)} should not be hidden as it will remove the ability of a user to quit. Use {nameof(ShowHud)} instead.");
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
ShowHud.BindValueChanged(visible => hideTargets.ForEach(d => d.FadeTo(visible.NewValue ? 1 : 0, fade_duration, fade_easing)));
|
||||
|
||||
ShowHealthbar.BindValueChanged(healthBar =>
|
||||
{
|
||||
if (healthBar.NewValue)
|
||||
{
|
||||
HealthDisplay.FadeIn(fade_duration, fade_easing);
|
||||
topScoreContainer.MoveToY(30, fade_duration, fade_easing);
|
||||
}
|
||||
else
|
||||
{
|
||||
HealthDisplay.FadeOut(fade_duration, fade_easing);
|
||||
topScoreContainer.MoveToY(0, fade_duration, fade_easing);
|
||||
}
|
||||
}, true);
|
||||
|
||||
configShowHud.BindValueChanged(visible =>
|
||||
{
|
||||
if (!ShowHud.Disabled)
|
||||
ShowHud.Value = visible.NewValue;
|
||||
}, true);
|
||||
|
||||
replayLoaded.BindValueChanged(replayLoadedValueChanged, true);
|
||||
}
|
||||
|
||||
@ -189,7 +216,7 @@ namespace osu.Game.Screens.Play
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Tab:
|
||||
showHud.Value = !showHud.Value;
|
||||
configShowHud.Value = !configShowHud.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -257,7 +284,7 @@ namespace osu.Game.Screens.Play
|
||||
Margin = new MarginPadding { Top = 20, Right = 10 },
|
||||
};
|
||||
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.FirstAvailableHitWindows);
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset?.FirstAvailableHitWindows);
|
||||
|
||||
protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user