From e3a1b07172ec3253b1de7af5e450bcdfc48976c2 Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 25 Feb 2018 19:18:39 +0530 Subject: [PATCH 01/48] Create API request and reponse model. --- .../GetUserRecentActivitiesRequest.cs | 89 +++++++++++++++++++ .../PaginatedRecentActivityContainer.cs | 63 +++++++++++++ .../Profile/Sections/RecentSection.cs | 10 ++- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- osu.Game/osu.Game.csproj | 4 +- 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs new file mode 100644 index 0000000000..cb7d0323f4 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -0,0 +1,89 @@ +using Newtonsoft.Json; +using osu.Game.Rulesets.Scoring; +using Humanizer; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Game.Rulesets; +using osu.Game.Overlays.Profile.Sections.Recent; + +namespace osu.Game.Online.API.Requests +{ + public class GetUserRecentActivitiesRequest : APIRequest> + { + } + + public class RecentActivity + { + [JsonProperty("id")] + public int ID; + + [JsonProperty("created_at")] + public DateTimeOffset CreatedAt; + + [JsonProperty] + private string type + { + set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize()); + } + + public RecentActivityType Type; + + [JsonProperty] + private string scoreRank + { + set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); + } + + public ScoreRank ScoreRank; + + [JsonProperty("rank")] + public int Rank; + + [JsonProperty("mode")] + public string Mode; + + [JsonProperty("beatmap")] + public RecentActivityBeatmap Beatmap; + + [JsonProperty("user")] + public RecentActivityUser User; + + public class RecentActivityBeatmap + { + [JsonProperty("title")] + public string Title; + + [JsonProperty("url")] + public string Url; + } + + public class RecentActivityUser + { + [JsonProperty("username")] + public string Username; + + [JsonProperty("url")] + public string Url; + } + } + + public enum RecentActivityType + { + Achievement, + BeatmapPlaycount, + BeatmapsetApprove, + BeatmapsetDelete, + BeatmapsetRevive, + BeatmapsetUpdate, + Medal, + Rank, + RankLost, + UserSupportAgain, + UserSupportFirst, + UserSupportGift, + UsernameChange, + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs new file mode 100644 index 0000000000..11b48ad68e --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -0,0 +1,63 @@ +using osu.Framework.Configuration; +using osu.Game.Online.API.Requests; +using osu.Game.Users; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Overlays.Profile.Sections +{ + class PaginatedRecentActivityContainer : PaginatedContainer + { + public PaginatedRecentActivityContainer(Bindable user, string header, string missing) + : base(user, header, missing) + { + ItemsPerPage = 5; + } + + //protected override void ShowMore() + //{ + // base.ShowMore(); + + // var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); + + // req.Success += scores => + // { + // foreach (var s in scores) + // s.ApplyRuleset(Rulesets.GetRuleset(s.OnlineRulesetID)); + + // ShowMoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); + // ShowMoreLoading.Hide(); + + // if (!scores.Any() && VisiblePages == 1) + // { + // MissingText.Show(); + // return; + // } + + // MissingText.Hide(); + + // foreach (OnlineScore score in scores) + // { + // DrawableProfileScore drawableScore; + + // switch (type) + // { + // default: + // drawableScore = new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + // break; + // case ScoreType.Recent: + // drawableScore = new DrawableTotalScore(score); + // break; + // } + + // ItemsContainer.Add(drawableScore); + // } + // }; + + // Api.Queue(req); + //} + } +} diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 78b139efe8..757e2457d2 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -7,6 +7,14 @@ namespace osu.Game.Overlays.Profile.Sections { public override string Title => "Recent"; - public override string Identifier => "recent_activities"; + public override string Identifier => "recent_activity"; + + public RecentSection() + { + Children = new[] + { + new PaginatedRecentActivityContainer(User, @"Recent", @"This user hasn't done anything notable recently!"), + }; + } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 59f940a19d..3bc12ccb24 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays sections = new ProfileSection[] { //new AboutSection(), - //new RecentSection(), + new RecentSection(), new RanksSection(), //new MedalsSection(), new HistoricalSection(), diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6a06bf540b..ad9105f1e8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -293,12 +293,14 @@ + 20180125143340_Settings.cs + @@ -936,4 +938,4 @@ - + \ No newline at end of file From 7e4bd363916f6c85b18b94807c3b83981c7f323f Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 25 Feb 2018 22:41:47 +0530 Subject: [PATCH 02/48] Create drawable and add response to profile. - Add missing JSON fields to response model - Add missing enum value --- .../GetUserRecentActivitiesRequest.cs | 21 +++- .../Sections/Recent/DrawableRecentActivity.cs | 117 ++++++++++++++++++ .../PaginatedRecentActivityContainer.cs | 59 ++++----- osu.Game/osu.Game.csproj | 1 + 4 files changed, 161 insertions(+), 37 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index cb7d0323f4..14997b070b 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -7,12 +7,21 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using osu.Game.Rulesets; -using osu.Game.Overlays.Profile.Sections.Recent; namespace osu.Game.Online.API.Requests { public class GetUserRecentActivitiesRequest : APIRequest> { + private readonly long userId; + private readonly int offset; + + public GetUserRecentActivitiesRequest(long userId, int offset = 0) + { + this.userId = userId; + this.offset = offset; + } + + protected override string Target => $"users/{userId}/recent_activity?offset={offset}"; } public class RecentActivity @@ -42,6 +51,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("rank")] public int Rank; + [JsonProperty("count")] + public int Count; + [JsonProperty("mode")] public string Mode; @@ -51,6 +63,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("user")] public RecentActivityUser User; + [JsonProperty("achivementName")] + public string AchivementName; + public class RecentActivityBeatmap { [JsonProperty("title")] @@ -67,6 +82,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("url")] public string Url; + + [JsonProperty("previousUsername")] + public string PreviousUsername; } } @@ -78,6 +96,7 @@ namespace osu.Game.Online.API.Requests BeatmapsetDelete, BeatmapsetRevive, BeatmapsetUpdate, + BeatmapsetUpload, Medal, Rank, RankLost, diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs new file mode 100644 index 0000000000..e0f7a97140 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests; +using osu.Game.Screens.Select.Leaderboards; +using osu.Game.Users; + +namespace osu.Game.Overlays.Profile.Sections.Recent +{ + public class DrawableRecentActivity : DrawableProfileRow + { + private RecentActivity activity; + private User user; + + public DrawableRecentActivity(RecentActivity activity, User user) + { + this.activity = activity; + this.user = user; + } + + [BackgroundDependencyLoader] + private void load() + { + LeftFlowContainer.Add(new OsuSpriteText + { + Text = activityToString(), + }); + + RightFlowContainer.Add(new OsuSpriteText + { + Text = activity.CreatedAt.LocalDateTime.ToShortDateString(), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = "Exo2.0-RegularItalic", + TextSize = 12, + Colour = OsuColour.Gray(0xAA), + }); + } + + protected override Drawable CreateLeftVisual() + { + switch (activity.Type) + { + case RecentActivityType.Rank: + return new DrawableRank(activity.ScoreRank) + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + + default: + return new Container + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + } + } + + private string activityToString() + { + switch (activity.Type) + { + case RecentActivityType.Achievement: + return $"{activity.User.Username} unlocked the {activity.AchivementName} achievement!"; + + case RecentActivityType.BeatmapPlaycount: + return $"{activity.Beatmap.Title} has been played {activity.Count} times!"; + + case RecentActivityType.BeatmapsetDelete: + return $"{activity.Beatmap.Title} has been deleted."; + + case RecentActivityType.BeatmapsetRevive: + return $"{activity.Beatmap.Title} has been revived from eternal slumber by ${activity.User.Username}"; + + case RecentActivityType.BeatmapsetUpdate: + return $"{activity.User.Username} has updated the beatmap ${activity.Beatmap.Title}"; + + case RecentActivityType.BeatmapsetUpload: + return $"{activity.User.Username} has submitted a new beatmap ${activity.Beatmap.Title}"; + + case RecentActivityType.Medal: + return $"{activity.User.Username} has unlocked the {activity.AchivementName} medal!"; + + case RecentActivityType.Rank: + return $"{activity.User.Username} achieved rank #{activity.Rank} on {activity.Beatmap?.Title}"; + + case RecentActivityType.RankLost: + return $"{activity.User.Username} has lost first place on {activity.Beatmap.Title}!"; + + case RecentActivityType.UserSupportAgain: + return $"{activity.User.Username} has once again chosen to support osu! - thanks for your generosity!"; + + case RecentActivityType.UserSupportFirst: + return $"{activity.User.Username} has become an osu! supporter - thanks for your generosity!"; + + case RecentActivityType.UsernameChange: + return $"{activity.User.PreviousUsername} has changed their username to {activity.User.Username}"; + + case RecentActivityType.UserSupportGift: + return $"{activity.User.Username} has received the gift of osu! supporter!"; + + default: + return string.Empty; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 11b48ad68e..307c06b744 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,5 +1,7 @@ using osu.Framework.Configuration; +using osu.Framework.Graphics; using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Profile.Sections.Recent; using osu.Game.Users; using System; using System.Collections.Generic; @@ -17,47 +19,32 @@ namespace osu.Game.Overlays.Profile.Sections ItemsPerPage = 5; } - //protected override void ShowMore() - //{ - // base.ShowMore(); + protected override void ShowMore() + { + base.ShowMore(); - // var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); + var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); - // req.Success += scores => - // { - // foreach (var s in scores) - // s.ApplyRuleset(Rulesets.GetRuleset(s.OnlineRulesetID)); + req.Success += activities => + { + ShowMoreButton.FadeTo(activities.Count == ItemsPerPage ? 1 : 0); + ShowMoreLoading.Hide(); - // ShowMoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); - // ShowMoreLoading.Hide(); + if (!activities.Any() && VisiblePages == 1) + { + MissingText.Show(); + return; + } - // if (!scores.Any() && VisiblePages == 1) - // { - // MissingText.Show(); - // return; - // } + MissingText.Hide(); - // MissingText.Hide(); + foreach (RecentActivity activity in activities) + { + ItemsContainer.Add(new DrawableRecentActivity(activity, User)); + } + }; - // foreach (OnlineScore score in scores) - // { - // DrawableProfileScore drawableScore; - - // switch (type) - // { - // default: - // drawableScore = new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); - // break; - // case ScoreType.Recent: - // drawableScore = new DrawableTotalScore(score); - // break; - // } - - // ItemsContainer.Add(drawableScore); - // } - // }; - - // Api.Queue(req); - //} + Api.Queue(req); + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ad9105f1e8..cd40b42365 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -300,6 +300,7 @@ 20180125143340_Settings.cs + From bb40919f9ce2e8948ac73548cd075ac3024ce1d3 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 00:36:55 +0530 Subject: [PATCH 03/48] Add link handling to recent activities. - Add a show user action to link handling --- .../Graphics/Containers/LinkFlowContainer.cs | 7 ++- osu.Game/Online/Chat/MessageFormatter.cs | 15 ++++++ .../Sections/Recent/DrawableRecentActivity.cs | 54 +++++++++++++------ osu.Game/Overlays/UserProfileOverlay.cs | 5 ++ 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 9f1b44af44..8edae7a976 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -23,14 +23,16 @@ namespace osu.Game.Graphics.Containers public override bool HandleMouseInput => true; private OsuGame game; + private UserProfileOverlay userProfile; private Action showNotImplementedError; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications) + private void load(OsuGame game, NotificationOverlay notifications, UserProfileOverlay userProfile) { // will be null in tests this.game = game; + this.userProfile = userProfile; showNotImplementedError = () => notifications?.Post(new SimpleNotification { @@ -90,6 +92,9 @@ namespace osu.Game.Graphics.Containers case LinkAction.External: Process.Start(url); break; + case LinkAction.OpenUserProfile: + userProfile?.ShowUser(Convert.ToInt64(linkArgument)); + break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); } diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 906f42d50e..3fdce3ec12 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -118,6 +118,8 @@ namespace osu.Game.Online.Chat case "beatmapsets": case "d": return new LinkDetails(LinkAction.OpenBeatmapSet, args[3]); + case "u": + return new LinkDetails(LinkAction.OpenUserProfile, args[3]); } } @@ -146,6 +148,9 @@ namespace osu.Game.Online.Chat case "spectate": linkType = LinkAction.Spectate; break; + case "u": + linkType = LinkAction.OpenUserProfile; + break; default: linkType = LinkAction.External; break; @@ -205,6 +210,15 @@ namespace osu.Game.Online.Chat return inputMessage; } + public static List GetLinks(string text) + { + var result = format(text); + + result.Links.Sort(); + + return result.Links; + } + public class MessageFormatterResult { public List Links = new List(); @@ -239,6 +253,7 @@ namespace osu.Game.Online.Chat OpenEditorTimestamp, JoinMultiplayerMatch, Spectate, + OpenUserProfile, } public class Link : IComparable diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index e0f7a97140..6abf68e3e9 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -7,10 +7,14 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; +using static osu.Game.Online.API.Requests.RecentActivity; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -18,19 +22,31 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private RecentActivity activity; private User user; + private APIAccess api; + + private string userLinkTemplate; + private string beatmapLinkTemplate; + + private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity, User user) { this.activity = activity; this.user = user; + + userLinkTemplate = $"[{activity.User?.Username}]({urlToAbsolute(activity.User?.Url)})"; + beatmapLinkTemplate = $"[{activity.Beatmap?.Title}]({urlToAbsolute(activity.Beatmap?.Url)})"; } [BackgroundDependencyLoader] - private void load() + private void load(APIAccess api) { - LeftFlowContainer.Add(new OsuSpriteText + this.api = api; + + LeftFlowContainer.Add(content = new LinkFlowContainer { - Text = activityToString(), + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, }); RightFlowContainer.Add(new OsuSpriteText @@ -42,6 +58,10 @@ namespace osu.Game.Overlays.Profile.Sections.Recent TextSize = 12, Colour = OsuColour.Gray(0xAA), }); + + string text = activityToString(); + + content.AddLinks(text, MessageFormatter.GetLinks(text)); } protected override Drawable CreateLeftVisual() @@ -66,48 +86,50 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } + private string urlToAbsolute(string url) => $"{api?.Endpoint ?? @"https://osu.ppy.sh"}{url}"; + private string activityToString() { switch (activity.Type) { case RecentActivityType.Achievement: - return $"{activity.User.Username} unlocked the {activity.AchivementName} achievement!"; + return $"{userLinkTemplate} unlocked the {activity.AchivementName} achievement!"; case RecentActivityType.BeatmapPlaycount: - return $"{activity.Beatmap.Title} has been played {activity.Count} times!"; + return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; case RecentActivityType.BeatmapsetDelete: - return $"{activity.Beatmap.Title} has been deleted."; + return $"{beatmapLinkTemplate} has been deleted."; case RecentActivityType.BeatmapsetRevive: - return $"{activity.Beatmap.Title} has been revived from eternal slumber by ${activity.User.Username}"; + return $"{beatmapLinkTemplate} has been revived from eternal slumber by ${userLinkTemplate}"; case RecentActivityType.BeatmapsetUpdate: - return $"{activity.User.Username} has updated the beatmap ${activity.Beatmap.Title}"; + return $"{userLinkTemplate} has updated the beatmap ${beatmapLinkTemplate}"; case RecentActivityType.BeatmapsetUpload: - return $"{activity.User.Username} has submitted a new beatmap ${activity.Beatmap.Title}"; + return $"{userLinkTemplate} has submitted a new beatmap ${beatmapLinkTemplate}"; case RecentActivityType.Medal: - return $"{activity.User.Username} has unlocked the {activity.AchivementName} medal!"; + return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; case RecentActivityType.Rank: - return $"{activity.User.Username} achieved rank #{activity.Rank} on {activity.Beatmap?.Title}"; + return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate}"; case RecentActivityType.RankLost: - return $"{activity.User.Username} has lost first place on {activity.Beatmap.Title}!"; + return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate}!"; case RecentActivityType.UserSupportAgain: - return $"{activity.User.Username} has once again chosen to support osu! - thanks for your generosity!"; + return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; case RecentActivityType.UserSupportFirst: - return $"{activity.User.Username} has become an osu! supporter - thanks for your generosity!"; + return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {activity.User.Username}"; + return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}"; case RecentActivityType.UserSupportGift: - return $"{activity.User.Username} has received the gift of osu! supporter!"; + return $"{userLinkTemplate} has received the gift of osu! supporter!"; default: return string.Empty; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 3bc12ccb24..39cb71ea27 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -73,6 +73,11 @@ namespace osu.Game.Overlays FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); } + public void ShowUser(long userId) + { + ShowUser(new User { Id = userId }, true); + } + public void ShowUser(User user, bool fetchOnline = true) { userReq?.Cancel(); From 75fdca928e9d19ae12e2a8ce739cc9af42fda20b Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 00:58:20 +0530 Subject: [PATCH 04/48] Handle links correctly and don't re-open profile if the user is same. --- osu.Game/Online/Chat/MessageFormatter.cs | 4 ++-- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 8 ++++---- osu.Game/Overlays/UserProfileOverlay.cs | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 3fdce3ec12..9966f78435 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -210,13 +210,13 @@ namespace osu.Game.Online.Chat return inputMessage; } - public static List GetLinks(string text) + public static MessageFormatterResult FormatText(string text) { var result = format(text); result.Links.Sort(); - return result.Links; + return result; } public class MessageFormatterResult diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 6abf68e3e9..4d215467bb 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -34,8 +34,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent this.activity = activity; this.user = user; - userLinkTemplate = $"[{activity.User?.Username}]({urlToAbsolute(activity.User?.Url)})"; - beatmapLinkTemplate = $"[{activity.Beatmap?.Title}]({urlToAbsolute(activity.Beatmap?.Url)})"; + userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; + beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; } [BackgroundDependencyLoader] @@ -59,9 +59,9 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Colour = OsuColour.Gray(0xAA), }); - string text = activityToString(); + var formatted = MessageFormatter.FormatText(activityToString()); - content.AddLinks(text, MessageFormatter.GetLinks(text)); + content.AddLinks(formatted.Text, formatted.Links); } protected override Drawable CreateLeftVisual() diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 39cb71ea27..f19fc4062c 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -75,6 +75,9 @@ namespace osu.Game.Overlays public void ShowUser(long userId) { + if (userId == Header.User.Id) + return; + ShowUser(new User { Id = userId }, true); } From 1ad45b094178dc644ffcbc3ca808a2cb1c4ad0ac Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 01:16:46 +0530 Subject: [PATCH 05/48] R# fixes. --- .../GetUserRecentActivitiesRequest.cs | 4 ---- .../Sections/Recent/DrawableRecentActivity.cs | 19 +++++-------------- .../PaginatedRecentActivityContainer.cs | 11 +++-------- .../Profile/Sections/RecentSection.cs | 2 ++ osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 5 files changed, 11 insertions(+), 27 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 14997b070b..d52d0c884e 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -3,10 +3,6 @@ using osu.Game.Rulesets.Scoring; using Humanizer; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4d215467bb..940cd7f5ac 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Framework.Allocation; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -13,26 +8,22 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; -using osu.Game.Users; -using static osu.Game.Online.API.Requests.RecentActivity; namespace osu.Game.Overlays.Profile.Sections.Recent { public class DrawableRecentActivity : DrawableProfileRow { - private RecentActivity activity; - private User user; private APIAccess api; - private string userLinkTemplate; - private string beatmapLinkTemplate; + private readonly RecentActivity activity; + private readonly string userLinkTemplate; + private readonly string beatmapLinkTemplate; private LinkFlowContainer content; - public DrawableRecentActivity(RecentActivity activity, User user) + public DrawableRecentActivity(RecentActivity activity) { this.activity = activity; - this.user = user; userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 307c06b744..f1857096aa 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,17 +1,12 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Profile.Sections.Recent; using osu.Game.Users; -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace osu.Game.Overlays.Profile.Sections +namespace osu.Game.Overlays.Profile.Sections.Recent { - class PaginatedRecentActivityContainer : PaginatedContainer + internal class PaginatedRecentActivityContainer : PaginatedContainer { public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) @@ -40,7 +35,7 @@ namespace osu.Game.Overlays.Profile.Sections foreach (RecentActivity activity in activities) { - ItemsContainer.Add(new DrawableRecentActivity(activity, User)); + ItemsContainer.Add(new DrawableRecentActivity(activity)); } }; diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 757e2457d2..db97dca440 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.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 osu.Game.Overlays.Profile.Sections.Recent; + namespace osu.Game.Overlays.Profile.Sections { public class RecentSection : ProfileSection diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f19fc4062c..f3fd7aeac5 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays if (userId == Header.User.Id) return; - ShowUser(new User { Id = userId }, true); + ShowUser(new User { Id = userId }); } public void ShowUser(User user, bool fetchOnline = true) From 5724618b2a3f8109254246c493b00738fa1117df Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 09:38:37 +0530 Subject: [PATCH 06/48] Add license headers and sanitise open profile argument. --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 3 ++- .../Online/API/Requests/GetUserRecentActivitiesRequest.cs | 5 ++++- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 ++++- .../Sections/Recent/PaginatedRecentActivityContainer.cs | 5 ++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 8edae7a976..c16ccbce86 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -93,7 +93,8 @@ namespace osu.Game.Graphics.Containers Process.Start(url); break; case LinkAction.OpenUserProfile: - userProfile?.ShowUser(Convert.ToInt64(linkArgument)); + if (long.TryParse(linkArgument, out long userId)) + userProfile?.ShowUser(userId); break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index d52d0c884e..451c39fdfe 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; using osu.Game.Rulesets.Scoring; using Humanizer; using System; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 940cd7f5ac..901791d340 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// 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.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index f1857096aa..3de005cf9b 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,4 +1,7 @@ -using osu.Framework.Configuration; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; From a20e4bc2c3494f37d14448f8ccb1d712dad5a0f5 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 11:46:16 +0530 Subject: [PATCH 07/48] Fix typos and missing fields in JSON mappings. --- .../GetUserRecentActivitiesRequest.cs | 17 +++++++++++-- .../Sections/Recent/DrawableRecentActivity.cs | 25 ++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 451c39fdfe..7926bd9d34 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -28,7 +28,7 @@ namespace osu.Game.Online.API.Requests [JsonProperty("id")] public int ID; - [JsonProperty("created_at")] + [JsonProperty("createdAt")] public DateTimeOffset CreatedAt; [JsonProperty] @@ -50,6 +50,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("rank")] public int Rank; + [JsonProperty("approval")] + public BeatmapApproval Approval; + [JsonProperty("count")] public int Count; @@ -59,10 +62,13 @@ namespace osu.Game.Online.API.Requests [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; + [JsonProperty("beatmapset")] + public RecentActivityBeatmap Beatmapset; + [JsonProperty("user")] public RecentActivityUser User; - [JsonProperty("achivementName")] + [JsonProperty("achievementName")] public string AchivementName; public class RecentActivityBeatmap @@ -104,4 +110,11 @@ namespace osu.Game.Online.API.Requests UserSupportGift, UsernameChange, } + + public enum BeatmapApproval + { + Ranked, + Approved, + Qualified, + } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 901791d340..012418967f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -21,6 +21,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private readonly RecentActivity activity; private readonly string userLinkTemplate; private readonly string beatmapLinkTemplate; + private readonly string beatmapsetLinkTemplate; private LinkFlowContainer content; @@ -30,6 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + beatmapsetLinkTemplate = $"[{urlToAbsolute(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; } [BackgroundDependencyLoader] @@ -70,6 +72,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent FillMode = FillMode.Fit, }; + case RecentActivityType.Medal: + // TODO: add medal visual default: return new Container { @@ -92,26 +96,29 @@ namespace osu.Game.Overlays.Profile.Sections.Recent case RecentActivityType.BeatmapPlaycount: return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; + case RecentActivityType.BeatmapsetApprove: + return $"{beatmapsetLinkTemplate} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + case RecentActivityType.BeatmapsetDelete: - return $"{beatmapLinkTemplate} has been deleted."; + return $"{beatmapsetLinkTemplate} has been deleted."; case RecentActivityType.BeatmapsetRevive: - return $"{beatmapLinkTemplate} has been revived from eternal slumber by ${userLinkTemplate}"; + return $"{beatmapsetLinkTemplate} has been revived from eternal slumber by {userLinkTemplate}."; case RecentActivityType.BeatmapsetUpdate: - return $"{userLinkTemplate} has updated the beatmap ${beatmapLinkTemplate}"; + return $"{userLinkTemplate} has updated the beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.BeatmapsetUpload: - return $"{userLinkTemplate} has submitted a new beatmap ${beatmapLinkTemplate}"; + return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.Medal: return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; case RecentActivityType.Rank: - return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate}"; + return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; case RecentActivityType.RankLost: - return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate}!"; + return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate} ({activity.Mode}!)"; case RecentActivityType.UserSupportAgain: return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; @@ -119,12 +126,12 @@ namespace osu.Game.Overlays.Profile.Sections.Recent case RecentActivityType.UserSupportFirst: return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; - case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}"; - case RecentActivityType.UserSupportGift: return $"{userLinkTemplate} has received the gift of osu! supporter!"; + case RecentActivityType.UsernameChange: + return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}!"; + default: return string.Empty; } From a77d1eedae0b2756e5ad7cb6ac96d87eb7c8d129 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 13:08:12 +0530 Subject: [PATCH 08/48] Fix achievements parsing and add badges to recent activity. --- .../GetUserRecentActivitiesRequest.cs | 14 ++++++- .../Sections/Recent/DrawableRecentActivity.cs | 15 ++++++-- .../Profile/Sections/Recent/MedalIcon.cs | 38 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 7926bd9d34..d1685b01f3 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -68,8 +68,8 @@ namespace osu.Game.Online.API.Requests [JsonProperty("user")] public RecentActivityUser User; - [JsonProperty("achievementName")] - public string AchivementName; + [JsonProperty("achievement")] + public RecentActivityAchievement Achievement; public class RecentActivityBeatmap { @@ -91,6 +91,16 @@ namespace osu.Game.Online.API.Requests [JsonProperty("previousUsername")] public string PreviousUsername; } + + public class RecentActivityAchievement + { + [JsonProperty("slug")] + public string Slug; + + [JsonProperty("name")] + public string Name; + } + } public enum RecentActivityType diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 012418967f..282b2e242a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -72,8 +72,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent FillMode = FillMode.Fit, }; - case RecentActivityType.Medal: - // TODO: add medal visual + case RecentActivityType.Achievement: + return new MedalIcon(activity.Achievement.Slug) + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + default: return new Container { @@ -91,7 +97,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent switch (activity.Type) { case RecentActivityType.Achievement: - return $"{userLinkTemplate} unlocked the {activity.AchivementName} achievement!"; + return $"{userLinkTemplate} unlocked the {activity.Achievement.Name} medal!"; case RecentActivityType.BeatmapPlaycount: return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; @@ -112,7 +118,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.Medal: - return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; + // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) + return string.Empty; case RecentActivityType.Rank: return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs new file mode 100644 index 0000000000..9ef2b89269 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -0,0 +1,38 @@ +// 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.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Overlays.Profile.Sections.Recent +{ + internal class MedalIcon : Container + { + private readonly string slug; + private readonly Sprite sprite; + + private string url => $@"https://s.ppy.sh/images/medals-client/{slug}@2x.png"; + + public MedalIcon(string slug) + { + this.slug = slug; + + Child = sprite = new Sprite + { + Height = 40, + Width = 40, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + sprite.Texture = textures.Get(url); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cd40b42365..e420ec6b71 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -301,6 +301,7 @@ + From 62913163e02ca776174bcb1f01388ce6b2c95f53 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 27 Feb 2018 21:21:53 +0530 Subject: [PATCH 09/48] Fix long recent activity text overlapping timestamp. - Also remove unnecessary fallback from absolute URL helper --- .../Sections/Recent/DrawableRecentActivity.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 282b2e242a..4785b1e8d3 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -19,19 +19,16 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private APIAccess api; private readonly RecentActivity activity; - private readonly string userLinkTemplate; - private readonly string beatmapLinkTemplate; - private readonly string beatmapsetLinkTemplate; + + private string userLinkTemplate; + private string beatmapLinkTemplate; + private string beatmapsetLinkTemplate; private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity) { this.activity = activity; - - userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; - beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - beatmapsetLinkTemplate = $"[{urlToAbsolute(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; } [BackgroundDependencyLoader] @@ -39,6 +36,12 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { this.api = api; + userLinkTemplate = $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; + beatmapLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + beatmapsetLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; + + LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; + LeftFlowContainer.Add(content = new LinkFlowContainer { AutoSizeAxes = Axes.Y, @@ -90,7 +93,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string urlToAbsolute(string url) => $"{api?.Endpoint ?? @"https://osu.ppy.sh"}{url}"; + private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; private string activityToString() { From 2e535afb845bb1b6719d6df5611a771879c0d7de Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 28 Feb 2018 15:19:27 +0530 Subject: [PATCH 10/48] Remove redundant subsection title. - Also handle opening UserProfile in LinkFlowContainer similar to how beatmaps and channels are handled --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 6 ++---- osu.Game/OsuGame.cs | 6 ++++++ osu.Game/Overlays/Profile/Sections/RecentSection.cs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index c16ccbce86..1d231ada23 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -23,16 +23,14 @@ namespace osu.Game.Graphics.Containers public override bool HandleMouseInput => true; private OsuGame game; - private UserProfileOverlay userProfile; private Action showNotImplementedError; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications, UserProfileOverlay userProfile) + private void load(OsuGame game, NotificationOverlay notifications) { // will be null in tests this.game = game; - this.userProfile = userProfile; showNotImplementedError = () => notifications?.Post(new SimpleNotification { @@ -94,7 +92,7 @@ namespace osu.Game.Graphics.Containers break; case LinkAction.OpenUserProfile: if (long.TryParse(linkArgument, out long userId)) - userProfile?.ShowUser(userId); + game?.ShowUser(userId); break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 95eb88c5c8..cff7007fd5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -154,6 +154,12 @@ namespace osu.Game /// The set to display. public void ShowBeatmapSet(int setId) => beatmapSetOverlay.ShowBeatmapSet(setId); + /// + /// Show a user's profile as an overlay. + /// + /// The user to display. + public void ShowUser(long userId) => userProfile.ShowUser(userId); + protected void LoadScore(Score s) { scoreLoad?.Cancel(); diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index db97dca440..84a941aa1a 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(User, @"Recent", @"This user hasn't done anything notable recently!"), + new PaginatedRecentActivityContainer(User, null, @"This user hasn't done anything notable recently!"), }; } } From 46dfb761c57e1804576760ce217ddf4a44544cba Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 28 Feb 2018 16:14:52 +0100 Subject: [PATCH 11/48] basic volume meter and testcase --- .../Visual/TestCaseVolumeControl.cs | 29 +++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + osu.Game/Overlays/Volume/MuteButton.cs | 58 ++++++ osu.Game/Overlays/Volume/VolumeMeter.cs | 193 ++++++++++++++++++ osu.Game/osu.Game.csproj | 2 + 5 files changed, 283 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseVolumeControl.cs create mode 100644 osu.Game/Overlays/Volume/MuteButton.cs create mode 100644 osu.Game/Overlays/Volume/VolumeMeter.cs diff --git a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs new file mode 100644 index 0000000000..04390d6d19 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Overlays.Volume; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseVolumeControl : TestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + VolumeMeter meter; + Add(meter = new VolumeMeter("MASTER", 125, colours.PinkDarker)); + Add(new MuteButton + { + Margin = new MarginPadding { Top = 200 } + }); + + meter.Bindable.BindTo(audio.Volume); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8301f1f734..63adbc8b43 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -162,6 +162,7 @@ + diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs new file mode 100644 index 0000000000..b45034c166 --- /dev/null +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -0,0 +1,58 @@ +using osu.Framework.Allocation; +using osu.Framework.Configuration; +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.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class MuteButton : Container, IHasCurrentValue + { + public Bindable Current { get; } = new Bindable(); + + private Color4 hoveredColour, unhoveredColour; + + public MuteButton() + { + Masking = true; + BorderThickness = 3; + CornerRadius = 20; + Size = new Vector2(100, 40); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoveredColour = colours.YellowDark; + BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); + + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + }); + } + + protected override bool OnHover(InputState state) + { + this.TransformTo("BorderColour", hoveredColour, 500, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(InputState state) + { + this.TransformTo("BorderColour", unhoveredColour, 500, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs new file mode 100644 index 0000000000..3351dbed9a --- /dev/null +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -0,0 +1,193 @@ +using System; +using System.Globalization; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Bindings; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class VolumeMeter : Container, IKeyBindingHandler + { + private CircularProgress volumeCircle; + public BindableDouble Bindable { get; } = new BindableDouble(); + private readonly float circleSize; + private readonly Color4 meterColour; + private readonly string name; + + public VolumeMeter(string name, float circleSize, Color4 meterColour) + { + this.circleSize = circleSize; + this.meterColour = meterColour; + this.name = name; + + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Add(new Container + { + Size = new Vector2(120, 20), + CornerRadius = 10, + Masking = true, + Margin = new MarginPadding { Left = circleSize + 10 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Exo2.0-Bold", + Text = name + } + } + }); + + + OsuSpriteText text, maxText; + CircularProgress bgProgress; + BufferedContainer maxGlow; + + Add(new CircularContainer + { + Masking = true, + Size = new Vector2(circleSize), + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + bgProgress = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 0.05f, + Rotation = 180, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = colours.Gray2, + Size = new Vector2(0.8f) + }, + (volumeCircle = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 0.05f, + Rotation = 180, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.8f) + }).WithEffect(new GlowEffect + { + Colour = meterColour, + Strength = 2 + }), + maxGlow = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + Text = "MAX", + TextSize = 0.16f * circleSize + }.WithEffect(new GlowEffect + { + Colour = meterColour, + PadExtent = true, + Strength = 2, + }), + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + TextSize = 0.16f * circleSize + } + } + }); + + Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); + volumeCircle.Current.ValueChanged += newVolume => + { + if (newVolume > 0.745) + { + text.Alpha = 0; + maxGlow.Alpha = 1; //show "MAX" + } + else + { + text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); + text.Alpha = 1; + maxGlow.Alpha = 0; + } + }; + + bgProgress.Current.Value = 0.75f; + } + + /// + /// This is needed because doesn't support + /// + private double circleBindable + { + get => volumeCircle.Current; + set => volumeCircle.Current.Value = value; + } + + public double Volume + { + get => Bindable; + private set => Bindable.Value = value; + } + + public void Increase() + { + Volume += 0.05f; + } + + public void Decrease() + { + Volume -= 0.05f; + } + + public bool OnPressed(GlobalAction action) + { + if (!IsHovered) return false; + + switch (action) + { + case GlobalAction.DecreaseVolume: + Decrease(); + return true; + case GlobalAction.IncreaseVolume: + Increase(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4944613828..b94da5badb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -330,6 +330,8 @@ + + From 3a420ba8269920c45ba166076a14a82f6f6815da Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:08:35 +0100 Subject: [PATCH 12/48] add the volume overlay --- ...lumeControl.cs => TestCaseVolumePieces.cs} | 3 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- .../UserInterface/Volume/VolumeMeter.cs | 108 ------------- osu.Game/OsuGame.cs | 6 +- osu.Game/Overlays/Volume/MuteButton.cs | 27 +++- .../Volume/VolumeControlReceptor.cs | 2 +- osu.Game/Overlays/Volume/VolumeMeter.cs | 4 +- .../VolumeOverlay.cs} | 145 +++++++++--------- osu.Game/osu.Game.csproj | 5 +- 9 files changed, 109 insertions(+), 193 deletions(-) rename osu.Game.Tests/Visual/{TestCaseVolumeControl.cs => TestCaseVolumePieces.cs} (90%) delete mode 100644 osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs rename osu.Game/{Graphics/UserInterface => Overlays}/Volume/VolumeControlReceptor.cs (90%) rename osu.Game/{Graphics/UserInterface/Volume/VolumeControl.cs => Overlays/VolumeOverlay.cs} (54%) diff --git a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs similarity index 90% rename from osu.Game.Tests/Visual/TestCaseVolumeControl.cs rename to osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 04390d6d19..5a43574a9d 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Volume; namespace osu.Game.Tests.Visual { - public class TestCaseVolumeControl : TestCase + public class TestCaseVolumePieces : TestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; @@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual }); meter.Bindable.BindTo(audio.Volume); + } } } diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index dde04201f2..8cbeb6aab6 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -174,7 +174,7 @@ - + diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs deleted file mode 100644 index ef3702fdf3..0000000000 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; - -namespace osu.Game.Graphics.UserInterface.Volume -{ - public class VolumeMeter : Container, IKeyBindingHandler - { - private readonly Box meterFill; - public BindableDouble Bindable { get; } = new BindableDouble(); - - public VolumeMeter(string meterName) - { - Size = new Vector2(40, 180); - Children = new Drawable[] - { - new Box - { - Colour = Color4.Black, - RelativeSizeAxes = Axes.Both - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.5f, 0.9f), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] - { - new Box - { - Colour = Color4.DarkGray, - RelativeSizeAxes = Axes.Both - }, - meterFill = new Box - { - Colour = Color4.White, - Scale = new Vector2(1, 0), - RelativeSizeAxes = Axes.Both, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre - } - } - }, - new OsuSpriteText - { - Text = meterName, - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre - } - }; - - Bindable.ValueChanged += delegate { updateFill(); }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - updateFill(); - } - - public double Volume - { - get => Bindable.Value; - private set => Bindable.Value = value; - } - - public void Increase() - { - Volume += 0.05f; - } - - public void Decrease() - { - Volume -= 0.05f; - } - - private void updateFill() => meterFill.ScaleTo(new Vector2(1, (float)Volume), 300, Easing.OutQuint); - - public bool OnPressed(GlobalAction action) - { - if (!IsHovered) return false; - - switch (action) - { - case GlobalAction.DecreaseVolume: - Decrease(); - return true; - case GlobalAction.IncreaseVolume: - Increase(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => false; - } -} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index aeb23dccd7..a6f650d23d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Framework.Logging; -using osu.Game.Graphics.UserInterface.Volume; using osu.Framework.Allocation; using osu.Game.Overlays.Toolbar; using osu.Game.Screens; @@ -33,6 +32,7 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets.Mods; using osu.Game.Skinning; using OpenTK.Graphics; +using osu.Game.Overlays.Volume; namespace osu.Game { @@ -75,7 +75,7 @@ namespace osu.Game private OsuScreen screenStack; - private VolumeControl volume; + private VolumeOverlay volume; private OnScreenDisplay onscreenDisplay; private Bindable configRuleset; @@ -232,7 +232,7 @@ namespace osu.Game }, }, overlayContent.Add); - loadComponentSingleFile(volume = new VolumeControl(), Add); + loadComponentSingleFile(volume = new VolumeOverlay(), Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); //overlay elements diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index b45034c166..82e61c8f0b 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -18,13 +18,15 @@ namespace osu.Game.Overlays.Volume public Bindable Current { get; } = new Bindable(); private Color4 hoveredColour, unhoveredColour; + private const float width = 100; + public const float HEIGHT = 35; public MuteButton() { Masking = true; BorderThickness = 3; - CornerRadius = 20; - Size = new Vector2(100, 40); + CornerRadius = HEIGHT / 2; + Size = new Vector2(width, HEIGHT); } [BackgroundDependencyLoader] @@ -33,6 +35,8 @@ namespace osu.Game.Overlays.Volume hoveredColour = colours.YellowDark; BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); + + SpriteIcon icon; AddRange(new Drawable[] { new Box @@ -41,7 +45,20 @@ namespace osu.Game.Overlays.Volume Colour = colours.Gray1, Alpha = 0.9f, }, + icon = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20), + } }); + + Current.ValueChanged += newValue => + { + icon.Icon = newValue ? FontAwesome.fa_volume_off : FontAwesome.fa_volume_up; + icon.Margin = new MarginPadding { Left = newValue ? width / 2 - 15 : width / 2 - 10 }; //Magic numbers to line up both icons because they're different widths + }; + Current.TriggerChange(); } protected override bool OnHover(InputState state) @@ -54,5 +71,11 @@ namespace osu.Game.Overlays.Volume { this.TransformTo("BorderColour", unhoveredColour, 500, Easing.OutQuint); } + + protected override bool OnClick(InputState state) + { + Current.Value = !Current.Value; + return true; + } } } diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs similarity index 90% rename from osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs rename to osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 2328533665..a5be7dc445 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -7,7 +7,7 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; -namespace osu.Game.Graphics.UserInterface.Volume +namespace osu.Game.Overlays.Volume { public class VolumeControlReceptor : Container, IKeyBindingHandler, IHandleGlobalInput { diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 3351dbed9a..92b5c3f0bd 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -128,9 +128,9 @@ namespace osu.Game.Overlays.Volume }); Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); - volumeCircle.Current.ValueChanged += newVolume => + volumeCircle.Current.ValueChanged += newVolume => //by using this event we sync the meter with the text. newValue has to be divided by 0.75 to give the actual percentage { - if (newVolume > 0.745) + if (Precision.DefinitelyBigger(newVolume, 0.74)) { text.Alpha = 0; maxGlow.Alpha = 1; //show "MAX" diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Overlays/VolumeOverlay.cs similarity index 54% rename from osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs rename to osu.Game/Overlays/VolumeOverlay.cs index ccf70af6ed..aa94667901 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -1,57 +1,87 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// 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.Threading; -using OpenTK; +using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Allocation; using osu.Framework.Configuration; +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.Threading; +using osu.Game.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Overlays.Volume; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Graphics.UserInterface.Volume +namespace osu.Game.Overlays { - public class VolumeControl : OverlayContainer + public class VolumeOverlay : OverlayContainer { - private readonly VolumeMeter volumeMeterMaster; - private readonly IconButton muteIcon; + private const float offset = 10; + + private VolumeMeter volumeMeterMaster; + private VolumeMeter volumeMeterEffect; + private VolumeMeter volumeMeterMusic; + private MuteButton muteButton; protected override bool BlockPassThroughMouse => false; - public VolumeControl() - { - AutoSizeAxes = Axes.Both; - Anchor = Anchor.BottomRight; - Origin = Anchor.BottomRight; + private readonly BindableDouble muteAdjustment = new BindableDouble(); - Children = new Drawable[] + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + AddRange(new Drawable[] { + new Box + { + RelativeSizeAxes = Axes.Y, + Width = 300, + Colour = new ColourInfo + { + TopLeft = Color4.Black.Opacity(0.5f), + BottomLeft = Color4.Black.Opacity(0.5f), + TopRight = Color4.Black.Opacity(0), + BottomRight = Color4.Black.Opacity(0), + } + }, new FillFlowContainer { + Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Both, - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding { Left = 10, Right = 10, Top = 30, Bottom = 30 }, - Spacing = new Vector2(15, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Spacing = new Vector2(0, offset), + Margin = new MarginPadding { Left = offset }, Children = new Drawable[] { - new Container + volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.Blue) { - Size = new Vector2(IconButton.BUTTON_SIZE), - Child = muteIcon = new IconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_volume_up, - Action = () => Adjust(GlobalAction.ToggleMute), - } + Margin = new MarginPadding { Top = 100 + MuteButton.HEIGHT } //to counter the mute button and re-center the volume meters }, - volumeMeterMaster = new VolumeMeter("Master"), - volumeMeterEffect = new VolumeMeter("Effects"), - volumeMeterMusic = new VolumeMeter("Music") + volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.Pink), + volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.Blue), + muteButton = new MuteButton + { + Margin = new MarginPadding { Top = 100 } + } } - } + }, + }); + + + volumeMeterMaster.Bindable.BindTo(audio.Volume); + volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); + volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); + + muteButton.Current.ValueChanged += mute => + { + if (mute) + audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); + else + audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); }; } @@ -62,7 +92,13 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMaster.Bindable.ValueChanged += _ => settingChanged(); volumeMeterEffect.Bindable.ValueChanged += _ => settingChanged(); volumeMeterMusic.Bindable.ValueChanged += _ => settingChanged(); - muted.ValueChanged += _ => settingChanged(); + muteButton.Current.ValueChanged += _ => settingChanged(); + } + + private void settingChanged() + { + Show(); + schedulePopOut(); } public bool Adjust(GlobalAction action) @@ -83,50 +119,15 @@ namespace osu.Game.Graphics.UserInterface.Volume return true; case GlobalAction.ToggleMute: Show(); - muted.Toggle(); + muteButton.Current.Value = !muteButton.Current; return true; } return false; } - private void settingChanged() - { - Show(); - schedulePopOut(); - } - - private readonly BindableDouble muteAdjustment = new BindableDouble(); - - private readonly BindableBool muted = new BindableBool(); - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - volumeMeterMaster.Bindable.BindTo(audio.Volume); - volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); - volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); - - muted.ValueChanged += mute => - { - if (mute) - { - audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); - muteIcon.Icon = FontAwesome.fa_volume_off; - } - else - { - audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); - muteIcon.Icon = FontAwesome.fa_volume_up; - } - }; - } - private ScheduledDelegate popOutDelegate; - private readonly VolumeMeter volumeMeterEffect; - private readonly VolumeMeter volumeMeterMusic; - protected override void PopIn() { ClearTransforms(); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 847b4469e5..e99fd16aef 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -351,7 +351,9 @@ + + @@ -471,9 +473,6 @@ - - - From ef63366d91028c93f1478618793abff7de97e29c Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:25:34 +0100 Subject: [PATCH 13/48] simplify VolumeMeter --- osu.Game/Overlays/Volume/VolumeMeter.cs | 30 ++++++++++--------------- osu.Game/Overlays/VolumeOverlay.cs | 3 ++- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 92b5c3f0bd..525b4e315a 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -1,7 +1,9 @@ using System; using System.Globalization; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -65,7 +67,7 @@ namespace osu.Game.Overlays.Volume }); - OsuSpriteText text, maxText; + OsuSpriteText text; CircularProgress bgProgress; BufferedContainer maxGlow; @@ -104,26 +106,17 @@ namespace osu.Game.Overlays.Volume Colour = meterColour, Strength = 2 }), - maxGlow = new OsuSpriteText + maxGlow = (text = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = "Venera", - Text = "MAX", TextSize = 0.16f * circleSize - }.WithEffect(new GlowEffect + }).WithEffect(new GlowEffect { - Colour = meterColour, + Colour = Color4.Transparent, PadExtent = true, - Strength = 2, - }), - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = "Venera", - TextSize = 0.16f * circleSize - } + }) } }); @@ -132,14 +125,14 @@ namespace osu.Game.Overlays.Volume { if (Precision.DefinitelyBigger(newVolume, 0.74)) { - text.Alpha = 0; - maxGlow.Alpha = 1; //show "MAX" + text.Text = "MAX"; + maxGlow.EffectColour = meterColour.Opacity(2f); } else { + if (text.Text == "MAX") + maxGlow.EffectColour = Color4.Transparent; text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); - text.Alpha = 1; - maxGlow.Alpha = 0; } }; @@ -149,6 +142,7 @@ namespace osu.Game.Overlays.Volume /// /// This is needed because doesn't support /// + [UsedImplicitly] private double circleBindable { get => volumeCircle.Current; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index aa94667901..a8be219fc4 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -31,7 +31,8 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colours) { - RelativeSizeAxes = Axes.Both; + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; AddRange(new Drawable[] { From 8e0a524c4d6368469fe11072c0465409cf766b6b Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:31:29 +0100 Subject: [PATCH 14/48] change colours --- osu.Game/Overlays/VolumeOverlay.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index a8be219fc4..cc57b468fb 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -42,8 +42,8 @@ namespace osu.Game.Overlays Width = 300, Colour = new ColourInfo { - TopLeft = Color4.Black.Opacity(0.5f), - BottomLeft = Color4.Black.Opacity(0.5f), + TopLeft = Color4.Black.Opacity(0.75f), + BottomLeft = Color4.Black.Opacity(0.75f), TopRight = Color4.Black.Opacity(0), BottomRight = Color4.Black.Opacity(0), } @@ -58,12 +58,12 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Left = offset }, Children = new Drawable[] { - volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.Blue) + volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker) { Margin = new MarginPadding { Top = 100 + MuteButton.HEIGHT } //to counter the mute button and re-center the volume meters }, - volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.Pink), - volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.Blue), + volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker), + volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker), muteButton = new MuteButton { Margin = new MarginPadding { Top = 100 } From 9293ec635a44b4ca679fcea02048b5315f9ee8f5 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:49:38 +0100 Subject: [PATCH 15/48] add license headers and remove blank line --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 5 ++++- osu.Game/Overlays/Volume/MuteButton.cs | 5 ++++- osu.Game/Overlays/Volume/VolumeMeter.cs | 6 ++++-- osu.Game/Overlays/VolumeOverlay.cs | 5 ++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5a43574a9d..1894470df9 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -1,4 +1,7 @@ -using System; +// 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.Allocation; using osu.Framework.Audio; diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 82e61c8f0b..f056bf62ba 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// 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.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 525b4e315a..984ade9de0 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Globalization; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -66,7 +69,6 @@ namespace osu.Game.Overlays.Volume } }); - OsuSpriteText text; CircularProgress bgProgress; BufferedContainer maxGlow; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index cc57b468fb..27c699e365 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// 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.Audio; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; From 1cda58fe29b16dfb624fc2895bc0cc2772032f16 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:51:11 +0100 Subject: [PATCH 16/48] another blank line --- osu.Game/Overlays/Volume/MuteButton.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index f056bf62ba..adfc9c610f 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Volume hoveredColour = colours.YellowDark; BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); - SpriteIcon icon; AddRange(new Drawable[] { From ba80cd5f34823a8048928ea4d5eedd2caa4573c9 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:01:39 +0100 Subject: [PATCH 17/48] OsuColour can't be used in TestCases..? --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 1894470df9..5c97c3e368 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -7,8 +7,8 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Testing; -using osu.Game.Graphics; using osu.Game.Overlays.Volume; +using OpenTK.Graphics; namespace osu.Game.Tests.Visual { @@ -17,10 +17,10 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colours) + private void load(AudioManager audio) { VolumeMeter meter; - Add(meter = new VolumeMeter("MASTER", 125, colours.PinkDarker)); + Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); Add(new MuteButton { Margin = new MarginPadding { Top = 200 } From 033d06652095019b39c4c84b85b2183255e07129 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:03:24 +0100 Subject: [PATCH 18/48] blank line --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5c97c3e368..db868c00d7 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -27,7 +27,6 @@ namespace osu.Game.Tests.Visual }); meter.Bindable.BindTo(audio.Volume); - } } } From bafcab1349266a40e8c4c36a2aaddebc05bb0e36 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:20:07 +0100 Subject: [PATCH 19/48] redo the test case --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index db868c00d7..7bfdca82c3 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Overlays.Volume; @@ -16,17 +14,18 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; - [BackgroundDependencyLoader] - private void load(AudioManager audio) + protected override void LoadComplete() { VolumeMeter meter; + MuteButton mute; Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); - Add(new MuteButton + Add(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } }); - meter.Bindable.BindTo(audio.Volume); + AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); + AddToggleStep("mute", b => mute.Current.Value = b); } } } From ec013dbee860fdd170889f81103adfdbd0c00241 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 21:55:19 +0100 Subject: [PATCH 20/48] remove blank line and try to get test case working --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 6 +++--- osu.Game/Overlays/VolumeOverlay.cs | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 7bfdca82c3..5bacdf1f58 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -18,11 +18,11 @@ namespace osu.Game.Tests.Visual { VolumeMeter meter; MuteButton mute; - Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); - Add(mute = new MuteButton + LoadComponentAsync(meter = new VolumeMeter("MASTER", 125, Color4.Blue), Add); + LoadComponentAsync(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } - }); + }, Add); AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); AddToggleStep("mute", b => mute.Current.Value = b); diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 27c699e365..f764a83c7a 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -75,7 +75,6 @@ namespace osu.Game.Overlays }, }); - volumeMeterMaster.Bindable.BindTo(audio.Volume); volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); From 0a571278c975c3f496b928afed9f576d88c52769 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 4 Mar 2018 14:03:53 +0100 Subject: [PATCH 21/48] change TestCase to OsuTestCase --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5bacdf1f58..cfbf7fdb4d 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -4,13 +4,12 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Overlays.Volume; using OpenTK.Graphics; namespace osu.Game.Tests.Visual { - public class TestCaseVolumePieces : TestCase + public class TestCaseVolumePieces : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; @@ -18,11 +17,11 @@ namespace osu.Game.Tests.Visual { VolumeMeter meter; MuteButton mute; - LoadComponentAsync(meter = new VolumeMeter("MASTER", 125, Color4.Blue), Add); - LoadComponentAsync(mute = new MuteButton + Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); + Add(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } - }, Add); + }); AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); AddToggleStep("mute", b => mute.Current.Value = b); From 49b8670dfc917f261a770308ec268d2c8203a8c4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 14:53:57 +0900 Subject: [PATCH 22/48] Fix beatmap conversion tests not properly constructing decoder --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 596dbe84ba..7423005850 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -109,10 +109,9 @@ namespace osu.Game.Tests.Beatmaps private Beatmap getBeatmap(string name) { - var decoder = new LegacyBeatmapDecoder(); using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) - return decoder.DecodeBeatmap(stream); + return Decoder.GetDecoder(stream).DecodeBeatmap(stream); } private Stream openResource(string name) From 63155f169e500c5f92c9f46f167c0236d800da5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 15:11:50 +0900 Subject: [PATCH 23/48] Fix incorrect taiko slider conversions due to beatlength adjustments Fixes ppy/osu#2152 . --- .../Beatmaps/TaikoBeatmapConverter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index e5fe288f20..9d6b5b5ce4 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -101,16 +101,16 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps // The duration of the taiko hit object double taikoDuration = distance / taikoVelocity; - // For some reason, old osu! always uses speedAdjustment to determine the taiko velocity, but - // only uses it to determine osu! velocity if beatmap version < 8. Let's account for that here. - if (beatmap.BeatmapInfo.BeatmapVersion >= 8) - speedAdjustedBeatLength *= speedAdjustment; - // The velocity of the osu! hit object - calculated as the velocity of a slider double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; + // osu-stable always uses the speed-adjusted beatlength to determine the velocities, but + // only uses it for tick rate if beatmap version < 8 + if (beatmap.BeatmapInfo.BeatmapVersion >= 8) + speedAdjustedBeatLength *= speedAdjustment; + // If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate, taikoDuration / spans); From d44dc1a4f928c3a64dc685789e9d21c4a5d680ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:01:05 +0900 Subject: [PATCH 24/48] Fix SliderMultiplier/SliderTickRate parsing inaccuracy --- osu.Game/Beatmaps/BeatmapDifficulty.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index 16e6692887..38b84b4b03 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -29,8 +29,8 @@ namespace osu.Game.Beatmaps set => approachRate = value; } - public float SliderMultiplier { get; set; } = 1; - public float SliderTickRate { get; set; } = 1; + public double SliderMultiplier { get; set; } = 1; + public double SliderTickRate { get; set; } = 1; /// /// Maps a difficulty value [0, 10] to a two-piece linear range of values. diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 3e7b36f324..6ca74ebedb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -232,10 +232,10 @@ namespace osu.Game.Beatmaps.Formats difficulty.ApproachRate = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; case @"SliderMultiplier": - difficulty.SliderMultiplier = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); + difficulty.SliderMultiplier = double.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; case @"SliderTickRate": - difficulty.SliderTickRate = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); + difficulty.SliderTickRate = double.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; } } From 88c33e31e853f33a90dc80061bd2765aa676c130 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:01:45 +0900 Subject: [PATCH 25/48] Add slider conversion testcases --- ...nerating-drumroll-expected-conversion.json | 87 +++++++++++++++++++ .../Beatmaps/slider-generating-drumroll.osu | 25 ++++++ .../Tests/TaikoBeatmapConversionTest.cs | 3 +- .../osu.Game.Rulesets.Taiko.csproj | 2 + 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json new file mode 100644 index 0000000000..fc7d466c1b --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json @@ -0,0 +1,87 @@ +{ + "Mappings": [{ + "StartTime": 6590, + "Objects": [{ + "StartTime": 6590, + "EndTime": 8320, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 8436, + "Objects": [{ + "StartTime": 8436, + "EndTime": 10166, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 10282, + "Objects": [{ + "StartTime": 10282, + "EndTime": 12012, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 12128, + "Objects": [{ + "StartTime": 12128, + "EndTime": 13858, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 41666, + "Objects": [{ + "StartTime": 41666, + "EndTime": 42589, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 62666, + "Objects": [{ + "StartTime": 62666, + "EndTime": 63127, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 208743, + "Objects": [{ + "StartTime": 208743, + "EndTime": 209204, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu new file mode 100644 index 0000000000..4c493b47d4 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu @@ -0,0 +1,25 @@ +osu file format v14 + +[Difficulty] +HPDrainRate:6 +CircleSize:4.2 +OverallDifficulty:9 +ApproachRate:9.8 +SliderMultiplier:1.87 +SliderTickRate:1 + +[TimingPoints] +6590,461.538461538462,4,2,2,15,1,0 +6590,-200,4,2,2,15,0,0 +49051,230.769230769231,4,2,1,15,1,0 +62666,-200,4,2,1,60,0,0 +197666,-100,4,2,1,85,0,1 + +[HitObjects] +88,104,6590,6,0,B|176:156|256:108|256:108|336:60|423:112,1,350.625,6|0,0:0|0:0,0:0:0:0: +396,213,8436,2,0,P|277:247|376:172,1,350.625,6|0,0:0|0:0,0:0:0:0: +472,220,10282,2,0,P|456:288|220:300,1,350.625,6|0,0:0|0:0,0:0:0:0: +277,200,12128,2,0,P|398:225|276:244,1,350.625,6|0,0:0|0:0,0:0:0:0: +268,229,41666,2,0,L|473:210,1,187,2|2,0:0|0:0,0:0:0:0: +133,342,62666,2,0,B|132:316|132:316|128:316|128:316|130:295|130:295|126:296|126:296|129:275|129:275|125:275|125:275|127:254|127:254|123:255|123:255|125:234|125:234|121:234|121:234|123:213|123:213|119:214|119:214|121:193|121:193|118:193|118:193|118:172,1,187,8|8,0:0|0:0,0:0:0:0: +481,338,208743,6,0,P|492:262|383:195,2,187,2|8|2,0:0|0:0|0:0,0:0:0:0: diff --git a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs index 64f728a018..dd93c7df6a 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs @@ -21,7 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Tests private bool isForCurrentRuleset; [NonParallelizable] - [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] + [TestCase("basic", false)] + [TestCase("slider-generating-drumroll", false)] public void Test(string name, bool isForCurrentRuleset) { this.isForCurrentRuleset = isForCurrentRuleset; diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 07d27455b8..8f0aa88e62 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -149,6 +149,8 @@ + + From a6b6c016d63ca0aa8f38f94e61ee814026460018 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:14:36 +0900 Subject: [PATCH 26/48] Fix beatmap decoder tests --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 21bbc4993c..d1797e3a7d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8f, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 186bd44640..fc47aff91e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8f, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } From c013f8326786bcedb9019c1cdf5cd6bef9d8b559 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 17:01:27 +0900 Subject: [PATCH 27/48] Restore IgnoreAttribute --- osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs index dd93c7df6a..385e041ace 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.Tests private bool isForCurrentRuleset; [NonParallelizable] - [TestCase("basic", false)] + [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] [TestCase("slider-generating-drumroll", false)] public void Test(string name, bool isForCurrentRuleset) { From c4c1b0b6ffb7d366e7d786d5ebb209b5e093f3c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 01:39:01 +0900 Subject: [PATCH 28/48] Fix merge regression --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 7423005850..219d805bc1 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -111,7 +111,11 @@ namespace osu.Game.Tests.Beatmaps { using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) - return Decoder.GetDecoder(stream).DecodeBeatmap(stream); + { + var decoder = Decoder.GetDecoder(stream); + ((LegacyBeatmapDecoder)decoder).ApplyOffsets = false; + return decoder.DecodeBeatmap(stream); + } } private Stream openResource(string name) From 90828cca8fcf5b692564eafa5b43203165567bdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 08:59:02 +0900 Subject: [PATCH 29/48] Fix left and right arrows keys in chat overlay not working Misplaced override. Resolves ppy/osu-framework#1444 --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 2 -- osu.Game/Graphics/UserInterface/SearchTextBox.cs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 43a3f06236..6d9bf231c3 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -18,8 +18,6 @@ namespace osu.Game.Graphics.UserInterface public Action Exit; - public override bool HandleLeftRightArrows => false; - private bool focus; public bool HoldFocus { diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 9398eb55f3..28d33bbacd 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -12,6 +12,8 @@ namespace osu.Game.Graphics.UserInterface { protected virtual bool AllowCommit => false; + public override bool HandleLeftRightArrows => false; + public SearchTextBox() { Height = 35; From 9669c5aee3fa3770bb9639fe3d600087fb0b90c0 Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 4 Mar 2018 00:01:47 +0530 Subject: [PATCH 30/48] Make locally used things local and rename method. --- .../Sections/Recent/DrawableRecentActivity.cs | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4785b1e8d3..2dde8a3d54 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -20,10 +20,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private readonly RecentActivity activity; - private string userLinkTemplate; - private string beatmapLinkTemplate; - private string beatmapsetLinkTemplate; - private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity) @@ -36,10 +32,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { this.api = api; - userLinkTemplate = $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; - beatmapLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - beatmapsetLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; - LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; LeftFlowContainer.Add(content = new LinkFlowContainer @@ -58,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Colour = OsuColour.Gray(0xAA), }); - var formatted = MessageFormatter.FormatText(activityToString()); + var formatted = createMessage(); content.AddLinks(formatted.Text, formatted.Links); } @@ -95,56 +87,79 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; - private string activityToString() + private MessageFormatter.MessageFormatterResult createMessage() { + string userLinkTemplate() => $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; + string beatmapLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + string beatmapsetLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; + + string message; + switch (activity.Type) { case RecentActivityType.Achievement: - return $"{userLinkTemplate} unlocked the {activity.Achievement.Name} medal!"; + message = $"{userLinkTemplate()} unlocked the {activity.Achievement.Name} medal!"; + break; case RecentActivityType.BeatmapPlaycount: - return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; + message = $"{beatmapLinkTemplate()} has been played {activity.Count} times!"; + break; case RecentActivityType.BeatmapsetApprove: - return $"{beatmapsetLinkTemplate} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + message = $"{beatmapsetLinkTemplate()} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + break; case RecentActivityType.BeatmapsetDelete: - return $"{beatmapsetLinkTemplate} has been deleted."; + message = $"{beatmapsetLinkTemplate()} has been deleted."; + break; case RecentActivityType.BeatmapsetRevive: - return $"{beatmapsetLinkTemplate} has been revived from eternal slumber by {userLinkTemplate}."; + message = $"{beatmapsetLinkTemplate()} has been revived from eternal slumber by {userLinkTemplate()}."; + break; case RecentActivityType.BeatmapsetUpdate: - return $"{userLinkTemplate} has updated the beatmap {beatmapsetLinkTemplate}!"; + message = $"{userLinkTemplate()} has updated the beatmap {beatmapsetLinkTemplate()}!"; + break; case RecentActivityType.BeatmapsetUpload: - return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; + message = $"{userLinkTemplate()} has submitted a new beatmap {beatmapsetLinkTemplate()}!"; + break; case RecentActivityType.Medal: // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) - return string.Empty; + message = string.Empty; + break; case RecentActivityType.Rank: - return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; + message = $"{userLinkTemplate()} achieved rank #{activity.Rank} on {beatmapLinkTemplate()} ({activity.Mode}!)"; + break; case RecentActivityType.RankLost: - return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate} ({activity.Mode}!)"; + message = $"{userLinkTemplate()} has lost first place on {beatmapLinkTemplate()} ({activity.Mode}!)"; + break; case RecentActivityType.UserSupportAgain: - return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; + message = $"{userLinkTemplate()} has once again chosen to support osu! - thanks for your generosity!"; + break; case RecentActivityType.UserSupportFirst: - return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; + message = $"{userLinkTemplate()} has become an osu! supporter - thanks for your generosity!"; + break; case RecentActivityType.UserSupportGift: - return $"{userLinkTemplate} has received the gift of osu! supporter!"; + message = $"{userLinkTemplate()} has received the gift of osu! supporter!"; + break; case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}!"; + message = $"{activity.User?.PreviousUsername} has changed their username to {userLinkTemplate()}!"; + break; default: - return string.Empty; + message = string.Empty; + break; } + + return MessageFormatter.FormatText(message); } } } From 148551afa2874088f34319a20c0ed967d377a526 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 14:12:37 +0900 Subject: [PATCH 31/48] osu!-side changes in-line with framework layout changes --- osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs | 2 +- osu.Game/Screens/Menu/FlowContainerWithOrigin.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index 9f028490ef..5e92eead46 100644 --- a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs @@ -12,6 +12,6 @@ namespace osu.Game.Graphics.Containers { protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); + public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); } } diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index 29ae35fca4..e61c309931 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Menu protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); + public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); public override Anchor Origin => Anchor.Custom; From 27e0ed4ea8fb6299ddc8b8c54949fbd9bbf6dccc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 14:16:17 +0900 Subject: [PATCH 32/48] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 71900dc350..adf1e9548d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 71900dc350bcebbb60d912d4023a1d2a6bbbc3c1 +Subproject commit adf1e9548d1fff8717c87eedb358a3c2517358a8 From 78d73d4c11c40772221a75a9dd859a5e92aec1b9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 17:20:58 +0900 Subject: [PATCH 33/48] Additional fixes for flow ordering after framework changes --- .../ReverseChildIDFillFlowContainer.cs | 4 --- .../Graphics/UserInterface/OsuTabControl.cs | 14 +++++++++ osu.Game/Overlays/Chat/ChatTabControl.cs | 4 +-- osu.Game/Overlays/Music/PlaylistList.cs | 20 +++++-------- osu.Game/Overlays/NotificationOverlay.cs | 5 ++-- .../Notifications/NotificationSection.cs | 7 +++-- .../Sections/Ranks/DrawableProfileScore.cs | 10 ++++--- osu.Game/Overlays/Settings/SettingsItem.cs | 3 +- .../Screens/Menu/FlowContainerWithOrigin.cs | 4 --- osu.Game/Screens/Select/Footer.cs | 30 +++++++++++-------- .../Select/Options/BeatmapOptionsOverlay.cs | 7 +++-- 11 files changed, 63 insertions(+), 45 deletions(-) diff --git a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index 5e92eead46..5803c8a5db 100644 --- a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs @@ -1,8 +1,6 @@ // 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; @@ -11,7 +9,5 @@ namespace osu.Game.Graphics.Containers public class ReverseChildIDFillFlowContainer : FillFlowContainer where T : Drawable { protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - - public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); } } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 7ad9bc73a8..20385a7dae 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -56,6 +57,14 @@ namespace osu.Game.Graphics.UserInterface } } + protected override TabFillFlowContainer CreateTabFlow() => new OsuTabFillFlowContainer + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.Both, + Depth = -1, + Masking = true + }; + public class OsuTabItem : TabItem, IHasAccentColour { protected readonly SpriteText Text; @@ -239,5 +248,10 @@ namespace osu.Game.Graphics.UserInterface } } } + + private class OsuTabFillFlowContainer : TabFillFlowContainer + { + protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); + } } } diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index f028590bb4..1d3dab249d 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -53,9 +53,9 @@ namespace osu.Game.Overlays.Chat protected override void AddTabItem(TabItem item, bool addToDropdown = true) { - if (selectorTab.Depth < float.MaxValue) + if (item != selectorTab && TabContainer.GetLayoutPosition(selectorTab) < float.MaxValue) // performTabSort might've made selectorTab's position wonky, fix it - TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); + TabContainer.SetLayoutPosition(selectorTab, float.MaxValue); base.AddTabItem(item, addToDropdown); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 31b7d0f9aa..03ce7fd88f 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -101,11 +101,10 @@ namespace osu.Game.Overlays.Music public void AddBeatmapSet(BeatmapSetInfo beatmapSet) { - items.Add(new PlaylistItem(beatmapSet) - { - OnSelect = set => OnSelect?.Invoke(set), - Depth = items.Count - }); + var newItem = new PlaylistItem(beatmapSet) { OnSelect = set => OnSelect?.Invoke(set) }; + + items.Add(newItem); + items.SetLayoutPosition(newItem, items.Count); } public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) @@ -197,7 +196,7 @@ namespace osu.Game.Overlays.Music { var itemsPos = items.ToLocalSpace(nativeDragPosition); - int srcIndex = (int)draggedItem.Depth; + int srcIndex = (int)items.GetLayoutPosition(draggedItem); // Find the last item with position < mouse position. Note we can't directly use // the item positions as they are being transformed @@ -219,15 +218,15 @@ namespace osu.Game.Overlays.Music if (srcIndex < dstIndex) { for (int i = srcIndex + 1; i <= dstIndex; i++) - items.ChangeChildDepth(items[i], i - 1); + items.SetLayoutPosition(items[i], i - 1); } else { for (int i = dstIndex; i < srcIndex; i++) - items.ChangeChildDepth(items[i], i + 1); + items.SetLayoutPosition(items[i], i + 1); } - items.ChangeChildDepth(draggedItem, dstIndex); + items.SetLayoutPosition(draggedItem, dstIndex); } private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren @@ -243,9 +242,6 @@ namespace osu.Game.Overlays.Music } } - // Compare with reversed ChildID and Depth - protected override int Compare(Drawable x, Drawable y) => base.Compare(y, x); - public IEnumerable FilterableChildren => Children; public ItemSearchContainer() diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 2f46bb4a71..48ad507d88 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -129,7 +129,6 @@ namespace osu.Game.Overlays public void Post(Notification notification) => postScheduler.Add(() => { ++runningDepth; - notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; notification.Closed += notificationClosed; @@ -138,7 +137,9 @@ namespace osu.Game.Overlays hasCompletionTarget.CompletionTarget = Post; var ourType = notification.GetType(); - sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); + + var section = sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType))); + section?.Add(notification, notification.DisplayOnTop ? -runningDepth : runningDepth); updateCounts(); }); diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index 13a69fbe3a..533f5326e3 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -25,10 +25,13 @@ namespace osu.Game.Overlays.Notifications private FlowContainer notifications; public int DisplayedCount => notifications.Count(n => !n.WasClosed); - public int UnreadCount => notifications.Count(n => !n.WasClosed && !n.Read); - public void Add(Notification notification) => notifications.Add(notification); + public void Add(Notification notification, float position) + { + notifications.Add(notification); + notifications.SetLayoutPosition(notification, position); + } public IEnumerable AcceptTypes; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 51b202844a..bb1a409f2e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -40,16 +40,18 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader(true)] private void load(OsuColour colour) { - RightFlowContainer.Add(new OsuSpriteText + var text = new OsuSpriteText { Text = $"accuracy: {Score.Accuracy:P2}", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, TextSize = 11, - Font = "Exo2.0-RegularItalic", - Depth = -1, - }); + Font = "Exo2.0-RegularItalic" + }; + + RightFlowContainer.Add(text); + RightFlowContainer.SetLayoutPosition(text, 1); LeftFlowContainer.Add(new BeatmapMetadataContainer(Score.Beatmap)); LeftFlowContainer.Add(new OsuSpriteText diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 5afc415d83..cc290fe1bb 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -45,7 +45,8 @@ namespace osu.Game.Overlays.Settings if (text == null) { // construct lazily for cases where the label is not needed (may be provided by the Control). - Add(text = new OsuSpriteText { Depth = 1 }); + Add(text = new OsuSpriteText()); + FlowContent.SetLayoutPosition(text, -1); } text.Text = value; diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index e61c309931..ae1e995373 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -4,8 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; -using System.Collections.Generic; -using System.Linq; namespace osu.Game.Screens.Menu { @@ -22,8 +20,6 @@ namespace osu.Game.Screens.Menu protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); - public override Anchor Origin => Anchor.Custom; public override Vector2 OriginPosition diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 21e6108489..be83d7b500 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -41,19 +41,25 @@ namespace osu.Game.Screens.Select /// Higher depth to be put on the left, and lower to be put on the right. /// Notice this is different to ! /// - public void AddButton(string text, Color4 colour, Action action, Key? hotkey = null, float depth = 0) => buttons.Add(new FooterButton + public void AddButton(string text, Color4 colour, Action action, Key? hotkey = null, float depth = 0) { - Text = text, - Height = play_song_select_button_height, - Width = play_song_select_button_width, - Depth = depth, - SelectedColour = colour, - DeselectedColour = colour.Opacity(0.5f), - Hotkey = hotkey, - Hovered = updateModeLight, - HoverLost = updateModeLight, - Action = action, - }); + var button = new FooterButton + { + Text = text, + Height = play_song_select_button_height, + Width = play_song_select_button_width, + Depth = depth, + SelectedColour = colour, + DeselectedColour = colour.Opacity(0.5f), + Hotkey = hotkey, + Hovered = updateModeLight, + HoverLost = updateModeLight, + Action = action, + }; + + buttons.Add(button); + buttons.SetLayoutPosition(button, -depth); + } private readonly List overlays = new List(); diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index 2e8b2f9014..dee1ec4511 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select.Options /// public void AddButton(string firstLine, string secondLine, FontAwesome icon, Color4 colour, Action action, Key? hotkey = null, float depth = 0) { - buttonsContainer.Add(new BeatmapOptionsButton + var button = new BeatmapOptionsButton { FirstLineText = firstLine, SecondLineText = secondLine, @@ -108,7 +108,10 @@ namespace osu.Game.Screens.Select.Options action?.Invoke(); }, HotKey = hotkey - }); + }; + + buttonsContainer.Add(button); + buttonsContainer.SetLayoutPosition(button, depth); } } } From 07bf8549ebffabfd40fdce3f3db3a756e90a4037 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:29:22 +0900 Subject: [PATCH 34/48] Fix arbitrary API request errors getting identified as timeouts --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 90f3999ddd..1325179e0d 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -199,7 +199,7 @@ namespace osu.Game.Online.API } catch (WebException we) { - HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? HttpStatusCode.RequestTimeout; + HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout); switch (statusCode) { From e82cadc811de0413e6b566b2a6b8762c26f5ab55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:29:58 +0900 Subject: [PATCH 35/48] Make LegacyID nullable The -1 default was getting stored to the database. --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index d49e9c7c26..4dbe65b3ce 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Catch public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap); - public override int LegacyID => 2; + public override int? LegacyID => 2; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame(); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 3ad498e6ea..16b6888f2b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Mania public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap); - public override int LegacyID => 3; + public override int? LegacyID => 3; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame(); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 3f0aea5cb2..d407835a96 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Osu public override SettingsSubsection CreateSettings() => new OsuSettings(); - public override int LegacyID => 0; + public override int? LegacyID => 0; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new OsuReplayFrame(); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 713506e831..0a9719f27b 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap); - public override int LegacyID => 1; + public override int? LegacyID => 1; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f9b64995f9..cba849a491 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets /// /// Do not override this unless you are a legacy mode. /// - public virtual int LegacyID => -1; + public virtual int? LegacyID => null; /// /// A unique short name to reference this ruleset in online requests. From 7cf1d4450ac671f7c6a44e1d08b4c14ce7e0dbc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:33:42 +0900 Subject: [PATCH 36/48] SliderTick transform improvements --- .../Objects/Drawables/DrawableSliderTick.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index baa9eac1a3..c2d13e4e08 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables BorderThickness = 2; BorderColour = Color4.White; + Alpha = 0; + Children = new Drawable[] { new Box @@ -50,10 +52,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - this.Animate( - d => d.FadeIn(ANIM_DURATION), - d => d.ScaleTo(0.5f).ScaleTo(1f, ANIM_DURATION * 4, Easing.OutElasticHalf) - ); + this.FadeOut().FadeIn(ANIM_DURATION); + this.ScaleTo(0.5f).ScaleTo(1f, ANIM_DURATION * 4, Easing.OutElasticHalf); } protected override void UpdateCurrentState(ArmedState state) @@ -64,12 +64,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables this.Delay(HitObject.TimePreempt).FadeOut(); break; case ArmedState.Miss: - this.FadeOut(ANIM_DURATION) - .FadeColour(Color4.Red, ANIM_DURATION / 2); + this.FadeOut(ANIM_DURATION); + this.FadeColour(Color4.Red, ANIM_DURATION / 2); break; case ArmedState.Hit: - this.FadeOut(ANIM_DURATION, Easing.OutQuint) - .ScaleTo(Scale * 1.5f, ANIM_DURATION, Easing.Out); + this.FadeOut(ANIM_DURATION, Easing.OutQuint); + this.ScaleTo(Scale * 1.5f, ANIM_DURATION, Easing.Out); break; } } From 4dfd3a61ccd8b0fb6871d29ef1f1269bd47f9a2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 18:40:39 +0900 Subject: [PATCH 37/48] Remove alpha setting --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index c2d13e4e08..058e3606f4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -31,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables BorderThickness = 2; BorderColour = Color4.White; - Alpha = 0; - Children = new Drawable[] { new Box From 08c469a8b3494446ea5d4d9e7294164a86cfc9f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 13:22:08 +0900 Subject: [PATCH 38/48] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index adf1e9548d..6372fb22c1 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit adf1e9548d1fff8717c87eedb358a3c2517358a8 +Subproject commit 6372fb22c1c85f600921a139849b8dedf71026d5 From e2f9e237e8dc8e73174f62cf7fc35744041c86e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:07:04 +0900 Subject: [PATCH 39/48] Use GradientHorizontal helper function --- osu.Game/Overlays/VolumeOverlay.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index f764a83c7a..17a4b139b0 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -43,13 +43,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Y, Width = 300, - Colour = new ColourInfo - { - TopLeft = Color4.Black.Opacity(0.75f), - BottomLeft = Color4.Black.Opacity(0.75f), - TopRight = Color4.Black.Opacity(0), - BottomRight = Color4.Black.Opacity(0), - } + Colour = ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.75f), Color4.Black.Opacity(0)) }, new FillFlowContainer { From fac4cd6a32b63463163c6a91bd5490bf6149c525 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:19:31 +0900 Subject: [PATCH 40/48] Move to overlayContent --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a6f650d23d..e2bc240e8c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -232,7 +232,7 @@ namespace osu.Game }, }, overlayContent.Add); - loadComponentSingleFile(volume = new VolumeOverlay(), Add); + loadComponentSingleFile(volume = new VolumeOverlay(), overlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); //overlay elements From 51a9dd038ee5c09b429706e71710c85bfb0e3b71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:38:41 +0900 Subject: [PATCH 41/48] Add default bindable values --- osu.Game/Overlays/Volume/VolumeMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 984ade9de0..c840eb790d 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Volume public class VolumeMeter : Container, IKeyBindingHandler { private CircularProgress volumeCircle; - public BindableDouble Bindable { get; } = new BindableDouble(); + public BindableDouble Bindable { get; } = new BindableDouble { MinValue = 0, MaxValue = 1 }; private readonly float circleSize; private readonly Color4 meterColour; private readonly string name; From 05a13d4d393e10cdd87e06ebb9ef7c89cf8b7de8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:50:50 +0900 Subject: [PATCH 42/48] Improve the way bindings are done --- osu.Game/Overlays/Volume/VolumeMeter.cs | 46 +++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index c840eb790d..99ac4d3a79 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -3,7 +3,6 @@ using System; using System.Globalization; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -14,7 +13,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; -using osu.Framework.MathUtils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -31,6 +29,9 @@ namespace osu.Game.Overlays.Volume private readonly Color4 meterColour; private readonly string name; + private OsuSpriteText text; + private BufferedContainer maxGlow; + public VolumeMeter(string name, float circleSize, Color4 meterColour) { this.circleSize = circleSize; @@ -69,9 +70,7 @@ namespace osu.Game.Overlays.Volume } }); - OsuSpriteText text; CircularProgress bgProgress; - BufferedContainer maxGlow; Add(new CircularContainer { @@ -122,33 +121,36 @@ namespace osu.Game.Overlays.Volume } }); - Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); - volumeCircle.Current.ValueChanged += newVolume => //by using this event we sync the meter with the text. newValue has to be divided by 0.75 to give the actual percentage + Bindable.ValueChanged += newVolume => { this.TransformTo("DisplayVolume", newVolume, 400, Easing.OutQuint); }; + + bgProgress.Current.Value = 0.75f; + } + + private double displayVolume; + + /// + /// This is needed because doesn't support + /// + protected double DisplayVolume + { + get => displayVolume; + set { - if (Precision.DefinitelyBigger(newVolume, 0.74)) + displayVolume = value; + + if (displayVolume > 0.99f) { text.Text = "MAX"; maxGlow.EffectColour = meterColour.Opacity(2f); } else { - if (text.Text == "MAX") - maxGlow.EffectColour = Color4.Transparent; - text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); + maxGlow.EffectColour = Color4.Transparent; + text.Text = Math.Round(displayVolume * 100).ToString(CultureInfo.CurrentCulture); } - }; - bgProgress.Current.Value = 0.75f; - } - - /// - /// This is needed because doesn't support - /// - [UsedImplicitly] - private double circleBindable - { - get => volumeCircle.Current; - set => volumeCircle.Current.Value = value; + volumeCircle.Current.Value = displayVolume * 0.75f; + } } public double Volume From 96ea42d3ba8353c2b812108ce610e2322fe5298a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:51:34 +0900 Subject: [PATCH 43/48] Ensure initial value is set even if that value is zero --- osu.Game/Overlays/Volume/VolumeMeter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 99ac4d3a79..b9bd39163a 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -122,10 +122,15 @@ namespace osu.Game.Overlays.Volume }); Bindable.ValueChanged += newVolume => { this.TransformTo("DisplayVolume", newVolume, 400, Easing.OutQuint); }; - bgProgress.Current.Value = 0.75f; } + protected override void LoadComplete() + { + base.LoadComplete(); + Bindable.TriggerChange(); + } + private double displayVolume; /// From 4094ffbddd141ced057da4a9283931ac37ecf271 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:54:15 +0900 Subject: [PATCH 44/48] Remove unnecessary comment --- osu.Game/Overlays/Volume/VolumeMeter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index b9bd39163a..056ba6aa8d 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -133,9 +133,6 @@ namespace osu.Game.Overlays.Volume private double displayVolume; - /// - /// This is needed because doesn't support - /// protected double DisplayVolume { get => displayVolume; From a71e5ce19c1f42eb2d0dc18e40d925644dad63d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:54:54 +0900 Subject: [PATCH 45/48] Tidy up --- osu.Game/Overlays/Volume/VolumeMeter.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 056ba6aa8d..64b9e513c4 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Game.Graphics; @@ -161,15 +160,9 @@ namespace osu.Game.Overlays.Volume private set => Bindable.Value = value; } - public void Increase() - { - Volume += 0.05f; - } + public void Increase() => Volume += 0.05f; - public void Decrease() - { - Volume -= 0.05f; - } + public void Decrease() => Volume -= 0.05f; public bool OnPressed(GlobalAction action) { From 3731cbe5eba7c729209d10bf38e272b51a9769bc Mon Sep 17 00:00:00 2001 From: pdrapoport Date: Wed, 7 Mar 2018 14:20:59 +0100 Subject: [PATCH 46/48] Removing "mouse wheel disabled" checkbox from visual settings gameplay menu --- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 1a7b80ec9a..6c4d929c71 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -15,7 +15,6 @@ namespace osu.Game.Screens.Play.PlayerSettings private readonly PlayerSliderBar dimSliderBar; private readonly PlayerSliderBar blurSliderBar; private readonly PlayerCheckbox showStoryboardToggle; - private readonly PlayerCheckbox mouseWheelDisabledToggle; public VisualSettings() { @@ -35,8 +34,7 @@ namespace osu.Game.Screens.Play.PlayerSettings { Text = "Toggles:" }, - showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboards" }, - mouseWheelDisabledToggle = new PlayerCheckbox { LabelText = "Disable mouse wheel" } + showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboards" } }; } @@ -46,7 +44,6 @@ namespace osu.Game.Screens.Play.PlayerSettings dimSliderBar.Bindable = config.GetBindable(OsuSetting.DimLevel); blurSliderBar.Bindable = config.GetBindable(OsuSetting.BlurLevel); showStoryboardToggle.Bindable = config.GetBindable(OsuSetting.ShowStoryboard); - mouseWheelDisabledToggle.Bindable = config.GetBindable(OsuSetting.MouseDisableWheel); } } } From 983cefbe40b651961a9566a4fc22a651e611e6fa Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 7 Mar 2018 17:33:21 +0530 Subject: [PATCH 47/48] Add VisualTest. --- .../TestCaseUserProfileRecentSection.cs | 162 ++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + .../Profile/Sections/Recent/MedalIcon.cs | 2 +- .../PaginatedRecentActivityContainer.cs | 2 +- 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs new file mode 100644 index 0000000000..23eb7f68f9 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -0,0 +1,162 @@ +// 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.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Recent; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseUserProfileRecentSection : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RecentSection), + typeof(DrawableRecentActivity), + typeof(PaginatedRecentActivityContainer), + typeof(MedalIcon) + }; + + public TestCaseUserProfileRecentSection() + { + var flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }; + + flow.AddRange(createDummyActivities().Select(a => new DrawableRecentActivity(a))); + + Add(new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }); + + Add(new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = flow, + }); + } + + private IEnumerable createDummyActivities() + { + var dummyBeatmap = new RecentActivity.RecentActivityBeatmap + { + Title = @"Dummy beatmap", + Url = "/b/1337", + }; + + var dummyUser = new RecentActivity.RecentActivityUser + { + Username = "DummyReborn", + Url = "/u/666", + PreviousUsername = "Dummy", + }; + + return new[] + { + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.Achievement, + Achievement = new RecentActivity.RecentActivityAchievement + { + Name = @"Feelin' It", + Slug = @"all-secret-feelinit", + }, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapPlaycount, + Count = 1337, + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetApprove, + Approval = BeatmapApproval.Qualified, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetDelete, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetRevive, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetRevive, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetUpdate, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetUpload, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "osu!", + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.RankLost, + Mode = "osu!", + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UsernameChange, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportAgain, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportFirst, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportGift, + }, + }; + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8cbeb6aab6..1cfa7bc111 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -173,6 +173,7 @@ + diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index 9ef2b89269..6ffbe7193f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays.Profile.Sections.Recent { - internal class MedalIcon : Container + public class MedalIcon : Container { private readonly string slug; private readonly Sprite sprite; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 3de005cf9b..d479627cde 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -9,7 +9,7 @@ using System.Linq; namespace osu.Game.Overlays.Profile.Sections.Recent { - internal class PaginatedRecentActivityContainer : PaginatedContainer + public class PaginatedRecentActivityContainer : PaginatedContainer { public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) From e55a503f79735df4abd83d867fb5db21db18fccb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Mar 2018 00:58:16 +0900 Subject: [PATCH 48/48] Tidy up test case --- .../TestCaseUserProfileRecentSection.cs | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs index 23eb7f68f9..1f7a7e7165 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -28,26 +28,25 @@ namespace osu.Game.Tests.Visual public TestCaseUserProfileRecentSection() { - var flow = new FillFlowContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + ChildrenEnumerable = createDummyActivities().Select(a => new DrawableRecentActivity(a)) + }, + } }; - - flow.AddRange(createDummyActivities().Select(a => new DrawableRecentActivity(a))); - - Add(new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.2f) - }); - - Add(new ScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = flow, - }); } private IEnumerable createDummyActivities()