mirror of
https://github.com/ppy/osu
synced 2025-01-02 20:32:10 +00:00
Merge branch 'master' into fix-skin-layout-editor-crash
This commit is contained in:
commit
d24fbc6ade
167
osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs
Normal file
167
osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
// 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 System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneDrawableLoungeRoom : OsuManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
private readonly Room room = new Room
|
||||||
|
{
|
||||||
|
HasPassword = { Value = true }
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
|
||||||
|
|
||||||
|
private DrawableLoungeRoom drawableRoom;
|
||||||
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
|
private readonly ManualResetEventSlim allowResponseCallback = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var mockLounge = new Mock<LoungeSubScreen>();
|
||||||
|
mockLounge
|
||||||
|
.Setup(l => l.Join(It.IsAny<Room>(), It.IsAny<string>(), It.IsAny<Action<Room>>(), It.IsAny<Action<string>>()))
|
||||||
|
.Callback<Room, string, Action<Room>, Action<string>>((a, b, c, d) =>
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
allowResponseCallback.Wait();
|
||||||
|
allowResponseCallback.Reset();
|
||||||
|
Schedule(() => d?.Invoke("Incorrect password"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Dependencies.CacheAs(mockLounge.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("create drawable", () =>
|
||||||
|
{
|
||||||
|
Child = new PopoverContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
searchTextBox = new SearchTextBox
|
||||||
|
{
|
||||||
|
HoldFocus = true,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Margin = new MarginPadding(50),
|
||||||
|
Width = 500,
|
||||||
|
Depth = float.MaxValue
|
||||||
|
},
|
||||||
|
drawableRoom = new DrawableLoungeRoom(room)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusViaKeyboardCommit()
|
||||||
|
{
|
||||||
|
DrawableLoungeRoom.PasswordEntryPopover popover = null;
|
||||||
|
|
||||||
|
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
AddStep("click room twice", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(drawableRoom);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().SingleOrDefault()) != null);
|
||||||
|
|
||||||
|
AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("enter password", () => popover.ChildrenOfType<OsuPasswordTextBox>().Single().Text = "password");
|
||||||
|
AddStep("commit via enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddAssert("popover has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("attempt another enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddAssert("popover still has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("unblock response", () => allowResponseCallback.Set());
|
||||||
|
|
||||||
|
AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
|
AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusViaMouseCommit()
|
||||||
|
{
|
||||||
|
DrawableLoungeRoom.PasswordEntryPopover popover = null;
|
||||||
|
|
||||||
|
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
AddStep("click room twice", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(drawableRoom);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().SingleOrDefault()) != null);
|
||||||
|
|
||||||
|
AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("enter password", () => popover.ChildrenOfType<OsuPasswordTextBox>().Single().Text = "password");
|
||||||
|
|
||||||
|
AddStep("commit via click button", () =>
|
||||||
|
{
|
||||||
|
var button = popover.ChildrenOfType<OsuButton>().Single();
|
||||||
|
InputManager.MoveMouseTo(button);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("popover has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("attempt another click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
AddAssert("popover still has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("unblock response", () => allowResponseCallback.Set());
|
||||||
|
|
||||||
|
AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("click away", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(searchTextBox);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool checkFocus(Drawable expected) =>
|
||||||
|
InputManager.FocusedDrawable == expected;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
@ -25,12 +26,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public new void Setup() => Schedule(() =>
|
public new void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Child = container = new RoomsContainer
|
Child = new PopoverContainer
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Width = 0.5f,
|
Width = 0.5f,
|
||||||
SelectedRoom = { BindTarget = SelectedRoom }
|
|
||||||
|
Child = container = new RoomsContainer
|
||||||
|
{
|
||||||
|
SelectedRoom = { BindTarget = SelectedRoom }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -107,27 +107,15 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public DateTimeOffset Submitted
|
public DateTimeOffset Submitted => OnlineInfo.Submitted;
|
||||||
{
|
|
||||||
get => OnlineInfo.Submitted;
|
|
||||||
set => OnlineInfo.Submitted = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public DateTimeOffset? Ranked
|
public DateTimeOffset? Ranked => OnlineInfo.Ranked;
|
||||||
{
|
|
||||||
get => OnlineInfo.Ranked;
|
|
||||||
set => OnlineInfo.Ranked = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public DateTimeOffset? LastUpdated
|
public DateTimeOffset? LastUpdated => OnlineInfo.LastUpdated;
|
||||||
{
|
|
||||||
get => OnlineInfo.LastUpdated;
|
|
||||||
set => OnlineInfo.LastUpdated = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@ -135,107 +123,55 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool HasExplicitContent
|
public bool HasExplicitContent => OnlineInfo.HasExplicitContent;
|
||||||
{
|
|
||||||
get => OnlineInfo.HasExplicitContent;
|
|
||||||
set => OnlineInfo.HasExplicitContent = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool HasVideo
|
public bool HasVideo => OnlineInfo.HasVideo;
|
||||||
{
|
|
||||||
get => OnlineInfo.HasVideo;
|
|
||||||
set => OnlineInfo.HasVideo = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool HasStoryboard
|
public bool HasStoryboard => OnlineInfo.HasStoryboard;
|
||||||
{
|
|
||||||
get => OnlineInfo.HasStoryboard;
|
|
||||||
set => OnlineInfo.HasStoryboard = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BeatmapSetOnlineCovers Covers
|
public BeatmapSetOnlineCovers Covers => OnlineInfo.Covers;
|
||||||
{
|
|
||||||
get => OnlineInfo.Covers;
|
|
||||||
set => OnlineInfo.Covers = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string Preview
|
public string Preview => OnlineInfo.Preview;
|
||||||
{
|
|
||||||
get => OnlineInfo.Preview;
|
|
||||||
set => OnlineInfo.Preview = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public double BPM
|
public double BPM => OnlineInfo.BPM;
|
||||||
{
|
|
||||||
get => OnlineInfo.BPM;
|
|
||||||
set => OnlineInfo.BPM = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int PlayCount
|
public int PlayCount => OnlineInfo.PlayCount;
|
||||||
{
|
|
||||||
get => OnlineInfo.PlayCount;
|
|
||||||
set => OnlineInfo.PlayCount = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int FavouriteCount
|
public int FavouriteCount => OnlineInfo.FavouriteCount;
|
||||||
{
|
|
||||||
get => OnlineInfo.FavouriteCount;
|
|
||||||
set => OnlineInfo.FavouriteCount = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool HasFavourited
|
public bool HasFavourited => OnlineInfo.HasFavourited;
|
||||||
{
|
|
||||||
get => OnlineInfo.HasFavourited;
|
|
||||||
set => OnlineInfo.HasFavourited = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BeatmapSetOnlineAvailability Availability
|
public BeatmapSetOnlineAvailability Availability => OnlineInfo.Availability;
|
||||||
{
|
|
||||||
get => OnlineInfo.Availability;
|
|
||||||
set => OnlineInfo.Availability = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BeatmapSetOnlineGenre Genre
|
public BeatmapSetOnlineGenre Genre => OnlineInfo.Genre;
|
||||||
{
|
|
||||||
get => OnlineInfo.Genre;
|
|
||||||
set => OnlineInfo.Genre = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BeatmapSetOnlineLanguage Language
|
public BeatmapSetOnlineLanguage Language => OnlineInfo.Language;
|
||||||
{
|
|
||||||
get => OnlineInfo.Language;
|
|
||||||
set => OnlineInfo.Language = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int? TrackId
|
public int? TrackId => OnlineInfo?.TrackId;
|
||||||
{
|
|
||||||
get => OnlineInfo.TrackId;
|
|
||||||
set => OnlineInfo.TrackId = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -15,87 +15,87 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date this beatmap set was submitted to the online listing.
|
/// The date this beatmap set was submitted to the online listing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTimeOffset Submitted { get; set; }
|
DateTimeOffset Submitted { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date this beatmap set was ranked.
|
/// The date this beatmap set was ranked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTimeOffset? Ranked { get; set; }
|
DateTimeOffset? Ranked { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date this beatmap set was last updated.
|
/// The date this beatmap set was last updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTimeOffset? LastUpdated { get; set; }
|
DateTimeOffset? LastUpdated { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The status of this beatmap set.
|
/// The status of this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BeatmapSetOnlineStatus Status { get; set; }
|
BeatmapSetOnlineStatus Status { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this beatmap set has explicit content.
|
/// Whether or not this beatmap set has explicit content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool HasExplicitContent { get; set; }
|
bool HasExplicitContent { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this beatmap set has a background video.
|
/// Whether or not this beatmap set has a background video.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool HasVideo { get; set; }
|
bool HasVideo { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this beatmap set has a storyboard.
|
/// Whether or not this beatmap set has a storyboard.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool HasStoryboard { get; set; }
|
bool HasStoryboard { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The different sizes of cover art for this beatmap set.
|
/// The different sizes of cover art for this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BeatmapSetOnlineCovers Covers { get; set; }
|
BeatmapSetOnlineCovers Covers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A small sample clip of this beatmap set's song.
|
/// A small sample clip of this beatmap set's song.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Preview { get; set; }
|
string Preview { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beats per minute of this beatmap set's song.
|
/// The beats per minute of this beatmap set's song.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
double BPM { get; set; }
|
double BPM { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of plays this beatmap set has.
|
/// The amount of plays this beatmap set has.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int PlayCount { get; set; }
|
int PlayCount { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of people who have favourited this beatmap set.
|
/// The amount of people who have favourited this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int FavouriteCount { get; set; }
|
int FavouriteCount { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this beatmap set has been favourited by the current user.
|
/// Whether this beatmap set has been favourited by the current user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool HasFavourited { get; set; }
|
bool HasFavourited { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The availability of this beatmap set.
|
/// The availability of this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BeatmapSetOnlineAvailability Availability { get; set; }
|
BeatmapSetOnlineAvailability Availability { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The song genre of this beatmap set.
|
/// The song genre of this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BeatmapSetOnlineGenre Genre { get; set; }
|
BeatmapSetOnlineGenre Genre { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The song language of this beatmap set.
|
/// The song language of this beatmap set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BeatmapSetOnlineLanguage Language { get; set; }
|
BeatmapSetOnlineLanguage Language { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The track ID of this beatmap set.
|
/// The track ID of this beatmap set.
|
||||||
/// Non-null only if the track is linked to a featured artist track entry.
|
/// Non-null only if the track is linked to a featured artist track entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int? TrackId { get; set; }
|
int? TrackId { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,9 @@ namespace osu.Game.Configuration
|
|||||||
rawValue: skinName,
|
rawValue: skinName,
|
||||||
name: SkinSettingsStrings.SkinSectionHeader,
|
name: SkinSettingsStrings.SkinSectionHeader,
|
||||||
value: skinName,
|
value: skinName,
|
||||||
shortcut: $"{GlobalActionKeyBindingStrings.RandomSkin}: {LookupKeyBindings(GlobalAction.RandomSkin)}"
|
shortcut: new TranslatableString(@"_", @"{0}: {1}",
|
||||||
|
GlobalActionKeyBindingStrings.RandomSkin,
|
||||||
|
LookupKeyBindings(GlobalAction.RandomSkin))
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
new TrackedSetting<float>(OsuSetting.UIScale, scale => new SettingDescription(
|
new TrackedSetting<float>(OsuSetting.UIScale, scale => new SettingDescription(
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets;
|
|||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
public class APIBeatmap : BeatmapMetadata, IBeatmapInfo
|
public class APIBeatmap : IBeatmapInfo
|
||||||
{
|
{
|
||||||
[JsonProperty(@"id")]
|
[JsonProperty(@"id")]
|
||||||
public int OnlineID { get; set; }
|
public int OnlineID { get; set; }
|
||||||
@ -24,6 +24,9 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty("checksum")]
|
[JsonProperty("checksum")]
|
||||||
public string Checksum { get; set; } = string.Empty;
|
public string Checksum { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty(@"user_id")]
|
||||||
|
public int AuthorID { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"beatmapset")]
|
[JsonProperty(@"beatmapset")]
|
||||||
public APIBeatmapSet? BeatmapSet { get; set; }
|
public APIBeatmapSet? BeatmapSet { get; set; }
|
||||||
|
|
||||||
@ -51,8 +54,10 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"accuracy")]
|
[JsonProperty(@"accuracy")]
|
||||||
private float overallDifficulty { get; set; }
|
private float overallDifficulty { get; set; }
|
||||||
|
|
||||||
|
public double Length => lengthInSeconds * 1000;
|
||||||
|
|
||||||
[JsonProperty(@"total_length")]
|
[JsonProperty(@"total_length")]
|
||||||
public double Length { get; set; }
|
private double lengthInSeconds { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"count_circles")]
|
[JsonProperty(@"count_circles")]
|
||||||
private int circleCount { get; set; }
|
private int circleCount { get; set; }
|
||||||
@ -75,7 +80,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
|
|
||||||
return new BeatmapInfo
|
return new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = set?.Metadata ?? this,
|
Metadata = set?.Metadata ?? new BeatmapMetadata(),
|
||||||
Ruleset = rulesets.GetRuleset(RulesetID),
|
Ruleset = rulesets.GetRuleset(RulesetID),
|
||||||
StarDifficulty = StarRating,
|
StarDifficulty = StarRating,
|
||||||
OnlineBeatmapID = OnlineID,
|
OnlineBeatmapID = OnlineID,
|
||||||
@ -106,7 +111,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
|
|
||||||
#region Implementation of IBeatmapInfo
|
#region Implementation of IBeatmapInfo
|
||||||
|
|
||||||
public IBeatmapMetadataInfo Metadata => this;
|
public IBeatmapMetadataInfo Metadata => (BeatmapSet as IBeatmapSetInfo)?.Metadata ?? new BeatmapMetadata();
|
||||||
|
|
||||||
public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty
|
public IBeatmapDifficultyInfo Difficulty => new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
|
@ -8,12 +8,13 @@ using Newtonsoft.Json;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
public class APIBeatmapSet : BeatmapMetadata, IBeatmapSetOnlineInfo, IBeatmapSetInfo
|
public class APIBeatmapSet : IBeatmapSetOnlineInfo, IBeatmapSetInfo
|
||||||
{
|
{
|
||||||
[JsonProperty(@"covers")]
|
[JsonProperty(@"covers")]
|
||||||
public BeatmapSetOnlineCovers Covers { get; set; }
|
public BeatmapSetOnlineCovers Covers { get; set; }
|
||||||
@ -63,10 +64,44 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"track_id")]
|
[JsonProperty(@"track_id")]
|
||||||
public int? TrackId { get; set; }
|
public int? TrackId { get; set; }
|
||||||
|
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty("title_unicode")]
|
||||||
|
public string TitleUnicode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Artist { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty("artist_unicode")]
|
||||||
|
public string ArtistUnicode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public User? Author = new User();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper property to deserialize a username to <see cref="User"/>.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty(@"user_id")]
|
[JsonProperty(@"user_id")]
|
||||||
private int creatorId
|
public int AuthorID
|
||||||
{
|
{
|
||||||
set => Author.Id = value;
|
get => Author?.Id ?? 1;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Author ??= new User();
|
||||||
|
Author.Id = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper property to deserialize a username to <see cref="User"/>.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(@"creator")]
|
||||||
|
public string AuthorString
|
||||||
|
{
|
||||||
|
get => Author?.Username ?? string.Empty;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Author ??= new User();
|
||||||
|
Author.Username = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonProperty(@"availability")]
|
[JsonProperty(@"availability")]
|
||||||
@ -78,6 +113,11 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"language")]
|
[JsonProperty(@"language")]
|
||||||
public BeatmapSetOnlineLanguage Language { get; set; }
|
public BeatmapSetOnlineLanguage Language { get; set; }
|
||||||
|
|
||||||
|
public string Source { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty(@"tags")]
|
||||||
|
public string Tags { get; set; } = string.Empty;
|
||||||
|
|
||||||
[JsonProperty(@"beatmaps")]
|
[JsonProperty(@"beatmaps")]
|
||||||
private IEnumerable<APIBeatmap> beatmaps { get; set; } = Array.Empty<APIBeatmap>();
|
private IEnumerable<APIBeatmap> beatmaps { get; set; } = Array.Empty<APIBeatmap>();
|
||||||
|
|
||||||
@ -86,7 +126,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
var beatmapSet = new BeatmapSetInfo
|
var beatmapSet = new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
OnlineBeatmapSetID = OnlineID,
|
OnlineBeatmapSetID = OnlineID,
|
||||||
Metadata = this,
|
Metadata = metadata,
|
||||||
Status = Status,
|
Status = Status,
|
||||||
Metrics = new BeatmapSetMetrics { Ratings = ratings },
|
Metrics = new BeatmapSetMetrics { Ratings = ratings },
|
||||||
OnlineInfo = this
|
OnlineInfo = this
|
||||||
@ -103,11 +143,23 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
return beatmapSet;
|
return beatmapSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BeatmapMetadata metadata => new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = Title,
|
||||||
|
TitleUnicode = TitleUnicode,
|
||||||
|
Artist = Artist,
|
||||||
|
ArtistUnicode = ArtistUnicode,
|
||||||
|
AuthorID = AuthorID,
|
||||||
|
Author = Author,
|
||||||
|
Source = Source,
|
||||||
|
Tags = Tags,
|
||||||
|
};
|
||||||
|
|
||||||
#region Implementation of IBeatmapSetInfo
|
#region Implementation of IBeatmapSetInfo
|
||||||
|
|
||||||
IEnumerable<IBeatmapInfo> IBeatmapSetInfo.Beatmaps => beatmaps;
|
IEnumerable<IBeatmapInfo> IBeatmapSetInfo.Beatmaps => beatmaps;
|
||||||
|
|
||||||
IBeatmapMetadataInfo IBeatmapSetInfo.Metadata => this;
|
IBeatmapMetadataInfo IBeatmapSetInfo.Metadata => metadata;
|
||||||
|
|
||||||
DateTimeOffset IBeatmapSetInfo.DateAdded => throw new NotImplementedException();
|
DateTimeOffset IBeatmapSetInfo.DateAdded => throw new NotImplementedException();
|
||||||
IEnumerable<INamedFileUsage> IBeatmapSetInfo.Files => throw new NotImplementedException();
|
IEnumerable<INamedFileUsage> IBeatmapSetInfo.Files => throw new NotImplementedException();
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
@ -16,17 +14,19 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public int PlayCount { get; set; }
|
public int PlayCount { get; set; }
|
||||||
|
|
||||||
[JsonProperty("beatmap")]
|
[JsonProperty("beatmap")]
|
||||||
private BeatmapInfo beatmapInfo { get; set; }
|
private APIBeatmap beatmap { get; set; }
|
||||||
|
|
||||||
[JsonProperty]
|
public APIBeatmap BeatmapInfo
|
||||||
private APIBeatmapSet beatmapSet { get; set; }
|
|
||||||
|
|
||||||
public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets)
|
|
||||||
{
|
{
|
||||||
BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets);
|
get
|
||||||
beatmapInfo.BeatmapSet = setInfo;
|
{
|
||||||
beatmapInfo.Metadata = setInfo.Metadata;
|
// old osu-web code doesn't nest set.
|
||||||
return beatmapInfo;
|
beatmap.BeatmapSet = BeatmapSet;
|
||||||
|
return beatmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonProperty("beatmapset")]
|
||||||
|
public APIBeatmapSet BeatmapSet { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,9 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BeatmapMetadataContainer : OsuHoverContainer
|
public abstract class BeatmapMetadataContainer : OsuHoverContainer
|
||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmapInfo;
|
private readonly IBeatmapInfo beatmapInfo;
|
||||||
|
|
||||||
protected BeatmapMetadataContainer(BeatmapInfo beatmapInfo)
|
protected BeatmapMetadataContainer(IBeatmapInfo beatmapInfo)
|
||||||
: base(HoverSampleSet.Submit)
|
: base(HoverSampleSet.Submit)
|
||||||
{
|
{
|
||||||
this.beatmapInfo = beatmapInfo;
|
this.beatmapInfo = beatmapInfo;
|
||||||
@ -30,10 +30,7 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
Action = () =>
|
Action = () =>
|
||||||
{
|
{
|
||||||
if (beatmapInfo.OnlineBeatmapID != null)
|
beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineID);
|
||||||
beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineBeatmapID.Value);
|
|
||||||
else if (beatmapInfo.BeatmapSet?.OnlineBeatmapSetID != null)
|
|
||||||
beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapInfo.BeatmapSet.OnlineBeatmapSetID.Value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Child = new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
@ -43,6 +40,6 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Drawable[] CreateText(BeatmapInfo beatmapInfo);
|
protected abstract Drawable[] CreateText(IBeatmapInfo beatmapInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -13,6 +14,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Historical
|
namespace osu.Game.Overlays.Profile.Sections.Historical
|
||||||
@ -22,13 +24,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
private const int cover_width = 100;
|
private const int cover_width = 100;
|
||||||
private const int corner_radius = 6;
|
private const int corner_radius = 6;
|
||||||
|
|
||||||
private readonly BeatmapInfo beatmapInfo;
|
private readonly APIUserMostPlayedBeatmap mostPlayed;
|
||||||
private readonly int playCount;
|
|
||||||
|
|
||||||
public DrawableMostPlayedBeatmap(BeatmapInfo beatmapInfo, int playCount)
|
public DrawableMostPlayedBeatmap(APIUserMostPlayedBeatmap mostPlayed)
|
||||||
{
|
{
|
||||||
this.beatmapInfo = beatmapInfo;
|
this.mostPlayed = mostPlayed;
|
||||||
this.playCount = playCount;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = 50;
|
Height = 50;
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
Width = cover_width,
|
Width = cover_width,
|
||||||
BeatmapSet = beatmapInfo.BeatmapSet,
|
BeatmapSet = mostPlayed.BeatmapSet,
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new MostPlayedBeatmapMetadataContainer(beatmapInfo),
|
new MostPlayedBeatmapMetadataContainer(mostPlayed.BeatmapInfo),
|
||||||
new LinkFlowContainer(t =>
|
new LinkFlowContainer(t =>
|
||||||
{
|
{
|
||||||
t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular);
|
t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular);
|
||||||
@ -89,11 +89,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
}.With(d =>
|
}.With(d =>
|
||||||
{
|
{
|
||||||
d.AddText("mapped by ");
|
d.AddText("mapped by ");
|
||||||
d.AddUserLink(beatmapInfo.Metadata.Author);
|
d.AddUserLink(mostPlayed.BeatmapSet.Author);
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new PlayCountText(playCount)
|
new PlayCountText(mostPlayed.PlayCount)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight
|
Origin = Anchor.CentreRight
|
||||||
@ -120,26 +120,41 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
|
|
||||||
private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer
|
private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer
|
||||||
{
|
{
|
||||||
public MostPlayedBeatmapMetadataContainer(BeatmapInfo beatmapInfo)
|
public MostPlayedBeatmapMetadataContainer(IBeatmapInfo beatmapInfo)
|
||||||
: base(beatmapInfo)
|
: base(beatmapInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[]
|
protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo)
|
||||||
{
|
{
|
||||||
new OsuSpriteText
|
var metadata = beatmapInfo.Metadata;
|
||||||
|
|
||||||
|
Debug.Assert(metadata != null);
|
||||||
|
|
||||||
|
return new Drawable[]
|
||||||
{
|
{
|
||||||
Text = new RomanisableString(
|
new OsuSpriteText
|
||||||
$"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} [{beatmapInfo.Version}] ",
|
{
|
||||||
$"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} [{beatmapInfo.Version}] "),
|
Text = new RomanisableString(metadata.TitleUnicode, metadata.Title),
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist),
|
Text = $" [{beatmapInfo.DifficultyName}]",
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Regular)
|
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
||||||
},
|
},
|
||||||
};
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = " by ",
|
||||||
|
Font = OsuFont.GetFont(weight: FontWeight.Regular)
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist),
|
||||||
|
Font = OsuFont.GetFont(weight: FontWeight.Regular)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PlayCountText : CompositeDrawable, IHasTooltip
|
private class PlayCountText : CompositeDrawable, IHasTooltip
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest() =>
|
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest() =>
|
||||||
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
||||||
|
|
||||||
protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap model) =>
|
protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) =>
|
||||||
new DrawableMostPlayedBeatmap(model.GetBeatmapInfo(Rulesets), model.PlayCount);
|
new DrawableMostPlayedBeatmap(mostPlayed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -245,30 +246,42 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
|
|
||||||
private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer
|
private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer
|
||||||
{
|
{
|
||||||
public ScoreBeatmapMetadataContainer(BeatmapInfo beatmapInfo)
|
public ScoreBeatmapMetadataContainer(IBeatmapInfo beatmapInfo)
|
||||||
: base(beatmapInfo)
|
: base(beatmapInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable[] CreateText(BeatmapInfo beatmapInfo) => new Drawable[]
|
protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo)
|
||||||
{
|
{
|
||||||
new OsuSpriteText
|
var metadata = beatmapInfo.Metadata;
|
||||||
|
|
||||||
|
Debug.Assert(metadata != null);
|
||||||
|
|
||||||
|
return new Drawable[]
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
new OsuSpriteText
|
||||||
Origin = Anchor.BottomLeft,
|
{
|
||||||
Text = new RomanisableString(
|
Anchor = Anchor.BottomLeft,
|
||||||
$"{beatmapInfo.Metadata.TitleUnicode ?? beatmapInfo.Metadata.Title} ",
|
Origin = Anchor.BottomLeft,
|
||||||
$"{beatmapInfo.Metadata.Title ?? beatmapInfo.Metadata.TitleUnicode} "),
|
Text = new RomanisableString(metadata.TitleUnicode, metadata.Title),
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Text = "by " + new RomanisableString(beatmapInfo.Metadata.ArtistUnicode, beatmapInfo.Metadata.Artist),
|
Text = " by ",
|
||||||
Font = OsuFont.GetFont(size: 12, italics: true)
|
Font = OsuFont.GetFont(size: 12, italics: true)
|
||||||
},
|
},
|
||||||
};
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist),
|
||||||
|
Font = OsuFont.GetFont(size: 12, italics: true)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,72 +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.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay.Components
|
|
||||||
{
|
|
||||||
public class BeatmapTypeInfo : OnlinePlayComposite
|
|
||||||
{
|
|
||||||
private LinkFlowContainer beatmapAuthor;
|
|
||||||
|
|
||||||
public BeatmapTypeInfo()
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
InternalChild = new FillFlowContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
LayoutDuration = 100,
|
|
||||||
Spacing = new Vector2(5, 0),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new ModeTypeInfo(),
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.X,
|
|
||||||
Height = 30,
|
|
||||||
Margin = new MarginPadding { Left = 5 },
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new BeatmapTitle(),
|
|
||||||
beatmapAuthor = new LinkFlowContainer(s => s.Font = s.Font.With(size: 14))
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
AutoSizeAxes = Axes.Both
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Playlist.CollectionChanged += (_, __) => updateInfo();
|
|
||||||
|
|
||||||
updateInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateInfo()
|
|
||||||
{
|
|
||||||
beatmapAuthor.Clear();
|
|
||||||
|
|
||||||
var beatmap = Playlist.FirstOrDefault()?.Beatmap;
|
|
||||||
|
|
||||||
if (beatmap != null)
|
|
||||||
{
|
|
||||||
beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f));
|
|
||||||
beatmapAuthor.AddUserLink(beatmap.Value.Metadata.Author);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -103,7 +103,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
|
|
||||||
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
||||||
|
|
||||||
private bool matchingFilter;
|
private bool matchingFilter = true;
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
@ -181,6 +181,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private LoungeSubScreen lounge { get; set; }
|
private LoungeSubScreen lounge { get; set; }
|
||||||
|
|
||||||
|
public override bool HandleNonPositionalInput => true;
|
||||||
|
|
||||||
|
protected override bool BlockNonPositionalInput => true;
|
||||||
|
|
||||||
public PasswordEntryPopover(Room room)
|
public PasswordEntryPopover(Room room)
|
||||||
{
|
{
|
||||||
this.room = room;
|
this.room = room;
|
||||||
@ -200,6 +204,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
Spacing = new Vector2(5),
|
Spacing = new Vector2(5),
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
|
LayoutDuration = 500,
|
||||||
|
LayoutEasing = Easing.OutQuint,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
@ -230,10 +236,24 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
|
|
||||||
sampleJoinFail = audio.Samples.Get(@"UI/password-fail");
|
sampleJoinFail = audio.Samples.Get(@"UI/password-fail");
|
||||||
|
|
||||||
joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
joinButton.Action = performJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void joinFailed(string error)
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
|
||||||
|
passwordTextbox.OnCommit += (_, __) => performJoin();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performJoin()
|
||||||
|
{
|
||||||
|
lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
||||||
|
GetContainingInputManager().TriggerFocusContention(passwordTextbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinFailed(string error) => Schedule(() =>
|
||||||
{
|
{
|
||||||
passwordTextbox.Text = string.Empty;
|
passwordTextbox.Text = string.Empty;
|
||||||
|
|
||||||
@ -249,15 +269,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
Body.Shake();
|
Body.Shake();
|
||||||
|
|
||||||
sampleJoinFail?.Play();
|
sampleJoinFail?.Play();
|
||||||
}
|
});
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
|
|
||||||
passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
popoverContainer.HidePopover();
|
popoverContainer.HidePopover();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
|
public virtual void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
|
||||||
{
|
{
|
||||||
if (joiningRoomOperation != null)
|
if (joiningRoomOperation != null)
|
||||||
return;
|
return;
|
||||||
|
@ -106,6 +106,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
this.TransformBindableTo(trackFreq, 0, duration).OnComplete(_ =>
|
this.TransformBindableTo(trackFreq, 0, duration).OnComplete(_ =>
|
||||||
{
|
{
|
||||||
|
RemoveFilters();
|
||||||
OnComplete?.Invoke();
|
OnComplete?.Invoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -137,6 +138,9 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
public void RemoveFilters()
|
public void RemoveFilters()
|
||||||
{
|
{
|
||||||
|
if (filters.Parent == null)
|
||||||
|
return;
|
||||||
|
|
||||||
RemoveInternal(filters);
|
RemoveInternal(filters);
|
||||||
filters.Dispose();
|
filters.Dispose();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user