diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid.cs
index 87072e8d9e..c88feb12bd 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid.cs
@@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osuTK;
+using osuTK.Graphics;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
@@ -15,20 +16,21 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
///
public partial class PlayerGrid : CompositeDrawable
{
+ public const float ANIMATION_DELAY = 400;
+
///
/// A temporary limitation on the number of players, because only layouts up to 16 players are supported for a single screen.
/// Todo: Can be removed in the future with scrolling support + performance improvements.
///
public const int MAX_PLAYERS = 16;
- private const float player_spacing = 5;
+ private const float player_spacing = 6;
///
/// The currently-maximised facade.
///
- public Drawable MaximisedFacade => maximisedFacade;
+ public Facade MaximisedFacade { get; }
- private readonly Facade maximisedFacade;
private readonly Container paddingContainer;
private readonly FillFlowContainer facadeContainer;
private readonly Container cellContainer;
@@ -48,12 +50,18 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
RelativeSizeAxes = Axes.Both,
Child = facadeContainer = new FillFlowContainer
{
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(player_spacing),
}
},
- maximisedFacade = new Facade { RelativeSizeAxes = Axes.Both }
+ MaximisedFacade = new Facade
+ {
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(0.8f),
+ }
}
},
cellContainer = new Container { RelativeSizeAxes = Axes.Both }
@@ -91,26 +99,30 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
private void toggleMaximisationState(Cell target)
{
- // Iterate through all cells to ensure only one is maximised at any time.
- foreach (var i in cellContainer.ToList())
- {
- if (i == target)
- i.IsMaximised = !i.IsMaximised;
- else
- i.IsMaximised = false;
+ bool anyMaximised = target.IsMaximised = !target.IsMaximised;
- if (i.IsMaximised)
+ // Iterate through all cells to ensure only one is maximised at any time.
+ foreach (var cell in cellContainer.ToList())
+ {
+ if (cell != target)
+ cell.IsMaximised = false;
+
+ if (cell.IsMaximised)
{
// Transfer cell to the maximised facade.
- i.SetFacade(maximisedFacade);
- cellContainer.ChangeChildDepth(i, maximisedInstanceDepth -= 0.001f);
+ cell.SetFacade(MaximisedFacade);
+ cellContainer.ChangeChildDepth(cell, maximisedInstanceDepth -= 0.001f);
}
else
{
// Transfer cell back to its original facade.
- i.SetFacade(facadeContainer[i.FacadeIndex]);
+ cell.SetFacade(facadeContainer[cell.FacadeIndex]);
}
+
+ cell.FadeColour(anyMaximised && cell != target ? Color4.Gray : Color4.White, ANIMATION_DELAY, Easing.Out);
}
+
+ facadeContainer.ScaleTo(anyMaximised ? 0.95f : 1, ANIMATION_DELAY, Easing.OutQuint);
}
protected override void Update()
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs
index 4a8b8f49e1..d11e79d820 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs
@@ -8,6 +8,7 @@ using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
+using osu.Framework.Utils;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
@@ -40,7 +41,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
public bool IsMaximised;
private Facade facade;
- private bool isTracking = true;
+
+ private bool isAnimating;
public Cell(int facadeIndex, Drawable content)
{
@@ -54,11 +56,23 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
base.Update();
- if (isTracking)
- {
- Position = getFinalPosition();
- Size = getFinalSize();
- }
+ var targetPos = getFinalPosition();
+ var targetSize = getFinalSize();
+
+ double duration = isAnimating ? 60 : 0;
+
+ Position = new Vector2(
+ (float)Interpolation.DampContinuously(Position.X, targetPos.X, duration, Time.Elapsed),
+ (float)Interpolation.DampContinuously(Position.Y, targetPos.Y, duration, Time.Elapsed)
+ );
+
+ Size = new Vector2(
+ (float)Interpolation.DampContinuously(Size.X, targetSize.X, duration, Time.Elapsed),
+ (float)Interpolation.DampContinuously(Size.Y, targetSize.Y, duration, Time.Elapsed)
+ );
+
+ // If we don't track the animating state, the animation will also occur when resizing the window.
+ isAnimating &= !Precision.AlmostEquals(Position, targetPos, 0.01f);
}
///
@@ -66,30 +80,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
///
public void SetFacade([NotNull] Facade newFacade)
{
- Facade lastFacade = facade;
facade = newFacade;
-
- if (lastFacade == null || lastFacade == newFacade)
- return;
-
- isTracking = false;
-
- this.MoveTo(getFinalPosition(), 400, Easing.OutQuint).ResizeTo(getFinalSize(), 400, Easing.OutQuint)
- .Then()
- .OnComplete(_ =>
- {
- if (facade == newFacade)
- isTracking = true;
- });
+ isAnimating = true;
}
- private Vector2 getFinalPosition()
- {
- var topLeft = Parent.ToLocalSpace(facade.ToScreenSpace(Vector2.Zero));
- return topLeft + facade.DrawSize / 2;
- }
+ private Vector2 getFinalPosition() =>
+ Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre);
- private Vector2 getFinalSize() => facade.DrawSize;
+ private Vector2 getFinalSize() =>
+ Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.BottomRight)
+ - Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.TopLeft);
protected override bool OnClick(ClickEvent e)
{
| |