mirror of
https://github.com/ppy/osu.git
synced 2025-01-19 09:12:54 +08:00
Merge pull request #2603 from DrabWeb/multiplayer-lounge
Multiplayer lounge
This commit is contained in:
commit
ce8a6cfc53
211
osu.Game.Tests/Visual/TestCaseLounge.cs
Normal file
211
osu.Game.Tests/Visual/TestCaseLounge.cs
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
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.Components;
|
||||||
|
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestCaseLounge : ManualInputManagerTestCase
|
||||||
|
{
|
||||||
|
private TestLounge lounge;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(RulesetStore rulesets)
|
||||||
|
{
|
||||||
|
lounge = new TestLounge();
|
||||||
|
|
||||||
|
Room[] rooms =
|
||||||
|
{
|
||||||
|
new Room
|
||||||
|
{
|
||||||
|
Name = { Value = @"Just Another Room" },
|
||||||
|
Host = { Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } } },
|
||||||
|
Status = { Value = new RoomStatusPlaying() },
|
||||||
|
Availability = { Value = RoomAvailability.Public },
|
||||||
|
Type = { Value = new GameTypeTagTeam() },
|
||||||
|
Beatmap =
|
||||||
|
{
|
||||||
|
Value = new BeatmapInfo
|
||||||
|
{
|
||||||
|
StarDifficulty = 5.65,
|
||||||
|
Ruleset = rulesets.GetRuleset(0),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"Sidetracked Day (Short Ver.)",
|
||||||
|
Artist = @"VINXIS",
|
||||||
|
AuthorString = @"Hobbes2",
|
||||||
|
},
|
||||||
|
BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new BeatmapSetOnlineCovers
|
||||||
|
{
|
||||||
|
Cover = @"https://assets.ppy.sh/beatmaps/767600/covers/cover.jpg?1526243446",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MaxParticipants = { Value = 10 },
|
||||||
|
Participants =
|
||||||
|
{
|
||||||
|
Value = new[]
|
||||||
|
{
|
||||||
|
new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } },
|
||||||
|
new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } },
|
||||||
|
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } },
|
||||||
|
new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } },
|
||||||
|
new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } },
|
||||||
|
new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Room
|
||||||
|
{
|
||||||
|
Name = { Value = @"Not Just Any Room" },
|
||||||
|
Host = { Value = new User { Username = @"Monstrata", Id = 2706438, Country = new Country { FlagName = @"CA" } } },
|
||||||
|
Status = { Value = new RoomStatusOpen() },
|
||||||
|
Availability = { Value = RoomAvailability.FriendsOnly },
|
||||||
|
Type = { Value = new GameTypeTeamVersus() },
|
||||||
|
Beatmap =
|
||||||
|
{
|
||||||
|
Value = new BeatmapInfo
|
||||||
|
{
|
||||||
|
StarDifficulty = 2.73,
|
||||||
|
Ruleset = rulesets.GetRuleset(0),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"lit(var)",
|
||||||
|
Artist = @"kensuke ushio",
|
||||||
|
AuthorString = @"Monstrata",
|
||||||
|
},
|
||||||
|
BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new BeatmapSetOnlineCovers
|
||||||
|
{
|
||||||
|
Cover = @"https://assets.ppy.sh/beatmaps/623972/covers/cover.jpg?1521167183",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Participants =
|
||||||
|
{
|
||||||
|
Value = new[]
|
||||||
|
{
|
||||||
|
new User { Username = @"Jeby", Id = 3136279, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 3497 } } },
|
||||||
|
new User { Username = @"DualAkira", Id = 5220933, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 643 } } },
|
||||||
|
new User { Username = @"Datenshi Yohane", Id = 7171857, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10555 } } },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Room
|
||||||
|
{
|
||||||
|
Name = { Value = @"room THE FINAL" },
|
||||||
|
Host = { Value = new User { Username = @"Delis", Id = 1603923, Country = new Country { FlagName = @"JP" } } },
|
||||||
|
Status = { Value = new RoomStatusPlaying() },
|
||||||
|
Availability = { Value = RoomAvailability.Public },
|
||||||
|
Type = { Value = new GameTypeTagTeam() },
|
||||||
|
Beatmap =
|
||||||
|
{
|
||||||
|
Value = new BeatmapInfo
|
||||||
|
{
|
||||||
|
StarDifficulty = 4.48,
|
||||||
|
Ruleset = rulesets.GetRuleset(3),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = @"ONIGIRI FREEWAY",
|
||||||
|
Artist = @"OISHII",
|
||||||
|
AuthorString = @"Mentholzzz",
|
||||||
|
},
|
||||||
|
BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Covers = new BeatmapSetOnlineCovers
|
||||||
|
{
|
||||||
|
Cover = @"https://assets.ppy.sh/beatmaps/663098/covers/cover.jpg?1521898837",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MaxParticipants = { Value = 30 },
|
||||||
|
Participants =
|
||||||
|
{
|
||||||
|
Value = new[]
|
||||||
|
{
|
||||||
|
new User { Username = @"KizuA", Id = 6510442, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 5372 } } },
|
||||||
|
new User { Username = @"Colored", Id = 827563, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 810 } } },
|
||||||
|
new User { Username = @"Beryl", Id = 3817591, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10096 } } },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
AddStep(@"show", () => Add(lounge));
|
||||||
|
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||||
|
selectAssert(0);
|
||||||
|
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
||||||
|
AddAssert(@"no room selected", () => lounge.SelectedRoom == null);
|
||||||
|
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||||
|
selectAssert(1);
|
||||||
|
AddStep(@"open room 1", () => clickRoom(1));
|
||||||
|
AddStep(@"make lounge current", lounge.MakeCurrent);
|
||||||
|
filterAssert(@"THE FINAL", LoungeTab.Public, 1);
|
||||||
|
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||||
|
filterAssert(string.Empty, LoungeTab.Private, 1);
|
||||||
|
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||||
|
filterAssert(@"no matches", LoungeTab.Public, 0);
|
||||||
|
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
||||||
|
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||||
|
AddAssert(@"no matches after clear", () => !lounge.ChildRooms.Any());
|
||||||
|
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||||
|
AddStep(@"exit", lounge.Exit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clickRoom(int n)
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(lounge.ChildRooms.ElementAt(n));
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectAssert(int n)
|
||||||
|
{
|
||||||
|
AddStep($@"select room {n}", () => clickRoom(n));
|
||||||
|
AddAssert($@"room {n} selected", () => lounge.SelectedRoom == lounge.ChildRooms.ElementAt(n).Room);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterAssert(string filter, LoungeTab tab, int endCount)
|
||||||
|
{
|
||||||
|
AddStep($@"filter '{filter}', {tab}", () => lounge.SetFilter(filter, tab));
|
||||||
|
AddAssert(@"filtered correctly", () => lounge.ChildRooms.Count() == endCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestLounge : Lounge
|
||||||
|
{
|
||||||
|
public IEnumerable<DrawableRoom> ChildRooms => RoomsContainer.Children.Where(r => r.MatchingFilter);
|
||||||
|
public Room SelectedRoom => Inspector.Room;
|
||||||
|
|
||||||
|
public void SetFilter(string filter, LoungeTab tab)
|
||||||
|
{
|
||||||
|
Filter.Search.Current.Value = filter;
|
||||||
|
Filter.Tabs.Current.Value = tab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Multi;
|
using osu.Game.Screens.Multi;
|
||||||
using osu.Game.Screens.Multi.Screens;
|
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -13,14 +13,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public TestCaseMultiHeader()
|
public TestCaseMultiHeader()
|
||||||
{
|
{
|
||||||
Lobby lobby;
|
Lounge lounge;
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
lobby = new Lobby
|
lounge = new Lounge
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||||
},
|
},
|
||||||
new Header(lobby),
|
new Header(lounge),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,12 +84,9 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private abstract class TestScreen : OsuScreen
|
private abstract class TestScreen : OsuScreen
|
||||||
{
|
{
|
||||||
protected abstract string Title { get; }
|
|
||||||
protected abstract string NextTitle { get; }
|
protected abstract string NextTitle { get; }
|
||||||
protected abstract TestScreen CreateNextScreen();
|
protected abstract TestScreen CreateNextScreen();
|
||||||
|
|
||||||
public override string ToString() => Title;
|
|
||||||
|
|
||||||
public TestScreen PushNext()
|
public TestScreen PushNext()
|
||||||
{
|
{
|
||||||
TestScreen screen = CreateNextScreen();
|
TestScreen screen = CreateNextScreen();
|
||||||
@ -130,14 +127,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private class TestScreenOne : TestScreen
|
private class TestScreenOne : TestScreen
|
||||||
{
|
{
|
||||||
protected override string Title => @"Screen One";
|
public override string Title => @"Screen One";
|
||||||
protected override string NextTitle => @"Two";
|
protected override string NextTitle => @"Two";
|
||||||
protected override TestScreen CreateNextScreen() => new TestScreenTwo();
|
protected override TestScreen CreateNextScreen() => new TestScreenTwo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestScreenTwo : TestScreen
|
private class TestScreenTwo : TestScreen
|
||||||
{
|
{
|
||||||
protected override string Title => @"Screen Two";
|
public override string Title => @"Screen Two";
|
||||||
protected override string NextTitle => @"One";
|
protected override string NextTitle => @"One";
|
||||||
protected override TestScreen CreateNextScreen() => new TestScreenOne();
|
protected override TestScreen CreateNextScreen() => new TestScreenOne();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -157,7 +158,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
|
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetDescription() ?? value.ToString(),
|
||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
|
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
|
||||||
},
|
},
|
||||||
|
@ -12,6 +12,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
public Bindable<string> Name = new Bindable<string>();
|
public Bindable<string> Name = new Bindable<string>();
|
||||||
public Bindable<User> Host = new Bindable<User>();
|
public Bindable<User> Host = new Bindable<User>();
|
||||||
public Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
public Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
||||||
|
public Bindable<RoomAvailability> Availability = new Bindable<RoomAvailability>();
|
||||||
public Bindable<GameType> Type = new Bindable<GameType>();
|
public Bindable<GameType> Type = new Bindable<GameType>();
|
||||||
public Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
public Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||||
public Bindable<int?> MaxParticipants = new Bindable<int?>();
|
public Bindable<int?> MaxParticipants = new Bindable<int?>();
|
||||||
|
18
osu.Game/Online/Multiplayer/RoomAvailability.cs
Normal file
18
osu.Game/Online/Multiplayer/RoomAvailability.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Multiplayer
|
||||||
|
{
|
||||||
|
public enum RoomAvailability
|
||||||
|
{
|
||||||
|
Public,
|
||||||
|
|
||||||
|
[Description(@"Friends Only")]
|
||||||
|
FriendsOnly,
|
||||||
|
|
||||||
|
[Description(@"Invite Only")]
|
||||||
|
InviteOnly,
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
@ -9,6 +10,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
@ -23,11 +25,11 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Multi.Components
|
namespace osu.Game.Screens.Multi.Components
|
||||||
{
|
{
|
||||||
public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>
|
public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>, IFilterable
|
||||||
{
|
{
|
||||||
|
public const float SELECTION_BORDER_WIDTH = 4;
|
||||||
private const float corner_radius = 5;
|
private const float corner_radius = 5;
|
||||||
private const float selection_border_width = 4;
|
private const float transition_duration = 60;
|
||||||
private const float transition_duration = 100;
|
|
||||||
private const float content_padding = 10;
|
private const float content_padding = 10;
|
||||||
private const float height = 100;
|
private const float height = 100;
|
||||||
private const float side_strip_width = 5;
|
private const float side_strip_width = 5;
|
||||||
@ -62,6 +64,30 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
||||||
|
|
||||||
|
private bool matchingFilter;
|
||||||
|
public bool MatchingFilter
|
||||||
|
{
|
||||||
|
get { return matchingFilter; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
matchingFilter = value;
|
||||||
|
this.FadeTo(MatchingFilter ? 1 : 0, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action<DrawableRoom> action;
|
||||||
|
public new Action<DrawableRoom> Action
|
||||||
|
{
|
||||||
|
get { return action; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
action = value;
|
||||||
|
Enabled.Value = action != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event Action<SelectionState> StateChanged;
|
public event Action<SelectionState> StateChanged;
|
||||||
|
|
||||||
public DrawableRoom(Room room)
|
public DrawableRoom(Room room)
|
||||||
@ -69,8 +95,8 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
Room = room;
|
Room = room;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = height + selection_border_width * 2;
|
Height = height + SELECTION_BORDER_WIDTH * 2;
|
||||||
CornerRadius = corner_radius + selection_border_width / 2;
|
CornerRadius = corner_radius + SELECTION_BORDER_WIDTH / 2;
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
// create selectionBox here so State can be set before being loaded
|
// create selectionBox here so State can be set before being loaded
|
||||||
@ -79,8 +105,6 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Alpha = 0f,
|
Alpha = 0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
Action += () => State = SelectionState.Selected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -98,7 +122,7 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding(selection_border_width),
|
Padding = new MarginPadding(SELECTION_BORDER_WIDTH),
|
||||||
Child = new Container
|
Child = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@ -230,7 +254,7 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
status.Text = s.Message;
|
status.Text = s.Message;
|
||||||
|
|
||||||
foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status })
|
foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status })
|
||||||
d.FadeColour(s.GetAppropriateColour(colours), 100);
|
d.FadeColour(s.GetAppropriateColour(colours), transition_duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
beatmapBind.ValueChanged += b =>
|
beatmapBind.ValueChanged += b =>
|
||||||
@ -272,5 +296,22 @@ namespace osu.Game.Screens.Multi.Components
|
|||||||
beatmapBind.BindTo(Room.Beatmap);
|
beatmapBind.BindTo(Room.Beatmap);
|
||||||
participantsBind.BindTo(Room.Participants);
|
participantsBind.BindTo(Room.Participants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
this.FadeInFromZero(transition_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(InputState state)
|
||||||
|
{
|
||||||
|
if (Enabled.Value)
|
||||||
|
{
|
||||||
|
Action?.Invoke(this);
|
||||||
|
State = SelectionState.Selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.SearchableList;
|
using osu.Game.Overlays.SearchableList;
|
||||||
|
using osu.Game.Screens.Multi.Screens;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ namespace osu.Game.Screens.Multi
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
breadcrumbs.Current.ValueChanged += s => screenTitle.Text = s.ToString();
|
breadcrumbs.Current.ValueChanged += s => screenTitle.Text = ((MultiplayerScreen)s).Title;
|
||||||
breadcrumbs.Current.TriggerChange();
|
breadcrumbs.Current.TriggerChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@ using osu.Framework.Screens;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Screens.Multi.Screens;
|
using osu.Game.Screens.Menu;
|
||||||
|
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Multi
|
namespace osu.Game.Screens.Multi
|
||||||
{
|
{
|
||||||
@ -25,7 +26,7 @@ namespace osu.Game.Screens.Multi
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
};
|
};
|
||||||
|
|
||||||
Lobby lobby;
|
Lounge lounge;
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Container
|
new Container
|
||||||
@ -52,12 +53,12 @@ namespace osu.Game.Screens.Multi
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||||
Child = lobby = new Lobby(),
|
Child = lounge = new Lounge(),
|
||||||
},
|
},
|
||||||
new Header(lobby),
|
new Header(lounge),
|
||||||
};
|
};
|
||||||
|
|
||||||
lobby.Exited += s => Exit();
|
lounge.Exited += s => Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnEntering(Screen last)
|
protected override void OnEntering(Screen last)
|
||||||
@ -84,6 +85,13 @@ namespace osu.Game.Screens.Multi
|
|||||||
waves.Hide();
|
waves.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LogoExiting(OsuLogo logo)
|
||||||
|
{
|
||||||
|
// the wave overlay transition takes longer than expected to run.
|
||||||
|
logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut();
|
||||||
|
base.LogoExiting(logo);
|
||||||
|
}
|
||||||
|
|
||||||
private class MultiplayerWaveContainer : WaveContainer
|
private class MultiplayerWaveContainer : WaveContainer
|
||||||
{
|
{
|
||||||
protected override bool StartHidden => true;
|
protected override bool StartHidden => true;
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// 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 Lobby : ScreenWhiteBox
|
|
||||||
{
|
|
||||||
protected override IEnumerable<Type> PossibleChildren => new[] {
|
|
||||||
typeof(MatchCreate),
|
|
||||||
typeof(Match)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
27
osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs
Normal file
27
osu.Game/Screens/Multi/Screens/Lounge/FilterControl.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Overlays.SearchableList;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Multi.Screens.Lounge
|
||||||
|
{
|
||||||
|
public class FilterControl : SearchableListFilterControl<LoungeTab, LoungeTab>
|
||||||
|
{
|
||||||
|
protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42");
|
||||||
|
protected override LoungeTab DefaultTab => LoungeTab.Public;
|
||||||
|
|
||||||
|
public FilterControl()
|
||||||
|
{
|
||||||
|
DisplayStyleControl.Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LoungeTab
|
||||||
|
{
|
||||||
|
Public = RoomAvailability.Public,
|
||||||
|
Private = RoomAvailability.FriendsOnly,
|
||||||
|
}
|
||||||
|
}
|
191
osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs
Normal file
191
osu.Game/Screens/Multi/Screens/Lounge/Lounge.cs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
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.Lounge
|
||||||
|
{
|
||||||
|
public class Lounge : MultiplayerScreen
|
||||||
|
{
|
||||||
|
private readonly Container content;
|
||||||
|
private readonly SearchContainer search;
|
||||||
|
|
||||||
|
protected readonly FilterControl Filter;
|
||||||
|
protected readonly FillFlowContainer<DrawableRoom> RoomsContainer;
|
||||||
|
protected readonly RoomInspector Inspector;
|
||||||
|
|
||||||
|
public override string Title => "lounge";
|
||||||
|
|
||||||
|
protected override Container<Drawable> TransitionContent => content;
|
||||||
|
|
||||||
|
private IEnumerable<Room> rooms;
|
||||||
|
public IEnumerable<Room> Rooms
|
||||||
|
{
|
||||||
|
get { return rooms; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Equals(value, rooms)) return;
|
||||||
|
rooms = value;
|
||||||
|
|
||||||
|
var enumerable = rooms.ToList();
|
||||||
|
|
||||||
|
RoomsContainer.Children = enumerable.Select(r => new DrawableRoom(r)
|
||||||
|
{
|
||||||
|
Action = didSelect,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
if (!enumerable.Contains(Inspector.Room))
|
||||||
|
Inspector.Room = null;
|
||||||
|
|
||||||
|
filterRooms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lounge()
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
Filter = new FilterControl(),
|
||||||
|
content = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new ScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = 0.55f,
|
||||||
|
Padding = new MarginPadding
|
||||||
|
{
|
||||||
|
Vertical = 35 - DrawableRoom.SELECTION_BORDER_WIDTH,
|
||||||
|
Right = 20 - DrawableRoom.SELECTION_BORDER_WIDTH
|
||||||
|
},
|
||||||
|
Child = search = new SearchContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Child = RoomsContainer = new RoomsFilterContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(10 - DrawableRoom.SELECTION_BORDER_WIDTH * 2),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Inspector = new RoomInspector
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Width = 0.45f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Filter.Search.Current.ValueChanged += s => filterRooms();
|
||||||
|
Filter.Tabs.Current.ValueChanged += t => filterRooms();
|
||||||
|
Filter.Search.Exit += Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
content.Padding = new MarginPadding
|
||||||
|
{
|
||||||
|
Top = Filter.DrawHeight,
|
||||||
|
Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH,
|
||||||
|
Right = SearchableListOverlay.WIDTH_PADDING,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocus(InputState state)
|
||||||
|
{
|
||||||
|
GetContainingInputManager().ChangeFocus(Filter.Search);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnEntering(Screen last)
|
||||||
|
{
|
||||||
|
base.OnEntering(last);
|
||||||
|
Filter.Search.HoldFocus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnExiting(Screen next)
|
||||||
|
{
|
||||||
|
Filter.Search.HoldFocus = false;
|
||||||
|
return base.OnExiting(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnResuming(Screen last)
|
||||||
|
{
|
||||||
|
base.OnResuming(last);
|
||||||
|
Filter.Search.HoldFocus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSuspending(Screen next)
|
||||||
|
{
|
||||||
|
base.OnSuspending(next);
|
||||||
|
Filter.Search.HoldFocus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterRooms()
|
||||||
|
{
|
||||||
|
search.SearchTerm = Filter.Search.Current.Value ?? string.Empty;
|
||||||
|
|
||||||
|
foreach (DrawableRoom r in RoomsContainer.Children)
|
||||||
|
{
|
||||||
|
r.MatchingFilter = r.MatchingFilter &&
|
||||||
|
r.Room.Availability.Value == (RoomAvailability)Filter.Tabs.Current.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void didSelect(DrawableRoom room)
|
||||||
|
{
|
||||||
|
RoomsContainer.Children.ForEach(c =>
|
||||||
|
{
|
||||||
|
if (c != room)
|
||||||
|
c.State = SelectionState.NotSelected;
|
||||||
|
});
|
||||||
|
|
||||||
|
Inspector.Room = room.Room;
|
||||||
|
|
||||||
|
// open the room if its selected and is clicked again
|
||||||
|
if (room.State == SelectionState.Selected)
|
||||||
|
Push(new Match());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RoomsFilterContainer : FillFlowContainer<DrawableRoom>, IHasFilterableChildren
|
||||||
|
{
|
||||||
|
public IEnumerable<string> FilterTerms => new string[] { };
|
||||||
|
public IEnumerable<IFilterable> FilterableChildren => Children;
|
||||||
|
|
||||||
|
public bool MatchingFilter
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
InvalidateLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomsFilterContainer()
|
||||||
|
{
|
||||||
|
LayoutDuration = 200;
|
||||||
|
LayoutEasing = Easing.OutQuint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs
Normal file
52
osu.Game/Screens/Multi/Screens/MultiplayerScreen.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
|
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<Drawable> TransitionContent => Content;
|
||||||
|
|
||||||
|
protected override void OnEntering(Screen last)
|
||||||
|
{
|
||||||
|
base.OnEntering(last);
|
||||||
|
|
||||||
|
TransitionContent.MoveToX(200);
|
||||||
|
|
||||||
|
TransitionContent.FadeInFromZero(WaveContainer.APPEAR_DURATION, in_easing);
|
||||||
|
TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnExiting(Screen next)
|
||||||
|
{
|
||||||
|
Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||||
|
TransitionContent.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||||
|
|
||||||
|
return base.OnExiting(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnResuming(Screen last)
|
||||||
|
{
|
||||||
|
base.OnResuming(last);
|
||||||
|
|
||||||
|
Content.FadeIn(WaveContainer.APPEAR_DURATION, in_easing);
|
||||||
|
TransitionContent.MoveToX(0, WaveContainer.APPEAR_DURATION, in_easing);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSuspending(Screen next)
|
||||||
|
{
|
||||||
|
base.OnSuspending(next);
|
||||||
|
|
||||||
|
Content.FadeOut(WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||||
|
TransitionContent.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, out_easing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Internal;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
@ -20,10 +21,17 @@ using OpenTK.Input;
|
|||||||
|
|
||||||
namespace osu.Game.Screens
|
namespace osu.Game.Screens
|
||||||
{
|
{
|
||||||
public abstract class OsuScreen : Screen, IKeyBindingHandler<GlobalAction>
|
public abstract class OsuScreen : Screen, IKeyBindingHandler<GlobalAction>, IHasDescription
|
||||||
{
|
{
|
||||||
public BackgroundScreen Background { get; private set; }
|
public BackgroundScreen Background { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A user-facing title for this screen.
|
||||||
|
/// </summary>
|
||||||
|
public virtual string Title => GetType().ShortDisplayName();
|
||||||
|
|
||||||
|
public string Description => Title;
|
||||||
|
|
||||||
protected virtual bool AllowBackButton => true;
|
protected virtual bool AllowBackButton => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user