1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 17:07:38 +08:00

Merge branch 'master' into ruleset_fix

This commit is contained in:
Dan Balasescu 2019-06-07 20:36:29 +09:00 committed by GitHub
commit 6a06ea2aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 550 additions and 188 deletions

View File

@ -54,7 +54,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
for (int i = 0; i < max_sprites; i++)
{
parts[i].InvalidationID = 0;
// InvalidationID 1 forces an update of each part of the cursor trail the first time ApplyState is run on the draw node
// This is to prevent garbage data from being sent to the vertex shader, resulting in visual issues on some platforms
parts[i].InvalidationID = 1;
parts[i].WasUpdated = true;
}
}

View File

@ -84,7 +84,6 @@ namespace osu.Game.Tests.Visual.UserInterface
testLocalCursor();
testUserCursorOverride();
testMultipleLocalCursors();
ReturnUserInput();
}
/// <summary>

View File

@ -0,0 +1,194 @@
// 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 NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneOsuHoverContainer : ManualInputManagerTestScene
{
private OsuHoverTestContainer hoverContainer;
private Box colourContainer;
[SetUp]
public void SetUp() => Schedule(() =>
{
Child = hoverContainer = new OsuHoverTestContainer
{
Enabled = { Value = true },
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(100),
Child = colourContainer = new Box
{
RelativeSizeAxes = Axes.Both,
},
};
doMoveOut();
});
[Description("Checks IsHovered property value on a container when it is hovered/unhovered.")]
[TestCase(true, TestName = "Enabled_Check_IsHovered")]
[TestCase(false, TestName = "Disabled_Check_IsHovered")]
public void TestIsHoveredHasProperValue(bool isEnabled)
{
setContainerEnabledTo(isEnabled);
checkNotHovered();
moveToText();
checkHovered();
moveOut();
checkNotHovered();
moveToText();
checkHovered();
moveOut();
checkNotHovered();
}
[Test]
[Description("Checks colour fading on an enabled container when it is hovered/unhovered.")]
public void TestTransitionWhileEnabled()
{
enableContainer();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
moveOut();
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
moveOut();
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
}
[Test]
[Description("Checks colour fading on a disabled container when it is hovered/unhovered.")]
public void TestNoTransitionWhileDisabled()
{
disableContainer();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveOut();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveOut();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
}
[Test]
[Description("Checks that when a disabled & hovered container gets enabled, colour fading happens")]
public void TestBecomesEnabledTransition()
{
disableContainer();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
enableContainer();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
}
[Test]
[Description("Checks that when an enabled & hovered container gets disabled, colour fading happens")]
public void TestBecomesDisabledTransition()
{
enableContainer();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
disableContainer();
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
}
[Test]
[Description("Checks that when a hovered container gets enabled and disabled multiple times, colour fading happens")]
public void TestDisabledChangesMultipleTimes()
{
enableContainer();
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
moveToText();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
disableContainer();
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
enableContainer();
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
disableContainer();
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
}
private void enableContainer() => setContainerEnabledTo(true);
private void disableContainer() => setContainerEnabledTo(false);
private void setContainerEnabledTo(bool newValue)
{
string word = newValue ? "Enable" : "Disable";
AddStep($"{word} container", () => hoverContainer.Enabled.Value = newValue);
}
private void moveToText() => AddStep("Move mouse to text", () => InputManager.MoveMouseTo(hoverContainer));
private void moveOut() => AddStep("Move out", doMoveOut);
private void checkHovered() => AddAssert("Check hovered", () => hoverContainer.IsHovered);
private void checkNotHovered() => AddAssert("Check not hovered", () => !hoverContainer.IsHovered);
private void checkColour(ColourInfo expectedColour)
=> AddAssert($"Check colour to be '{expectedColour}'", () => currentColour.Equals(expectedColour));
private void waitUntilColourIs(ColourInfo expectedColour)
=> AddUntilStep($"Wait until hover colour is {expectedColour}", () => currentColour.Equals(expectedColour));
private ColourInfo currentColour => colourContainer.DrawColourInfo.Colour;
/// <summary>
/// Moves the cursor to top left corner of the screen
/// </summary>
private void doMoveOut()
=> InputManager.MoveMouseTo(new Vector2(InputManager.ScreenSpaceDrawQuad.TopLeft.X, InputManager.ScreenSpaceDrawQuad.TopLeft.Y));
private sealed class OsuHoverTestContainer : OsuHoverContainer
{
public static readonly Color4 HOVER_COLOUR = Color4.Red;
public static readonly Color4 IDLE_COLOUR = Color4.Green;
public OsuHoverTestContainer()
{
HoverColour = HOVER_COLOUR;
IdleColour = IDLE_COLOUR;
}
}
}
}

View File

@ -1,6 +1,10 @@
// 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 System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
@ -12,22 +16,24 @@ using osu.Game.Beatmaps;
namespace osu.Game.Audio
{
/// <summary>
/// A central store for the retrieval of <see cref="PreviewTrack"/>s.
/// </summary>
public class PreviewTrackManager : Component
{
private readonly BindableDouble muteBindable = new BindableDouble();
private AudioManager audio;
private ITrackStore trackStore;
private PreviewTrackStore trackStore;
private TrackManagerPreviewTrack current;
[BackgroundDependencyLoader]
private void load(AudioManager audio, FrameworkConfigManager config)
{
trackStore = audio.GetTrackStore(new OnlineStore());
// this is a temporary solution to get around muting ourselves.
// todo: update this once we have a BackgroundTrackManager or similar.
trackStore = new PreviewTrackStore(new OnlineStore());
audio.AddItem(trackStore);
trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack);
this.audio = audio;
@ -103,5 +109,46 @@ namespace osu.Game.Audio
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
}
private class PreviewTrackStore : AudioCollectionManager<AdjustableAudioComponent>, ITrackStore
{
private readonly IResourceStore<byte[]> store;
internal PreviewTrackStore(IResourceStore<byte[]> store)
{
this.store = store;
}
public Track GetVirtual(double length = double.PositiveInfinity)
{
if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
var track = new TrackVirtual(length);
AddItem(track);
return track;
}
public Track Get(string name)
{
if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
if (string.IsNullOrEmpty(name)) return null;
var dataStream = store.GetStream(name);
if (dataStream == null)
return null;
Track track = new TrackBass(dataStream);
AddItem(track);
return track;
}
public Task<Track> GetAsync(string name) => Task.Run(() => Get(name));
public Stream GetStream(string name) => store.GetStream(name);
public IEnumerable<string> GetAvailableResources() => store.GetAvailableResources();
}
}
}

View File

@ -24,8 +24,13 @@ namespace osu.Game.Graphics.Containers
{
Enabled.ValueChanged += e =>
{
if (!e.NewValue)
unhover();
if (isHovered)
{
if (e.NewValue)
fadeIn();
else
fadeOut();
}
};
}
@ -33,28 +38,28 @@ namespace osu.Game.Graphics.Containers
protected override bool OnHover(HoverEvent e)
{
if (isHovered)
return false;
isHovered = true;
if (!Enabled.Value)
return false;
EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint));
isHovered = true;
fadeIn();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
unhover();
base.OnHoverLost(e);
}
private void unhover()
{
if (!isHovered)
return;
isHovered = false;
EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint));
fadeOut();
base.OnHoverLost(e);
}
[BackgroundDependencyLoader]
@ -69,5 +74,9 @@ namespace osu.Game.Graphics.Containers
base.LoadComplete();
EffectTargets.ForEach(d => d.FadeColour(IdleColour));
}
private void fadeIn() => EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint));
private void fadeOut() => EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint));
}
}

View File

@ -1,40 +1,40 @@
// 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 osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods.Sections;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Overlays.Mods
{
public class ModSelectOverlay : WaveOverlayContainer
{
private const float content_width = 0.8f;
protected Color4 LowMultiplierColour, HighMultiplierColour;
protected readonly TriangleButton DeselectAllButton;
protected readonly OsuSpriteText MultiplierLabel, UnrankedLabel;
private readonly FillFlowContainer footerContainer;
protected readonly TriangleButton CloseButton;
protected readonly OsuSpriteText MultiplierLabel;
protected readonly OsuSpriteText UnrankedLabel;
protected override bool BlockNonPositionalInput => false;
@ -46,154 +46,14 @@ namespace osu.Game.Overlays.Mods
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods)
{
LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
protected Color4 LowMultiplierColour;
protected Color4 HighMultiplierColour;
Ruleset.BindTo(ruleset);
if (mods != null) SelectedMods.BindTo(mods);
sampleOn = audio.Samples.Get(@"UI/check-on");
sampleOff = audio.Samples.Get(@"UI/check-off");
}
protected override void LoadComplete()
{
base.LoadComplete();
Ruleset.BindValueChanged(rulesetChanged, true);
SelectedMods.BindValueChanged(selectedModsChanged, true);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
{
if (e.NewValue == null) return;
var instance = e.NewValue.CreateInstance();
foreach (ModSection section in ModSectionsContainer.Children)
section.Mods = instance.GetModsFor(section.ModType);
// attempt to re-select any already selected mods.
// this may be the first time we are receiving the ruleset, in which case they will still match.
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
// this generally isn't required as the previous line will perform deselection; just here for safety.
refreshSelectedMods();
}
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> e)
{
foreach (ModSection section in ModSectionsContainer.Children)
section.SelectTypes(e.NewValue.Select(m => m.GetType()).ToList());
updateMods();
}
private void updateMods()
{
double multiplier = 1.0;
bool ranked = true;
foreach (Mod mod in SelectedMods.Value)
{
multiplier *= mod.ScoreMultiplier;
ranked &= mod.Ranked;
}
MultiplierLabel.Text = $"{multiplier:N2}x";
if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else
MultiplierLabel.FadeColour(Color4.White, 200);
UnrankedLabel.FadeTo(ranked ? 0 : 1, 200);
}
protected override void PopOut()
{
base.PopOut();
footerContainer.MoveToX(footerContainer.DrawSize.X, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
footerContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
foreach (ModSection section in ModSectionsContainer.Children)
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.MoveToX(100f, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
}
}
protected override void PopIn()
{
base.PopIn();
footerContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
footerContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
foreach (ModSection section in ModSectionsContainer.Children)
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), WaveContainer.APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
}
}
public void DeselectAll()
{
foreach (ModSection section in ModSectionsContainer.Children)
section.DeselectAll();
refreshSelectedMods();
}
/// <summary>
/// Deselect one or more mods.
/// </summary>
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
public void DeselectTypes(Type[] modTypes, bool immediate = false)
{
if (modTypes.Length == 0) return;
foreach (ModSection section in ModSectionsContainer.Children)
section.DeselectTypes(modTypes, immediate);
}
private const float content_width = 0.8f;
private readonly FillFlowContainer footerContainer;
private SampleChannel sampleOn, sampleOff;
private void modButtonPressed(Mod selectedMod)
{
if (selectedMod != null)
{
if (State == Visibility.Visible) sampleOn?.Play();
DeselectTypes(selectedMod.IncompatibleMods, true);
}
else
{
if (State == Visibility.Visible) sampleOff?.Play();
}
refreshSelectedMods();
}
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
public ModSelectOverlay()
{
Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2");
@ -364,6 +224,16 @@ namespace osu.Game.Overlays.Mods
Right = 20
}
},
CloseButton = new TriangleButton
{
Width = 180,
Text = "Close",
Action = Hide,
Margin = new MarginPadding
{
Right = 20
}
},
new OsuSpriteText
{
Text = @"Score Multiplier:",
@ -401,5 +271,171 @@ namespace osu.Game.Overlays.Mods
},
};
}
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods)
{
LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
Ruleset.BindTo(ruleset);
if (mods != null) SelectedMods.BindTo(mods);
sampleOn = audio.Samples.Get(@"UI/check-on");
sampleOff = audio.Samples.Get(@"UI/check-off");
}
public void DeselectAll()
{
foreach (var section in ModSectionsContainer.Children)
section.DeselectAll();
refreshSelectedMods();
}
/// <summary>
/// Deselect one or more mods.
/// </summary>
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
public void DeselectTypes(Type[] modTypes, bool immediate = false)
{
if (modTypes.Length == 0) return;
foreach (var section in ModSectionsContainer.Children)
section.DeselectTypes(modTypes, immediate);
}
protected override void LoadComplete()
{
base.LoadComplete();
Ruleset.BindValueChanged(rulesetChanged, true);
SelectedMods.BindValueChanged(selectedModsChanged, true);
}
protected override void PopOut()
{
base.PopOut();
footerContainer.MoveToX(footerContainer.DrawSize.X, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
footerContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
foreach (var section in ModSectionsContainer.Children)
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.MoveToX(100f, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
}
}
protected override void PopIn()
{
base.PopIn();
footerContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
footerContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
foreach (var section in ModSectionsContainer.Children)
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), WaveContainer.APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
}
}
protected override bool OnKeyDown(KeyDownEvent e)
{
switch (e.Key)
{
case Key.Number1:
DeselectAllButton.Click();
return true;
case Key.Number2:
CloseButton.Click();
return true;
}
return base.OnKeyDown(e);
}
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
{
if (e.NewValue == null) return;
var instance = e.NewValue.CreateInstance();
foreach (var section in ModSectionsContainer.Children)
section.Mods = instance.GetModsFor(section.ModType);
// attempt to re-select any already selected mods.
// this may be the first time we are receiving the ruleset, in which case they will still match.
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
// this generally isn't required as the previous line will perform deselection; just here for safety.
refreshSelectedMods();
}
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> e)
{
foreach (var section in ModSectionsContainer.Children)
section.SelectTypes(e.NewValue.Select(m => m.GetType()).ToList());
updateMods();
}
private void updateMods()
{
var multiplier = 1.0;
var ranked = true;
foreach (var mod in SelectedMods.Value)
{
multiplier *= mod.ScoreMultiplier;
ranked &= mod.Ranked;
}
MultiplierLabel.Text = $"{multiplier:N2}x";
if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else
MultiplierLabel.FadeColour(Color4.White, 200);
UnrankedLabel.FadeTo(ranked ? 0 : 1, 200);
}
private void modButtonPressed(Mod selectedMod)
{
if (selectedMod != null)
{
if (State == Visibility.Visible) sampleOn?.Play();
DeselectTypes(selectedMod.IncompatibleMods, true);
}
else
{
if (State == Visibility.Visible) sampleOff?.Play();
}
refreshSelectedMods();
}
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
#region Disposal
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
#endregion
}
}

View File

@ -49,7 +49,6 @@ namespace osu.Game.Overlays.Profile.Sections
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 2),
},
MoreButton = new ShowMoreButton

View File

@ -3,8 +3,13 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing.Input;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
@ -15,21 +20,92 @@ namespace osu.Game.Tests.Visual
protected readonly ManualInputManager InputManager;
private readonly TriangleButton buttonTest;
private readonly TriangleButton buttonLocal;
protected ManualInputManagerTestScene()
{
base.Content.Add(InputManager = new ManualInputManager
base.Content.AddRange(new Drawable[]
{
UseParentInput = true,
Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
InputManager = new ManualInputManager
{
UseParentInput = true,
Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
},
new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Margin = new MarginPadding(5),
CornerRadius = 5,
Masking = true,
Children = new Drawable[]
{
new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
Alpha = 0.5f,
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Margin = new MarginPadding(5),
Spacing = new Vector2(5),
Children = new Drawable[]
{
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = "Input Priority"
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Margin = new MarginPadding(5),
Spacing = new Vector2(5),
Direction = FillDirection.Horizontal,
Children = new Drawable[]
{
buttonLocal = new TriangleButton
{
Text = "local",
Size = new Vector2(50, 30),
Action = returnUserInput
},
buttonTest = new TriangleButton
{
Text = "test",
Size = new Vector2(50, 30),
Action = returnTestInput
},
}
},
}
},
}
},
});
}
/// <summary>
/// Returns input back to the user.
/// </summary>
protected void ReturnUserInput()
protected override void Update()
{
AddStep("Return user input", () => InputManager.UseParentInput = true);
base.Update();
buttonTest.Enabled.Value = InputManager.UseParentInput;
buttonLocal.Enabled.Value = !InputManager.UseParentInput;
}
private void returnUserInput() =>
InputManager.UseParentInput = true;
private void returnTestInput() =>
InputManager.UseParentInput = false;
}
}