diff --git a/osu.Game.Tests/Visual/TestCaseLounge.cs b/osu.Game.Tests/Visual/TestCaseLounge.cs index b96d705d5c..c5e0d1c4bf 100644 --- a/osu.Game.Tests/Visual/TestCaseLounge.cs +++ b/osu.Game.Tests/Visual/TestCaseLounge.cs @@ -8,6 +8,8 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Screens; +using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Screens.Lounge; using osu.Game.Users; @@ -198,6 +200,8 @@ namespace osu.Game.Tests.Visual private class TestLounge : Lounge { + protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); + public IEnumerable ChildRooms => RoomsContainer.Children.Where(r => r.MatchingFilter); public Room SelectedRoom => Inspector.Room; diff --git a/osu.Game.Tests/Visual/TestCaseMatch.cs b/osu.Game.Tests/Visual/TestCaseMatch.cs new file mode 100644 index 0000000000..bb22358425 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatch.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMatch : OsuTestCase + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + Room room = new Room + { + Name = { Value = @"One Awesome Room" }, + Status = { Value = new RoomStatusOpen() }, + Availability = { Value = RoomAvailability.Public }, + Type = { Value = new GameTypeTeamVersus() }, + Beatmap = + { + Value = new BeatmapInfo + { + StarDifficulty = 5.02, + Ruleset = rulesets.GetRuleset(1), + Metadata = new BeatmapMetadata + { + Title = @"Paradigm Shift", + Artist = @"Morimori Atsushi", + AuthorString = @"eiri-", + }, + BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/765055/covers/cover.jpg?1526955337", + }, + }, + }, + }, + }, + MaxParticipants = { Value = 5 }, + Participants = + { + Value = new[] + { + new User + { + Username = @"eiri-", + Id = 3388410, + Country = new Country { FlagName = @"US" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3388410/00a8486a247831e1cc4375db519f611ac970bda8bc0057d78b0f540ea38c3e58.jpeg", + IsSupporter = true, + }, + new User + { + Username = @"Nepuri", + Id = 6637817, + Country = new Country { FlagName = @"DE" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/6637817/9085fc60248b6b5327a72c1dcdecf2dbedba810ae0ab6bcf7224e46b1339632a.jpeg", + IsSupporter = true, + }, + new User + { + Username = @"goheegy", + Id = 8057655, + Country = new Country { FlagName = @"GB" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8057655/21cec27c25a11dc197a4ec6a74253dbabb495949b0e0697113352f12007018c5.jpeg", + }, + new User + { + Username = @"Alumetri", + Id = 5371497, + Country = new Country { FlagName = @"RU" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5371497/e023b8c7fbe3613e64bd4856703517ea50fbed8a5805dc9acda9efe9897c67e2.jpeg", + }, + } + }, + }; + + Match match = new Match(room); + + AddStep(@"show", () => Add(match)); + AddStep(@"null beatmap", () => room.Beatmap.Value = null); + AddStep(@"change name", () => room.Name.Value = @"Two Awesome Rooms"); + AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); + AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.FriendsOnly); + AddStep(@"change type", () => room.Type.Value = new GameTypeTag()); + AddStep(@"change beatmap", () => room.Beatmap.Value = new BeatmapInfo + { + StarDifficulty = 4.33, + Ruleset = rulesets.GetRuleset(2), + Metadata = new BeatmapMetadata + { + Title = @"Yasashisa no Riyuu", + Artist = @"ChouCho", + AuthorString = @"celerih", + }, + BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/685391/covers/cover.jpg?1524597970", + }, + }, + }, + }); + + AddStep(@"null max participants", () => room.MaxParticipants.Value = null); + AddStep(@"change participants", () => room.Participants.Value = new[] + { + new User + { + Username = @"Spectator", + Id = 702598, + Country = new Country { FlagName = @"KR" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/702598/3bbf4cb8b8d2cf8b03145000a975ff27e191ab99b0920832e7dd67386280e288.jpeg", + IsSupporter = true, + }, + new User + { + Username = @"celerih", + Id = 4696296, + Country = new Country { FlagName = @"CA" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/4696296/7f8500731d0ac66d5472569d146a7be07d9460273361913f22c038867baddaef.jpeg", + }, + }); + + AddStep(@"exit", match.Exit); + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseMatchHeader.cs b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs new file mode 100644 index 0000000000..34f98f97c2 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchHeader.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Screens.Multi.Screens.Match; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMatchHeader : OsuTestCase + { + public TestCaseMatchHeader() + { + Header header = new Header(); + Add(header); + + AddStep(@"set beatmap set", () => header.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/760757/covers/cover.jpg?1526944540", + }, + }, + }); + + AddStep(@"change beatmap set", () => header.BeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = @"https://assets.ppy.sh/beatmaps/761883/covers/cover.jpg?1525557400", + }, + }, + }); + + AddStep(@"null beatmap set", () => header.BeatmapSet = null); + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseMatchInfo.cs b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs new file mode 100644 index 0000000000..205da6932f --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchInfo.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Screens.Multi.Screens.Match; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMatchInfo : OsuTestCase + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + Info info = new Info(); + Add(info); + + AddStep(@"set name", () => info.Name = @"Room Name?"); + AddStep(@"set availability", () => info.Availability = RoomAvailability.FriendsOnly); + AddStep(@"set status", () => info.Status = new RoomStatusPlaying()); + AddStep(@"set beatmap", () => info.Beatmap = new BeatmapInfo + { + StarDifficulty = 2.4, + Ruleset = rulesets.GetRuleset(0), + Metadata = new BeatmapMetadata + { + Title = @"My Song", + Artist = @"VisualTests", + AuthorString = @"osu!lazer", + }, + }); + + AddStep(@"set type", () => info.Type = new GameTypeTagTeam()); + + AddStep(@"change name", () => info.Name = @"Room Name!"); + AddStep(@"change availability", () => info.Availability = RoomAvailability.InviteOnly); + AddStep(@"change status", () => info.Status = new RoomStatusOpen()); + AddStep(@"null beatmap", () => info.Beatmap = null); + AddStep(@"change type", () => info.Type = new GameTypeTeamVersus()); + AddStep(@"change beatmap", () => info.Beatmap = new BeatmapInfo + { + StarDifficulty = 4.2, + Ruleset = rulesets.GetRuleset(3), + Metadata = new BeatmapMetadata + { + Title = @"Your Song", + Artist = @"Tester", + AuthorString = @"Someone", + }, + }); + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs new file mode 100644 index 0000000000..d6ae07252b --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMatchParticipants.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Screens.Multi.Screens.Match; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMatchParticipants : OsuTestCase + { + public TestCaseMatchParticipants() + { + Participants participants; + Add(participants = new Participants + { + RelativeSizeAxes = Axes.Both, + }); + + AddStep(@"set max to null", () => participants.Max = null); + AddStep(@"set users", () => participants.Users = new[] + { + new User + { + Username = @"Feppla", + Id = 4271601, + Country = new Country { FlagName = @"SE" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg", + IsSupporter = true, + }, + new User + { + Username = @"Xilver", + Id = 3099689, + Country = new Country { FlagName = @"IL" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg", + IsSupporter = true, + }, + new User + { + Username = @"Wucki", + Id = 5287410, + Country = new Country { FlagName = @"FI" }, + CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5287410/5cfeaa9dd41cbce038ecdc9d781396ed4b0108089170bf7f50492ef8eadeb368.jpeg", + IsSupporter = true, + }, + }); + + AddStep(@"set max", () => participants.Max = 10); + AddStep(@"clear users", () => participants.Users = new User[] { }); + AddStep(@"set max to null", () => participants.Max = null); + } + } +} diff --git a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs index 016babcaa5..51dea355bf 100644 --- a/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs +++ b/osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs @@ -164,7 +164,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge // open the room if its selected and is clicked again if (room.State == SelectionState.Selected) - Push(new Match()); + Push(new Match.Match(room.Room)); } private class RoomsFilterContainer : FillFlowContainer, IHasFilterableChildren diff --git a/osu.Game/Screens/Multi/Screens/Match.cs b/osu.Game/Screens/Multi/Screens/Match.cs deleted file mode 100644 index 4ba7fe9f6a..0000000000 --- a/osu.Game/Screens/Multi/Screens/Match.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Screens; -using osu.Game.Screens.Backgrounds; -using osu.Game.Screens.Play; -using osu.Game.Screens.Select; -using OpenTK.Graphics; - -namespace osu.Game.Screens.Multi.Screens -{ - public class Match : ScreenWhiteBox - { - protected override IEnumerable PossibleChildren => new[] { - typeof(MatchSongSelect), - typeof(Player), - }; - - protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); - - protected override void OnEntering(Screen last) - { - base.OnEntering(last); - - Background.FadeColour(Color4.DarkGray, 500); - } - - protected override bool OnExiting(Screen next) - { - Background.FadeColour(Color4.White, 500); - return base.OnExiting(next); - } - } -} diff --git a/osu.Game/Screens/Multi/Screens/Match/Header.cs b/osu.Game/Screens/Multi/Screens/Match/Header.cs new file mode 100644 index 0000000000..02e717d4be --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/Header.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.SearchableList; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public class Header : Container + { + public const float HEIGHT = 200; + + private readonly Box tabStrip; + private readonly UpdateableBeatmapSetCover cover; + + public readonly PageTabControl Tabs; + + public BeatmapSetInfo BeatmapSet + { + set => cover.BeatmapSet = value; + } + + public Action OnRequestSelectBeatmap; + + public Header() + { + RelativeSizeAxes = Axes.X; + Height = HEIGHT; + + BeatmapSelectButton beatmapButton; + Children = new Drawable[] + { + cover = new UpdateableBeatmapSetCover + { + RelativeSizeAxes = Axes.Both, + Masking = true, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Color4.Black.Opacity(0.5f)), + }, + tabStrip = new Box + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = 1, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = 200, + Padding = new MarginPadding { Vertical = 5 }, + Child = beatmapButton = new BeatmapSelectButton + { + RelativeSizeAxes = Axes.Both, + }, + }, + Tabs = new PageTabControl + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + }, + }, + }, + }; + + beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + tabStrip.Colour = colours.Yellow; + } + + private class BeatmapSelectButton : OsuClickableContainer + { + private const float corner_radius = 5; + private const float bg_opacity = 0.5f; + private const float transition_duration = 100; + + private readonly Box bg; + private readonly Container border; + + public BeatmapSelectButton() + { + Masking = true; + CornerRadius = corner_radius; + + Children = new Drawable[] + { + bg = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = bg_opacity, + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = @"Exo2.0-Bold", + Text = "Select Beatmap", + }, + border = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = corner_radius, + BorderThickness = 4, + Alpha = 0, + Child = new Box // needs a child to show the border + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + border.BorderColour = colours.Yellow; + } + + protected override bool OnHover(InputState state) + { + border.FadeIn(transition_duration); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + base.OnHoverLost(state); + border.FadeOut(transition_duration); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + bg.FadeTo(0.75f, 1000, Easing.Out); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + bg.FadeTo(bg_opacity, transition_duration); + return base.OnMouseUp(state, args); + } + } + } + + public enum MatchHeaderPage + { + Settings, + Room, + } +} diff --git a/osu.Game/Screens/Multi/Screens/Match/Info.cs b/osu.Game/Screens/Multi/Screens/Match/Info.cs new file mode 100644 index 0000000000..ec93eb90b1 --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/Info.cs @@ -0,0 +1,210 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osu.Game.Overlays.SearchableList; +using osu.Game.Screens.Multi.Components; +using OpenTK; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public class Info : Container + { + public const float HEIGHT = 128; + + private readonly OsuSpriteText name, availabilityStatus; + private readonly BeatmapTypeInfo beatmapTypeInfo; + private readonly ReadyButton readyButton; + + private OsuColour colours; + + public Bindable Ready => readyButton.Ready; + + public string Name + { + set { name.Text = value; } + } + + private RoomAvailability availability; + public RoomAvailability Availability + { + set + { + if (value == availability) return; + availability = value; + + if (IsLoaded) + updateAvailabilityStatus(); + } + } + + private RoomStatus status; + public RoomStatus Status + { + set + { + if (value == status) return; + status = value; + + if (IsLoaded) + updateAvailabilityStatus(); + } + } + + public BeatmapInfo Beatmap + { + set { beatmapTypeInfo.Beatmap = value; } + } + + public GameType Type + { + set { beatmapTypeInfo.Type = value; } + } + + public Info() + { + RelativeSizeAxes = Axes.X; + Height = HEIGHT; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"28242d"), + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 20 }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + name = new OsuSpriteText + { + TextSize = 30, + }, + availabilityStatus = new OsuSpriteText + { + TextSize = 14, + }, + }, + }, + beatmapTypeInfo = new BeatmapTypeInfo + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }, + }, + }, + readyButton = new ReadyButton + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(200, 1), + Padding = new MarginPadding { Vertical = 10 }, + }, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + this.colours = colours; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + updateAvailabilityStatus(); + } + + private void updateAvailabilityStatus() + { + if (status != null) + { + availabilityStatus.FadeColour(status.GetAppropriateColour(colours), 100); + availabilityStatus.Text = $"{availability.GetDescription()}, {status.Message}"; + } + } + + private class ReadyButton : TriangleButton + { + public readonly Bindable Ready = new Bindable(); + + protected override SpriteText CreateText() => new OsuSpriteText + { + Depth = -1, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Font = @"Exo2.0-Light", + TextSize = 30, + }; + + [BackgroundDependencyLoader] + private void load() + { + BackgroundColour = OsuColour.FromHex(@"1187aa"); + Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); + Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); + Triangles.TriangleScale = 1.5f; + + Container active; + Add(active = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.15f, + Blending = BlendingMode.Additive, + }, + }); + + Action = () => Ready.Value = !Ready.Value; + + Ready.BindValueChanged(value => + { + if (value) + { + Text = "Not Ready"; + active.FadeIn(200); + } + else + { + Text = "Ready"; + active.FadeOut(200); + } + }, true); + } + } + } +} diff --git a/osu.Game/Screens/Multi/Screens/Match/Match.cs b/osu.Game/Screens/Multi/Screens/Match/Match.cs new file mode 100644 index 0000000000..ce3f7825a4 --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/Match.cs @@ -0,0 +1,81 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Select; +using osu.Game.Users; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public class Match : MultiplayerScreen + { + private readonly Room room; + private readonly Participants participants; + + private readonly Bindable nameBind = new Bindable(); + private readonly Bindable statusBind = new Bindable(); + private readonly Bindable availabilityBind = new Bindable(); + private readonly Bindable typeBind = new Bindable(); + private readonly Bindable beatmapBind = new Bindable(); + private readonly Bindable maxParticipantsBind = new Bindable(); + private readonly Bindable> participantsBind = new Bindable>(); + + protected override Container TransitionContent => participants; + + public override string Type => "room"; + public override string Title => room.Name.Value; + + public Match(Room room) + { + this.room = room; + Header header; + Info info; + + Children = new Drawable[] + { + header = new Header(), + info = new Info + { + Margin = new MarginPadding { Top = Header.HEIGHT }, + }, + participants = new Participants + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = Header.HEIGHT + Info.HEIGHT }, + }, + }; + + header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect()); + + beatmapBind.BindTo(room.Beatmap); + beatmapBind.BindValueChanged(b => + { + header.BeatmapSet = b?.BeatmapSet; + info.Beatmap = b; + }, true); + + nameBind.BindTo(room.Name); + nameBind.BindValueChanged(n => info.Name = n, true); + + statusBind.BindTo(room.Status); + statusBind.BindValueChanged(s => info.Status = s, true); + + availabilityBind.BindTo(room.Availability); + availabilityBind.BindValueChanged(a => info.Availability = a, true); + + typeBind.BindTo(room.Type); + typeBind.BindValueChanged(t => info.Type = t, true); + + maxParticipantsBind.BindTo(room.MaxParticipants); + maxParticipantsBind.BindValueChanged(m => { participants.Max = m; }, true); + + participantsBind.BindTo(room.Participants); + participantsBind.BindValueChanged(p => participants.Users = p, true); + } + } +} diff --git a/osu.Game/Screens/Multi/Screens/Match/Participants.cs b/osu.Game/Screens/Multi/Screens/Match/Participants.cs new file mode 100644 index 0000000000..9fa90f8752 --- /dev/null +++ b/osu.Game/Screens/Multi/Screens/Match/Participants.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays.SearchableList; +using osu.Game.Screens.Multi.Components; +using osu.Game.Users; +using OpenTK; + +namespace osu.Game.Screens.Multi.Screens.Match +{ + public class Participants : Container + { + private readonly ParticipantCount count; + private readonly FillFlowContainer usersFlow; + + public IEnumerable Users + { + set { + usersFlow.Children = value.Select(u => new UserPanel(u) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Width = 300, + OnLoadComplete = d => d.FadeInFromZero(60), + }).ToList(); + + count.Count = value.Count(); + } + } + + public int? Max + { + set => count.Max = value; + } + + public Participants() + { + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 10 }, + Children = new Drawable[] + { + count = new ParticipantCount + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }, + usersFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(5), + Padding = new MarginPadding { Top = 40 }, + LayoutDuration = 200, + LayoutEasing = Easing.OutQuint, + }, + }, + }, + }, + }; + } + } +} diff --git a/osu.Game/Screens/Multi/Screens/MatchCreate.cs b/osu.Game/Screens/Multi/Screens/MatchCreate.cs deleted file mode 100644 index 6b4e26d5e5..0000000000 --- a/osu.Game/Screens/Multi/Screens/MatchCreate.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; - -namespace osu.Game.Screens.Multi.Screens -{ - public class MatchCreate : ScreenWhiteBox - { - protected override IEnumerable PossibleChildren => new[] { - typeof(Match) - }; - - public MatchCreate() - { - ValidForResume = false; - } - } -} diff --git a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs index fa9b40684c..00c2613d54 100644 --- a/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs +++ b/osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs @@ -10,9 +10,6 @@ namespace osu.Game.Screens.Multi.Screens { public abstract class MultiplayerScreen : OsuScreen { - private const Easing in_easing = Easing.OutQuint; - private const Easing out_easing = Easing.InSine; - protected virtual Container TransitionContent => Content; /// @@ -24,16 +21,15 @@ namespace osu.Game.Screens.Multi.Screens { base.OnEntering(last); - TransitionContent.MoveToX(200); - - TransitionContent.FadeInFromZero(WaveContainer.APPEAR_DURATION, in_easing); - TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing); + Content.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); + TransitionContent.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); + TransitionContent.MoveToX(200).MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); } protected override bool OnExiting(Screen next) { - Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing); - TransitionContent.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, out_easing); + Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + TransitionContent.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); return base.OnExiting(next); } @@ -42,16 +38,16 @@ namespace osu.Game.Screens.Multi.Screens { base.OnResuming(last); - Content.FadeIn(WaveContainer.APPEAR_DURATION, in_easing); - TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing); + Content.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint); + TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); } protected override void OnSuspending(Screen next) { base.OnSuspending(next); - Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing); - TransitionContent.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, out_easing); + Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + TransitionContent.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index a0c96d0cee..339392d5cf 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -7,12 +7,7 @@ namespace osu.Game.Screens.Select { protected override bool OnStart() { - Schedule(() => - { - // needs to be scheduled else we enter an infinite feedback loop. - if (IsCurrentScreen) Exit(); - }); - + if (IsCurrentScreen) Exit(); return true; } }