Apply reviews, add safety for multiple facades

This commit is contained in:
David Zhao
2019-04-05 12:02:47 +09:00
parent 6f5e9fe50d
commit 7047f305a1
6 changed files with 223 additions and 171 deletions

View File

@ -21,13 +21,13 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface namespace osu.Game.Tests.Visual.UserInterface
{ {
public class TestCaseLogoFacadeContainer : OsuTestCase public class TestCaseLogoTrackingContainer : OsuTestCase
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(PlayerLoader), typeof(PlayerLoader),
typeof(Player), typeof(Player),
typeof(LogoFacadeContainer), typeof(LogoTrackingContainer),
typeof(ButtonSystem), typeof(ButtonSystem),
typeof(ButtonSystemState), typeof(ButtonSystemState),
typeof(Menu), typeof(Menu),
@ -36,11 +36,11 @@ namespace osu.Game.Tests.Visual.UserInterface
private OsuLogo logo; private OsuLogo logo;
private readonly Bindable<float> uiScale = new Bindable<float>(); private readonly Bindable<float> uiScale = new Bindable<float>();
private TestLogoFacadeContainer facadeContainer; private TestLogoTrackingContainer trackingContainer;
private Container transferContainer; private Container transferContainer;
private Box visualBox; private Box visualBox;
private Box transferContainerBox; private Box transferContainerBox;
private Container logoFacade; private Drawable logoFacade;
private bool randomPositions; private bool randomPositions;
private const float visual_box_size = 72; private const float visual_box_size = 72;
@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
Clear(); Clear();
Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.Both }); Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.Both });
facadeContainer = null; trackingContainer = null;
transferContainer = null; transferContainer = null;
}); });
} }
@ -72,10 +72,10 @@ namespace osu.Game.Tests.Visual.UserInterface
public void MoveFacadeTest() public void MoveFacadeTest()
{ {
AddToggleStep("Toggle move continuously", b => randomPositions = b); AddToggleStep("Toggle move continuously", b => randomPositions = b);
AddStep("Add facade containers", addFacadeContainers); AddStep("Add tracking containers", addFacadeContainers);
AddStep("Move facade to random position", startTrackingRandom); AddStep("Move facade to random position", startTrackingRandom);
waitForMove(); waitForMove();
AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking);
} }
/// <summary> /// <summary>
@ -84,11 +84,11 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test] [Test]
public void RemoveFacadeTest() public void RemoveFacadeTest()
{ {
AddStep("Add facade containers", addFacadeContainers); AddStep("Add tracking containers", addFacadeContainers);
AddStep("Move facade to random position", startTrackingRandom); AddStep("Move facade to random position", startTrackingRandom);
AddStep("Remove facade from FacadeContainer", removeFacade); AddStep("Remove facade from FacadeContainer", removeFacade);
waitForMove(); waitForMove();
AddAssert("Logo is not tracking", () => !facadeContainer.IsLogoTracking); AddAssert("Logo is not tracking", () => !trackingContainer.IsLogoTracking);
} }
/// <summary> /// <summary>
@ -97,17 +97,12 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test] [Test]
public void TransferFacadeTest() public void TransferFacadeTest()
{ {
AddStep("Add facade containers", addFacadeContainers); AddStep("Add tracking containers", addFacadeContainers);
AddStep("Move facade to random position", startTrackingRandom); AddStep("Move facade to random position", startTrackingRandom);
AddStep("Remove facade from FacadeContainer", removeFacade); AddStep("Remove facade from FacadeContainer", removeFacade);
AddStep("Transfer facade to a new container", () => AddStep("Transfer facade to a new container", addFacadeToNewContainer);
{
transferContainer.Add(logoFacade);
transferContainerBox.Colour = Color4.Tomato;
moveLogoFacade();
});
waitForMove(); waitForMove();
AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking);
} }
/// <summary> /// <summary>
@ -120,7 +115,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("Create new flow container with facade", () => AddStep("Create new flow container with facade", () =>
{ {
Add(facadeContainer = new TestLogoFacadeContainer Add(trackingContainer = new TestLogoTrackingContainer
{ {
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
@ -156,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Colour = Color4.White, Colour = Color4.White,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
facadeContainer.LogoFacade, trackingContainer.LogoFacade,
} }
}, },
new Box new Box
@ -171,27 +166,34 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("Perform logo movements", () => AddStep("Perform logo movements", () =>
{ {
facadeContainer.Tracking = false; trackingContainer.Tracking = false;
logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo);
facadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); trackingContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo);
visualBox.Colour = Color4.White; visualBox.Colour = Color4.White;
Scheduler.AddDelayed(() => Scheduler.AddDelayed(() =>
{ {
facadeContainer.Tracking = true; trackingContainer.Tracking = true;
visualBox.Colour = Color4.Tomato; visualBox.Colour = Color4.Tomato;
}, 700); }, 700);
}); });
waitForMove(8); waitForMove(8);
AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking);
}
[Test]
public void SetFacadeSizeTest()
{
AddStep("Add tracking containers", addFacadeContainers);
AddStep("Break shit", () => { logoFacade.Size = new Vector2(0, 0); });
} }
private void addFacadeContainers() private void addFacadeContainers()
{ {
AddRange(new Drawable[] AddRange(new Drawable[]
{ {
facadeContainer = new TestLogoFacadeContainer trackingContainer = new TestLogoTrackingContainer
{ {
Alpha = 0.35f, Alpha = 0.35f,
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
@ -215,22 +217,29 @@ namespace osu.Game.Tests.Visual.UserInterface
}, },
}); });
facadeContainer.Add(logoFacade = facadeContainer.LogoFacade); trackingContainer.Add(logoFacade = trackingContainer.LogoFacade);
facadeContainer.SetLogo(logo, 1.0f, 1000); trackingContainer.SetLogo(logo, 1.0f, 1000);
} }
private void waitForMove(int count = 5) => AddWaitStep("Wait for transforms to finish", count); private void waitForMove(int count = 5) => AddWaitStep("Wait for transforms to finish", count);
private void removeFacade() private void removeFacade()
{ {
facadeContainer.Remove(logoFacade); trackingContainer.Remove(logoFacade);
visualBox.Colour = Color4.White; visualBox.Colour = Color4.White;
moveLogoFacade(); moveLogoFacade();
} }
private void startTrackingRandom() private void startTrackingRandom()
{ {
facadeContainer.Tracking = true; trackingContainer.Tracking = true;
moveLogoFacade();
}
private void addFacadeToNewContainer()
{
transferContainer.Add(logoFacade);
transferContainerBox.Colour = Color4.Tomato;
moveLogoFacade(); moveLogoFacade();
} }
@ -239,7 +248,7 @@ namespace osu.Game.Tests.Visual.UserInterface
if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0)
{ {
Random random = new Random(); Random random = new Random();
facadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); trackingContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300);
transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300);
} }
@ -247,12 +256,12 @@ namespace osu.Game.Tests.Visual.UserInterface
Schedule(moveLogoFacade); Schedule(moveLogoFacade);
} }
private class TestLogoFacadeContainer : LogoFacadeContainer private class TestLogoTrackingContainer : LogoTrackingContainer
{ {
/// <summary> /// <summary>
/// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience.
/// </summary> /// </summary>
public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition()); public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition);
} }
} }
} }

View File

@ -1,114 +0,0 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Screens.Menu;
using osuTK;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that creates a <see cref="Facade"/> to be used to update and track the position of an <see cref="OsuLogo"/>.
/// </summary>
public class LogoFacadeContainer : Container
{
protected virtual Facade CreateFacade() => new Facade();
public Facade LogoFacade { get; }
/// <summary>
/// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade.
/// </summary>
public bool Tracking = false;
protected OsuLogo Logo;
private float facadeScale;
private Easing easing;
private Vector2? startPosition;
private double? startTime;
private double duration;
public LogoFacadeContainer()
{
LogoFacade = CreateFacade();
}
/// <summary>
/// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position.
/// </summary>
/// <param name="logo">The instance of the logo to be used for tracking.</param>
/// <param name="facadeScale">The scale of the facade. Does not actually affect the logo itself.</param>
/// <param name="duration">The duration of the initial transform. Default is instant.</param>
/// <param name="easing">The easing type of the initial transform.</param>
public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None)
{
Logo = logo ?? throw new ArgumentNullException(nameof(logo));
this.facadeScale = facadeScale;
this.duration = duration;
this.easing = easing;
startTime = null;
startPosition = null;
}
/// <summary>
/// Gets the position that the logo should move to with respect to the <see cref="LogoFacade"/>.
/// Manually performs a conversion of the Facade's position to the Logo's parent's relative space.
/// </summary>
/// <remarks>Will only be correct if the logo's <see cref="Drawable.RelativePositionAxes"/> are set to Axes.Both</remarks>
/// <returns>The position that the logo should move to in its parent's relative space.</returns>
protected Vector2 LogoTrackingPosition()
{
Vector2 local;
local.X = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X;
local.Y = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y;
return local;
}
protected override void Update()
{
base.Update();
if (Logo == null || !Tracking)
return;
// Account for the scale of the actual logo container, as SizeForFlow only accounts for the sprite scale.
LogoFacade.Size = new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale);
if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition())
{
// If this is our first update since tracking has started, initialize our starting values for interpolation
if (startTime == null || startPosition == null)
{
startTime = Time.Current;
startPosition = Logo.Position;
}
if (duration != 0)
{
double elapsedDuration = Time.Current - startTime ?? throw new ArgumentNullException(nameof(startTime));
var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1));
// Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location.
Logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), LogoTrackingPosition(), mount);
}
else
{
Logo.Position = LogoTrackingPosition();
}
}
}
/// <summary>
/// A placeholder container that serves as a dummy object to denote another object's location and size.
/// </summary>
public class Facade : Container
{
}
}
}

View File

@ -0,0 +1,156 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Screens.Menu;
using osuTK;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// A container that handles tracking of an <see cref="OsuLogo"/> through different layout scenarios
/// </summary>
public class LogoTrackingContainer : Container
{
public Facade LogoFacade { get; }
/// <summary>
/// Whether or not the logo assigned to this FacadeContainer should be tracking the position of its facade.
/// </summary>
public bool Tracking { get; set; }
protected OsuLogo Logo;
private float facadeScale;
private Easing easing;
private Vector2? startPosition;
private double? startTime;
private double duration;
public LogoTrackingContainer()
{
LogoFacade = new ExposedFacade();
}
/// <summary>
/// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position.
/// </summary>
/// <param name="logo">The instance of the logo to be used for tracking.</param>
/// <param name="facadeScale">The scale of the facade. Does not actually affect the logo itself.</param>
/// <param name="duration">The duration of the initial transform. Default is instant.</param>
/// <param name="easing">The easing type of the initial transform.</param>
public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None)
{
if (Logo != logo)
{
if (logo?.HasTrackingContainer ?? throw new ArgumentNullException(nameof(logo)))
{
// Prevent the same logo from being added to multiple LogoTrackingContainers.
throw new InvalidOperationException($"Cannot add an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s");
}
if (Logo != null)
{
// If we're replacing the logo to be tracked, the old one no longer has a tracking container
Logo.HasTrackingContainer = false;
}
}
Logo = logo;
Logo.HasTrackingContainer = true;
this.facadeScale = facadeScale;
this.duration = duration;
this.easing = easing;
startTime = null;
startPosition = null;
}
/// <summary>
/// Gets the position that the logo should move to with respect to the <see cref="LogoFacade"/>.
/// Manually performs a conversion of the Facade's position to the Logo's parent's relative space.
/// </summary>
/// <remarks>Will only be correct if the logo's <see cref="Drawable.RelativePositionAxes"/> are set to Axes.Both</remarks>
protected Vector2 LogoTrackingPosition => new Vector2(Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X,
Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y);
protected override void Update()
{
base.Update();
if (Logo == null || !Tracking)
return;
// Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale.
((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale));
if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition && Logo.RelativePositionAxes == Axes.Both)
{
// If this is our first update since tracking has started, initialize our starting values for interpolation
if (startTime == null || startPosition == null)
{
startTime = Time.Current;
startPosition = Logo.Position;
}
if (duration != 0)
{
double elapsedDuration = (double)(Time.Current - startTime);
var amount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1));
// Interpolate the position of the logo, where amount 0 is where the logo was when it first began interpolating, and amount 1 is the target location.
Logo.Position = Vector2.Lerp((Vector2)startPosition, LogoTrackingPosition, amount);
}
else
{
Logo.Position = LogoTrackingPosition;
}
}
}
protected override void Dispose(bool isDisposing)
{
if (Logo != null)
Logo.HasTrackingContainer = false;
base.Dispose(isDisposing);
}
private Vector2 size;
private class ExposedFacade : Facade
{
public override Vector2 Size
{
get => base.Size;
set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}");
}
public void SetSize(Vector2 size)
{
base.SetSize(size);
}
}
/// <summary>
/// A dummy object used to denote another object's location.
/// </summary>
public abstract class Facade : Drawable
{
public override Vector2 Size
{
get => base.Size;
set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}");
}
protected void SetSize(Vector2 size)
{
base.Size = size;
}
}
}
}

View File

@ -60,7 +60,7 @@ namespace osu.Game.Screens.Menu
if (this.logo != null) if (this.logo != null)
{ {
this.logo.Action = onOsuLogo; this.logo.Action = onOsuLogo;
logoFacadeContainer.SetLogo(logo, 0.74f); logoTrackingContainer.SetLogo(logo, 0.74f);
// osuLogo.SizeForFlow relies on loading to be complete. // osuLogo.SizeForFlow relies on loading to be complete.
buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0);
@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu
else else
{ {
// We should stop tracking as the facade is now out of scope. // We should stop tracking as the facade is now out of scope.
logoFacadeContainer.Tracking = false; logoTrackingContainer.Tracking = false;
} }
} }
@ -83,29 +83,29 @@ namespace osu.Game.Screens.Menu
private SampleChannel sampleBack; private SampleChannel sampleBack;
private readonly LogoFacadeContainer logoFacadeContainer; private readonly LogoTrackingContainer logoTrackingContainer;
public ButtonSystem() public ButtonSystem()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Child = logoFacadeContainer = new LogoFacadeContainer Child = logoTrackingContainer = new LogoTrackingContainer
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = buttonArea = new ButtonArea() Child = buttonArea = new ButtonArea()
}; };
buttonArea.AddRange(new Container[] buttonArea.AddRange(new Drawable[]
{ {
new Button(@"settings", string.Empty, FontAwesome.Gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), new Button(@"settings", string.Empty, FontAwesome.Gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
backButton = new Button(@"back", @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH) backButton = new Button(@"back", @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH)
{ {
VisibleState = ButtonSystemState.Play, VisibleState = ButtonSystemState.Play,
}, },
logoFacadeContainer.LogoFacade logoTrackingContainer.LogoFacade
}); });
buttonArea.Flow.CentreTarget = logoFacadeContainer.LogoFacade; buttonArea.Flow.CentreTarget = logoTrackingContainer.LogoFacade;
} }
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
@ -271,7 +271,7 @@ namespace osu.Game.Screens.Menu
logoDelayedAction?.Cancel(); logoDelayedAction?.Cancel();
logoDelayedAction = Scheduler.AddDelayed(() => logoDelayedAction = Scheduler.AddDelayed(() =>
{ {
logoFacadeContainer.Tracking = false; logoTrackingContainer.Tracking = false;
game?.Toolbar.Hide(); game?.Toolbar.Hide();
@ -294,8 +294,8 @@ namespace osu.Game.Screens.Menu
if (lastState == ButtonSystemState.Initial) if (lastState == ButtonSystemState.Initial)
logo.ScaleTo(0.5f, 200, Easing.In); logo.ScaleTo(0.5f, 200, Easing.In);
logoFacadeContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); logoTrackingContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In);
logoFacadeContainer.Tracking = true; logoTrackingContainer.Tracking = true;
logoDelayedAction?.Cancel(); logoDelayedAction?.Cancel();
logoDelayedAction = Scheduler.AddDelayed(() => logoDelayedAction = Scheduler.AddDelayed(() =>
@ -308,14 +308,14 @@ namespace osu.Game.Screens.Menu
break; break;
default: default:
logo.ClearTransforms(targetMember: nameof(Position)); logo.ClearTransforms(targetMember: nameof(Position));
logoFacadeContainer.Tracking = true; logoTrackingContainer.Tracking = true;
logo.ScaleTo(0.5f, 200, Easing.OutQuint); logo.ScaleTo(0.5f, 200, Easing.OutQuint);
break; break;
} }
break; break;
case ButtonSystemState.EnteringMode: case ButtonSystemState.EnteringMode:
logoFacadeContainer.Tracking = true; logoTrackingContainer.Tracking = true;
break; break;
} }
} }

View File

@ -54,8 +54,14 @@ namespace osu.Game.Screens.Menu
/// </summary> /// </summary>
public Func<bool> Action; public Func<bool> Action;
/// <summary>
/// The size of the logo Sprite with respect to the scale of its hover and bounce containers.
/// </summary>
/// <remarks>Does not account for the scale of this <see cref="OsuLogo"/></remarks>
public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X; public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X;
public bool HasTrackingContainer { get; set; }
private readonly Sprite ripple; private readonly Sprite ripple;
private readonly Container rippleContainer; private readonly Container rippleContainer;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play
private Player player; private Player player;
private LogoFacadeContainer content; private LogoTrackingContainer content;
private BeatmapMetadataDisplay info; private BeatmapMetadataDisplay info;
@ -60,14 +60,12 @@ namespace osu.Game.Screens.Play
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
InternalChild = content = new LogoFacadeContainer InternalChild = (content = new LogoTrackingContainer
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}; }).WithChildren(new Drawable[]
content.Children = new Drawable[]
{ {
info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade) info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade)
{ {
@ -89,7 +87,7 @@ namespace osu.Game.Screens.Play
new InputSettings() new InputSettings()
} }
} }
}; });
loadNewPlayer(); loadNewPlayer();
} }
@ -163,12 +161,9 @@ namespace osu.Game.Screens.Play
logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); logo.ScaleTo(new Vector2(0.15f), duration, Easing.In);
logo.FadeIn(350); logo.FadeIn(350);
content.SetLogo(logo, 1.0f, 500, Easing.InOutExpo); content.SetLogo(logo, 1.0f, resuming ? 0 : 500, Easing.InOutExpo);
Scheduler.AddDelayed(() => Scheduler.AddDelayed(() => { content.Tracking = true; }, resuming ? 0 : 500);
{
content.Tracking = true;
}, resuming ? 0 : 500);
} }
protected override void LogoExiting(OsuLogo logo) protected override void LogoExiting(OsuLogo logo)
@ -321,7 +316,7 @@ namespace osu.Game.Screens.Play
} }
private readonly WorkingBeatmap beatmap; private readonly WorkingBeatmap beatmap;
private readonly Container facade; private readonly Drawable facade;
private LoadingAnimation loading; private LoadingAnimation loading;
private Sprite backgroundSprite; private Sprite backgroundSprite;
private ModDisplay modDisplay; private ModDisplay modDisplay;
@ -343,7 +338,7 @@ namespace osu.Game.Screens.Play
} }
} }
public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Container facade) public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Drawable facade)
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
this.facade = facade; this.facade = facade;
@ -366,7 +361,7 @@ namespace osu.Game.Screens.Play
Origin = Anchor.TopCentre, Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre, Anchor = Anchor.TopCentre,
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new[]
{ {
facade, facade,
new OsuSpriteText new OsuSpriteText