1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-03 06:09:54 +08:00

Merge pull request #35053 from smoogipoo/matchmaking-player-list-modes

Add display styles to matchmaking player list
This commit is contained in:
Dean Herbert
2025-09-24 02:59:57 +09:00
committed by GitHub
Unverified
13 changed files with 588 additions and 190 deletions
@@ -53,6 +53,20 @@ namespace osu.Game.Tests.Visual.Matchmaking
WaitForJoined();
AddStep("join users", () =>
{
for (int i = 0; i < 7; i++)
{
MultiplayerClient.AddUser(new MultiplayerRoomUser(i)
{
User = new APIUser
{
Username = $"User {i}"
}
});
}
});
setupRequestHandler();
AddStep("load match", () =>
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Screens;
using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
@@ -80,7 +81,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
PickScreen screen = null!;
AddStep("add screen", () => LoadScreen(screen = new PickScreen()));
AddStep("add screen", () => Child = new ScreenStack(screen = new PickScreen()));
AddStep("select maps", () =>
{
@@ -7,7 +7,7 @@ using osu.Framework.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle;
using osu.Game.Screens.OnlinePlay.Matchmaking;
using osu.Game.Tests.Visual.Multiplayer;
using osu.Game.Users;
@@ -0,0 +1,137 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osu.Game.Screens.OnlinePlay.Matchmaking;
using osu.Game.Tests.Visual.Multiplayer;
using osuTK;
namespace osu.Game.Tests.Visual.Matchmaking
{
public partial class TestScenePlayerPanelList : MultiplayerTestScene
{
private PlayerPanelList list = null!;
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("join room", () => JoinRoom(CreateDefaultRoom()));
WaitForJoined();
AddStep("add list", () => Child = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.8f),
Child = list = new PlayerPanelList()
});
}
[Test]
public void TestChangeDisplayMode()
{
AddStep("join users", () =>
{
for (int i = 0; i < 7; i++)
{
MultiplayerClient.AddUser(new MultiplayerRoomUser(i)
{
User = new APIUser
{
Username = $"User {i}"
}
});
}
});
AddStep("change to split mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Split);
AddStep("change to grid mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Grid);
AddStep("change to hidden mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Hidden);
}
[Test]
public void AddPanelsGrid()
{
AddStep("change to grid mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Grid);
int userId = 0;
AddRepeatStep("join user", () =>
{
MultiplayerClient.AddUser(new MultiplayerRoomUser(userId)
{
User = new APIUser
{
Username = $"User {userId}"
}
});
userId++;
}, 8);
}
[Test]
public void AddPanelsSplit()
{
AddStep("change to split mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Split);
int userId = 0;
AddRepeatStep("join user", () =>
{
MultiplayerClient.AddUser(new MultiplayerRoomUser(userId)
{
User = new APIUser
{
Username = $"User {userId}"
}
});
userId++;
}, 8);
}
[Test]
public void ChangeRankings()
{
AddStep("join users", () =>
{
for (int i = 0; i < 7; i++)
{
MultiplayerClient.AddUser(new MultiplayerRoomUser(i)
{
User = new APIUser
{
Username = $"User {i}"
}
});
}
});
AddStep("set random placements", () =>
{
MultiplayerRoom room = MultiplayerClient.ServerRoom!;
int[] placements = Enumerable.Range(1, room.Users.Count).ToArray();
Random.Shared.Shuffle(placements);
MatchmakingRoomState state = new MatchmakingRoomState();
for (int i = 0; i < room.Users.Count; i++)
state.Users[room.Users[i].UserID].Placement = placements[i];
MultiplayerClient.ChangeMatchRoomState(state).WaitSafely();
});
}
}
}
@@ -14,10 +14,13 @@ using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
namespace osu.Game.Screens.OnlinePlay.Matchmaking
{
public partial class PlayerPanel : UserPanel
{
public static readonly Vector2 SIZE_HORIZONTAL = new Vector2(250, 100);
public static readonly Vector2 SIZE_VERTICAL = new Vector2(150, 200);
public readonly MultiplayerRoomUser RoomUser;
[Resolved]
@@ -32,6 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
private MatchmakingAvatar avatar = null!;
private OsuSpriteText username = null!;
private Container scaleContainer = null!;
private Container mainContent = null!;
public bool Horizontal
@@ -59,41 +63,47 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
Masking = true;
CornerRadius = 10;
Add(mainContent = new Container
Add(scaleContainer = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
Child = mainContent = new Container
{
avatar = new MatchmakingAvatar(User, isOwnUser: User.Id == api.LocalUser.Value.Id)
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
Anchor = Anchor.TopLeft,
Origin = Anchor.Centre,
Size = new Vector2(80),
},
rankText = new OsuSpriteText
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomCentre,
Blending = BlendingParameters.Additive,
Margin = new MarginPadding(4),
Font = OsuFont.Style.Title.With(size: 70),
},
username = new OsuSpriteText
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Text = User.Username,
Font = OsuFont.Style.Heading1,
},
scoreText = new OsuSpriteText
{
Margin = new MarginPadding(10),
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Font = OsuFont.Style.Heading2,
Text = "0 pts"
avatar = new MatchmakingAvatar(User, isOwnUser: User.Id == api.LocalUser.Value.Id)
{
Anchor = Anchor.TopLeft,
Origin = Anchor.Centre,
Size = new Vector2(80),
},
rankText = new OsuSpriteText
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomCentre,
Blending = BlendingParameters.Additive,
Margin = new MarginPadding(4),
Font = OsuFont.Style.Title.With(size: 70),
},
username = new OsuSpriteText
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Text = User.Username,
Font = OsuFont.Style.Heading1,
},
scoreText = new OsuSpriteText
{
Margin = new MarginPadding(10),
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Font = OsuFont.Style.Heading2,
Text = "0 pts"
}
}
}
});
@@ -141,7 +151,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
double duration = instant ? 0 : 1000;
avatar.MoveTo(avatarPosition, duration, Easing.OutPow10);
this.ResizeTo(horizontal ? new Vector2(250, 100) : new Vector2(150, 200), duration, Easing.OutPow10);
this.ResizeTo(horizontal ? SIZE_HORIZONTAL : SIZE_VERTICAL, duration, Easing.OutPow10);
rankText.MoveTo(horizontal ? new Vector2(-40, -10) : new Vector2(-70, 0), duration, Easing.OutPow10);
username.MoveTo(horizontal ? new Vector2(0, -46) : new Vector2(0, -86), duration, Easing.OutPow10);
@@ -150,14 +160,14 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
protected override bool OnHover(HoverEvent e)
{
this.ScaleTo(1.02f, 1000, Easing.OutQuint);
scaleContainer.ScaleTo(1.02f, 1000, Easing.OutQuint);
mainContent.ScaleTo(1.03f, 1000, Easing.OutQuint);
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
this.ScaleTo(1f, 500, Easing.OutQuint);
scaleContainer.ScaleTo(1f, 500, Easing.OutQuint);
mainContent.ScaleTo(1, 500, Easing.OutQuint);
mainContent.MoveTo(Vector2.Zero, 500, Easing.OutElasticHalf);
@@ -0,0 +1,305 @@
// 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.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Matchmaking
{
public partial class PlayerPanelList : CompositeDrawable
{
[Resolved]
private MultiplayerClient client { get; set; } = null!;
private Container<PlayerPanel> panels = null!;
private PlayerPanelCellContainer gridLayout = null!;
private PlayerPanelCellContainer splitLayoutLeft = null!;
private PlayerPanelCellContainer splitLayoutRight = null!;
private PanelDisplayStyle displayStyle;
private Drawable? displayArea;
private bool isAnimatingToDisplayArea;
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
gridLayout = new PlayerPanelCellContainer
{
RelativeSizeAxes = Axes.Both,
Spacing = new Vector2(20, 5),
},
splitLayoutLeft = new PlayerPanelCellContainer
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(20, 5),
},
splitLayoutRight = new PlayerPanelCellContainer
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Direction = FillDirection.Vertical,
Spacing = new Vector2(20, 5),
},
panels = new Container<PlayerPanel>
{
RelativeSizeAxes = Axes.Both
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
// Set position/size so we don't initially animate.
Position = getFinalPosition();
Size = getFinalSize();
client.MatchRoomStateChanged += onRoomStateChanged;
client.UserJoined += onUserJoined;
client.UserLeft += onUserLeft;
if (client.Room != null)
{
onRoomStateChanged(client.Room.MatchState);
foreach (var user in client.Room.Users)
onUserJoined(user);
}
updateDisplay();
}
public PanelDisplayStyle DisplayStyle
{
set
{
displayStyle = value;
if (IsLoaded)
updateDisplay();
}
}
public Drawable? DisplayArea
{
set
{
displayArea = value;
isAnimatingToDisplayArea = true;
}
}
private void onUserJoined(MultiplayerRoomUser user) => Scheduler.Add(() =>
{
panels.Add(new PlayerPanel(user)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.8f)
});
updateDisplay();
});
private void onUserLeft(MultiplayerRoomUser user) => Scheduler.Add(() =>
{
panels.Single(p => p.RoomUser.Equals(user)).Expire();
updateDisplay();
});
private void onRoomStateChanged(MatchRoomState? state) => Scheduler.Add(updateDisplay);
private void updateDisplay()
{
gridLayout.ReleasePanels();
splitLayoutLeft.ReleasePanels();
splitLayoutRight.ReleasePanels();
switch (displayStyle)
{
case PanelDisplayStyle.Grid:
foreach (var panel in panels)
{
panel.FadeTo(1, 200);
panel.Horizontal = false;
}
gridLayout.AcquirePanels(panels.ToArray());
break;
case PanelDisplayStyle.Split:
foreach (var panel in panels)
{
panel.FadeTo(1, 200);
panel.Horizontal = true;
}
int leftCount = (int)Math.Ceiling(panels.Count / 2f);
splitLayoutLeft.AcquirePanels(panels.Take(leftCount).ToArray());
splitLayoutRight.AcquirePanels(panels.Skip(leftCount).ToArray());
break;
case PanelDisplayStyle.Hidden:
foreach (var panel in panels)
panel.FadeTo(0, 200);
return;
}
}
protected override void Update()
{
base.Update();
var targetPos = getFinalPosition();
var targetSize = getFinalSize();
double duration = isAnimatingToDisplayArea ? 60 : 0;
if (Time.Elapsed > 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.
isAnimatingToDisplayArea &= !Precision.AlmostEquals(Size, targetSize, 0.5f);
}
private Vector2 getFinalPosition()
=> displayArea == null ? Vector2.Zero : Parent!.ToLocalSpace(displayArea.ScreenSpaceDrawQuad.TopLeft);
private Vector2 getFinalSize()
=> displayArea == null ? Parent!.DrawSize : Parent!.ToLocalSpace(displayArea.ScreenSpaceDrawQuad.BottomRight) - Parent!.ToLocalSpace(displayArea.ScreenSpaceDrawQuad.TopLeft);
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (client.IsNotNull())
{
client.MatchRoomStateChanged -= onRoomStateChanged;
client.UserJoined -= onUserJoined;
client.UserLeft -= onUserLeft;
}
}
private partial class PlayerPanelCellContainer : FillFlowContainer<PlayerPanelCell>
{
[Resolved]
private MultiplayerClient client { get; set; } = null!;
public void AcquirePanels(PlayerPanel[] panels)
{
while (Count < panels.Length)
{
Add(new PlayerPanelCell
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
});
}
while (Count > panels.Length)
Remove(Children[^1], true);
for (int i = 0; i < panels.Length; i++)
{
// We'll invalidate the layout position to represent the new placements and the re-flow will happen in UpdateAfterChildren().
// But the cells expect their positions to be valid as they're updated, which won't be the case until the re-flow happens.
int i2 = i;
ScheduleAfterChildren(() => Children[i2].AcquirePanel(panels[i2]));
if (client.Room?.MatchState is not MatchmakingRoomState matchmakingState)
continue;
if (matchmakingState.Users.UserDictionary.TryGetValue(panels[i].User.Id, out MatchmakingUser? user))
SetLayoutPosition(Children[i], user.Placement);
else
SetLayoutPosition(Children[i], float.MaxValue);
}
}
public void ReleasePanels()
{
foreach (var panel in Children)
panel.ReleasePanel();
}
}
private partial class PlayerPanelCell : Drawable
{
private PlayerPanel? panel;
private bool isAnimating;
public void AcquirePanel(PlayerPanel panel)
{
this.panel = panel;
isAnimating = true;
}
public void ReleasePanel()
{
panel = null;
}
protected override void Update()
{
base.Update();
if (panel == null)
return;
Size = panel.Horizontal ? PlayerPanel.SIZE_HORIZONTAL : PlayerPanel.SIZE_VERTICAL;
Size *= panel.Scale;
var targetPos = getFinalPosition();
double duration = isAnimating ? 60 : 0;
if (Time.Elapsed > 0)
{
panel.Position = new Vector2(
(float)Interpolation.DampContinuously(panel.Position.X, targetPos.X, duration, Time.Elapsed),
(float)Interpolation.DampContinuously(panel.Position.Y, targetPos.Y, duration, Time.Elapsed)
);
}
// If we don't track the animating state, the animation will also occur when resizing the window.
isAnimating &= !Precision.AlmostEquals(panel.Position, targetPos, 0.5f);
Vector2 getFinalPosition()
=> panel.Parent!.ToLocalSpace(ScreenSpaceDrawQuad.Centre) - panel.AnchorPosition;
}
}
public enum PanelDisplayStyle
{
Grid,
Split,
Hidden
}
}
}
@@ -1,7 +1,6 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Screens;
@@ -9,14 +8,8 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
{
public partial class IdleScreen : MatchmakingSubScreen
{
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new PlayerPanelList
{
RelativeSizeAxes = Axes.Both
};
}
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Grid;
public override Drawable PlayersDisplayArea => this;
public override void OnEntering(ScreenTransitionEvent e)
{
@@ -1,93 +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.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
{
public partial class PlayerPanelList : CompositeDrawable
{
[Resolved]
private MultiplayerClient client { get; set; } = null!;
public bool Horizontal { get; init; }
private FillFlowContainer<PlayerPanel> panels = null!;
[BackgroundDependencyLoader]
private void load()
{
InternalChild = panels = new FillFlowContainer<PlayerPanel>
{
RelativeSizeAxes = Axes.Both,
Spacing = new Vector2(20, 5),
LayoutEasing = Easing.InOutQuint,
LayoutDuration = 500
};
}
protected override void LoadComplete()
{
base.LoadComplete();
client.MatchRoomStateChanged += onRoomStateChanged;
client.UserJoined += onUserJoined;
client.UserLeft += onUserLeft;
if (client.Room != null)
{
onRoomStateChanged(client.Room.MatchState);
foreach (var user in client.Room.Users)
onUserJoined(user);
}
}
private void onUserJoined(MultiplayerRoomUser user) => Scheduler.Add(() =>
{
panels.Add(new PlayerPanel(user)
{
Horizontal = Horizontal,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});
});
private void onUserLeft(MultiplayerRoomUser user) => Scheduler.Add(() =>
{
panels.Single(p => p.RoomUser.Equals(user)).Expire();
});
private void onRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
{
if (state is not MatchmakingRoomState matchmakingState)
return;
foreach (var panel in panels)
{
if (matchmakingState.Users.UserDictionary.TryGetValue(panel.User.Id, out MatchmakingUser? user))
panels.SetLayoutPosition(panel, user.Placement);
else
panels.SetLayoutPosition(panel, float.MaxValue);
}
});
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (client.IsNotNull())
{
client.MatchRoomStateChanged -= onRoomStateChanged;
client.UserJoined -= onUserJoined;
client.UserLeft -= onUserLeft;
}
}
}
}
@@ -13,7 +13,6 @@ using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
{
@@ -23,6 +22,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
private MultiplayerClient client { get; set; } = null!;
private ScreenStack screenStack = null!;
private PlayerPanelList playersList = null!;
[BackgroundDependencyLoader]
private void load()
@@ -30,40 +30,28 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
RelativeSizeAxes = Axes.Both;
Padding = new MarginPadding(10);
InternalChild = new GridContainer
InternalChildren = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
RowDimensions = new[] { new Dimension(), new Dimension(GridSizeMode.AutoSize) },
Content = new Drawable[][]
new GridContainer
{
[
new GridContainer
{
RelativeSizeAxes = Axes.Both,
ColumnDimensions = new[] { new Dimension(), new Dimension(GridSizeMode.Absolute, 20), new Dimension(GridSizeMode.AutoSize) },
Padding = new MarginPadding { Bottom = 20 },
Content = new Drawable?[][]
RelativeSizeAxes = Axes.Both,
RowDimensions = new[] { new Dimension(), new Dimension(GridSizeMode.AutoSize) },
Content = new Drawable[][]
{
[
screenStack = new ScreenStack(),
],
[
new StageDisplay
{
[
screenStack = new ScreenStack(),
null,
new PlayerPanelList
{
Horizontal = true,
RelativeSizeAxes = Axes.Y,
Width = 250,
Scale = new Vector2(0.8f),
}
]
RelativeSizeAxes = Axes.X
}
}
],
[
new StageDisplay
{
RelativeSizeAxes = Axes.X
}
]
]
}
},
playersList = new PlayerPanelList
{
DisplayArea = this
}
};
}
@@ -72,12 +60,33 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
{
base.LoadComplete();
screenStack.ScreenPushed += onScreenPushed;
screenStack.ScreenExited += onScreenExited;
screenStack.Push(new IdleScreen());
client.MatchRoomStateChanged += onMatchRoomStateChanged;
onMatchRoomStateChanged(client.Room!.MatchState);
}
private void onScreenPushed(IScreen lastScreen, IScreen newScreen)
{
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
return;
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
}
private void onScreenExited(IScreen lastScreen, IScreen newScreen)
{
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
return;
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
}
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
{
if (state is not MatchmakingRoomState matchmakingState)
@@ -6,9 +6,12 @@ using osu.Framework.Screens;
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
{
public partial class MatchmakingSubScreen : Screen
public abstract partial class MatchmakingSubScreen : Screen
{
public MatchmakingSubScreen()
public abstract PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle { get; }
public abstract Drawable? PlayersDisplayArea { get; }
protected MatchmakingSubScreen()
{
RelativePositionAxes = Axes.X;
}
@@ -16,19 +19,19 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
public override void OnEntering(ScreenTransitionEvent e)
{
base.OnEntering(e);
this.MoveToX(1).MoveToX(0, 200);
this.FadeInFromZero(200);
}
public override void OnSuspending(ScreenTransitionEvent e)
{
base.OnSuspending(e);
this.MoveToX(-1, 200);
this.FadeOutFromOne(200);
}
public override void OnResuming(ScreenTransitionEvent e)
{
base.OnResuming(e);
this.MoveToX(0, 200);
this.FadeInFromZero(200);
}
public override bool OnExiting(ScreenExitEvent e)
@@ -36,7 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
if (base.OnExiting(e))
return true;
this.MoveToX(1, 200);
this.FadeOutFromOne(200);
return false;
}
}
@@ -11,23 +11,38 @@ using osu.Game.Online.Rooms;
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
{
public partial class PickScreen : OsuScreen
public partial class PickScreen : MatchmakingSubScreen
{
private BeatmapSelectionGrid selectionGrid = null!;
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Split;
public override Drawable PlayersDisplayArea { get; }
private readonly BeatmapSelectionGrid selectionGrid;
[Resolved]
private MultiplayerClient client { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
public PickScreen()
{
InternalChild = new Container
InternalChildren = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Child = selectionGrid = new BeatmapSelectionGrid
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = 200 },
Child = selectionGrid = new BeatmapSelectionGrid
{
RelativeSizeAxes = Axes.Both,
},
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = 5 },
Child = PlayersDisplayArea = Empty().With(d =>
{
d.RelativeSizeAxes = Axes.Both;
})
}
};
}
@@ -11,7 +11,6 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle;
using osu.Game.Utils;
using osuTK;
@@ -21,15 +20,17 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
{
private const float grid_spacing = 5;
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Grid;
public override Drawable PlayersDisplayArea { get; }
[Resolved]
private MultiplayerClient client { get; set; } = null!;
private OsuSpriteText placementText = null!;
private FillFlowContainer<UserStatisticPanel> userStatistics = null!;
private FillFlowContainer<RoomStatisticPanel> roomStatistics = null!;
private readonly OsuSpriteText placementText;
private readonly FillFlowContainer<UserStatisticPanel> userStatistics;
private readonly FillFlowContainer<RoomStatisticPanel> roomStatistics;
[BackgroundDependencyLoader]
private void load()
public ResultsScreen()
{
InternalChild = new GridContainer
{
@@ -113,10 +114,10 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
}
},
null,
new PlayerPanelList
PlayersDisplayArea = Empty().With(d =>
{
RelativeSizeAxes = Axes.Both
}
d.RelativeSizeAxes = Axes.Both;
})
]
}
}
@@ -29,6 +29,9 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults
{
private const int panel_spacing = 5;
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Hidden;
public override Drawable? PlayersDisplayArea => null;
[Resolved]
private IAPIProvider api { get; set; } = null!;