diff --git a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs index 19e27ddefe..f44c7de721 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomSettings.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual MaxParticipants = { Value = 10 }, }; - Add(overlay = new TestRoomSettingsOverlay + Add(overlay = new TestRoomSettingsOverlay(new Room()) { RelativeSizeAxes = Axes.Both, Height = 0.75f, @@ -84,6 +84,11 @@ namespace osu.Game.Tests.Visual private class TestRoomSettingsOverlay : RoomSettingsOverlay { + public TestRoomSettingsOverlay(Room room) + : base(room) + { + } + public string CurrentName { get => NameField.Text; diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 0317b3c3e8..0b10992ada 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -29,12 +29,18 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("playlist")] public readonly BindableCollection Playlist = new BindableCollection(); - [JsonProperty("duration")] - public readonly Bindable Duration = new Bindable(100); + [JsonIgnore] + public readonly Bindable Duration = new Bindable(TimeSpan.FromMinutes(30)); [JsonIgnore] public readonly Bindable MaxAttempts = new Bindable(); + [JsonProperty("duration")] + private int duration + { + get => (int)Duration.Value.TotalMinutes; + set => Duration.Value = TimeSpan.FromMinutes(value); + } // Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930) [JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)] private int? maxAttempts diff --git a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs index 4d5f572531..a7149fbb6d 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomSettingsOverlay.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -26,25 +28,28 @@ namespace osu.Game.Screens.Multi.Match.Components private readonly Bindable typeBind = new Bindable(); private readonly Bindable maxParticipantsBind = new Bindable(); private readonly IBindableCollection playlistBind = new BindableCollection(); + private readonly Bindable durationBind = new Bindable(); private readonly Container content; private readonly OsuSpriteText typeLabel; protected readonly OsuTextBox NameField, MaxParticipantsField; + protected readonly OsuDropdown DurationField; protected readonly RoomAvailabilityPicker AvailabilityPicker; protected readonly GameTypePicker TypePicker; protected readonly TriangleButton ApplyButton; protected readonly OsuPasswordTextBox PasswordField; - [Resolved] + private readonly Room room; + + [Resolved(CanBeNull = true)] private RoomManager manager { get; set; } - [Resolved] - private Room room { get; set; } - - public RoomSettingsOverlay() + public RoomSettingsOverlay(Room room) { + this.room = room; + Masking = true; Child = content = new Container @@ -121,6 +126,26 @@ namespace osu.Game.Screens.Multi.Match.Components OnCommit = (sender, text) => apply(), }, }, + new Section("DURATION") + { + Child = DurationField = new DurationDropdown + { + RelativeSizeAxes = Axes.X, + Items = new[] + { + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) + } + } + }, new Section("PASSWORD (OPTIONAL)") { Child = PasswordField = new SettingsPasswordTextBox @@ -151,6 +176,7 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityBind.ValueChanged += a => AvailabilityPicker.Current.Value = a; typeBind.ValueChanged += t => TypePicker.Current.Value = t; maxParticipantsBind.ValueChanged += m => MaxParticipantsField.Text = m?.ToString(); + durationBind.ValueChanged += d => DurationField.Current.Value = d; } [BackgroundDependencyLoader] @@ -163,6 +189,7 @@ namespace osu.Game.Screens.Multi.Match.Components availabilityBind.BindTo(room.Availability); typeBind.BindTo(room.Type); maxParticipantsBind.BindTo(room.MaxParticipants); + durationBind.BindTo(room.Duration); MaxParticipantsField.ReadOnly = true; PasswordField.ReadOnly = true; @@ -210,7 +237,7 @@ namespace osu.Game.Screens.Multi.Match.Components else maxParticipantsBind.Value = null; - manager.CreateRoom(room); + manager?.CreateRoom(room); } private class SettingsTextBox : OsuTextBox @@ -291,5 +318,18 @@ namespace osu.Game.Screens.Multi.Match.Components Triangles.ColourDark = colours.YellowDark; } } + + private class DurationDropdown : OsuDropdown + { + public DurationDropdown() + { + Menu.MaxHeight = 100; + } + + protected override string GenerateItemText(TimeSpan item) + { + return item.Humanize(); + } + } } } diff --git a/osu.Game/Screens/Multi/Match/MatchScreen.cs b/osu.Game/Screens/Multi/Match/MatchScreen.cs index ecb5ced5fa..812f20f377 100644 --- a/osu.Game/Screens/Multi/Match/MatchScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchScreen.cs @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new RoomSettingsOverlay + Child = settings = new RoomSettingsOverlay(room) { RelativeSizeAxes = Axes.Both, Height = 0.9f,