From 11dad7bf746820b56fa426f63f8582062de52a6d Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 10 Oct 2018 16:46:02 +0200 Subject: [PATCH 001/628] filter beatmaps by star range --- .../Visual/TestCaseBeatmapCarousel.cs | 49 +++++++++++++++++++ .../Select/Carousel/CarouselBeatmap.cs | 6 +++ osu.Game/Screens/Select/FilterControl.cs | 40 +++++++++------ osu.Game/Screens/Select/FilterCriteria.cs | 2 + 4 files changed, 81 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index db66c01814..df42ba9d16 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -77,6 +77,7 @@ namespace osu.Game.Tests.Visual testEmptyTraversal(); testHiding(); testSelectingFilteredRuleset(); + testFilterByStarRange(); testCarouselRootIsRandom(); } @@ -245,6 +246,54 @@ namespace osu.Game.Tests.Visual AddAssert("Selection is non-null", () => currentSelection != null); } + /// + /// Test filtering by restricting the desired star range + /// + private void testFilterByStarRange() + { + var manyStarDiffs = createTestBeatmapSet(set_count + 1); + manyStarDiffs.Beatmaps.Clear(); + + for (int i = 0; i < 12; i++) + { + manyStarDiffs.Beatmaps.Add(new BeatmapInfo + { + OnlineBeatmapID = manyStarDiffs.ID * 10 + i, + Path = $"randomDiff{i}.osu", + Version = $"Totally Normal {i}", + StarDifficulty = i, + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 5, + } + }); + } + + AddStep("add set with many stars", () => carousel.UpdateBeatmapSet(manyStarDiffs)); + + AddStep("select added set", () => carousel.SelectBeatmap(manyStarDiffs.Beatmaps[0], false)); + + AddStep("Filter to 1-3 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 1, DisplayStarsMaximum = 3 }, false)); + checkVisibleItemCount(diff: false, count: 1); + checkVisibleItemCount(diff: true, count: 3); + + AddStep("Filter to 3-3 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 3, DisplayStarsMaximum = 3 }, false)); + checkVisibleItemCount(diff: false, count: 1); + checkVisibleItemCount(diff: true, count: 1); + + AddStep("Filter to 4-2 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 4, DisplayStarsMaximum = 2 }, false)); + checkVisibleItemCount(diff: false, count: 0); + checkVisibleItemCount(diff: true, count: 0); + + AddStep("remove added set", () => + { + carousel.RemoveBeatmapSet(manyStarDiffs); + manyStarDiffs = null; + }); + + AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); + } + /// /// Test random non-repeating algorithm /// diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 272332f1ce..c9ed2f3573 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -26,6 +26,12 @@ namespace osu.Game.Screens.Select.Carousel bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps; + if(criteria.DisplayStarsMinimum.HasValue) + match &= Beatmap.StarDifficulty >= criteria.DisplayStarsMinimum; + + if (criteria.DisplayStarsMaximum.HasValue) + match &= Beatmap.StarDifficulty <= criteria.DisplayStarsMaximum; + if (!string.IsNullOrEmpty(criteria.SearchText)) match &= Beatmap.Metadata.SearchableTerms.Any(term => term.IndexOf(criteria.SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) || diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index fce7af1400..78b452b6f5 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -32,14 +32,13 @@ namespace osu.Game.Screens.Select public SortMode Sort { - get { return sort; } + get => sort; set { - if (sort != value) - { - sort = value; - FilterChanged?.Invoke(CreateCriteria()); - } + if (sort == value) return; + + sort = value; + FilterChanged?.Invoke(CreateCriteria()); } } @@ -47,14 +46,13 @@ namespace osu.Game.Screens.Select public GroupMode Group { - get { return group; } + get => group; set { - if (group != value) - { - group = value; - FilterChanged?.Invoke(CreateCriteria()); - } + if (group == value) return; + + group = value; + FilterChanged?.Invoke(CreateCriteria()); } } @@ -64,7 +62,9 @@ namespace osu.Game.Screens.Select Sort = sort, SearchText = searchTextBox.Text, AllowConvertedBeatmaps = showConverted, - Ruleset = ruleset.Value + Ruleset = ruleset.Value, + DisplayStarsMinimum = minimumStars, + DisplayStarsMaximum = maximumStars, }; public Action Exit; @@ -168,7 +168,9 @@ namespace osu.Game.Screens.Select private readonly IBindable ruleset = new Bindable(); - private Bindable showConverted; + private readonly Bindable showConverted = new Bindable(); + private readonly Bindable minimumStars = new Bindable(); + private readonly Bindable maximumStars = new Bindable(); public readonly Box Background; @@ -177,8 +179,14 @@ namespace osu.Game.Screens.Select { sortTabs.AccentColour = colours.GreenLight; - showConverted = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); - showConverted.ValueChanged += val => updateCriteria(); + config.BindWith(OsuSetting.ShowConvertedBeatmaps, showConverted); + showConverted.ValueChanged += _ => updateCriteria(); + + config.BindWith(OsuSetting.DisplayStarsMinimum, minimumStars); + minimumStars.ValueChanged += _ => updateCriteria(); + + config.BindWith(OsuSetting.DisplayStarsMaximum, maximumStars); + maximumStars.ValueChanged += _ => updateCriteria(); ruleset.BindTo(parentRuleset); ruleset.BindValueChanged(_ => updateCriteria(), true); diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index bea806f00f..f97eb1bea1 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -13,5 +13,7 @@ namespace osu.Game.Screens.Select public string SearchText; public RulesetInfo Ruleset; public bool AllowConvertedBeatmaps; + public double? DisplayStarsMinimum; + public double? DisplayStarsMaximum; } } From d83ce7e4bb35b352f112d1353c4766b4006281be Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 19 Oct 2018 12:22:05 +0200 Subject: [PATCH 002/628] don't allow null values in FilterCriteria, ensure values in test instead --- .../Visual/TestCaseBeatmapCarousel.cs | 51 +++++++++++-------- .../Select/Carousel/CarouselBeatmap.cs | 7 +-- osu.Game/Screens/Select/FilterCriteria.cs | 4 +- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index df42ba9d16..a57ef21dd9 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -65,6 +65,10 @@ namespace osu.Game.Tests.Visual carousel.SelectionChanged = s => currentSelection = s; + // not being hooked up to the config leads to the SR filter only showing 0 to 0 SR maps + // thus "filter" once to assume a 0 to 10 range + carousel.Filter(new TestCriteria()); + loadBeatmaps(beatmapSets); testTraversal(); @@ -150,9 +154,7 @@ namespace osu.Game.Tests.Visual private bool selectedBeatmapVisible() { var currentlySelected = carousel.Items.FirstOrDefault(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected); - if (currentlySelected == null) - return true; - return currentlySelected.Item.Visible; + return currentlySelected?.Item.Visible ?? true; } private void checkInvisibleDifficultiesUnselectable() @@ -165,8 +167,8 @@ namespace osu.Game.Tests.Visual { AddStep("Toggle non-matching filter", () => { - carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false); - carousel.Filter(new FilterCriteria(), false); + carousel.Filter(new TestCriteria { SearchText = "Dingo" }, false); + carousel.Filter(new TestCriteria(), false); eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID); } ); @@ -207,7 +209,7 @@ namespace osu.Game.Tests.Visual setSelected(1, 1); - AddStep("Filter", () => carousel.Filter(new FilterCriteria { SearchText = "set #3!" }, false)); + AddStep("Filter", () => carousel.Filter(new TestCriteria { SearchText = "set #3!" }, false)); checkVisibleItemCount(diff: false, count: 1); checkVisibleItemCount(diff: true, count: 3); checkSelected(3, 1); @@ -215,7 +217,7 @@ namespace osu.Game.Tests.Visual advanceSelection(diff: true, count: 4); checkSelected(3, 2); - AddStep("Un-filter (debounce)", () => carousel.Filter(new FilterCriteria())); + AddStep("Un-filter (debounce)", () => carousel.Filter(new TestCriteria())); AddUntilStep(() => !carousel.PendingFilterTask, "Wait for debounce"); checkVisibleItemCount(diff: false, count: set_count); checkVisibleItemCount(diff: true, count: 3); @@ -223,13 +225,13 @@ namespace osu.Game.Tests.Visual // test filtering some difficulties (and keeping current beatmap set selected). setSelected(1, 2); - AddStep("Filter some difficulties", () => carousel.Filter(new FilterCriteria { SearchText = "Normal" }, false)); + AddStep("Filter some difficulties", () => carousel.Filter(new TestCriteria { SearchText = "Normal" }, false)); checkSelected(1, 1); - AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); + AddStep("Un-filter", () => carousel.Filter(new TestCriteria(), false)); checkSelected(1, 1); - AddStep("Filter all", () => carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false)); + AddStep("Filter all", () => carousel.Filter(new TestCriteria { SearchText = "Dingo" }, false)); checkVisibleItemCount(false, 0); checkVisibleItemCount(true, 0); @@ -241,7 +243,7 @@ namespace osu.Game.Tests.Visual advanceSelection(false); AddAssert("Selection is null", () => currentSelection == null); - AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); + AddStep("Un-filter", () => carousel.Filter(new TestCriteria(), false)); AddAssert("Selection is non-null", () => currentSelection != null); } @@ -273,15 +275,15 @@ namespace osu.Game.Tests.Visual AddStep("select added set", () => carousel.SelectBeatmap(manyStarDiffs.Beatmaps[0], false)); - AddStep("Filter to 1-3 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 1, DisplayStarsMaximum = 3 }, false)); + AddStep("Filter to 1-3 stars", () => carousel.Filter(new TestCriteria { DisplayStarsMinimum = 1, DisplayStarsMaximum = 3 }, false)); checkVisibleItemCount(diff: false, count: 1); checkVisibleItemCount(diff: true, count: 3); - AddStep("Filter to 3-3 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 3, DisplayStarsMaximum = 3 }, false)); + AddStep("Filter to 3-3 stars", () => carousel.Filter(new TestCriteria { DisplayStarsMinimum = 3, DisplayStarsMaximum = 3 }, false)); checkVisibleItemCount(diff: false, count: 1); checkVisibleItemCount(diff: true, count: 1); - AddStep("Filter to 4-2 stars", () => carousel.Filter(new FilterCriteria { DisplayStarsMinimum = 4, DisplayStarsMaximum = 2 }, false)); + AddStep("Filter to 4-2 stars", () => carousel.Filter(new TestCriteria { DisplayStarsMinimum = 4, DisplayStarsMaximum = 2 }, false)); checkVisibleItemCount(diff: false, count: 0); checkVisibleItemCount(diff: true, count: 0); @@ -291,7 +293,7 @@ namespace osu.Game.Tests.Visual manyStarDiffs = null; }); - AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); + AddStep("Un-filter", () => carousel.Filter(new TestCriteria(), false)); } /// @@ -322,13 +324,13 @@ namespace osu.Game.Tests.Visual AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet)); AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(createTestBeatmapSetWithManyDifficulties(set_count + 1))); - AddStep("Filter Extra", () => carousel.Filter(new FilterCriteria { SearchText = "Extra 10" }, false)); + AddStep("Filter Extra", () => carousel.Filter(new TestCriteria { SearchText = "Extra 10" }, false)); checkInvisibleDifficultiesUnselectable(); checkInvisibleDifficultiesUnselectable(); checkInvisibleDifficultiesUnselectable(); checkInvisibleDifficultiesUnselectable(); checkInvisibleDifficultiesUnselectable(); - AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); + AddStep("Un-filter", () => carousel.Filter(new TestCriteria(), false)); } /// @@ -359,9 +361,9 @@ namespace osu.Game.Tests.Visual /// private void testSorting() { - AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false)); + AddStep("Sort by author", () => carousel.Filter(new TestCriteria { Sort = SortMode.Author }, false)); AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.AuthorString == "zzzzz"); - AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); + AddStep("Sort by artist", () => carousel.Filter(new TestCriteria { Sort = SortMode.Artist }, false)); AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!")); } @@ -451,7 +453,7 @@ namespace osu.Game.Tests.Visual carousel.UpdateBeatmapSet(testMixed); }); AddStep("filter to ruleset 0", () => - carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false)); + carousel.Filter(new TestCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false)); AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false)); AddAssert("unfiltered beatmap selected", () => carousel.SelectedBeatmap.Equals(testMixed.Beatmaps[0])); @@ -581,5 +583,14 @@ namespace osu.Game.Tests.Visual public bool PendingFilterTask => PendingFilter != null; } + + private class TestCriteria : FilterCriteria + { + public TestCriteria() + { + DisplayStarsMinimum = 0; + DisplayStarsMaximum = 10; + } + } } } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index c9ed2f3573..2e1adaf66f 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -25,12 +25,7 @@ namespace osu.Game.Screens.Select.Carousel base.Filter(criteria); bool match = criteria.Ruleset == null || Beatmap.RulesetID == criteria.Ruleset.ID || Beatmap.RulesetID == 0 && criteria.Ruleset.ID > 0 && criteria.AllowConvertedBeatmaps; - - if(criteria.DisplayStarsMinimum.HasValue) - match &= Beatmap.StarDifficulty >= criteria.DisplayStarsMinimum; - - if (criteria.DisplayStarsMaximum.HasValue) - match &= Beatmap.StarDifficulty <= criteria.DisplayStarsMaximum; + match &= Beatmap.StarDifficulty >= criteria.DisplayStarsMinimum && Beatmap.StarDifficulty <= criteria.DisplayStarsMaximum; if (!string.IsNullOrEmpty(criteria.SearchText)) match &= diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index f97eb1bea1..bd8bb22e1c 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Select public string SearchText; public RulesetInfo Ruleset; public bool AllowConvertedBeatmaps; - public double? DisplayStarsMinimum; - public double? DisplayStarsMaximum; + public double DisplayStarsMinimum; + public double DisplayStarsMaximum; } } From 608223cbb408d33b27c45c8183c13c0d49172c4f Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 4 Jul 2019 11:59:38 +0200 Subject: [PATCH 003/628] Add setting to collapse the song progress graph --- .../Visual/Gameplay/TestSceneSongProgress.cs | 16 +++- osu.Game/Configuration/OsuConfigManager.cs | 2 + .../Sections/Gameplay/GeneralSettings.cs | 5 + osu.Game/Screens/Play/SongProgress.cs | 93 +++++++++++-------- osu.Game/Screens/Play/SongProgressBar.cs | 5 +- 5 files changed, 77 insertions(+), 44 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index af21007efe..eef7a25c7a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; @@ -15,6 +16,11 @@ namespace osu.Game.Tests.Visual.Gameplay [TestFixture] public class TestSceneSongProgress : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(SongProgressBar), + }; + private readonly SongProgress progress; private readonly TestSongProgressGraph graph; @@ -46,24 +52,26 @@ namespace osu.Game.Tests.Visual.Gameplay Origin = Anchor.TopLeft, }); - AddWaitStep("wait some", 5); AddAssert("ensure not created", () => graph.CreationCount == 0); AddStep("display values", displayNewValues); - AddWaitStep("wait some", 5); AddUntilStep("wait for creation count", () => graph.CreationCount == 1); AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); - AddWaitStep("wait some", 5); AddUntilStep("wait for creation count", () => graph.CreationCount == 1); AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); - AddWaitStep("wait some", 5); AddUntilStep("wait for creation count", () => graph.CreationCount == 1); AddRepeatStep("New Values", displayNewValues, 5); AddWaitStep("wait some", 5); AddAssert("ensure debounced", () => graph.CreationCount == 2); + + AddStep("hide graph", () => progress.CollapseGraph.Value = true); + AddStep("show graph", () => progress.CollapseGraph.Value = false); + + AddStep("start", clock.Start); + AddStep("pause", clock.Stop); } private void displayNewValues() diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 795f0b43f7..f3792fcb7f 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -77,6 +77,7 @@ namespace osu.Game.Configuration Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01); Set(OsuSetting.ShowInterface, true); + Set(OsuSetting.CollapseProgressGraph, false); Set(OsuSetting.KeyOverlay, false); Set(OsuSetting.FloatingComments, false); @@ -131,6 +132,7 @@ namespace osu.Game.Configuration KeyOverlay, FloatingComments, ShowInterface, + CollapseProgressGraph, MouseDisableButtons, MouseDisableWheel, AudioOffset, diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 997d1354b3..e365973c4b 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -35,6 +35,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay Bindable = config.GetBindable(OsuSetting.ShowInterface) }, new SettingsCheckbox + { + LabelText = "Collapse song progress graph", + Bindable = config.GetBindable(OsuSetting.CollapseProgressGraph) + }, + new SettingsCheckbox { LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 6642efdf8b..a535dc3333 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -11,6 +11,7 @@ using osu.Framework.Allocation; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Timing; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; @@ -20,7 +21,7 @@ namespace osu.Game.Screens.Play public class SongProgress : OverlayContainer { private const int bottom_bar_height = 5; - + private const float graph_height = SquareGraph.Column.WIDTH * 6; private static readonly Vector2 handle_size = new Vector2(10, 18); private const float transition_duration = 200; @@ -30,13 +31,13 @@ namespace osu.Game.Screens.Play private readonly SongProgressInfo info; public Action RequestSeek; + public readonly Bindable CollapseGraph = new Bindable(); public override bool HandleNonPositionalInput => AllowSeeking; public override bool HandlePositionalInput => AllowSeeking; - private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1; - private double firstHitTime => objects.First().StartTime; + private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1; private IEnumerable objects; @@ -54,25 +55,28 @@ namespace osu.Game.Screens.Play } } + private bool allowSeeking; + + public bool AllowSeeking + { + get => allowSeeking; + set + { + if (allowSeeking == value) return; + + allowSeeking = value; + updateBarVisibility(); + } + } + private readonly BindableBool replayLoaded = new BindableBool(); public IClock ReferenceClock; private IClock gameplayClock; - [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, GameplayClock clock) - { - if (clock != null) - gameplayClock = clock; - - graph.FillColour = bar.FillColour = colours.BlueLighter; - } - public SongProgress() { - const float graph_height = SquareGraph.Column.WIDTH * 6; - Height = bottom_bar_height + graph_height + handle_size.Y; Y = bottom_bar_height; @@ -104,12 +108,23 @@ namespace osu.Game.Screens.Play }; } + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, GameplayClock clock, OsuConfigManager config) + { + if (clock != null) + gameplayClock = clock; + + config.BindWith(OsuSetting.CollapseProgressGraph, CollapseGraph); + + graph.FillColour = bar.FillColour = colours.BlueLighter; + } + protected override void LoadComplete() { Show(); - replayLoaded.ValueChanged += loaded => AllowSeeking = loaded.NewValue; - replayLoaded.TriggerChange(); + replayLoaded.BindValueChanged(loaded => AllowSeeking = loaded.NewValue, true); + CollapseGraph.BindValueChanged(_ => updateGraphVisibility(), true); } public void BindDrawableRuleset(DrawableRuleset drawableRuleset) @@ -117,28 +132,6 @@ namespace osu.Game.Screens.Play replayLoaded.BindTo(drawableRuleset.HasReplayLoaded); } - private bool allowSeeking; - - public bool AllowSeeking - { - get => allowSeeking; - set - { - if (allowSeeking == value) return; - - allowSeeking = value; - updateBarVisibility(); - } - } - - private void updateBarVisibility() - { - bar.FadeTo(allowSeeking ? 1 : 0, transition_duration, Easing.In); - this.MoveTo(new Vector2(0, allowSeeking ? 0 : bottom_bar_height), transition_duration, Easing.In); - - info.Margin = new MarginPadding { Bottom = Height - (allowSeeking ? 0 : handle_size.Y) }; - } - protected override void PopIn() { updateBarVisibility(); @@ -165,5 +158,29 @@ namespace osu.Game.Screens.Play bar.CurrentTime = gameplayTime; graph.Progress = (int)(graph.ColumnCount * progress); } + + private void updateBarVisibility() + { + bar.FadeTo(allowSeeking ? 1 : 0, transition_duration, Easing.In); + this.MoveTo(new Vector2(0, allowSeeking ? 0 : bottom_bar_height), transition_duration, Easing.In); + + updateInfoMargin(); + } + + private void updateGraphVisibility() + { + float barHeight = bottom_bar_height + handle_size.Y; + + bar.ResizeHeightTo(CollapseGraph.Value ? barHeight : barHeight + graph_height, transition_duration, Easing.In); + graph.MoveToY(CollapseGraph.Value ? graph_height : 0, transition_duration, Easing.In); + + updateInfoMargin(); + } + + private void updateInfoMargin() + { + float finalMargin = bottom_bar_height + (allowSeeking ? handle_size.Y : 0) + (CollapseGraph.Value ? 0 : graph_height); + info.TransformTo(nameof(info.Margin), new MarginPadding { Bottom = finalMargin }, transition_duration, Easing.In); + } } } diff --git a/osu.Game/Screens/Play/SongProgressBar.cs b/osu.Game/Screens/Play/SongProgressBar.cs index dd7b5826d5..0a906845fc 100644 --- a/osu.Game/Screens/Play/SongProgressBar.cs +++ b/osu.Game/Screens/Play/SongProgressBar.cs @@ -18,6 +18,7 @@ namespace osu.Game.Screens.Play private readonly Box fill; private readonly Container handleBase; + private readonly Container handleContainer; public Color4 FillColour { @@ -73,7 +74,6 @@ namespace osu.Game.Screens.Play Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Width = 2, - Height = barHeight + handleBarHeight, Colour = Color4.White, Position = new Vector2(2, 0), Children = new Drawable[] @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Play Name = "HandleBar box", RelativeSizeAxes = Axes.Both, }, - new Container + handleContainer = new Container { Name = "Handle container", Origin = Anchor.BottomCentre, @@ -115,6 +115,7 @@ namespace osu.Game.Screens.Play { base.Update(); + handleBase.Height = Height - handleContainer.Height; float newX = (float)Interpolation.Lerp(handleBase.X, NormalizedValue * UsableWidth, MathHelper.Clamp(Time.Elapsed / 40, 0, 1)); fill.Width = newX; From e69160a0ce1f80bee073cc618c7205106ac5a206 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:05:18 +0200 Subject: [PATCH 004/628] fix graph not completely hiding --- osu.Game/Screens/Play/SongProgress.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index a535dc3333..a201b04864 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -172,7 +172,7 @@ namespace osu.Game.Screens.Play float barHeight = bottom_bar_height + handle_size.Y; bar.ResizeHeightTo(CollapseGraph.Value ? barHeight : barHeight + graph_height, transition_duration, Easing.In); - graph.MoveToY(CollapseGraph.Value ? graph_height : 0, transition_duration, Easing.In); + graph.MoveToY(CollapseGraph.Value ? bottom_bar_height + graph_height : 0, transition_duration, Easing.In); updateInfoMargin(); } From c22667bdf79eed3048331c1350526041553761f5 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:05:23 +0200 Subject: [PATCH 005/628] reorganise tests --- .../Visual/Gameplay/TestSceneSongProgress.cs | 128 ++++++++++++------ 1 file changed, 84 insertions(+), 44 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index eef7a25c7a..810659233b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.MathUtils; +using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Play; @@ -21,65 +22,104 @@ namespace osu.Game.Tests.Visual.Gameplay typeof(SongProgressBar), }; - private readonly SongProgress progress; - private readonly TestSongProgressGraph graph; + private SongProgress progress; + private TestSongProgressGraph graph; private readonly StopwatchClock clock; + private readonly FramedClock framedClock; [Cached] private readonly GameplayClock gameplayClock; - private readonly FramedClock framedClock; - public TestSceneSongProgress() { - clock = new StopwatchClock(true); - + clock = new StopwatchClock(); gameplayClock = new GameplayClock(framedClock = new FramedClock(clock)); - - Add(progress = new SongProgress - { - RelativeSizeAxes = Axes.X, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - }); - - Add(graph = new TestSongProgressGraph - { - RelativeSizeAxes = Axes.X, - Height = 200, - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, - }); - - AddAssert("ensure not created", () => graph.CreationCount == 0); - - AddStep("display values", displayNewValues); - AddUntilStep("wait for creation count", () => graph.CreationCount == 1); - - AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); - AddUntilStep("wait for creation count", () => graph.CreationCount == 1); - - AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); - AddUntilStep("wait for creation count", () => graph.CreationCount == 1); - AddRepeatStep("New Values", displayNewValues, 5); - - AddWaitStep("wait some", 5); - AddAssert("ensure debounced", () => graph.CreationCount == 2); - - AddStep("hide graph", () => progress.CollapseGraph.Value = true); - AddStep("show graph", () => progress.CollapseGraph.Value = false); - - AddStep("start", clock.Start); - AddStep("pause", clock.Stop); } - private void displayNewValues() + [SetUpSteps] + public void SetupSteps() { - List objects = new List(); + AddStep("add new song progress", () => + { + if (progress != null) + { + progress.Expire(); + progress = null; + } + + Add(progress = new SongProgress + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }); + }); + + AddStep("add new big graph", () => + { + if (graph != null) + { + graph.Expire(); + graph = null; + } + + Add(graph = new TestSongProgressGraph + { + RelativeSizeAxes = Axes.X, + Height = 200, + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + }); + }); + + AddStep("reset clock", clock.Reset); + } + + [Test] + public void TestGraphRecreation() + { + AddAssert("ensure not created", () => graph.CreationCount == 0); + AddStep("display values", displayRandomValues); + AddUntilStep("wait for creation count", () => graph.CreationCount == 1); + AddRepeatStep("new values", displayRandomValues, 5); + AddWaitStep("wait some", 5); + AddAssert("ensure recreation debounced", () => graph.CreationCount == 2); + } + + [Test] + public void TestDisplay() + { + AddStep("display max values", displayMaxValues); + AddStep("start", clock.Start); + AddStep("show bar", () => progress.AllowSeeking = true); + AddStep("hide graph", () => progress.CollapseGraph.Value = true); + AddStep("hide Bar", () => progress.AllowSeeking = false); + AddStep("show bar", () => progress.AllowSeeking = true); + AddStep("show graph", () => progress.CollapseGraph.Value = false); + AddStep("stop", clock.Stop); + } + + private void displayRandomValues() + { + var objects = new List(); for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000) objects.Add(new HitObject { StartTime = i }); + replaceObjects(objects); + } + + private void displayMaxValues() + { + var objects = new List(); + for (double i = 0; i < 5000; i++) + objects.Add(new HitObject { StartTime = i }); + + replaceObjects(objects); + } + + private void replaceObjects(List objects) + { progress.Objects = objects; graph.Objects = objects; From 1cb7a9617be89f5f01f6b21bc6ce280fdf8e2c95 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:29:57 +0200 Subject: [PATCH 006/628] move songprogress up to be able to see below for masking --- .../Visual/Gameplay/TestSceneSongProgress.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 810659233b..550115846b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -6,9 +6,12 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Framework.Testing; using osu.Framework.Timing; +using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Play; @@ -24,6 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay private SongProgress progress; private TestSongProgressGraph graph; + private readonly Container progressContainer; private readonly StopwatchClock clock; private readonly FramedClock framedClock; @@ -35,6 +39,20 @@ namespace osu.Game.Tests.Visual.Gameplay { clock = new StopwatchClock(); gameplayClock = new GameplayClock(framedClock = new FramedClock(clock)); + + Add(progressContainer = new Container + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Height = 100, + Y = -100, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(1), + } + }); } [SetUpSteps] @@ -48,7 +66,7 @@ namespace osu.Game.Tests.Visual.Gameplay progress = null; } - Add(progress = new SongProgress + progressContainer.Add(progress = new SongProgress { RelativeSizeAxes = Axes.X, Anchor = Anchor.BottomLeft, @@ -91,6 +109,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestDisplay() { AddStep("display max values", displayMaxValues); + AddUntilStep("wait for graph", () => graph.CreationCount == 1); AddStep("start", clock.Start); AddStep("show bar", () => progress.AllowSeeking = true); AddStep("hide graph", () => progress.CollapseGraph.Value = true); From ed22c23f37bf57a9d1de77db3a905a718a5394db Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:30:32 +0200 Subject: [PATCH 007/628] mask SongProgress --- osu.Game/Screens/Play/SongProgress.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index a201b04864..9ebfeb5c82 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -77,8 +77,8 @@ namespace osu.Game.Screens.Play public SongProgress() { - Height = bottom_bar_height + graph_height + handle_size.Y; - Y = bottom_bar_height; + Masking = true; + Height = bottom_bar_height + graph_height + handle_size.Y + OsuFont.Numeric.Size; Children = new Drawable[] { @@ -88,7 +88,6 @@ namespace osu.Game.Screens.Play Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = bottom_bar_height + graph_height }, }, graph = new SongProgressGraph { From b425df6c75afa792aa97165a798d3a884c6a8c04 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:48:40 +0200 Subject: [PATCH 008/628] various fixes - make AllowSeeking a Bindable which fixes incorrect initial position and removes unnecessary variables - make SongProgressInfo fixed height --- .../Visual/Gameplay/TestSceneSongProgress.cs | 6 +-- osu.Game/Screens/Play/SongProgress.cs | 45 ++++++++----------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 550115846b..e16ad42558 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -111,10 +111,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("display max values", displayMaxValues); AddUntilStep("wait for graph", () => graph.CreationCount == 1); AddStep("start", clock.Start); - AddStep("show bar", () => progress.AllowSeeking = true); + AddStep("show bar", () => progress.AllowSeeking.Value = true); AddStep("hide graph", () => progress.CollapseGraph.Value = true); - AddStep("hide Bar", () => progress.AllowSeeking = false); - AddStep("show bar", () => progress.AllowSeeking = true); + AddStep("hide Bar", () => progress.AllowSeeking.Value = false); + AddStep("show bar", () => progress.AllowSeeking.Value = true); AddStep("show graph", () => progress.CollapseGraph.Value = false); AddStep("stop", clock.Stop); } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 9ebfeb5c82..9d1978e4cd 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -20,6 +20,7 @@ namespace osu.Game.Screens.Play { public class SongProgress : OverlayContainer { + private const int info_height = 20; private const int bottom_bar_height = 5; private const float graph_height = SquareGraph.Column.WIDTH * 6; private static readonly Vector2 handle_size = new Vector2(10, 18); @@ -31,10 +32,19 @@ namespace osu.Game.Screens.Play private readonly SongProgressInfo info; public Action RequestSeek; + + /// + /// Whether seeking is allowed and the progress bar should be shown. + /// + public readonly Bindable AllowSeeking = new Bindable(); + + /// + /// Whether the difficulty graph should be shown. + /// public readonly Bindable CollapseGraph = new Bindable(); - public override bool HandleNonPositionalInput => AllowSeeking; - public override bool HandlePositionalInput => AllowSeeking; + public override bool HandleNonPositionalInput => AllowSeeking.Value; + public override bool HandlePositionalInput => AllowSeeking.Value; private double firstHitTime => objects.First().StartTime; private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1; @@ -55,22 +65,6 @@ namespace osu.Game.Screens.Play } } - private bool allowSeeking; - - public bool AllowSeeking - { - get => allowSeeking; - set - { - if (allowSeeking == value) return; - - allowSeeking = value; - updateBarVisibility(); - } - } - - private readonly BindableBool replayLoaded = new BindableBool(); - public IClock ReferenceClock; private IClock gameplayClock; @@ -78,7 +72,7 @@ namespace osu.Game.Screens.Play public SongProgress() { Masking = true; - Height = bottom_bar_height + graph_height + handle_size.Y + OsuFont.Numeric.Size; + Height = bottom_bar_height + graph_height + handle_size.Y + info_height; Children = new Drawable[] { @@ -87,7 +81,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + Height = info_height, }, graph = new SongProgressGraph { @@ -122,18 +116,17 @@ namespace osu.Game.Screens.Play { Show(); - replayLoaded.BindValueChanged(loaded => AllowSeeking = loaded.NewValue, true); + AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); CollapseGraph.BindValueChanged(_ => updateGraphVisibility(), true); } public void BindDrawableRuleset(DrawableRuleset drawableRuleset) { - replayLoaded.BindTo(drawableRuleset.HasReplayLoaded); + AllowSeeking.BindTo(drawableRuleset.HasReplayLoaded); } protected override void PopIn() { - updateBarVisibility(); this.FadeIn(500, Easing.OutQuint); } @@ -160,8 +153,8 @@ namespace osu.Game.Screens.Play private void updateBarVisibility() { - bar.FadeTo(allowSeeking ? 1 : 0, transition_duration, Easing.In); - this.MoveTo(new Vector2(0, allowSeeking ? 0 : bottom_bar_height), transition_duration, Easing.In); + bar.FadeTo(AllowSeeking.Value ? 1 : 0, transition_duration, Easing.In); + this.MoveTo(new Vector2(0, AllowSeeking.Value ? 0 : bottom_bar_height), transition_duration, Easing.In); updateInfoMargin(); } @@ -178,7 +171,7 @@ namespace osu.Game.Screens.Play private void updateInfoMargin() { - float finalMargin = bottom_bar_height + (allowSeeking ? handle_size.Y : 0) + (CollapseGraph.Value ? 0 : graph_height); + float finalMargin = bottom_bar_height + (AllowSeeking.Value ? handle_size.Y : 0) + (CollapseGraph.Value ? 0 : graph_height); info.TransformTo(nameof(info.Margin), new MarginPadding { Bottom = finalMargin }, transition_duration, Easing.In); } } From 2d5fd7f1c4fc789daabbebd0dad891ed3033a8f2 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:49:56 +0200 Subject: [PATCH 009/628] remove unnecessarily setting value of bindable that was already bound to --- osu.Game/Screens/Play/HUDOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 017bf70133..e0036cdeb9 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -106,7 +106,6 @@ namespace osu.Game.Screens.Play BindDrawableRuleset(drawableRuleset); Progress.Objects = drawableRuleset.Objects; - Progress.AllowSeeking = drawableRuleset.HasReplayLoaded.Value; Progress.RequestSeek = time => RequestSeek(time); Progress.ReferenceClock = drawableRuleset.FrameStableClock; From ee44caf964c59439449e8d65dfa4bf73ea9fb887 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 08:52:44 +0200 Subject: [PATCH 010/628] better setting description --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 4 ++-- osu.Game/Screens/Play/SongProgress.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f3792fcb7f..c055d7d321 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -77,7 +77,7 @@ namespace osu.Game.Configuration Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01); Set(OsuSetting.ShowInterface, true); - Set(OsuSetting.CollapseProgressGraph, false); + Set(OsuSetting.ShowProgressGraph, true); Set(OsuSetting.KeyOverlay, false); Set(OsuSetting.FloatingComments, false); @@ -132,7 +132,7 @@ namespace osu.Game.Configuration KeyOverlay, FloatingComments, ShowInterface, - CollapseProgressGraph, + ShowProgressGraph, MouseDisableButtons, MouseDisableWheel, AudioOffset, diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index e365973c4b..2169fc69cc 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -36,8 +36,8 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { - LabelText = "Collapse song progress graph", - Bindable = config.GetBindable(OsuSetting.CollapseProgressGraph) + LabelText = "Show difficulty graph on progress bar", + Bindable = config.GetBindable(OsuSetting.ShowProgressGraph) }, new SettingsCheckbox { diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 9d1978e4cd..7411afb688 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play if (clock != null) gameplayClock = clock; - config.BindWith(OsuSetting.CollapseProgressGraph, CollapseGraph); + config.BindWith(OsuSetting.ShowProgressGraph, CollapseGraph); graph.FillColour = bar.FillColour = colours.BlueLighter; } From d05512a12a3d7c41f8276473d0fb08c31e2ba092 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 5 Jul 2019 09:16:50 +0200 Subject: [PATCH 011/628] invert usage corresponding to previous description change --- .../Visual/Gameplay/TestSceneSongProgress.cs | 4 ++-- osu.Game/Screens/Play/SongProgress.cs | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index e16ad42558..15bf907b4f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -112,10 +112,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for graph", () => graph.CreationCount == 1); AddStep("start", clock.Start); AddStep("show bar", () => progress.AllowSeeking.Value = true); - AddStep("hide graph", () => progress.CollapseGraph.Value = true); + AddStep("hide graph", () => progress.ShowGraph.Value = false); AddStep("hide Bar", () => progress.AllowSeeking.Value = false); AddStep("show bar", () => progress.AllowSeeking.Value = true); - AddStep("show graph", () => progress.CollapseGraph.Value = false); + AddStep("show graph", () => progress.ShowGraph.Value = true); AddStep("stop", clock.Stop); } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 7411afb688..727fad84c9 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -38,10 +38,7 @@ namespace osu.Game.Screens.Play /// public readonly Bindable AllowSeeking = new Bindable(); - /// - /// Whether the difficulty graph should be shown. - /// - public readonly Bindable CollapseGraph = new Bindable(); + public readonly Bindable ShowGraph = new Bindable(); public override bool HandleNonPositionalInput => AllowSeeking.Value; public override bool HandlePositionalInput => AllowSeeking.Value; @@ -107,7 +104,7 @@ namespace osu.Game.Screens.Play if (clock != null) gameplayClock = clock; - config.BindWith(OsuSetting.ShowProgressGraph, CollapseGraph); + config.BindWith(OsuSetting.ShowProgressGraph, ShowGraph); graph.FillColour = bar.FillColour = colours.BlueLighter; } @@ -117,7 +114,7 @@ namespace osu.Game.Screens.Play Show(); AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); - CollapseGraph.BindValueChanged(_ => updateGraphVisibility(), true); + ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true); } public void BindDrawableRuleset(DrawableRuleset drawableRuleset) @@ -163,15 +160,15 @@ namespace osu.Game.Screens.Play { float barHeight = bottom_bar_height + handle_size.Y; - bar.ResizeHeightTo(CollapseGraph.Value ? barHeight : barHeight + graph_height, transition_duration, Easing.In); - graph.MoveToY(CollapseGraph.Value ? bottom_bar_height + graph_height : 0, transition_duration, Easing.In); + bar.ResizeHeightTo(ShowGraph.Value ? barHeight + graph_height : barHeight, transition_duration, Easing.In); + graph.MoveToY(ShowGraph.Value ? 0 : bottom_bar_height + graph_height, transition_duration, Easing.In); updateInfoMargin(); } private void updateInfoMargin() { - float finalMargin = bottom_bar_height + (AllowSeeking.Value ? handle_size.Y : 0) + (CollapseGraph.Value ? 0 : graph_height); + float finalMargin = bottom_bar_height + (AllowSeeking.Value ? handle_size.Y : 0) + (ShowGraph.Value ? graph_height : 0); info.TransformTo(nameof(info.Margin), new MarginPadding { Bottom = finalMargin }, transition_duration, Easing.In); } } From 54a8c00bb854c8bf70cd077302cd6fbba240504a Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Thu, 28 Nov 2019 17:09:54 +1030 Subject: [PATCH 012/628] Add support for --sdl command line arg --- .../.idea/runConfigurations/osu_SDL.xml | 20 +++++++++++++++++++ osu.Desktop/Program.cs | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml new file mode 100644 index 0000000000..1fd10e0e1a --- /dev/null +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index 141b2cdbbc..bd91bcc933 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -22,8 +22,9 @@ namespace osu.Desktop { // Back up the cwd before DesktopGameHost changes it var cwd = Environment.CurrentDirectory; + bool useSdl = args.Contains("--sdl"); - using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true)) + using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true, useSdl: useSdl)) { host.ExceptionThrown += handleException; From c06e558f874fe975502894658617d00214731777 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Dec 2019 18:12:37 +0800 Subject: [PATCH 013/628] add setting to start fully wounded --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 133f9ceb39..d21990ae91 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -23,6 +23,9 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } + [SettingSource("Start wounded", "Start at 100% of the final rate")] + public BindableBool Reverse { get; } = new BindableBool(); + private double finalRateTime; private double beginRampTime; @@ -61,7 +64,10 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { - applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); + if (!Reverse.Value) + applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); + else + applyAdjustment(1 - ((track.CurrentTime - beginRampTime) / finalRateTime)); } /// From c69e88eb97b90c73b3e2dcd2bebe18c8aa4b8540 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 13:32:25 +0300 Subject: [PATCH 014/628] Add more types to dropdown --- osu.Game/Configuration/ScoreMeterType.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Configuration/ScoreMeterType.cs b/osu.Game/Configuration/ScoreMeterType.cs index b85ef9309d..156c4b1377 100644 --- a/osu.Game/Configuration/ScoreMeterType.cs +++ b/osu.Game/Configuration/ScoreMeterType.cs @@ -18,5 +18,14 @@ namespace osu.Game.Configuration [Description("Hit Error (both)")] HitErrorBoth, + + [Description("Colour (left)")] + ColourLeft, + + [Description("Colour (right)")] + ColourRight, + + [Description("Colour (both)")] + ColourBoth, } } From 5b115d8d8a94fff0f265d8a5aba113c0c1b1ad53 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 13:41:50 +0300 Subject: [PATCH 015/628] Implement basic logic --- osu.Game/Screens/Play/HUD/HitErrorDisplay.cs | 31 +++++++++++++++++ .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 33 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs diff --git a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs index 6196ce4026..4d28f00f39 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorDisplay.cs @@ -77,6 +77,19 @@ namespace osu.Game.Screens.Play.HUD case ScoreMeterType.HitErrorRight: createBar(true); break; + + case ScoreMeterType.ColourBoth: + createColour(false); + createColour(true); + break; + + case ScoreMeterType.ColourLeft: + createColour(false); + break; + + case ScoreMeterType.ColourRight: + createColour(true); + break; } } @@ -90,6 +103,24 @@ namespace osu.Game.Screens.Play.HUD Alpha = 0, }; + completeDisplayLoading(display); + } + + private void createColour(bool rightAligned) + { + var display = new ColourHitErrorMeter(hitWindows) + { + Margin = new MarginPadding(margin), + Anchor = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Origin = rightAligned ? Anchor.CentreRight : Anchor.CentreLeft, + Alpha = 0, + }; + + completeDisplayLoading(display); + } + + private void completeDisplayLoading(HitErrorMeter display) + { Add(display); display.FadeInFromZero(fade_duration, Easing.OutQuint); } diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs new file mode 100644 index 0000000000..95d4940b17 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.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.Sprites; +using osu.Game.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Play.HUD.HitErrorMeters +{ + public class ColourHitErrorMeter : HitErrorMeter + { + public ColourHitErrorMeter(HitWindows hitWindows) + : base(hitWindows) + { + + } + + public override void OnNewJudgement(JudgementResult judgement) + { + throw new System.NotImplementedException(); + } + } +} From 5e3c3f2a90190b9a785800627b44e4af136d6dba Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 14:30:41 +0300 Subject: [PATCH 016/628] Make judgements work --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 70 +++++++++++++++++-- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 95d4940b17..41401a0048 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -1,33 +1,89 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using osu.Framework.Allocation; -using osu.Framework.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.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osuTK; -using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public class ColourHitErrorMeter : HitErrorMeter { + private const int bar_height = 200; + + private readonly FillFlowContainer judgementsFlow; + public ColourHitErrorMeter(HitWindows hitWindows) : base(hitWindows) { - + AutoSizeAxes = Axes.Both; + InternalChild = judgementsFlow = new FillFlowContainer + { + AutoSizeAxes = Axes.X, + Height = bar_height, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Masking = true, + }; } public override void OnNewJudgement(JudgementResult judgement) { - throw new System.NotImplementedException(); + judgementsFlow.Add(new DrawableJudgement(HitWindows.ResultFor(judgement.TimeOffset))); + } + + private class DrawableJudgement : CircularContainer + { + private readonly Box background; + private readonly HitResult result; + + public DrawableJudgement(HitResult result) + { + this.result = result; + + Masking = true; + Size = new Vector2(8); + Child = background = new Box + { + RelativeSizeAxes = Axes.Both, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + switch (result) + { + case HitResult.Miss: + background.Colour = colours.Red; + break; + + case HitResult.Meh: + background.Colour = colours.Yellow; + break; + + case HitResult.Ok: + background.Colour = colours.Green; + break; + + case HitResult.Good: + background.Colour = colours.GreenLight; + break; + + case HitResult.Great: + background.Colour = colours.Blue; + break; + + default: + background.Colour = colours.BlueLight; + break; + } + } } } } From 5af126009488554a4322fa292c24e39f8ef0f898 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 14:30:49 +0300 Subject: [PATCH 017/628] Improve testing --- ...rrorMeter.cs => TestSceneHitErrorMeter.cs} | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) rename osu.Game.Tests/Visual/Gameplay/{TestSceneBarHitErrorMeter.cs => TestSceneHitErrorMeter.cs} (75%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs similarity index 75% rename from osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index e3688c276f..b208a2e0e7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBarHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -19,18 +19,22 @@ using osu.Game.Screens.Play.HUD.HitErrorMeters; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneBarHitErrorMeter : OsuTestScene + public class TestSceneHitErrorMeter : OsuTestScene { public override IReadOnlyList RequiredTypes => new[] { typeof(HitErrorMeter), + typeof(BarHitErrorMeter), + typeof(ColourHitErrorMeter) }; - private HitErrorMeter meter; - private HitErrorMeter meter2; + private BarHitErrorMeter barMeter; + private BarHitErrorMeter barMeter2; + private ColourHitErrorMeter colourMeter; + private ColourHitErrorMeter colourMeter2; private HitWindows hitWindows; - public TestSceneBarHitErrorMeter() + public TestSceneHitErrorMeter() { recreateDisplay(new OsuHitWindows(), 5); @@ -91,17 +95,31 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Add(meter = new BarHitErrorMeter(hitWindows, true) + Add(barMeter = new BarHitErrorMeter(hitWindows, true) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, }); - Add(meter2 = new BarHitErrorMeter(hitWindows, false) + Add(barMeter2 = new BarHitErrorMeter(hitWindows, false) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }); + + Add(colourMeter = new ColourHitErrorMeter(hitWindows) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Margin = new MarginPadding { Right = 50 } + }); + + Add(colourMeter2 = new ColourHitErrorMeter(hitWindows) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 } + }); } private void newJudgement(double offset = 0) @@ -112,8 +130,10 @@ namespace osu.Game.Tests.Visual.Gameplay Type = HitResult.Perfect, }; - meter.OnNewJudgement(judgement); - meter2.OnNewJudgement(judgement); + barMeter.OnNewJudgement(judgement); + barMeter2.OnNewJudgement(judgement); + colourMeter.OnNewJudgement(judgement); + colourMeter2.OnNewJudgement(judgement); } } } From b61aa660c63f0e126f32643ef17e7bb458d2a1ae Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 14:52:53 +0300 Subject: [PATCH 018/628] Move colours to HitErrorMeter class --- .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 25 +--------- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 46 ++----------------- .../Play/HUD/HitErrorMeters/HitErrorMeter.cs | 30 ++++++++++++ 3 files changed, 37 insertions(+), 64 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 03a0f23fb6..208bdd17ad 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -163,30 +163,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters centre.Width = 2.5f; colourBars.Add(centre); - Color4 getColour(HitResult result) - { - switch (result) - { - case HitResult.Meh: - return colours.Yellow; - - case HitResult.Ok: - return colours.Green; - - case HitResult.Good: - return colours.GreenLight; - - case HitResult.Great: - return colours.Blue; - - default: - return colours.BlueLight; - } - } - Drawable createColourBar(HitResult result, float height, bool first = false) { - var colour = getColour(result); + var colour = GetColourForHitResult(result); if (first) { @@ -201,7 +180,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters new Box { RelativeSizeAxes = Axes.Both, - Colour = getColour(result), + Colour = colour, Height = height * gradient_start }, new Box diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 41401a0048..6775b98f84 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -1,14 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osuTK; +using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { @@ -34,56 +33,21 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public override void OnNewJudgement(JudgementResult judgement) { - judgementsFlow.Add(new DrawableJudgement(HitWindows.ResultFor(judgement.TimeOffset))); + judgementsFlow.Add(new DrawableJudgement(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)))); } private class DrawableJudgement : CircularContainer { - private readonly Box background; - private readonly HitResult result; - - public DrawableJudgement(HitResult result) + public DrawableJudgement(Color4 colour) { - this.result = result; - Masking = true; Size = new Vector2(8); - Child = background = new Box + Child = new Box { RelativeSizeAxes = Axes.Both, + Colour = colour }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - switch (result) - { - case HitResult.Miss: - background.Colour = colours.Red; - break; - - case HitResult.Meh: - background.Colour = colours.Yellow; - break; - - case HitResult.Ok: - background.Colour = colours.Green; - break; - - case HitResult.Good: - background.Colour = colours.GreenLight; - break; - - case HitResult.Great: - background.Colour = colours.Blue; - break; - - default: - background.Colour = colours.BlueLight; - break; - } - } } } } diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index dee25048ed..b3edfdedec 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -1,9 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; +using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { @@ -11,11 +14,38 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { protected readonly HitWindows HitWindows; + [Resolved] + private OsuColour colours { get; set; } + protected HitErrorMeter(HitWindows hitWindows) { HitWindows = hitWindows; } public abstract void OnNewJudgement(JudgementResult judgement); + + protected Color4 GetColourForHitResult(HitResult result) + { + switch (result) + { + case HitResult.Miss: + return colours.Red; + + case HitResult.Meh: + return colours.Yellow; + + case HitResult.Ok: + return colours.Green; + + case HitResult.Good: + return colours.GreenLight; + + case HitResult.Great: + return colours.Blue; + + default: + return colours.BlueLight; + } + } } } From 14a77a8f16d849483a59c68cf726e7784966052a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 16:08:28 +0300 Subject: [PATCH 019/628] Improve animations --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 83 +++++++++++++++---- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 6775b98f84..649f29810e 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -1,6 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -13,35 +17,86 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public class ColourHitErrorMeter : HitErrorMeter { - private const int bar_height = 200; + private const int max_available_judgements = 20; - private readonly FillFlowContainer judgementsFlow; + private readonly JudgementFlow judgementsFlow; + private readonly BindableList<(Color4 colour, JudgementResult result)> judgements = new BindableList<(Color4 colour, JudgementResult result)>(); public ColourHitErrorMeter(HitWindows hitWindows) : base(hitWindows) { AutoSizeAxes = Axes.Both; - InternalChild = judgementsFlow = new FillFlowContainer - { - AutoSizeAxes = Axes.X, - Height = bar_height, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), - Masking = true, - }; + InternalChild = judgementsFlow = new JudgementFlow(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + judgementsFlow.Judgements.BindTo(judgements); } public override void OnNewJudgement(JudgementResult judgement) { - judgementsFlow.Add(new DrawableJudgement(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)))); + judgements.Add((GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)), judgement)); + + if (judgements.Count > max_available_judgements) + judgements.RemoveAt(0); } - private class DrawableJudgement : CircularContainer + private class JudgementFlow : Container { - public DrawableJudgement(Color4 colour) + private const int drawable_judgement_size = 8; + private const int spacing = 2; + private const int animation_duration = 200; + + public readonly BindableList<(Color4 colour, JudgementResult result)> Judgements = new BindableList<(Color4 colour, JudgementResult result)>(); + + public JudgementFlow() { + AutoSizeAxes = Axes.X; + Height = max_available_judgements * (drawable_judgement_size + spacing); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Judgements.ItemsAdded += push; + Judgements.ItemsRemoved += pop; + } + + private void push(IEnumerable<(Color4 colour, JudgementResult result)> judgements) + { + Children.ForEach(c => c.FinishTransforms()); + + var (colour, result) = judgements.Single(); + var drawableJudgement = new DrawableResult(colour, result, drawable_judgement_size) + { + Alpha = 0, + Y = -(drawable_judgement_size + spacing) + }; + + Add(drawableJudgement); + drawableJudgement.FadeInFromZero(animation_duration, Easing.OutQuint); + + Children.ForEach(c => c.MoveToOffset(new Vector2(0, drawable_judgement_size + spacing), animation_duration, Easing.OutQuint)); + } + + private void pop(IEnumerable<(Color4 colour, JudgementResult result)> judgements) + { + Children.FirstOrDefault(c => c.Result == judgements.Single().result).FadeOut(animation_duration, Easing.OutQuint).Expire(); + } + } + + private class DrawableResult : CircularContainer + { + public JudgementResult Result { get; private set; } + + public DrawableResult(Color4 colour, JudgementResult result, int size) + { + Result = result; + Masking = true; - Size = new Vector2(8); + Size = new Vector2(size); Child = new Box { RelativeSizeAxes = Axes.Both, From 46501cf0ac2984537d8a96b885fc87804d4ece15 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 22 Dec 2019 03:06:57 +0300 Subject: [PATCH 020/628] Use FillFlowContainer --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 649f29810e..d730a8d321 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -43,7 +42,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters judgements.RemoveAt(0); } - private class JudgementFlow : Container + private class JudgementFlow : FillFlowContainer { private const int drawable_judgement_size = 8; private const int spacing = 2; @@ -51,10 +50,16 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public readonly BindableList<(Color4 colour, JudgementResult result)> Judgements = new BindableList<(Color4 colour, JudgementResult result)>(); + private int runningDepth; + public JudgementFlow() { AutoSizeAxes = Axes.X; Height = max_available_judgements * (drawable_judgement_size + spacing); + Spacing = new Vector2(0, spacing); + Direction = FillDirection.Vertical; + LayoutDuration = animation_duration; + LayoutEasing = Easing.OutQuint; } protected override void LoadComplete() @@ -66,24 +71,20 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private void push(IEnumerable<(Color4 colour, JudgementResult result)> judgements) { - Children.ForEach(c => c.FinishTransforms()); - var (colour, result) = judgements.Single(); var drawableJudgement = new DrawableResult(colour, result, drawable_judgement_size) { Alpha = 0, - Y = -(drawable_judgement_size + spacing) }; - Add(drawableJudgement); + Insert(runningDepth--, drawableJudgement); drawableJudgement.FadeInFromZero(animation_duration, Easing.OutQuint); - - Children.ForEach(c => c.MoveToOffset(new Vector2(0, drawable_judgement_size + spacing), animation_duration, Easing.OutQuint)); } private void pop(IEnumerable<(Color4 colour, JudgementResult result)> judgements) { - Children.FirstOrDefault(c => c.Result == judgements.Single().result).FadeOut(animation_duration, Easing.OutQuint).Expire(); + var (colour, result) = judgements.Single(); + Children.FirstOrDefault(c => c.Result == result).FadeOut(animation_duration, Easing.OutQuint).Expire(); } } From eb75c6c70f342ff84d50b038af92e6873f1d080c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 22 Dec 2019 03:17:56 +0300 Subject: [PATCH 021/628] Update FadeIn animation for new judgement --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index d730a8d321..b76f2c7817 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -17,6 +17,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public class ColourHitErrorMeter : HitErrorMeter { private const int max_available_judgements = 20; + private const int animation_duration = 200; private readonly JudgementFlow judgementsFlow; private readonly BindableList<(Color4 colour, JudgementResult result)> judgements = new BindableList<(Color4 colour, JudgementResult result)>(); @@ -46,7 +47,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { private const int drawable_judgement_size = 8; private const int spacing = 2; - private const int animation_duration = 200; public readonly BindableList<(Color4 colour, JudgementResult result)> Judgements = new BindableList<(Color4 colour, JudgementResult result)>(); @@ -72,13 +72,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private void push(IEnumerable<(Color4 colour, JudgementResult result)> judgements) { var (colour, result) = judgements.Single(); - var drawableJudgement = new DrawableResult(colour, result, drawable_judgement_size) - { - Alpha = 0, - }; - - Insert(runningDepth--, drawableJudgement); - drawableJudgement.FadeInFromZero(animation_duration, Easing.OutQuint); + Insert(runningDepth--, new DrawableResult(colour, result, drawable_judgement_size)); } private void pop(IEnumerable<(Color4 colour, JudgementResult result)> judgements) @@ -88,22 +82,37 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters } } - private class DrawableResult : CircularContainer + private class DrawableResult : Container { public JudgementResult Result { get; private set; } + private readonly CircularContainer content; + public DrawableResult(Color4 colour, JudgementResult result, int size) { Result = result; - Masking = true; Size = new Vector2(size); - Child = new Box + Child = content = new CircularContainer { RelativeSizeAxes = Axes.Both, - Colour = colour + Masking = true, + Alpha = 0, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colour + }, }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + content.FadeInFromZero(animation_duration, Easing.OutQuint); + content.MoveToY(-DrawSize.Y); + content.MoveToY(0, animation_duration, Easing.OutQuint); + } } } } From aded12af9e157ea0535dfbf8da48ed7fe3a8c2f0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 22 Dec 2019 03:30:17 +0300 Subject: [PATCH 022/628] Refactoor to avoid bindable usage --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 54 ++++++------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index b76f2c7817..196eb23da6 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -1,9 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using System.Linq; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,11 +14,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public class ColourHitErrorMeter : HitErrorMeter { - private const int max_available_judgements = 20; private const int animation_duration = 200; private readonly JudgementFlow judgementsFlow; - private readonly BindableList<(Color4 colour, JudgementResult result)> judgements = new BindableList<(Color4 colour, JudgementResult result)>(); public ColourHitErrorMeter(HitWindows hitWindows) : base(hitWindows) @@ -29,69 +25,43 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters InternalChild = judgementsFlow = new JudgementFlow(); } - protected override void LoadComplete() - { - base.LoadComplete(); - judgementsFlow.Judgements.BindTo(judgements); - } - - public override void OnNewJudgement(JudgementResult judgement) - { - judgements.Add((GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset)), judgement)); - - if (judgements.Count > max_available_judgements) - judgements.RemoveAt(0); - } + public override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset))); private class JudgementFlow : FillFlowContainer { + private const int max_available_judgements = 20; private const int drawable_judgement_size = 8; private const int spacing = 2; - public readonly BindableList<(Color4 colour, JudgementResult result)> Judgements = new BindableList<(Color4 colour, JudgementResult result)>(); - private int runningDepth; public JudgementFlow() { AutoSizeAxes = Axes.X; - Height = max_available_judgements * (drawable_judgement_size + spacing); + Height = max_available_judgements * (drawable_judgement_size + spacing) - spacing; Spacing = new Vector2(0, spacing); Direction = FillDirection.Vertical; LayoutDuration = animation_duration; LayoutEasing = Easing.OutQuint; } - protected override void LoadComplete() + public void Push(Color4 colour) { - base.LoadComplete(); - Judgements.ItemsAdded += push; - Judgements.ItemsRemoved += pop; - } + Insert(runningDepth--, new DrawableResult(colour, drawable_judgement_size)); - private void push(IEnumerable<(Color4 colour, JudgementResult result)> judgements) - { - var (colour, result) = judgements.Single(); - Insert(runningDepth--, new DrawableResult(colour, result, drawable_judgement_size)); - } - - private void pop(IEnumerable<(Color4 colour, JudgementResult result)> judgements) - { - var (colour, result) = judgements.Single(); - Children.FirstOrDefault(c => c.Result == result).FadeOut(animation_duration, Easing.OutQuint).Expire(); + if (Children.Count > max_available_judgements) + Children.FirstOrDefault(c => !c.IsRemoved).Remove(); } } private class DrawableResult : Container { - public JudgementResult Result { get; private set; } + public bool IsRemoved { get; private set; } private readonly CircularContainer content; - public DrawableResult(Color4 colour, JudgementResult result, int size) + public DrawableResult(Color4 colour, int size) { - Result = result; - Size = new Vector2(size); Child = content = new CircularContainer { @@ -113,6 +83,12 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters content.MoveToY(-DrawSize.Y); content.MoveToY(0, animation_duration, Easing.OutQuint); } + + public void Remove() + { + IsRemoved = true; + this.FadeOut(animation_duration, Easing.OutQuint).Expire(); + } } } } From 7a0d76ae77e5b830f158dcde6bfdb80797165e70 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 22 Dec 2019 03:41:19 +0300 Subject: [PATCH 023/628] Fix nullref --- osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 196eb23da6..d18f6f3743 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Insert(runningDepth--, new DrawableResult(colour, drawable_judgement_size)); if (Children.Count > max_available_judgements) - Children.FirstOrDefault(c => !c.IsRemoved).Remove(); + Children.FirstOrDefault(c => !c.IsRemoved)?.Remove(); } } From 2c1a65d90acfa70f206cf46a00b26da5d93111c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 26 Dec 2019 19:37:55 +0900 Subject: [PATCH 024/628] Add simple test --- .../Editor/TestSceneBlueprintContainer.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs diff --git a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs new file mode 100644 index 0000000000..5ccce5b3c6 --- /dev/null +++ b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Screens.Edit.Compose.Components; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Editor +{ + public class TestSceneBlueprintContainer : EditorClockTestScene + { + private BlueprintContainer blueprintContainer; + + [SetUp] + public void Setup() => Schedule(() => + { + Child = blueprintContainer = new BlueprintContainer(); + }); + } +} From b3d32710df2cf43bc3a969f88ea43b6cc7a5ed30 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 00:19:51 +0100 Subject: [PATCH 025/628] Centered button mods by adding padding to FillFlowContainer --- osu.Game/Screens/Select/FooterButtonMods.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 8419ee0c2a..bb733f10ed 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,11 +54,10 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 10 } } }, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70 } + Margin = new MarginPadding { Left = 70, Right = 15 } }); } From bf463fe5e0c13f2d07b257a2a21060620cb672b5 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 08:57:14 +0100 Subject: [PATCH 026/628] adjusted the margin values --- .../Visual/UserInterface/TestSceneFooterButtonMods.cs | 7 +++++++ osu.Game/Screens/Select/FooterButtonMods.cs | 1 + 2 files changed, 8 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index 6eb621ca3b..de67968fbc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -45,6 +45,13 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep(@"Add multiple Mods", () => changeMods(mutlipleIncrementMods)); AddAssert(@"Check multiple mod multiplier", () => assertModsMultiplier(mutlipleIncrementMods)); } + + [Test] + public void Temporary() + { + var hiddenMod = new Mod[] { new OsuModRelax() }; + AddStep(@"Add Hidden", () => changeMods(hiddenMod)); + } [Test] public void TestDecrementMultiplier() diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index bb733f10ed..d533d5444c 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,6 +54,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } } }, AutoSizeAxes = Axes.Both, From 875a25c5297b0797b84af4974c2bf5e0d68ed6c6 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 08:57:14 +0100 Subject: [PATCH 027/628] adjusted the margin values --- osu.Game/Screens/Select/FooterButtonMods.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index bb733f10ed..d533d5444c 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,6 +54,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } } }, AutoSizeAxes = Axes.Both, From e85910c4e465ab174ee8d328b75442d8886c8cb9 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 09:18:27 +0100 Subject: [PATCH 028/628] removed unnecessary test code --- .../Visual/UserInterface/TestSceneFooterButtonMods.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index de67968fbc..6eb621ca3b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -45,13 +45,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep(@"Add multiple Mods", () => changeMods(mutlipleIncrementMods)); AddAssert(@"Check multiple mod multiplier", () => assertModsMultiplier(mutlipleIncrementMods)); } - - [Test] - public void Temporary() - { - var hiddenMod = new Mod[] { new OsuModRelax() }; - AddStep(@"Add Hidden", () => changeMods(hiddenMod)); - } [Test] public void TestDecrementMultiplier() From b0bcbf8b93ab24b96a2fe3f73491c2703b31675b Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Mon, 30 Dec 2019 21:55:09 +0100 Subject: [PATCH 029/628] Adjusted margin to fix the 1 px increase --- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index d533d5444c..a0e34a7f87 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Select } }, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70, Right = 15 } + Margin = new MarginPadding { Left = 70, Right = 14 } }); } From f40ebc83caea08d02810065d7150c30c8fe60ffb Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Mon, 30 Dec 2019 23:58:49 +0100 Subject: [PATCH 030/628] Begun refractorization process of wrapping Button text in a FillFlowContainer --- .../TestSceneFooterButtonMods.cs | 3 +- osu.Game/Screens/Select/FooterButton.cs | 23 +++++++---- osu.Game/Screens/Select/FooterButtonMods.cs | 38 +++++++------------ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index 6eb621ca3b..63197ed26a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -16,7 +16,8 @@ namespace osu.Game.Tests.Visual.UserInterface { public override IReadOnlyList RequiredTypes => new[] { - typeof(FooterButtonMods) + typeof(FooterButtonMods), + typeof(FooterButton) }; private readonly TestFooterButtonMods footerButtonMods; diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index b77da36748..18c9d1091c 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Select } } - protected readonly Container TextContainer; + protected FillFlowContainer TextContainer; protected readonly SpriteText SpriteText; private readonly Box box; private readonly Box light; @@ -80,15 +80,24 @@ namespace osu.Game.Screens.Select EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, }, - TextContainer = new Container + TextContainer = new FillFlowContainer { - Size = new Vector2(100 - SHEAR_WIDTH, 50), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, Shear = -SHEAR, - Child = SpriteText = new OsuSpriteText + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } + SpriteText = new OsuSpriteText + { + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Shear = -SHEAR, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + AutoSizeAxes = Axes.Both, + // Margin = new MarginPadding { Left = 70, Right = 14 } }, }; } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index a0e34a7f87..2141c04cd6 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -3,7 +3,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +// using osu.Framework.Graphics.Containers; using osu.Game.Screens.Play.HUD; using osu.Game.Rulesets.Mods; using System.Collections.Generic; @@ -34,31 +34,19 @@ namespace osu.Game.Screens.Select public FooterButtonMods() { - Add(new FillFlowContainer + TextContainer.Add(modDisplay = new FooterModDisplay { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Shear = -SHEAR, - Children = new Drawable[] - { - modDisplay = new FooterModDisplay - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - DisplayUnrankedText = false, - Scale = new Vector2(0.8f) - }, - MultiplierText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 6 } - } - }, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70, Right = 14 } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + DisplayUnrankedText = false, + Scale = new Vector2(0.8f) + }); + TextContainer.Add(MultiplierText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } }); } From 8695e57f627aa2dc6da22c4eb53836265328cc30 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Tue, 31 Dec 2019 12:21:55 +0100 Subject: [PATCH 031/628] Hides mod display when no mods are active to fix issue of invisible margin --- osu.Game/Screens/Select/FooterButton.cs | 2 +- osu.Game/Screens/Select/FooterButtonMods.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 18c9d1091c..7acb2fd221 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Select SpriteText = new OsuSpriteText { Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = -SHEAR, + Shear = SHEAR, Anchor = Anchor.Centre, Origin = Anchor.Centre, } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 2141c04cd6..a3453fee05 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 6 } + // Margin = new MarginPadding { Right = 6 } }); } @@ -80,6 +80,11 @@ namespace osu.Game.Screens.Select MultiplierText.FadeColour(lowMultiplierColour, 200); else MultiplierText.FadeColour(Color4.White, 200); + + if (Current.Value?.Count > 0) + modDisplay.FadeIn(0); + else + modDisplay.FadeOut(0); } private class FooterModDisplay : ModDisplay From ddec59ec9158c0f88ca9a35048de161f232c5bd6 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Wed, 1 Jan 2020 12:22:19 +0100 Subject: [PATCH 032/628] Further refactoring. I think this may have polluted the FooterButton too much. Not sure what to do about the centering. --- osu.Game/Screens/Select/FooterButton.cs | 40 +++++++++++++-------- osu.Game/Screens/Select/FooterButtonMods.cs | 6 ++-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 7acb2fd221..869e9e8aa4 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -56,7 +56,8 @@ namespace osu.Game.Screens.Select } } - protected FillFlowContainer TextContainer; + protected FillFlowContainer ButtonContentContainer; + protected readonly Container TextContainer; protected readonly SpriteText SpriteText; private readonly Box box; private readonly Box light; @@ -80,24 +81,35 @@ namespace osu.Game.Screens.Select EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, }, - TextContainer = new FillFlowContainer + new Container { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Shear = -SHEAR, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { - SpriteText = new OsuSpriteText + ButtonContentContainer = new FillFlowContainer { - Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = SHEAR, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Shear = -SHEAR, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Horizontal = SHEAR_WIDTH / 4 }, + Children = new Drawable[] + { + TextContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Child = SpriteText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + }, + }, }, - AutoSizeAxes = Axes.Both, - // Margin = new MarginPadding { Left = 70, Right = 14 } }, }; } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index a3453fee05..67b491cf9e 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -34,19 +34,19 @@ namespace osu.Game.Screens.Select public FooterButtonMods() { - TextContainer.Add(modDisplay = new FooterModDisplay + ButtonContentContainer.Add(modDisplay = new FooterModDisplay { Anchor = Anchor.Centre, Origin = Anchor.Centre, DisplayUnrankedText = false, Scale = new Vector2(0.8f) }); - TextContainer.Add(MultiplierText = new OsuSpriteText + ButtonContentContainer.Add(MultiplierText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - // Margin = new MarginPadding { Right = 6 } + Margin = new MarginPadding { Right = 10 } }); } From af248457b02b9380c49dc09d8dd2085b9ebe7766 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:49:04 +0300 Subject: [PATCH 033/628] Implement OverlayRulesetSelector --- .../TestSceneOverlayRulesetSelector.cs | 68 +++++++++++++ osu.Game/Overlays/OverlayRulesetSelector.cs | 44 +++++++++ osu.Game/Overlays/OverlayRulesetTabItem.cs | 98 +++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetTabItem.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs new file mode 100644 index 0000000000..6c921b13b4 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -0,0 +1,68 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; +using osu.Framework.Bindables; +using osu.Game.Overlays; +using osu.Game.Rulesets; +using NUnit.Framework; +using osu.Game.Graphics; +using osu.Framework.Allocation; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneOverlayRulesetSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlayRulesetSelector), + typeof(OverlayRulesetTabItem), + }; + + private readonly OverlayRulesetSelector selector; + private readonly Bindable ruleset = new Bindable(); + + public TestSceneOverlayRulesetSelector() + { + Add(selector = new OverlayRulesetSelector + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Current = ruleset, + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + selector.AccentColour = colours.Lime; + } + + [Test] + public void TestSelection() + { + var osuRuleset = new OsuRuleset().RulesetInfo; + var maniaRuleset = new ManiaRuleset().RulesetInfo; + var taikoRuleset = new TaikoRuleset().RulesetInfo; + var catchRuleset = new CatchRuleset().RulesetInfo; + + AddStep("Select osu!", () => ruleset.Value = osuRuleset); + AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + + AddStep("Select mania", () => ruleset.Value = maniaRuleset); + AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + + AddStep("Select taiko", () => ruleset.Value = taikoRuleset); + AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + + AddStep("Select catch", () => ruleset.Value = catchRuleset); + AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + } + } +} diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs new file mode 100644 index 0000000000..1dcfc97562 --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; +using System.Linq; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetSelector : RulesetSelector + { + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + foreach (var i in TabContainer.Children.OfType()) + i.AccentColour = value; + } + } + + public OverlayRulesetSelector() + { + AutoSizeAxes = Axes.Both; + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(25, 0), + }; + } +} diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs new file mode 100644 index 0000000000..9d6d28a81f --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -0,0 +1,98 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK.Graphics; +using osuTK; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetTabItem : TabItem, IHasAccentColour + { + protected readonly OsuSpriteText Text; + private readonly FillFlowContainer content; + + public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + UpdateState(); + } + } + + protected override Container Content => content; + + public OverlayRulesetTabItem(RulesetInfo value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + AddRangeInternal(new Drawable[] + { + content = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Child = Text = new OsuSpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value.Name, + } + }, + new HoverClickSounds() + }); + + Enabled.Value = true; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Enabled.BindValueChanged(_ => UpdateState(), true); + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + UpdateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + UpdateState(); + } + + protected override void OnActivated() => UpdateState(); + + protected override void OnDeactivated() => UpdateState(); + + protected virtual void UpdateState() + { + Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + Text.FadeColour(GetColour(), 120, Easing.OutQuint); + } + + protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; + } +} From b016238c16f8ac0d8e2c6e97d1e2559c6c58930e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:55:28 +0300 Subject: [PATCH 034/628] Make ProfileRulesetSelector inherit from OverlayRulesetSelector --- .../Online/TestSceneProfileRulesetSelector.cs | 2 +- .../Components/ProfileRulesetSelector.cs | 33 +------ .../Components/ProfileRulesetTabItem.cs | 97 +++---------------- 3 files changed, 20 insertions(+), 112 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 1f5ba67e03..a36b6880d2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; - Bindable user = new Bindable(); + var user = new Bindable(); Child = selector = new ProfileRulesetSelector { diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 2c9a3dd5f9..e63102f989 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -3,37 +3,21 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Users; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetSelector : RulesetSelector + public class ProfileRulesetSelector : OverlayRulesetSelector { - private Color4 accentColour = Color4.White; - public readonly Bindable User = new Bindable(); - public ProfileRulesetSelector() - { - TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(10, 0); - AutoSizeAxes = Axes.Both; - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { - accentColour = colours.Seafoam; - - foreach (TabItem tabItem in TabContainer) - ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; + AccentColour = colours.Seafoam; } protected override void LoadComplete() @@ -45,19 +29,10 @@ namespace osu.Game.Overlays.Profile.Header.Components public void SetDefaultRuleset(RulesetInfo ruleset) { - foreach (TabItem tabItem in TabContainer) + foreach (var tabItem in TabContainer) ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; } - protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) - { - AccentColour = accentColour - }; - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - }; + protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index b5170ea3a2..adf324b259 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -2,38 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetTabItem : TabItem, IHasAccentColour + public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly OsuSpriteText text; private readonly SpriteIcon icon; - private Color4 accentColour; - - public Color4 AccentColour + public new Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => base.AccentColour; + set => base.AccentColour = icon.Colour = value; } private bool isDefault; @@ -55,71 +38,21 @@ namespace osu.Game.Overlays.Profile.Header.Components public ProfileRulesetTabItem(RulesetInfo value) : base(value) { - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] + Add(icon = new SpriteIcon { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - text = new OsuSpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = value.Name, - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Alpha = 0, - AlwaysPresent = true, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - }, - } - }, - new HoverClickSounds() - }; + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }); } - protected override bool OnHover(HoverEvent e) + protected override void UpdateState() { - base.OnHover(e); - updateState(); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - updateState(); - } - - protected override void OnActivated() => updateState(); - - protected override void OnDeactivated() => updateState(); - - private void updateState() - { - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - - if (IsHovered || Active.Value) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - } - else - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); - } + base.UpdateState(); + icon.FadeColour(GetColour(), 120, Easing.OutQuint); } } } From 2d6a07e970420893feea193e778f1ff3cc28e4f9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 23:14:26 +0300 Subject: [PATCH 035/628] Fix OverlayRulesetSelector don't have default colour --- .../TestSceneOverlayRulesetSelector.cs | 35 +++++++++---------- osu.Game/Overlays/OverlayRulesetSelector.cs | 8 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 6c921b13b4..93aa414c94 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -25,6 +25,9 @@ namespace osu.Game.Tests.Visual.UserInterface typeof(OverlayRulesetTabItem), }; + [Resolved] + private OsuColour colours { get; set; } + private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); @@ -38,31 +41,27 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - selector.AccentColour = colours.Lime; - } - [Test] public void TestSelection() { - var osuRuleset = new OsuRuleset().RulesetInfo; - var maniaRuleset = new ManiaRuleset().RulesetInfo; - var taikoRuleset = new TaikoRuleset().RulesetInfo; - var catchRuleset = new CatchRuleset().RulesetInfo; + AddStep("Select osu!", () => ruleset.Value = new OsuRuleset().RulesetInfo); + AddAssert("Check osu! selected", () => selector.Current.Value.Equals(new OsuRuleset().RulesetInfo)); - AddStep("Select osu!", () => ruleset.Value = osuRuleset); - AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + AddStep("Select mania", () => ruleset.Value = new ManiaRuleset().RulesetInfo); + AddAssert("Check mania selected", () => selector.Current.Value.Equals(new ManiaRuleset().RulesetInfo)); - AddStep("Select mania", () => ruleset.Value = maniaRuleset); - AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + AddStep("Select taiko", () => ruleset.Value = new TaikoRuleset().RulesetInfo); + AddAssert("Check taiko selected", () => selector.Current.Value.Equals(new TaikoRuleset().RulesetInfo)); - AddStep("Select taiko", () => ruleset.Value = taikoRuleset); - AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + AddStep("Select catch", () => ruleset.Value = new CatchRuleset().RulesetInfo); + AddAssert("Check catch selected", () => selector.Current.Value.Equals(new CatchRuleset().RulesetInfo)); + } - AddStep("Select catch", () => ruleset.Value = catchRuleset); - AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + [Test] + public void TestColours() + { + AddStep("Set colour to blue", () => selector.AccentColour = colours.Blue); + AddAssert("Check colour is blue", () => selector.AccentColour == colours.Blue); } } } diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index 1dcfc97562..da49335250 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; @@ -32,6 +33,13 @@ namespace osu.Game.Overlays AutoSizeAxes = Axes.Both; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + if (accentColour == default) + AccentColour = colours.Pink; + } + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer From ee332e0d424b0a8a76efc28b413208e14f8b1f6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 2 Jan 2020 11:46:18 +0900 Subject: [PATCH 036/628] Split out BlueprintContainer functionality further --- .../Edit/ManiaBlueprintContainer.cs | 28 +++++++++++++++ .../Edit/ManiaHitObjectComposer.cs | 21 ++--------- .../Edit/OsuBlueprintContainer.cs | 35 +++++++++++++++++++ .../Edit/OsuHitObjectComposer.cs | 24 +------------ .../Editor/TestSceneBlueprintContainer.cs | 4 +-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 15 ++------ .../Compose/Components/BlueprintContainer.cs | 23 +++++++++--- .../Components/ComposeBlueprintContainer.cs | 12 +++++++ 8 files changed, 101 insertions(+), 61 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs create mode 100644 osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs create mode 100644 osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs new file mode 100644 index 0000000000..9cb4e54234 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mania.Edit.Blueprints; +using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Screens.Edit.Compose.Components; + +namespace osu.Game.Rulesets.Mania.Edit +{ + public class ManiaBlueprintContainer : ComposeBlueprintContainer + { + public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) + { + switch (hitObject) + { + case DrawableNote note: + return new NoteSelectionBlueprint(note); + + case DrawableHoldNote holdNote: + return new HoldNoteSelectionBlueprint(holdNote); + } + + return base.CreateBlueprintFor(hitObject); + } + } +} diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 1632b6a583..824c92184a 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -5,11 +5,8 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Objects.Drawables; using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; @@ -52,26 +49,12 @@ namespace osu.Game.Rulesets.Mania.Edit return drawableRuleset; } + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new ManiaBlueprintContainer(); + protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { new NoteCompositionTool(), new HoldNoteCompositionTool() }; - - public override SelectionHandler CreateSelectionHandler() => new ManiaSelectionHandler(); - - public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) - { - switch (hitObject) - { - case DrawableNote note: - return new NoteSelectionBlueprint(note); - - case DrawableHoldNote holdNote: - return new HoldNoteSelectionBlueprint(holdNote); - } - - return base.CreateBlueprintFor(hitObject); - } } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs new file mode 100644 index 0000000000..a6a7d9bcc0 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -0,0 +1,35 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; +using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders; +using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Screens.Edit.Compose.Components; + +namespace osu.Game.Rulesets.Osu.Edit +{ + public class OsuBlueprintContainer : ComposeBlueprintContainer + { + public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); + + public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) + { + switch (hitObject) + { + case DrawableHitCircle circle: + return new HitCircleSelectionBlueprint(circle); + + case DrawableSlider slider: + return new SliderSelectionBlueprint(slider); + + case DrawableSpinner spinner: + return new SpinnerSelectionBlueprint(spinner); + } + + return base.CreateBlueprintFor(hitObject); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 49624ea733..28f7768aac 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -9,12 +9,7 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; -using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders; -using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Compose.Components; @@ -37,24 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit new SpinnerCompositionTool() }; - public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); - - public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) - { - switch (hitObject) - { - case DrawableHitCircle circle: - return new HitCircleSelectionBlueprint(circle); - - case DrawableSlider slider: - return new SliderSelectionBlueprint(slider); - - case DrawableSpinner spinner: - return new SpinnerSelectionBlueprint(spinner); - } - - return base.CreateBlueprintFor(hitObject); - } + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(); protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable selectedHitObjects) { diff --git a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs index 5ccce5b3c6..67b0b61545 100644 --- a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs +++ b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs @@ -9,12 +9,10 @@ namespace osu.Game.Tests.Editor { public class TestSceneBlueprintContainer : EditorClockTestScene { - private BlueprintContainer blueprintContainer; - [SetUp] public void Setup() => Schedule(() => { - Child = blueprintContainer = new BlueprintContainer(); + Child = new ComposeBlueprintContainer(); }); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index bfaa7e8872..536c7767b7 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Edit new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both } }); - var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(blueprintContainer = new BlueprintContainer()); + var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(blueprintContainer = CreateBlueprintContainer()); layerContainers.Add(layerBelowRuleset); layerContainers.Add(layerAboveRuleset); @@ -147,6 +147,8 @@ namespace osu.Game.Rulesets.Edit blueprintContainer.SelectionChanged += selectionChanged; } + protected abstract ComposeBlueprintContainer CreateBlueprintContainer(); + protected override void LoadComplete() { base.LoadComplete(); @@ -323,17 +325,6 @@ namespace osu.Game.Rulesets.Edit /// public abstract bool CursorInPlacementArea { get; } - /// - /// Creates a for a specific . - /// - /// The to create the overlay for. - public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; - - /// - /// Creates a which outlines s and handles movement of selections. - /// - public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); - /// /// Creates the applicable for a selection. /// diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index cafaddc39e..39ec42ba96 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -22,7 +22,11 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components { - public class BlueprintContainer : CompositeDrawable, IKeyBindingHandler + /// + /// A container which provides a "blueprint" display of hitobjects. + /// Includes selection and manipulation support via a . + /// + public abstract class BlueprintContainer : CompositeDrawable, IKeyBindingHandler { public event Action> SelectionChanged; @@ -42,15 +46,26 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private EditorBeatmap beatmap { get; set; } - public BlueprintContainer() + protected BlueprintContainer() { RelativeSizeAxes = Axes.Both; } + /// + /// Creates a which outlines s and handles movement of selections. + /// + public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); + + /// + /// Creates a for a specific . + /// + /// The to create the overlay for. + public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; + [BackgroundDependencyLoader] private void load() { - selectionHandler = composer.CreateSelectionHandler(); + selectionHandler = CreateSelectionHandler(); selectionHandler.DeselectAll = deselectAll; InternalChildren = new[] @@ -259,7 +274,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { refreshTool(); - var blueprint = composer.CreateBlueprintFor(hitObject); + var blueprint = CreateBlueprintFor(hitObject); if (blueprint == null) return; diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs new file mode 100644 index 0000000000..9267006e4c --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -0,0 +1,12 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Screens.Edit.Compose.Components +{ + /// + /// A blueprint container generally displayed as an overlay to a ruleset's playfield. + /// + public class ComposeBlueprintContainer : BlueprintContainer + { + } +} From d8d12cbbddfe864f96467e22a8b672f8ef4d22c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 2 Jan 2020 19:09:37 +0900 Subject: [PATCH 037/628] wip: Move more functionality into ComposeBlueprintContainer --- .../Timelines/Summary/Parts/TimelinePart.cs | 4 ++-- .../Edit/Compose/Components/BlueprintContainer.cs | 5 +---- .../Components/Timeline/TimelineHitObjectDisplay.cs | 12 ++++++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 7706e33179..119635ccd5 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// /// Represents a part of the summary timeline.. /// - public abstract class TimelinePart : Container + public class TimelinePart : Container { protected readonly IBindable Beatmap = new Bindable(); @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => timeline; - protected TimelinePart() + public TimelinePart() { AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 39ec42ba96..a8fb87c1b0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -40,9 +40,6 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private IAdjustableClock adjustableClock { get; set; } - [Resolved] - private HitObjectComposer composer { get; set; } - [Resolved] private EditorBeatmap beatmap { get; set; } @@ -77,7 +74,7 @@ namespace osu.Game.Screens.Edit.Compose.Components dragBox.CreateProxy() }; - foreach (var obj in composer.HitObjects) + foreach (var obj in beatmap.HitObjects) addBlueprintFor(obj); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index b20f2fa11d..12909f257d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -14,15 +14,19 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - internal class TimelineHitObjectDisplay : TimelinePart + internal class TimelineHitObjectDisplay : BlueprintContainer { private EditorBeatmap beatmap { get; } + private readonly TimelinePart content; + public TimelineHitObjectDisplay(EditorBeatmap beatmap) { RelativeSizeAxes = Axes.Both; this.beatmap = beatmap; + + AddInternal(content = new TimelinePart()); } [BackgroundDependencyLoader] @@ -42,15 +46,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void remove(HitObject h) { - foreach (var d in Children.OfType().Where(c => c.HitObject == h)) + foreach (var d in content.OfType().Where(c => c.HitObject == h)) d.Expire(); } private void add(HitObject h) { - var yOffset = Children.Count(d => d.X == h.StartTime); + var yOffset = content.Count(d => d.X == h.StartTime); - Add(new TimelineHitObjectRepresentation(h) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }); + content.Add(new TimelineHitObjectRepresentation(h) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }); } private class TimelineHitObjectRepresentation : CompositeDrawable From 904b068a15c5bb55629d70c8bb5ca035a1d65649 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 2 Jan 2020 13:18:18 +0300 Subject: [PATCH 038/628] Simplify colour setting for additional elements in OverlayRulesetTabItem --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 23 +++++++++++-------- .../Components/ProfileRulesetTabItem.cs | 13 +---------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 9d6d28a81f..e1cc1de8de 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; +using System; namespace osu.Game.Overlays { @@ -33,10 +34,12 @@ namespace osu.Game.Overlays accentColour = value; - UpdateState(); + updateState(); } } + protected Action OnStateUpdated; + protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -67,32 +70,32 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); - Enabled.BindValueChanged(_ => UpdateState(), true); + Enabled.BindValueChanged(_ => updateState(), true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - UpdateState(); + updateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - UpdateState(); + updateState(); } - protected override void OnActivated() => UpdateState(); + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() => UpdateState(); + protected override void OnDeactivated() => updateState(); - protected virtual void UpdateState() + private void updateState() { + var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(GetColour(), 120, Easing.OutQuint); + Text.FadeColour(updatedColour, 120, Easing.OutQuint); + OnStateUpdated?.Invoke(updatedColour); } - - protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index adf324b259..d416e98b31 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { @@ -13,12 +12,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { private readonly SpriteIcon icon; - public new Color4 AccentColour - { - get => base.AccentColour; - set => base.AccentColour = icon.Colour = value; - } - private bool isDefault; public bool IsDefault @@ -47,12 +40,8 @@ namespace osu.Game.Overlays.Profile.Header.Components Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); - } - protected override void UpdateState() - { - base.UpdateState(); - icon.FadeColour(GetColour(), 120, Easing.OutQuint); + OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); } } } From 7b71e568177f1d827316dd3930ac64fd2921f5c0 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Thu, 2 Jan 2020 17:07:28 +0100 Subject: [PATCH 039/628] Initial commit --- .../API/Requests/MarkChannelAsReadRequest.cs | 21 +++++++++++++++++++ osu.Game/Online/Chat/Channel.cs | 8 +++++++ osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++ 3 files changed, 37 insertions(+) create mode 100644 osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs diff --git a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs new file mode 100644 index 0000000000..3f28037816 --- /dev/null +++ b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.Chat; + +namespace osu.Game.Online.API.Requests +{ + public class MarkChannelAsReadRequest : APIRequest + { + private readonly Channel channel; + private readonly Message message; + + public MarkChannelAsReadRequest(Channel channel, Message message) + { + this.channel = channel; + this.message = message; + } + + protected override string Target => @"/chat/channels/{channel}/mark-as-read/{message}"; + } +} diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 451174a73c..6f67a95f53 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -36,6 +36,11 @@ namespace osu.Game.Online.Chat /// public readonly SortedList Messages = new SortedList(Comparer.Default); + /// + /// Contains all the messages that weren't read by the user. + /// + public IEnumerable UnreadMessages => Messages.Where(m => LastReadId < m.Id); + /// /// Contains all the messages that are still pending for submission to the server. /// @@ -75,6 +80,9 @@ namespace osu.Game.Online.Chat [JsonProperty(@"last_message_id")] public long? LastMessageId; + [JsonProperty(@"last_read_id")] + public long? LastReadId; + /// /// Signalles if the current user joined this channel or not. Defaults to false. /// diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 1d8c5609d9..e92a4853ff 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -445,6 +445,14 @@ namespace osu.Game.Online.Chat return tcs.Task; } + public void MarkChannelAsRead(Message message) + { + var channel = JoinedChannels.First(c => c.Id == message.ChannelId); + var req = new MarkChannelAsReadRequest(channel, message); + req.Success += () => channel.LastReadId = message.Id; + api.Queue(req); + } + [BackgroundDependencyLoader] private void load(IAPIProvider api) { From 51556a809d578f159387664cf23ce26a856643b1 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Thu, 2 Jan 2020 17:20:33 +0100 Subject: [PATCH 040/628] Fix variables not being used inside target string --- osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs index 3f28037816..76c925588b 100644 --- a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs +++ b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs @@ -16,6 +16,6 @@ namespace osu.Game.Online.API.Requests this.message = message; } - protected override string Target => @"/chat/channels/{channel}/mark-as-read/{message}"; + protected override string Target => $"/chat/channels/{channel}/mark-as-read/{message}"; } } From 79a6655e1f6d64cb4246fc197560e607cccbbe87 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:02:56 +0300 Subject: [PATCH 041/628] Use bindables for colour updates --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 31 +++++++++---------- .../Components/ProfileRulesetTabItem.cs | 12 +++++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index e1cc1de8de..bf24895306 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; -using System; +using osu.Framework.Bindables; namespace osu.Game.Overlays { @@ -22,24 +22,15 @@ namespace osu.Game.Overlays public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; - private Color4 accentColour; + private readonly Bindable accentColour = new Bindable(); + private readonly Bindable currentColour = new Bindable(); public Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => accentColour.Value; + set => accentColour.Value = value; } - protected Action OnStateUpdated; - protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -70,6 +61,9 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); + + currentColour.BindValueChanged(OnCurrentColourChanged); + accentColour.BindValueChanged(_ => updateState()); Enabled.BindValueChanged(_ => updateState(), true); } @@ -92,10 +86,13 @@ namespace osu.Game.Overlays private void updateState() { - var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(updatedColour, 120, Easing.OutQuint); - OnStateUpdated?.Invoke(updatedColour); + + currentColour.Value = IsHovered || Active.Value + ? Color4.White + : Enabled.Value ? AccentColour : Color4.DimGray; } + + protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index d416e98b31..038509d371 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,17 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly SpriteIcon icon; - private bool isDefault; public bool IsDefault @@ -28,6 +28,8 @@ namespace osu.Game.Overlays.Profile.Header.Components } } + private readonly SpriteIcon icon; + public ProfileRulesetTabItem(RulesetInfo value) : base(value) { @@ -40,8 +42,12 @@ namespace osu.Game.Overlays.Profile.Header.Components Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); + } - OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); + protected override void OnCurrentColourChanged(ValueChangedEvent colour) + { + base.OnCurrentColourChanged(colour); + icon.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } } From bd5140c3fa72b79d8f03b6e1eda6ccbd919e12f8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:20:31 +0300 Subject: [PATCH 042/628] Add missing line breaks --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index bf24895306..91cf2d6b96 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -90,7 +90,9 @@ namespace osu.Game.Overlays currentColour.Value = IsHovered || Active.Value ? Color4.White - : Enabled.Value ? AccentColour : Color4.DimGray; + : Enabled.Value + ? AccentColour + : Color4.DimGray; } protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); From 264523bc8babe7c9a5cdfd338b7c86ced3accd5f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 23:22:19 +0300 Subject: [PATCH 043/628] Split ControllableOverlayHeader from base class --- .../BreadcrumbControlOverlayHeader.cs | 2 +- .../Overlays/ControllableOverlayHeader.cs | 41 +++++++++++ osu.Game/Overlays/OverlayHeader.cs | 71 ++++++++----------- osu.Game/Overlays/TabControlOverlayHeader.cs | 2 +- 4 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 osu.Game/Overlays/ControllableOverlayHeader.cs diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index 8a82b1f0c0..d7fa346c15 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { - public abstract class BreadcrumbControlOverlayHeader : OverlayHeader + public abstract class BreadcrumbControlOverlayHeader : ControllableOverlayHeader { protected OverlayHeaderBreadcrumbControl BreadcrumbControl; diff --git a/osu.Game/Overlays/ControllableOverlayHeader.cs b/osu.Game/Overlays/ControllableOverlayHeader.cs new file mode 100644 index 0000000000..30509995dd --- /dev/null +++ b/osu.Game/Overlays/ControllableOverlayHeader.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public abstract class ControllableOverlayHeader : OverlayHeader + { + protected Color4 ControlBackgroundColour + { + set => controlBackground.Colour = value; + } + + private readonly Box controlBackground; + + protected ControllableOverlayHeader() + { + HeaderInfo.Add(new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + controlBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray, + }, + CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) + } + }); + } + + protected abstract TabControl CreateTabControl(); + } +} diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 53da2da634..8c36e8cc9b 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -5,7 +5,6 @@ using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osuTK.Graphics; @@ -14,19 +13,14 @@ namespace osu.Game.Overlays public abstract class OverlayHeader : Container { private readonly Box titleBackground; - private readonly Box controlBackground; private readonly Container background; + protected readonly FillFlowContainer HeaderInfo; protected Color4 TitleBackgroundColour { set => titleBackground.Colour = value; } - protected Color4 ControlBackgroundColour - { - set => controlBackground.Colour = value; - } - protected float BackgroundHeight { set => background.Height = value; @@ -44,47 +38,42 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new[] { - background = new Container - { - RelativeSizeAxes = Axes.X, - Height = 80, - Masking = true, - Child = CreateBackground() - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - titleBackground = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Gray, - }, - CreateTitle().With(title => - { - title.Margin = new MarginPadding - { - Vertical = 10, - Left = UserProfileOverlay.CONTENT_X_MARGIN - }; - }) - } - }, - new Container + HeaderInfo = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Depth = -float.MaxValue, Children = new Drawable[] { - controlBackground = new Box + background = new Container { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Gray, + RelativeSizeAxes = Axes.X, + Height = 80, + Masking = true, + Child = CreateBackground() + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + titleBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray, + }, + CreateTitle().With(title => + { + title.Margin = new MarginPadding + { + Vertical = 10, + Left = UserProfileOverlay.CONTENT_X_MARGIN + }; + }) + } }, - CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) } }, CreateContent() @@ -98,7 +87,5 @@ namespace osu.Game.Overlays protected virtual Drawable CreateContent() => new Container(); protected abstract ScreenTitle CreateTitle(); - - protected abstract TabControl CreateTabControl(); } } diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index f3521b66c8..1e6be9422d 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class TabControlOverlayHeader : OverlayHeader + public abstract class TabControlOverlayHeader : ControllableOverlayHeader { protected OverlayHeaderTabControl TabControl; From 53c8592cb9932d96fd1b4ab2894159c8df34052b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 23:54:56 +0300 Subject: [PATCH 044/628] Add test scene --- .../UserInterface/TestSceneOverlayHeaders.cs | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs new file mode 100644 index 0000000000..60cf0f6885 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs @@ -0,0 +1,168 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneOverlayHeaders : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlayHeader), + typeof(ControllableOverlayHeader), + typeof(TabControlOverlayHeader), + typeof(BreadcrumbControlOverlayHeader), + typeof(TestNoControlHeader), + typeof(TestTabControlHeader), + typeof(TestBreadcrumbControlHeader), + }; + + private readonly FillFlowContainer flow; + + public TestSceneOverlayHeaders() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new BasicScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = flow = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical + } + } + }); + + addHeader("OverlayHeader", new TestNoControlHeader()); + addHeader("TabControlOverlayHeader", new TestTabControlHeader()); + addHeader("BreadcrumbControlOverlayHeader", new TestBreadcrumbControlHeader()); + } + + private void addHeader(string name, OverlayHeader header) + { + flow.Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Margin = new MarginPadding(20), + Text = name, + }, + header + } + }); + } + + private class TestNoControlHeader : OverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + TitleBackgroundColour = colours.GreyVioletDarker; + } + } + + private class TestTabControlHeader : TabControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + public TestTabControlHeader() + { + TabControl.AddItem("tab1"); + TabControl.AddItem("tab2"); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + TitleBackgroundColour = colours.GreyVioletDarker; + ControlBackgroundColour = colours.GreyVioletDark; + TabControl.AccentColour = colours.Violet; + } + } + + private class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + public TestBreadcrumbControlHeader() + { + BreadcrumbControl.AddItem("tab1"); + BreadcrumbControl.AddItem("tab2"); + BreadcrumbControl.Current.Value = "tab2"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + TitleBackgroundColour = colours.GreyVioletDarker; + ControlBackgroundColour = colours.GreyVioletDark; + BreadcrumbControl.AccentColour = colours.Violet; + } + } + + private class TestBackground : Sprite + { + public TestBackground() + { + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fill; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get(@"Headers/changelog"); + } + } + + private class TestTitle : ScreenTitle + { + public TestTitle() + { + Title = "title"; + Section = "section"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.Violet; + } + + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); + } + } +} From 9b95ce1045e0d1eba172e41cf96367e656bedffd Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 4 Jan 2020 00:45:02 +0100 Subject: [PATCH 045/628] Change wrong values used to form target URL Dumb mistake by me, C# used ToString() on these objects. --- osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs index 76c925588b..689fd7e485 100644 --- a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs +++ b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs @@ -16,6 +16,6 @@ namespace osu.Game.Online.API.Requests this.message = message; } - protected override string Target => $"/chat/channels/{channel}/mark-as-read/{message}"; + protected override string Target => $"chat/channels/{channel.Id}/mark-as-read/{message.Id}"; } } From 8dbddfab559830ffe19f3c675af4ca0367a296d3 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 4 Jan 2020 00:45:51 +0100 Subject: [PATCH 046/628] Add HTTP method --- osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs index 689fd7e485..95a5d0acbd 100644 --- a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs +++ b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Net.Http; +using osu.Framework.IO.Network; using osu.Game.Online.Chat; namespace osu.Game.Online.API.Requests @@ -17,5 +19,12 @@ namespace osu.Game.Online.API.Requests } protected override string Target => $"chat/channels/{channel.Id}/mark-as-read/{message.Id}"; + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Put; + return req; + } } } From 4f36bc0fd399a69194d10535ea9c61c8c51f395d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 4 Jan 2020 00:49:35 +0100 Subject: [PATCH 047/628] Add error log message for debugging --- osu.Game/Online/Chat/ChannelManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index e92a4853ff..6eb1674f37 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -450,6 +450,7 @@ namespace osu.Game.Online.Chat var channel = JoinedChannels.First(c => c.Id == message.ChannelId); var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; + req.Failure += (e) => Logger.Error(e, "Failed to mark channel as read"); api.Queue(req); } From 7cc388b5abc56b5d49d9fabe9596db1701b22641 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 4 Jan 2020 00:50:12 +0100 Subject: [PATCH 048/628] Mark channel up to last message as read when switching channels --- osu.Game/Overlays/ChatOverlay.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index e80c51d82a..b64d3a1893 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -279,6 +279,10 @@ namespace osu.Game.Overlays currentChannelContainer.Clear(false); currentChannelContainer.Add(loaded); } + + // mark channel as read when channel switched + if (e.NewValue.Messages.Any()) + channelManager.MarkChannelAsRead(e.NewValue.Messages.Last()); } private float startDragChatHeight; From cd91cc860d52f029fc77b32034eb966cf4a08bba Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 4 Jan 2020 01:06:38 +0100 Subject: [PATCH 049/628] Resolve "Redundant lambda signature parentheses" --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 6eb1674f37..19c3be0d7b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -450,7 +450,7 @@ namespace osu.Game.Online.Chat var channel = JoinedChannels.First(c => c.Id == message.ChannelId); var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; - req.Failure += (e) => Logger.Error(e, "Failed to mark channel as read"); + req.Failure += e => Logger.Error(e, "Failed to mark channel as read"); api.Queue(req); } From 9da7eec0d91f4779c98ec094c321eba952440884 Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Sat, 4 Jan 2020 08:21:48 +0100 Subject: [PATCH 050/628] Add pulse to slider reverse arrows --- .../Objects/Drawables/DrawableRepeatPoint.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index b81d94a673..db8ad98f8a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -65,12 +65,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdateInitialTransforms() { - animDuration = Math.Min(150, repeatPoint.SpanDuration / 2); + animDuration = Math.Min(300, repeatPoint.SpanDuration); - this.Animate( - d => d.FadeIn(animDuration), - d => d.ScaleTo(0.5f).ScaleTo(1f, animDuration * 4, Easing.OutElasticHalf) - ); + this.FadeIn(animDuration); + + double fadeInStart = repeatPoint.StartTime - 2 * repeatPoint.SpanDuration; + + // We want first repeat arrow to start pulsing during snake in + if (repeatPoint.RepeatIndex == 0) + fadeInStart -= repeatPoint.TimePreempt; + + for (double pulseStartTime = fadeInStart; pulseStartTime < repeatPoint.StartTime; pulseStartTime += 300) + this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime)); } protected override void UpdateStateTransforms(ArmedState state) @@ -88,7 +94,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables break; case ArmedState.Hit: - this.FadeOut(animDuration, Easing.OutQuint) + this.FadeOut(animDuration, Easing.Out) .ScaleTo(Scale * 1.5f, animDuration, Easing.Out); break; } From fc0b622a69dc20e0104536d58b15f5a5f67cf45d Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Sat, 4 Jan 2020 10:35:10 +0100 Subject: [PATCH 051/628] Change reverse arrow pulse easing to OutQuad --- .../Objects/Drawables/DrawableRepeatPoint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index db8ad98f8a..e1cacfaaff 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables fadeInStart -= repeatPoint.TimePreempt; for (double pulseStartTime = fadeInStart; pulseStartTime < repeatPoint.StartTime; pulseStartTime += 300) - this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime)); + this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime), Easing.Out); } protected override void UpdateStateTransforms(ArmedState state) From 46271ccbc89e2a55059cda1070d1599321427bca Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Sat, 4 Jan 2020 13:01:42 +0100 Subject: [PATCH 052/628] Add slider reverse arrow pulse settings --- .../Configuration/OsuRulesetConfigManager.cs | 5 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 43 +++++++------- .../Drawables/Pieces/ReverseArrowPiece.cs | 58 +++++++++++++++++++ .../UI/OsuSettingsSubsection.cs | 5 ++ .../UI/ReverseArrowPulseMode.cs | 18 ++++++ 5 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs create mode 100644 osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs index f76635a932..77b0c728b0 100644 --- a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs @@ -3,6 +3,7 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; +using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Osu.Configuration { @@ -19,6 +20,7 @@ namespace osu.Game.Rulesets.Osu.Configuration Set(OsuRulesetSetting.SnakingInSliders, true); Set(OsuRulesetSetting.SnakingOutSliders, true); Set(OsuRulesetSetting.ShowCursorTrail, true); + Set(OsuRulesetSetting.ReverseArrowPulse, ReverseArrowPulseMode.Synced); } } @@ -26,6 +28,7 @@ namespace osu.Game.Rulesets.Osu.Configuration { SnakingInSliders, SnakingOutSliders, - ShowCursorTrail + ShowCursorTrail, + ReverseArrowPulse, } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index e1cacfaaff..1f3c5d54bc 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -6,13 +6,13 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Scoring; using osuTK; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -21,9 +21,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly RepeatPoint repeatPoint; private readonly DrawableSlider drawableSlider; + public readonly Bindable PulseMode = new Bindable(ReverseArrowPulseMode.Synced); + private double animDuration; - private readonly SkinnableDrawable scaleContainer; + private readonly Drawable scaleContainer; + + [Resolved(CanBeNull = true)] + private OsuRulesetConfigManager config { get; set; } public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) : base(repeatPoint) @@ -36,16 +41,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Blending = BlendingParameters.Additive; Origin = Anchor.Centre; - InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon - { - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Solid.ChevronRight, - Size = new Vector2(0.35f) - }, confineMode: ConfineMode.NoScaling) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }; + InternalChild = scaleContainer = new ReverseArrowPiece(); } private readonly IBindable scaleBindable = new Bindable(); @@ -55,6 +51,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { scaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true); scaleBindable.BindTo(HitObject.ScaleBindable); + + config?.BindWith(OsuRulesetSetting.ReverseArrowPulse, PulseMode); } protected override void CheckForResult(bool userTriggered, double timeOffset) @@ -69,14 +67,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables this.FadeIn(animDuration); - double fadeInStart = repeatPoint.StartTime - 2 * repeatPoint.SpanDuration; + if (PulseMode.Value == ReverseArrowPulseMode.Stable) + { + double fadeInStart = repeatPoint.StartTime - 2 * repeatPoint.SpanDuration; - // We want first repeat arrow to start pulsing during snake in - if (repeatPoint.RepeatIndex == 0) - fadeInStart -= repeatPoint.TimePreempt; + // We want first repeat arrow to start pulsing during snake in + if (repeatPoint.RepeatIndex == 0) + fadeInStart -= repeatPoint.TimePreempt; - for (double pulseStartTime = fadeInStart; pulseStartTime < repeatPoint.StartTime; pulseStartTime += 300) - this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime), Easing.Out); + for (double pulseStartTime = fadeInStart; pulseStartTime < repeatPoint.StartTime; pulseStartTime += 300) + this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime), Easing.Out); + } + else if (PulseMode.Value == ReverseArrowPulseMode.Off) + this.ScaleTo(0.5f).ScaleTo(1f, animDuration * 2, Easing.OutElasticHalf); } protected override void UpdateStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs new file mode 100644 index 0000000000..1ec175274e --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osuTK; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Osu.Configuration; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces +{ + public class ReverseArrowPiece : BeatSyncedContainer + { + public readonly Bindable PulseMode = new Bindable(ReverseArrowPulseMode.Synced); + + [Resolved(CanBeNull = true)] + private OsuRulesetConfigManager config { get; set; } + + public ReverseArrowPiece() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Blending = BlendingParameters.Additive; + + Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); + + InternalChild = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + { + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.ChevronRight, + Size = new Vector2(0.35f) + }, confineMode: ConfineMode.NoScaling) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) + { + if (PulseMode.Value == ReverseArrowPulseMode.Synced) + InternalChild.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out); + } + + [BackgroundDependencyLoader] + private void load() + { + config?.BindWith(OsuRulesetSetting.ReverseArrowPulse, PulseMode); + } + } +} diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 88adf72551..afde693316 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -39,6 +39,11 @@ namespace osu.Game.Rulesets.Osu.UI LabelText = "Cursor trail", Bindable = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, + new SettingsEnumDropdown + { + LabelText = "Slider reverse arrow pulse", + Bindable = config.GetBindable(OsuRulesetSetting.ReverseArrowPulse) + }, }; } } diff --git a/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs b/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs new file mode 100644 index 0000000000..d3261e71db --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.ComponentModel; + +namespace osu.Game.Rulesets.Osu.UI +{ + public enum ReverseArrowPulseMode + { + Off, + + [Description("Match osu!stable")] + Stable, + + [Description("Sync to beatmap")] + Synced + } +} From 319465899824dfde4a6ef3150c86651c3afc98f9 Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Sat, 4 Jan 2020 13:12:37 +0100 Subject: [PATCH 053/628] Fix repeat point pulsing when it is in fade out state --- .../Objects/Drawables/DrawableRepeatPoint.cs | 2 +- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 1f3c5d54bc..6bf2f95f41 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Blending = BlendingParameters.Additive; Origin = Anchor.Centre; - InternalChild = scaleContainer = new ReverseArrowPiece(); + InternalChild = scaleContainer = new ReverseArrowPiece(repeatPoint); } private readonly IBindable scaleBindable = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 1ec175274e..114cf9d27e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; @@ -22,8 +23,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces [Resolved(CanBeNull = true)] private OsuRulesetConfigManager config { get; set; } - public ReverseArrowPiece() + private readonly RepeatPoint repeatPoint; + + public ReverseArrowPiece(RepeatPoint repeatPoint) { + this.repeatPoint = repeatPoint; + Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -45,8 +50,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { - if (PulseMode.Value == ReverseArrowPulseMode.Synced) - InternalChild.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out); + if (PulseMode.Value == ReverseArrowPulseMode.Synced && Clock.CurrentTime < repeatPoint.StartTime) + InternalChild.ScaleTo(1.3f).ScaleTo(1f, Math.Min(timingPoint.BeatLength, repeatPoint.StartTime - Clock.CurrentTime), Easing.Out); } [BackgroundDependencyLoader] From e0f66928e6e76dfeef068327a4296d1482baff97 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 7 Jan 2020 01:07:50 +0300 Subject: [PATCH 054/628] Allow CommentsContainer refetch comments using a method --- .../Online/TestSceneCommentsContainer.cs | 28 +++++++---------- .../Overlays/Comments/CommentsContainer.cs | 30 ++++++++++++------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 86bd0ddd11..8134c10750 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -30,29 +30,23 @@ namespace osu.Game.Tests.Visual.Online public TestSceneCommentsContainer() { - BasicScrollContainer scrollFlow; + BasicScrollContainer scroll; + CommentsContainer comments; - Add(scrollFlow = new BasicScrollContainer + Add(scroll = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, + Child = comments = new CommentsContainer() }); - AddStep("Big Black comments", () => + AddStep("Big Black comments", () => comments.ShowComments(CommentableType.Beatmapset, 41823)); + AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); + AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); + AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); + AddStep("Idle state", () => { - scrollFlow.Clear(); - scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 41823)); - }); - - AddStep("Airman comments", () => - { - scrollFlow.Clear(); - scrollFlow.Add(new CommentsContainer(CommentableType.Beatmapset, 24313)); - }); - - AddStep("lazer build comments", () => - { - scrollFlow.Clear(); - scrollFlow.Add(new CommentsContainer(CommentableType.Build, 4772)); + scroll.Clear(); + scroll.Add(comments = new CommentsContainer()); }); } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 560123eb55..584f658673 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { - private readonly CommentableType type; - private readonly long id; + private CommentableType type; + private long id; public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -39,11 +39,8 @@ namespace osu.Game.Overlays.Comments private readonly DeletedChildrenPlaceholder deletedChildrenPlaceholder; private readonly CommentsShowMoreButton moreButton; - public CommentsContainer(CommentableType type, long id) + public CommentsContainer() { - this.type = type; - this.id = id; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; AddRangeInternal(new Drawable[] @@ -101,7 +98,8 @@ namespace osu.Game.Overlays.Comments Anchor = Anchor.Centre, Origin = Anchor.Centre, Margin = new MarginPadding(5), - Action = getComments + Action = getComments, + IsLoading = true, } } } @@ -121,12 +119,24 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { - Sort.BindValueChanged(onSortChanged, true); + Sort.BindValueChanged(_ => resetComments()); base.LoadComplete(); } - private void onSortChanged(ValueChangedEvent sort) + /// The type of resource to get comments for. + /// The id of the resource to get comments for. + public void ShowComments(CommentableType type, long id) { + this.type = type; + this.id = id; + Sort.TriggerChange(); + } + + private void resetComments() + { + if (id == default) + return; + clearComments(); getComments(); } @@ -152,7 +162,7 @@ namespace osu.Game.Overlays.Comments { loadCancellation = new CancellationTokenSource(); - FillFlowContainer page = new FillFlowContainer + var page = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, From 21468eb07011c8774f9de838a5a19d602fe01fc6 Mon Sep 17 00:00:00 2001 From: Sebastian Krajewski Date: Tue, 7 Jan 2020 04:55:05 +0100 Subject: [PATCH 055/628] Remove settings related to reverse arrow --- .../Configuration/OsuRulesetConfigManager.cs | 5 +--- .../Objects/Drawables/DrawableRepeatPoint.cs | 28 +++---------------- .../Drawables/Pieces/ReverseArrowPiece.cs | 17 +---------- .../UI/OsuSettingsSubsection.cs | 5 ---- .../UI/ReverseArrowPulseMode.cs | 18 ------------ 5 files changed, 6 insertions(+), 67 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs index 77b0c728b0..f76635a932 100644 --- a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs @@ -3,7 +3,6 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; -using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Osu.Configuration { @@ -20,7 +19,6 @@ namespace osu.Game.Rulesets.Osu.Configuration Set(OsuRulesetSetting.SnakingInSliders, true); Set(OsuRulesetSetting.SnakingOutSliders, true); Set(OsuRulesetSetting.ShowCursorTrail, true); - Set(OsuRulesetSetting.ReverseArrowPulse, ReverseArrowPulseMode.Synced); } } @@ -28,7 +26,6 @@ namespace osu.Game.Rulesets.Osu.Configuration { SnakingInSliders, SnakingOutSliders, - ShowCursorTrail, - ReverseArrowPulse, + ShowCursorTrail } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 6bf2f95f41..4873160af0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -8,9 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Scoring; using osuTK; @@ -21,15 +19,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly RepeatPoint repeatPoint; private readonly DrawableSlider drawableSlider; - public readonly Bindable PulseMode = new Bindable(ReverseArrowPulseMode.Synced); - private double animDuration; private readonly Drawable scaleContainer; - [Resolved(CanBeNull = true)] - private OsuRulesetConfigManager config { get; set; } - public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider) : base(repeatPoint) { @@ -51,8 +44,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { scaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true); scaleBindable.BindTo(HitObject.ScaleBindable); - - config?.BindWith(OsuRulesetSetting.ReverseArrowPulse, PulseMode); } protected override void CheckForResult(bool userTriggered, double timeOffset) @@ -65,21 +56,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { animDuration = Math.Min(300, repeatPoint.SpanDuration); - this.FadeIn(animDuration); - - if (PulseMode.Value == ReverseArrowPulseMode.Stable) - { - double fadeInStart = repeatPoint.StartTime - 2 * repeatPoint.SpanDuration; - - // We want first repeat arrow to start pulsing during snake in - if (repeatPoint.RepeatIndex == 0) - fadeInStart -= repeatPoint.TimePreempt; - - for (double pulseStartTime = fadeInStart; pulseStartTime < repeatPoint.StartTime; pulseStartTime += 300) - this.Delay(pulseStartTime - LifetimeStart).ScaleTo(1.3f).ScaleTo(1f, Math.Min(300, repeatPoint.StartTime - pulseStartTime), Easing.Out); - } - else if (PulseMode.Value == ReverseArrowPulseMode.Off) - this.ScaleTo(0.5f).ScaleTo(1f, animDuration * 2, Easing.OutElasticHalf); + this.Animate( + d => d.FadeIn(animDuration), + d => d.ScaleTo(0.5f).ScaleTo(1f, animDuration * 2, Easing.OutElasticHalf) + ); } protected override void UpdateStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 114cf9d27e..2b9a3aa197 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -2,27 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using System; -using osu.Framework.Allocation; using osu.Framework.Audio.Track; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osuTK; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; -using osu.Game.Rulesets.Osu.Configuration; -using osu.Game.Rulesets.Osu.UI; using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { public class ReverseArrowPiece : BeatSyncedContainer { - public readonly Bindable PulseMode = new Bindable(ReverseArrowPulseMode.Synced); - - [Resolved(CanBeNull = true)] - private OsuRulesetConfigManager config { get; set; } - private readonly RepeatPoint repeatPoint; public ReverseArrowPiece(RepeatPoint repeatPoint) @@ -50,14 +41,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { - if (PulseMode.Value == ReverseArrowPulseMode.Synced && Clock.CurrentTime < repeatPoint.StartTime) + if (Clock.CurrentTime < repeatPoint.StartTime) InternalChild.ScaleTo(1.3f).ScaleTo(1f, Math.Min(timingPoint.BeatLength, repeatPoint.StartTime - Clock.CurrentTime), Easing.Out); } - - [BackgroundDependencyLoader] - private void load() - { - config?.BindWith(OsuRulesetSetting.ReverseArrowPulse, PulseMode); - } } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index afde693316..88adf72551 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -39,11 +39,6 @@ namespace osu.Game.Rulesets.Osu.UI LabelText = "Cursor trail", Bindable = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, - new SettingsEnumDropdown - { - LabelText = "Slider reverse arrow pulse", - Bindable = config.GetBindable(OsuRulesetSetting.ReverseArrowPulse) - }, }; } } diff --git a/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs b/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs deleted file mode 100644 index d3261e71db..0000000000 --- a/osu.Game.Rulesets.Osu/UI/ReverseArrowPulseMode.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.ComponentModel; - -namespace osu.Game.Rulesets.Osu.UI -{ - public enum ReverseArrowPulseMode - { - Off, - - [Description("Match osu!stable")] - Stable, - - [Description("Sync to beatmap")] - Synced - } -} From 6adf5ba3813482e40cf3e0c391d136e7e9c596e9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 7 Jan 2020 12:29:21 +0300 Subject: [PATCH 056/628] Use nullable long type for id value --- osu.Game/Overlays/Comments/CommentsContainer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 584f658673..97bd0a75e9 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Comments public class CommentsContainer : CompositeDrawable { private CommentableType type; - private long id; + private long? id; public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -134,18 +134,18 @@ namespace osu.Game.Overlays.Comments private void resetComments() { - if (id == default) - return; - clearComments(); getComments(); } private void getComments() { + if (!id.HasValue) + return; + request?.Cancel(); loadCancellation?.Cancel(); - request = new GetCommentsRequest(type, id, Sort.Value, currentPage++); + request = new GetCommentsRequest(type, id.Value, Sort.Value, currentPage++); request.Success += onSuccess; api.Queue(request); } From 7dc03a1335f860ea0e190901bdc27827352e7286 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 7 Jan 2020 12:30:06 +0300 Subject: [PATCH 057/628] resetComments -> refetchComments --- osu.Game/Overlays/Comments/CommentsContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 97bd0a75e9..99f79cd940 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -119,7 +119,7 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { - Sort.BindValueChanged(_ => resetComments()); + Sort.BindValueChanged(_ => refetchComments()); base.LoadComplete(); } @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.Comments Sort.TriggerChange(); } - private void resetComments() + private void refetchComments() { clearComments(); getComments(); From eb828154eeb6a38c45b52d7a48c582122df3fef3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jan 2020 00:41:52 +0300 Subject: [PATCH 058/628] Allow any type to be used to create TabControl --- .../Online/TestSceneUserProfileHeader.cs | 2 +- .../UserInterface/TestSceneOverlayHeaders.cs | 44 ++++++++++++++++--- .../BreadcrumbControlOverlayHeader.cs | 2 +- .../Overlays/ControllableOverlayHeader.cs | 5 ++- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/TabControlOverlayHeader.cs | 19 +++++--- 6 files changed, 56 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 63b46c991f..b4408343c4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileHeader), typeof(RankGraph), typeof(LineGraph), - typeof(TabControlOverlayHeader.OverlayHeaderTabControl), + typeof(TabControlOverlayHeader<>.OverlayHeaderTabControl), typeof(CentreHeaderContainer), typeof(BottomHeaderContainer), typeof(DetailHeaderContainer), diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs index 60cf0f6885..3ed5e53260 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs @@ -22,11 +22,12 @@ namespace osu.Game.Tests.Visual.UserInterface public override IReadOnlyList RequiredTypes => new[] { typeof(OverlayHeader), - typeof(ControllableOverlayHeader), - typeof(TabControlOverlayHeader), + typeof(ControllableOverlayHeader<>), + typeof(TabControlOverlayHeader<>), typeof(BreadcrumbControlOverlayHeader), typeof(TestNoControlHeader), - typeof(TestTabControlHeader), + typeof(TestStringTabControlHeader), + typeof(TestEnumTabControlHeader), typeof(TestBreadcrumbControlHeader), }; @@ -54,7 +55,8 @@ namespace osu.Game.Tests.Visual.UserInterface }); addHeader("OverlayHeader", new TestNoControlHeader()); - addHeader("TabControlOverlayHeader", new TestTabControlHeader()); + addHeader("TabControlOverlayHeader (string)", new TestStringTabControlHeader()); + addHeader("TabControlOverlayHeader (enum)", new TestEnumTabControlHeader()); addHeader("BreadcrumbControlOverlayHeader", new TestBreadcrumbControlHeader()); } @@ -69,10 +71,16 @@ namespace osu.Game.Tests.Visual.UserInterface { new OsuSpriteText { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Margin = new MarginPadding(20), Text = name, }, - header + header.With(header => + { + header.Anchor = Anchor.TopCentre; + header.Origin = Anchor.TopCentre; + }) } }); } @@ -90,13 +98,13 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestTabControlHeader : TabControlOverlayHeader + private class TestStringTabControlHeader : TabControlOverlayHeader { protected override Drawable CreateBackground() => new TestBackground(); protected override ScreenTitle CreateTitle() => new TestTitle(); - public TestTabControlHeader() + public TestStringTabControlHeader() { TabControl.AddItem("tab1"); TabControl.AddItem("tab2"); @@ -111,6 +119,28 @@ namespace osu.Game.Tests.Visual.UserInterface } } + private class TestEnumTabControlHeader : TabControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + TitleBackgroundColour = colours.GreyVioletDarker; + ControlBackgroundColour = colours.GreyVioletDark; + TabControl.AccentColour = colours.Violet; + } + } + + private enum TestEnum + { + Some, + Cool, + Tabs + } + private class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader { protected override Drawable CreateBackground() => new TestBackground(); diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index d7fa346c15..a82ff44505 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { - public abstract class BreadcrumbControlOverlayHeader : ControllableOverlayHeader + public abstract class BreadcrumbControlOverlayHeader : ControllableOverlayHeader { protected OverlayHeaderBreadcrumbControl BreadcrumbControl; diff --git a/osu.Game/Overlays/ControllableOverlayHeader.cs b/osu.Game/Overlays/ControllableOverlayHeader.cs index 30509995dd..9b2bf526ca 100644 --- a/osu.Game/Overlays/ControllableOverlayHeader.cs +++ b/osu.Game/Overlays/ControllableOverlayHeader.cs @@ -9,7 +9,8 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class ControllableOverlayHeader : OverlayHeader + /// The type of item to be represented by tabs in . + public abstract class ControllableOverlayHeader : OverlayHeader { protected Color4 ControlBackgroundColour { @@ -36,6 +37,6 @@ namespace osu.Game.Overlays }); } - protected abstract TabControl CreateTabControl(); + protected abstract TabControl CreateTabControl(); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 59e64dfc26..768344dfee 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Profile { - public class ProfileHeader : TabControlOverlayHeader + public class ProfileHeader : TabControlOverlayHeader { private UserCoverBackground coverContainer; diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index 1e6be9422d..d108af4348 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; @@ -9,13 +10,13 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class TabControlOverlayHeader : ControllableOverlayHeader + public abstract class TabControlOverlayHeader : ControllableOverlayHeader { protected OverlayHeaderTabControl TabControl; - protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl(); + protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl(); - public class OverlayHeaderTabControl : OverlayTabControl + public class OverlayHeaderTabControl : OverlayTabControl { public OverlayHeaderTabControl() { @@ -25,9 +26,15 @@ namespace osu.Game.Overlays Anchor = Anchor.BottomLeft; Origin = Anchor.BottomLeft; Height = 35; + + if (typeof(T).IsEnum) + { + foreach (var val in (T[])Enum.GetValues(typeof(T))) + AddItem(val); + } } - protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value) + protected override TabItem CreateTabItem(T value) => new OverlayHeaderTabItem(value) { AccentColour = AccentColour, }; @@ -42,10 +49,10 @@ namespace osu.Game.Overlays private class OverlayHeaderTabItem : OverlayTabItem { - public OverlayHeaderTabItem(string value) + public OverlayHeaderTabItem(T value) : base(value) { - Text.Text = value; + Text.Text = value.ToString().ToLowerInvariant(); Text.Font = OsuFont.GetFont(size: 14); Bar.ExpandedSize = 5; } From 351aaf41d93765cb7e85a7299e18deffc10df473 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jan 2020 00:54:02 +0300 Subject: [PATCH 059/628] Fix parameter naming --- .../Visual/UserInterface/TestSceneOverlayHeaders.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs index 3ed5e53260..bede4e38b8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaders.cs @@ -76,10 +76,10 @@ namespace osu.Game.Tests.Visual.UserInterface Margin = new MarginPadding(20), Text = name, }, - header.With(header => + header.With(h => { - header.Anchor = Anchor.TopCentre; - header.Origin = Anchor.TopCentre; + h.Anchor = Anchor.TopCentre; + h.Origin = Anchor.TopCentre; }) } }); From c2fc7d5cbdb721887020dabc326bcf4443855da4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 6 Jan 2020 19:48:28 +0800 Subject: [PATCH 060/628] Add empty benchmark project. --- osu.Desktop.slnf | 1 + osu.Game.Benchmarks/Program.cs | 13 +++++++++++++ osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 9 +++++++++ osu.sln | 14 ++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 osu.Game.Benchmarks/Program.cs create mode 100644 osu.Game.Benchmarks/osu.Game.Benchmarks.csproj diff --git a/osu.Desktop.slnf b/osu.Desktop.slnf index e6b6446f72..d2c14d321a 100644 --- a/osu.Desktop.slnf +++ b/osu.Desktop.slnf @@ -3,6 +3,7 @@ "path": "osu.sln", "projects": [ "osu.Desktop\\osu.Desktop.csproj", + "osu.Game.Benchmarks\\osu.Game.Benchmarks.csproj", "osu.Game.Rulesets.Catch.Tests\\osu.Game.Rulesets.Catch.Tests.csproj", "osu.Game.Rulesets.Catch\\osu.Game.Rulesets.Catch.csproj", "osu.Game.Rulesets.Mania.Tests\\osu.Game.Rulesets.Mania.Tests.csproj", diff --git a/osu.Game.Benchmarks/Program.cs b/osu.Game.Benchmarks/Program.cs new file mode 100644 index 0000000000..ebd30c0a7a --- /dev/null +++ b/osu.Game.Benchmarks/Program.cs @@ -0,0 +1,13 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Benchmarks +{ + public static class Program + { + public static void Main(string[] args) + { + + } + } +} diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj new file mode 100644 index 0000000000..65bfa2be14 --- /dev/null +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -0,0 +1,9 @@ + + + + netcoreapp3.1 + Exe + false + + + diff --git a/osu.sln b/osu.sln index 79823848f0..1d64f6ff10 100644 --- a/osu.sln +++ b/osu.sln @@ -65,6 +65,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution osu.TestProject.props = osu.TestProject.props EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Benchmarks", "osu.Game.Benchmarks\osu.Game.Benchmarks.csproj", "{93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -399,6 +401,18 @@ Global {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|Any CPU.Build.0 = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|iPhone.Build.0 = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|Any CPU.ActiveCfg = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|Any CPU.Build.0 = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|iPhone.ActiveCfg = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|iPhone.Build.0 = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}.Release|iPhoneSimulator.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 1b9f8d27372f247ee3213ec7422536a691a470af Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 8 Jan 2020 20:36:00 +0800 Subject: [PATCH 061/628] Add benchmark runner. --- osu.Game.Benchmarks/BenchmarkTest.cs | 23 +++++++++++++++++++ osu.Game.Benchmarks/Program.cs | 6 ++++- .../osu.Game.Benchmarks.csproj | 10 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Benchmarks/BenchmarkTest.cs diff --git a/osu.Game.Benchmarks/BenchmarkTest.cs b/osu.Game.Benchmarks/BenchmarkTest.cs new file mode 100644 index 0000000000..34f5edd084 --- /dev/null +++ b/osu.Game.Benchmarks/BenchmarkTest.cs @@ -0,0 +1,23 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using NUnit.Framework; + +namespace osu.Game.Benchmarks +{ + [TestFixture] + [MemoryDiagnoser] + public abstract class BenchmarkTest + { + [GlobalSetup] + [OneTimeSetUp] + public virtual void SetUp() + { + } + + [Test] + public void RunBenchmark() => BenchmarkRunner.Run(GetType()); + } +} diff --git a/osu.Game.Benchmarks/Program.cs b/osu.Game.Benchmarks/Program.cs index ebd30c0a7a..c55075fea6 100644 --- a/osu.Game.Benchmarks/Program.cs +++ b/osu.Game.Benchmarks/Program.cs @@ -1,13 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using BenchmarkDotNet.Running; + namespace osu.Game.Benchmarks { public static class Program { public static void Main(string[] args) { - + BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); } } } diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index 65bfa2be14..3281fcc855 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -6,4 +6,14 @@ false + + + + + + + + + + From bd22d5b0f44522bf8293cfb9e8f9e69232534a6c Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 8 Jan 2020 21:31:58 +0800 Subject: [PATCH 062/628] Add benchmark launch profiles. --- .../.idea/runConfigurations/Benchmarks.xml | 20 +++++++++++++++++ .vscode/launch.json | 19 ++++++++++++++-- .vscode/tasks.json | 22 +++++++++++++++++-- .../Properties/launchSettings.json | 8 +++++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 .idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml create mode 100644 osu.Game.Benchmarks/Properties/launchSettings.json diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml new file mode 100644 index 0000000000..1815c271b4 --- /dev/null +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index e7b691909e..6480612b2e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,7 @@ { "version": "0.2.0", - "configurations": [{ + "configurations": [ + { "name": "osu! (Debug)", "type": "coreclr", "request": "launch", @@ -50,7 +51,8 @@ } }, "console": "internalConsole" - }, { + }, + { "name": "osu! (Tests, Release)", "type": "coreclr", "request": "launch", @@ -139,6 +141,19 @@ }, "console": "internalConsole" }, + { + "name": "Benchmark", + "type": "coreclr", + "request": "launch", + "program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/netcoreapp3.1/osu.Game.Benchmarks.dll", + "args": [ + "--filter", + "*" + ], + "cwd": "${workspaceRoot}", + "preLaunchTask": "Build benchmarks", + "console": "internalConsole" + }, { "name": "Cake: Debug Script", "type": "coreclr", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index c087800d2a..e638dec767 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,7 +2,8 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", - "tasks": [{ + "tasks": [ + { "label": "Build osu! (Debug)", "type": "shell", "command": "dotnet", @@ -78,7 +79,8 @@ ], "group": "build", "problemMatcher": "$msCompile" - }, { + }, + { "label": "Build tournament tests (Release)", "type": "shell", "command": "dotnet", @@ -94,6 +96,22 @@ "group": "build", "problemMatcher": "$msCompile" }, + { + "label": "Build benchmarks", + "type": "shell", + "command": "dotnet", + "args": [ + "build", + "--no-restore", + "osu.Game.Benchmarks", + "/p:Configuration=Release", + "/p:GenerateFullPaths=true", + "/m", + "/verbosity:m" + ], + "group": "build", + "problemMatcher": "$msCompile" + }, { "label": "Restore (netcoreapp3.1)", "type": "shell", diff --git a/osu.Game.Benchmarks/Properties/launchSettings.json b/osu.Game.Benchmarks/Properties/launchSettings.json new file mode 100644 index 0000000000..c1868088f9 --- /dev/null +++ b/osu.Game.Benchmarks/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "All Benchmarks": { + "commandName": "Project", + "commandLineArgs": "--filter *" + } + } +} \ No newline at end of file From 7f393c61f8679e4a57847a97a07d6988b1b3a2f4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 8 Jan 2020 21:55:39 +0800 Subject: [PATCH 063/628] Add BDN artifacts to gitignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e6b5db5904..732b171f69 100644 --- a/.gitignore +++ b/.gitignore @@ -331,3 +331,6 @@ fastlane/report.xml # inspectcode inspectcodereport.xml inspectcode + +# BenchmarkDotNet +/BenchmarkDotNet.Artifacts From 14289523777302fbcb3aa3c524964f9d43a365af Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jan 2020 18:59:13 +0300 Subject: [PATCH 064/628] Implement CountryFilter component for RankingsOverlay --- .../Online/TestSceneRankingsCountryFilter.cs | 45 ++++ osu.Game/Overlays/Rankings/CountryFilter.cs | 231 ++++++++++++++++++ 2 files changed, 276 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs create mode 100644 osu.Game/Overlays/Rankings/CountryFilter.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs new file mode 100644 index 0000000000..968be62a7c --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Bindables; +using osu.Game.Overlays.Rankings; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneRankingsCountryFilter : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CountryFilter), + }; + + public TestSceneRankingsCountryFilter() + { + var countryBindable = new Bindable(); + CountryFilter filter; + + Add(filter = new CountryFilter + { + Country = { BindTarget = countryBindable } + }); + + var country = new Country + { + FlagName = "BY", + FullName = "Belarus" + }; + var unknownCountry = new Country + { + FlagName = "CK", + FullName = "Cook Islands" + }; + + AddStep("Set country", () => countryBindable.Value = country); + AddStep("Set null country", () => countryBindable.Value = null); + AddStep("Set country with no flag", () => countryBindable.Value = unknownCountry); + } + } +} diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs new file mode 100644 index 0000000000..4a24a440cc --- /dev/null +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -0,0 +1,231 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Users; +using osu.Game.Users.Drawables; +using osuTK; + +namespace osu.Game.Overlays.Rankings +{ + public class CountryFilter : Container + { + private const int duration = 200; + private const int height = 50; + + public readonly Bindable Country = new Bindable(); + + private readonly Box background; + private readonly CountryPill countryPill; + private readonly Container content; + + public CountryFilter() + { + RelativeSizeAxes = Axes.X; + Child = content = new Container + { + RelativeSizeAxes = Axes.X, + Height = height, + Alpha = 0, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = @"filtered by country:", + Font = OsuFont.GetFont(size: 14) + }, + countryPill = new CountryPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Alpha = 0, + Country = { BindTarget = Country } + } + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoam; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Country.BindValueChanged(onCountryChanged, true); + } + + private void onCountryChanged(ValueChangedEvent country) + { + countryPill.ClearTransforms(); + + if (country.NewValue == null) + { + countryPill.Collapse(); + this.ResizeHeightTo(0, duration, Easing.OutQuint); + content.FadeOut(duration, Easing.OutQuint); + return; + } + + this.ResizeHeightTo(height, duration, Easing.OutQuint); + content.FadeIn(duration, Easing.OutQuint).Finally(_ => countryPill.Expand()); + } + + private class CountryPill : CircularContainer + { + private readonly Box background; + private readonly UpdateableFlag flag; + private readonly OsuSpriteText countryName; + + public readonly Bindable Country = new Bindable(); + + public CountryPill() + { + AutoSizeDuration = duration; + AutoSizeEasing = Easing.OutQuint; + Height = 25; + Masking = true; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Margin = new MarginPadding { Horizontal = 10 }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(8, 0), + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] + { + flag = new UpdateableFlag + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(22, 15) + }, + countryName = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 14) + } + } + }, + new CloseButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + ClickAction = () => Country.Value = null + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Country.BindValueChanged(onCountryChanged, true); + } + + public void Expand() + { + AutoSizeAxes = Axes.X; + this.FadeIn(duration, Easing.OutQuint); + } + + public void Collapse() + { + AutoSizeAxes = Axes.None; + this.ResizeWidthTo(0, duration, Easing.OutQuint); + this.FadeOut(duration, Easing.OutQuint); + } + + private void onCountryChanged(ValueChangedEvent country) + { + if (country.NewValue == null) + return; + + flag.Country = country.NewValue; + countryName.Text = country.NewValue.FullName; + } + + private class CloseButton : Container + { + public Action ClickAction; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + new SpriteIcon + { + Size = new Vector2(8), + Icon = FontAwesome.Solid.Times, + Colour = colours.GreySeafoamLighter, + }, + new HoverClickSounds(), + }; + } + + protected override bool OnClick(ClickEvent e) + { + ClickAction?.Invoke(); + return base.OnClick(e); + } + } + } + } +} From dc64ba8ed81d21aef0c4368f53c5fcfda795161a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jan 2020 19:22:07 +0300 Subject: [PATCH 065/628] Remove unused variable --- osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs index 968be62a7c..9a8ddf9cad 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -19,9 +19,8 @@ namespace osu.Game.Tests.Visual.Online public TestSceneRankingsCountryFilter() { var countryBindable = new Bindable(); - CountryFilter filter; - Add(filter = new CountryFilter + Add(new CountryFilter { Country = { BindTarget = countryBindable } }); From 1dbae21f981852f878154d73af241d7e44e0073a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 8 Jan 2020 19:40:28 +0300 Subject: [PATCH 066/628] Fix crashing test --- osu.Game/Overlays/Rankings/CountryFilter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index 4a24a440cc..008214a9a4 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -86,6 +86,7 @@ namespace osu.Game.Overlays.Rankings private void onCountryChanged(ValueChangedEvent country) { + content.ClearTransforms(); countryPill.ClearTransforms(); if (country.NewValue == null) From 6cb763a019b3ecc34d47d683390a5b476ee94334 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jan 2020 00:06:28 +0300 Subject: [PATCH 067/628] Improve animations --- osu.Game/Overlays/Rankings/CountryFilter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index 008214a9a4..5452bc9327 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -86,9 +86,6 @@ namespace osu.Game.Overlays.Rankings private void onCountryChanged(ValueChangedEvent country) { - content.ClearTransforms(); - countryPill.ClearTransforms(); - if (country.NewValue == null) { countryPill.Collapse(); @@ -98,7 +95,8 @@ namespace osu.Game.Overlays.Rankings } this.ResizeHeightTo(height, duration, Easing.OutQuint); - content.FadeIn(duration, Easing.OutQuint).Finally(_ => countryPill.Expand()); + content.FadeIn(duration, Easing.OutQuint); + countryPill.Expand(); } private class CountryPill : CircularContainer @@ -181,12 +179,14 @@ namespace osu.Game.Overlays.Rankings public void Expand() { + ClearTransforms(); AutoSizeAxes = Axes.X; this.FadeIn(duration, Easing.OutQuint); } public void Collapse() { + ClearTransforms(); AutoSizeAxes = Axes.None; this.ResizeWidthTo(0, duration, Easing.OutQuint); this.FadeOut(duration, Easing.OutQuint); From 29c4ae68d91e8bb06f6197eb7da2ee24dc2725bb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jan 2020 00:14:29 +0300 Subject: [PATCH 068/628] Add some content to test scene for better visual representation --- .../Online/TestSceneRankingsCountryFilter.cs | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs index 9a8ddf9cad..360bb81715 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -4,8 +4,13 @@ using System; using System.Collections.Generic; using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Rankings; using osu.Game.Users; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; +using osu.Game.Graphics.Sprites; namespace osu.Game.Tests.Visual.Online { @@ -20,9 +25,35 @@ namespace osu.Game.Tests.Visual.Online { var countryBindable = new Bindable(); - Add(new CountryFilter + AddRange(new Drawable[] { - Country = { BindTarget = countryBindable } + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new CountryFilter + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Country = { BindTarget = countryBindable } + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Some content", + Margin = new MarginPadding { Vertical = 20 } + } + } + } }); var country = new Country From 0d9fb065da462b36074c9b292cc50c001b39236a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 9 Jan 2020 00:27:22 +0300 Subject: [PATCH 069/628] Move CountryPill to it's own class --- .../Online/TestSceneRankingsCountryFilter.cs | 1 + osu.Game/Overlays/Rankings/CountryFilter.cs | 135 ---------------- osu.Game/Overlays/Rankings/CountryPill.cs | 149 ++++++++++++++++++ 3 files changed, 150 insertions(+), 135 deletions(-) create mode 100644 osu.Game/Overlays/Rankings/CountryPill.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs index 360bb81715..3d38710b59 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -19,6 +19,7 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(CountryFilter), + typeof(CountryPill) }; public TestSceneRankingsCountryFilter() diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index 5452bc9327..7cd56100db 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -1,19 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Users; -using osu.Game.Users.Drawables; using osuTK; namespace osu.Game.Overlays.Rankings @@ -98,135 +93,5 @@ namespace osu.Game.Overlays.Rankings content.FadeIn(duration, Easing.OutQuint); countryPill.Expand(); } - - private class CountryPill : CircularContainer - { - private readonly Box background; - private readonly UpdateableFlag flag; - private readonly OsuSpriteText countryName; - - public readonly Bindable Country = new Bindable(); - - public CountryPill() - { - AutoSizeDuration = duration; - AutoSizeEasing = Easing.OutQuint; - Height = 25; - Masking = true; - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both - }, - new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Margin = new MarginPadding { Horizontal = 10 }, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(8, 0), - Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - flag = new UpdateableFlag - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(22, 15) - }, - countryName = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 14) - } - } - }, - new CloseButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - ClickAction = () => Country.Value = null - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.GreySeafoamDarker; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - Country.BindValueChanged(onCountryChanged, true); - } - - public void Expand() - { - ClearTransforms(); - AutoSizeAxes = Axes.X; - this.FadeIn(duration, Easing.OutQuint); - } - - public void Collapse() - { - ClearTransforms(); - AutoSizeAxes = Axes.None; - this.ResizeWidthTo(0, duration, Easing.OutQuint); - this.FadeOut(duration, Easing.OutQuint); - } - - private void onCountryChanged(ValueChangedEvent country) - { - if (country.NewValue == null) - return; - - flag.Country = country.NewValue; - countryName.Text = country.NewValue.FullName; - } - - private class CloseButton : Container - { - public Action ClickAction; - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - AutoSizeAxes = Axes.Both; - Children = new Drawable[] - { - new SpriteIcon - { - Size = new Vector2(8), - Icon = FontAwesome.Solid.Times, - Colour = colours.GreySeafoamLighter, - }, - new HoverClickSounds(), - }; - } - - protected override bool OnClick(ClickEvent e) - { - ClickAction?.Invoke(); - return base.OnClick(e); - } - } - } } } diff --git a/osu.Game/Overlays/Rankings/CountryPill.cs b/osu.Game/Overlays/Rankings/CountryPill.cs new file mode 100644 index 0000000000..65fce3b909 --- /dev/null +++ b/osu.Game/Overlays/Rankings/CountryPill.cs @@ -0,0 +1,149 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; +using osu.Game.Users.Drawables; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Rankings +{ + public class CountryPill : CircularContainer + { + private const int duration = 200; + + private readonly Box background; + private readonly UpdateableFlag flag; + private readonly OsuSpriteText countryName; + + public readonly Bindable Country = new Bindable(); + + public CountryPill() + { + AutoSizeDuration = duration; + AutoSizeEasing = Easing.OutQuint; + Height = 25; + Masking = true; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Margin = new MarginPadding { Horizontal = 10 }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(8, 0), + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] + { + flag = new UpdateableFlag + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(22, 15) + }, + countryName = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 14) + } + } + }, + new CloseButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Action = () => Country.Value = null + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Country.BindValueChanged(onCountryChanged, true); + } + + public void Expand() + { + ClearTransforms(); + AutoSizeAxes = Axes.X; + this.FadeIn(duration, Easing.OutQuint); + } + + public void Collapse() + { + ClearTransforms(); + AutoSizeAxes = Axes.None; + this.ResizeWidthTo(0, duration, Easing.OutQuint); + this.FadeOut(duration, Easing.OutQuint); + } + + private void onCountryChanged(ValueChangedEvent country) + { + if (country.NewValue == null) + return; + + flag.Country = country.NewValue; + countryName.Text = country.NewValue.FullName; + } + + private class CloseButton : OsuHoverContainer + { + private readonly SpriteIcon icon; + + protected override IEnumerable EffectTargets => new[] { icon }; + + public CloseButton() + { + AutoSizeAxes = Axes.Both; + Add(icon = new SpriteIcon + { + Size = new Vector2(8), + Icon = FontAwesome.Solid.Times + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IdleColour = colours.GreySeafoamLighter; + HoverColour = Color4.White; + } + } + } +} From 20f426cda0348a8ad4f45cd7b75b0d3ce8a91951 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 8 Jan 2020 22:06:18 +0800 Subject: [PATCH 070/628] Add beatmap parsing as sample benchmark. --- .../BenchmarkBeatmapParsing.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs diff --git a/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs b/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs new file mode 100644 index 0000000000..394fd75488 --- /dev/null +++ b/osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.IO; +using BenchmarkDotNet.Attributes; +using osu.Framework.IO.Stores; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Formats; +using osu.Game.IO; +using osu.Game.IO.Archives; +using osu.Game.Resources; + +namespace osu.Game.Benchmarks +{ + public class BenchmarkBeatmapParsing : BenchmarkTest + { + private readonly MemoryStream beatmapStream = new MemoryStream(); + + public override void SetUp() + { + using (var resources = new DllResourceStore(OsuResources.ResourceAssembly)) + using (var archive = resources.GetStream("Beatmaps/241526 Soleily - Renatus.osz")) + using (var reader = new ZipArchiveReader(archive)) + reader.GetStream("Soleily - Renatus (Gamu) [Insane].osu").CopyTo(beatmapStream); + } + + [Benchmark] + public Beatmap BenchmarkBundledBeatmap() + { + beatmapStream.Seek(0, SeekOrigin.Begin); + var reader = new LineBufferedReader(beatmapStream); // no disposal + + var decoder = Decoder.GetDecoder(reader); + return decoder.Decode(reader); + } + } +} From c4131e01da7341984450a11d8e5349f02e2c0d58 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 10 Jan 2020 20:20:44 +0800 Subject: [PATCH 071/628] Downgrade NUnit for now. --- osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index 3281fcc855..f2e1c0ec3b 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -9,7 +9,7 @@ - + From f65f030e79ff6756fe11156311e1bceaf95720f0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 15:48:54 +0300 Subject: [PATCH 072/628] Implement GetSpotlightsRequest --- .../API/Requests/GetSpotlightsRequest.cs | 13 +++++++ .../API/Requests/Responses/APISpotlight.cs | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetSpotlightsRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APISpotlight.cs diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs new file mode 100644 index 0000000000..7a6a988c09 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -0,0 +1,13 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetSpotlightsRequest : APIRequest> + { + protected override string Target => "spotlights"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs new file mode 100644 index 0000000000..210ef04dac --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APISpotlight + { + [JsonProperty("id")] + public int Id; + + [JsonProperty("name")] + public string Name; + + [JsonProperty("type")] + public string Type; + + [JsonProperty("mode_specific")] + public bool ModeSpecific; + + [JsonProperty(@"start_date")] + public DateTimeOffset StartDate; + + [JsonProperty(@"end_date")] + public DateTimeOffset EndDate; + + [JsonProperty(@"participant_count")] + public int? ParticipiantCount; + + public override string ToString() => Name; + } +} From 08fb68ddfeddb891b2ddc9972544a0bf6f2bff68 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:28:52 +0300 Subject: [PATCH 073/628] Fix incorrect return type for spotlight request --- osu.Game/Online/API/Requests/GetSpotlightsRequest.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs index 7a6a988c09..d5b03e52e2 100644 --- a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -2,12 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using Newtonsoft.Json; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetSpotlightsRequest : APIRequest> + public class GetSpotlightsRequest : APIRequest { protected override string Target => "spotlights"; } + + public class SpotlightsArray + { + [JsonProperty("spotlights")] + public List Spotlights; + } } From d48b161662ec0058d8f1aed526bb5fa1d9d1af50 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:33:00 +0300 Subject: [PATCH 074/628] Implement basic SpotlightSelector component --- .../TestSceneRankingsSpotlightSelector.cs | 28 ++++++++ .../Overlays/Rankings/SpotlightSelector.cs | 67 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs create mode 100644 osu.Game/Overlays/Rankings/SpotlightSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs new file mode 100644 index 0000000000..9320213844 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Overlays.Rankings; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneRankingsSpotlightSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(SpotlightSelector), + }; + + protected override bool UseOnlineAPI => true; + + public TestSceneRankingsSpotlightSelector() + { + SpotlightSelector selector; + + Add(selector = new SpotlightSelector()); + + AddStep("Fetch spotlights", selector.FetchSpotlights); + } + } +} diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs new file mode 100644 index 0000000000..95bcc10631 --- /dev/null +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -0,0 +1,67 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Rankings +{ + public class SpotlightSelector : Container + { + private readonly Box background; + private readonly OsuDropdown dropdown; + private readonly DimmedLoadingLayer loading; + + [Resolved] + private IAPIProvider api { get; set; } + + public SpotlightSelector() + { + RelativeSizeAxes = Axes.X; + Height = 200; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + dropdown = new OsuDropdown + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Width = 0.8f, + Margin = new MarginPadding { Top = 10 } + }, + loading = new DimmedLoadingLayer(), + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoam; + dropdown.AccentColour = colours.GreySeafoamDarker; + } + + public void FetchSpotlights() + { + loading.Show(); + + var request = new GetSpotlightsRequest(); + request.Success += response => + { + dropdown.Items = response.Spotlights; + loading.Hide(); + }; + api.Queue(request); + } + } +} From 474d7e92d92ef7a20dc07ee4a75cb2e62b5bd2e2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:41:17 +0300 Subject: [PATCH 075/628] Fix incorrect dropdown menu height --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 95bcc10631..482db10796 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Rankings public class SpotlightSelector : Container { private readonly Box background; - private readonly OsuDropdown dropdown; + private readonly SpotlightsDropdown dropdown; private readonly DimmedLoadingLayer loading; [Resolved] @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.Both, }, - dropdown = new OsuDropdown + dropdown = new SpotlightsDropdown { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -63,5 +63,10 @@ namespace osu.Game.Overlays.Rankings }; api.Queue(request); } + + private class SpotlightsDropdown : OsuDropdown + { + protected override DropdownMenu CreateMenu() => base.CreateMenu().With(menu => menu.MaxHeight = 400); + } } } From 2e627f4b7c4f52d827941399cf67fce87087ebc3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 17:30:51 +0300 Subject: [PATCH 076/628] Implement InfoColumn component --- .../Overlays/Rankings/SpotlightSelector.cs | 111 ++++++++++++++++-- 1 file changed, 102 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 482db10796..66c5f37917 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -2,14 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osuTK; +using System; namespace osu.Game.Overlays.Rankings { @@ -22,23 +26,49 @@ namespace osu.Game.Overlays.Rankings [Resolved] private IAPIProvider api { get; set; } + public readonly Bindable SelectedSpotlight = new Bindable(); + + private readonly InfoCoulmn startDateColumn; + private readonly InfoCoulmn endDateColumn; + public SpotlightSelector() { RelativeSizeAxes = Axes.X; - Height = 200; + Height = 100; Children = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - dropdown = new SpotlightsDropdown + new Container { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Width = 0.8f, - Margin = new MarginPadding { Top = 10 } + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Children = new Drawable[] + { + dropdown = new SpotlightsDropdown + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Current = SelectedSpotlight, + Depth = -float.MaxValue + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] + { + startDateColumn = new InfoCoulmn(@"Start Date"), + endDateColumn = new InfoCoulmn(@"End Date"), + } + } + } }, loading = new DimmedLoadingLayer(), }; @@ -48,7 +78,12 @@ namespace osu.Game.Overlays.Rankings private void load(OsuColour colours) { background.Colour = colours.GreySeafoam; - dropdown.AccentColour = colours.GreySeafoamDarker; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + SelectedSpotlight.BindValueChanged(onSelectionChanged); } public void FetchSpotlights() @@ -64,9 +99,67 @@ namespace osu.Game.Overlays.Rankings api.Queue(request); } + private void onSelectionChanged(ValueChangedEvent spotlight) + { + startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); + endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + } + + private string dateToString(DateTimeOffset date) => $"{date.Year}-{date.Month:D2}-{date.Day:D2}"; + + private class InfoCoulmn : FillFlowContainer + { + public string Value + { + set => valueText.Text = value; + } + + private readonly OsuSpriteText valueText; + + public InfoCoulmn(string name) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Vertical; + Children = new Drawable[] + { + new OsuSpriteText + { + Text = name, + Font = OsuFont.GetFont(size: 10), + }, + new Container + { + AutoSizeAxes = Axes.X, + Height = 20, + Child = valueText = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Light), + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + valueText.Colour = colours.GreySeafoamLighter; + } + } + private class SpotlightsDropdown : OsuDropdown { - protected override DropdownMenu CreateMenu() => base.CreateMenu().With(menu => menu.MaxHeight = 400); + private DropdownMenu menu; + + protected override DropdownMenu CreateMenu() => menu = base.CreateMenu().With(m => m.MaxHeight = 400); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + menu.BackgroundColour = colours.Gray1; + AccentColour = colours.GreySeafoamDarker; + } } } } From 9260ea91955fdcf56e4edbbb3770e39ac0eb21a0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 20:46:35 +0300 Subject: [PATCH 077/628] Apply suggestions --- .../Online/API/Requests/GetSpotlightsRequest.cs | 4 ++-- .../Online/API/Requests/Responses/APISpotlight.cs | 2 +- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs index d5b03e52e2..6fafb3933c 100644 --- a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -7,12 +7,12 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetSpotlightsRequest : APIRequest + public class GetSpotlightsRequest : APIRequest { protected override string Target => "spotlights"; } - public class SpotlightsArray + public class SpotlightsCollection { [JsonProperty("spotlights")] public List Spotlights; diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 210ef04dac..63c47e7812 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset EndDate; [JsonProperty(@"participant_count")] - public int? ParticipiantCount; + public int? ParticipantCount; public override string ToString() => Name; } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 66c5f37917..fb61555c20 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -28,8 +28,8 @@ namespace osu.Game.Overlays.Rankings public readonly Bindable SelectedSpotlight = new Bindable(); - private readonly InfoCoulmn startDateColumn; - private readonly InfoCoulmn endDateColumn; + private readonly InfoColumn startDateColumn; + private readonly InfoColumn endDateColumn; public SpotlightSelector() { @@ -64,8 +64,8 @@ namespace osu.Game.Overlays.Rankings Spacing = new Vector2(15, 0), Children = new Drawable[] { - startDateColumn = new InfoCoulmn(@"Start Date"), - endDateColumn = new InfoCoulmn(@"End Date"), + startDateColumn = new InfoColumn(@"Start Date"), + endDateColumn = new InfoColumn(@"End Date"), } } } @@ -105,9 +105,9 @@ namespace osu.Game.Overlays.Rankings endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); } - private string dateToString(DateTimeOffset date) => $"{date.Year}-{date.Month:D2}-{date.Day:D2}"; + private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); - private class InfoCoulmn : FillFlowContainer + private class InfoColumn : FillFlowContainer { public string Value { @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Rankings private readonly OsuSpriteText valueText; - public InfoCoulmn(string name) + public InfoColumn(string name) { AutoSizeAxes = Axes.Both; Direction = FillDirection.Vertical; From 19033e0ef85fba4086d303825718de15affc268c Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 10 Jan 2020 19:25:33 -0800 Subject: [PATCH 078/628] Fix user status dropdown having no padding around items --- osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 27796c1e32..e485aa5ea9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -323,8 +323,6 @@ namespace osu.Game.Overlays.Settings.Sections.General Colour = Color4.Black.Opacity(0.25f), Radius = 4, }; - - ItemsContainer.Padding = new MarginPadding(); } [BackgroundDependencyLoader] From 6500cc967fff845a8e65cd3fc1a7a666be43669e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 06:58:35 +0300 Subject: [PATCH 079/628] Implement SongTicker component --- osu.Game/Screens/Menu/MainMenu.cs | 7 +++ osu.Game/Screens/Menu/SongTicker.cs | 66 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 osu.Game/Screens/Menu/SongTicker.cs diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index b28d572b5c..47c86fc1ae 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -75,6 +75,13 @@ namespace osu.Game.Screens.Menu holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); + AddInternal(new SongTicker + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = 15 } + }); + if (host.CanExit) { AddInternal(exitConfirmOverlay = new ExitConfirmOverlay diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs new file mode 100644 index 0000000000..504b016019 --- /dev/null +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -0,0 +1,66 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osuTK; +using osu.Game.Graphics; +using osu.Framework.Bindables; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Menu +{ + public class SongTicker : Container + { + private const int duration = 500; + + [Resolved] + private Bindable beatmap { get; set; } + + private readonly Bindable workingBeatmap = new Bindable(); + private readonly OsuSpriteText title, artist; + + public SongTicker() + { + AutoSizeAxes = Axes.Both; + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 3), + Children = new Drawable[] + { + title = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = OsuFont.GetFont(size: 24, weight: FontWeight.Light, italics: true) + }, + artist = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = OsuFont.GetFont(size: 16) + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + workingBeatmap.BindTo(beatmap); + workingBeatmap.BindValueChanged(onBeatmapChanged); + } + + private void onBeatmapChanged(ValueChangedEvent working) + { + title.Text = working.NewValue?.Metadata?.Title; + artist.Text = working.NewValue?.Metadata?.Artist; + + this.FadeIn(duration, Easing.OutQuint).Delay(4000).Then().FadeOut(duration, Easing.OutQuint); + } + } +} From 7716a555ecb71fd5d3ad290bc22d89daf4a281c1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 07:08:00 +0300 Subject: [PATCH 080/628] Move only ButtonSystem on screen changes rather than everything --- osu.Game/Screens/Menu/MainMenu.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 47c86fc1ae..c4465dce17 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -69,6 +69,8 @@ namespace osu.Game.Screens.Menu private ExitConfirmOverlay exitConfirmOverlay; + private ParallaxContainer buttonsContainer; + [BackgroundDependencyLoader(true)] private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics) { @@ -79,7 +81,7 @@ namespace osu.Game.Screens.Menu { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = 15 } + Margin = new MarginPadding { Right = 15, Top = 5 } }); if (host.CanExit) @@ -98,7 +100,7 @@ namespace osu.Game.Screens.Menu AddRangeInternal(new Drawable[] { - new ParallaxContainer + buttonsContainer = new ParallaxContainer { ParallaxAmount = 0.01f, Children = new Drawable[] @@ -197,7 +199,7 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.TopLevel; this.FadeIn(FADE_IN_DURATION, Easing.OutQuint); - this.MoveTo(new Vector2(0, 0), FADE_IN_DURATION, Easing.OutQuint); + buttonsContainer.MoveTo(new Vector2(0, 0), FADE_IN_DURATION, Easing.OutQuint); sideFlashes.Delay(FADE_IN_DURATION).FadeIn(64, Easing.InQuint); } @@ -234,7 +236,7 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.EnteringMode; this.FadeOut(FADE_OUT_DURATION, Easing.InSine); - this.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine); + buttonsContainer.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine); sideFlashes.FadeOut(64, Easing.OutQuint); } From d59cae33d3f0ff67fc5f6a38a7a2c02449bcb110 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 07:17:13 +0300 Subject: [PATCH 081/628] Some animation adjustments --- osu.Game/Screens/Menu/MainMenu.cs | 6 +++++- osu.Game/Screens/Menu/SongTicker.cs | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index c4465dce17..0b267731d8 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -70,6 +70,7 @@ namespace osu.Game.Screens.Menu private ExitConfirmOverlay exitConfirmOverlay; private ParallaxContainer buttonsContainer; + private SongTicker songTicker; [BackgroundDependencyLoader(true)] private void load(DirectOverlay direct, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics) @@ -77,7 +78,7 @@ namespace osu.Game.Screens.Menu holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); - AddInternal(new SongTicker + AddInternal(songTicker = new SongTicker { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -235,6 +236,7 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.EnteringMode; + songTicker.Hide(); this.FadeOut(FADE_OUT_DURATION, Easing.InSine); buttonsContainer.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine); @@ -244,6 +246,7 @@ namespace osu.Game.Screens.Menu public override void OnResuming(IScreen last) { base.OnResuming(last); + songTicker.Hide(); (Background as BackgroundScreenDefault)?.Next(); @@ -272,6 +275,7 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.Exit; this.FadeOut(3000); + songTicker.Hide(); return base.OnExiting(next); } diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index 504b016019..eb7012a150 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Menu { public class SongTicker : Container { - private const int duration = 500; + private const int fade_duration = 800; [Resolved] private Bindable beatmap { get; set; } @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Menu title.Text = working.NewValue?.Metadata?.Title; artist.Text = working.NewValue?.Metadata?.Artist; - this.FadeIn(duration, Easing.OutQuint).Delay(4000).Then().FadeOut(duration, Easing.OutQuint); + this.FadeIn(fade_duration, Easing.OutQuint).Delay(4000).Then().FadeOut(fade_duration, Easing.OutQuint); } } } From e6210f10b7de81a12ef03148202ae14933a77fb7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 07:32:40 +0300 Subject: [PATCH 082/628] Add unicode metadata support --- osu.Game/Screens/Menu/SongTicker.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index eb7012a150..d9b66d06e9 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -9,6 +9,7 @@ using osuTK; using osu.Game.Graphics; using osu.Framework.Bindables; using osu.Game.Beatmaps; +using osu.Framework.Localisation; namespace osu.Game.Screens.Menu { @@ -57,8 +58,13 @@ namespace osu.Game.Screens.Menu private void onBeatmapChanged(ValueChangedEvent working) { - title.Text = working.NewValue?.Metadata?.Title; - artist.Text = working.NewValue?.Metadata?.Artist; + if (working.NewValue?.Beatmap == null) + return; + + var metadata = working.NewValue?.Metadata; + + title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); + artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)); this.FadeIn(fade_duration, Easing.OutQuint).Delay(4000).Then().FadeOut(fade_duration, Easing.OutQuint); } From 76c70a76229a956c186d304c9232a604015148e8 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 11 Jan 2020 21:19:46 +0800 Subject: [PATCH 083/628] Move hit target bar height def to defaulthittarget --- osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index ee2cec1bbd..90e78c3899 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -18,8 +18,6 @@ namespace osu.Game.Rulesets.Mania.UI.Components { public class ColumnHitObjectArea : CompositeDrawable, IHasAccentColour { - private const float hit_target_bar_height = 2; - private readonly IBindable direction = new Bindable(); private readonly Drawable hitTarget; @@ -67,6 +65,8 @@ namespace osu.Game.Rulesets.Mania.UI.Components private class DefaultHitTarget : CompositeDrawable, IHasAccentColour { + private const float hit_target_bar_height = 2; + private readonly IBindable direction = new Bindable(); private readonly Container hitTargetLine; From d25ef1966d32bda80e258da550a6c87768ca0eeb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 17:48:09 +0300 Subject: [PATCH 084/628] Remove unnecessary local bindable --- osu.Game/Screens/Menu/SongTicker.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index d9b66d06e9..f2c861a296 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -20,7 +20,6 @@ namespace osu.Game.Screens.Menu [Resolved] private Bindable beatmap { get; set; } - private readonly Bindable workingBeatmap = new Bindable(); private readonly OsuSpriteText title, artist; public SongTicker() @@ -52,8 +51,7 @@ namespace osu.Game.Screens.Menu protected override void LoadComplete() { base.LoadComplete(); - workingBeatmap.BindTo(beatmap); - workingBeatmap.BindValueChanged(onBeatmapChanged); + beatmap.BindValueChanged(onBeatmapChanged); } private void onBeatmapChanged(ValueChangedEvent working) From 81948744d056acd6ca24d0f6875236fcef3f034a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 17:50:13 +0300 Subject: [PATCH 085/628] remove unnecessary null checks --- osu.Game/Screens/Menu/SongTicker.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index f2c861a296..8eae94ae1d 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -56,10 +56,7 @@ namespace osu.Game.Screens.Menu private void onBeatmapChanged(ValueChangedEvent working) { - if (working.NewValue?.Beatmap == null) - return; - - var metadata = working.NewValue?.Metadata; + var metadata = working.NewValue.Metadata; title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)); From ec95cbd0affc9e9c91817459740f46f4ba964a4d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 11 Jan 2020 16:03:00 +0100 Subject: [PATCH 086/628] Don't update rich presence if the rpc client isn't initialized. --- osu.Desktop/DiscordRichPresence.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 80bb82c769..08cc0e7f5f 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -75,6 +75,9 @@ namespace osu.Desktop private void updateStatus() { + if (!client.IsInitialized) + return; + if (status.Value is UserStatusOffline) { client.ClearPresence(); From bd33687f533a969d7bd855054b50f840614ef754 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 18:27:22 +0300 Subject: [PATCH 087/628] Add AllowUpdates flag to SongTicker --- osu.Game/Screens/Menu/MainMenu.cs | 5 ++++- osu.Game/Screens/Menu/SongTicker.cs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 0b267731d8..72b61eb05c 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -237,6 +237,8 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.EnteringMode; songTicker.Hide(); + songTicker.AllowUpdates = false; + this.FadeOut(FADE_OUT_DURATION, Easing.InSine); buttonsContainer.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine); @@ -246,7 +248,8 @@ namespace osu.Game.Screens.Menu public override void OnResuming(IScreen last) { base.OnResuming(last); - songTicker.Hide(); + + songTicker.AllowUpdates = true; (Background as BackgroundScreenDefault)?.Next(); diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index 8eae94ae1d..f858d162d2 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -17,6 +17,8 @@ namespace osu.Game.Screens.Menu { private const int fade_duration = 800; + public bool AllowUpdates { get; set; } = true; + [Resolved] private Bindable beatmap { get; set; } @@ -56,6 +58,9 @@ namespace osu.Game.Screens.Menu private void onBeatmapChanged(ValueChangedEvent working) { + if (!AllowUpdates) + return; + var metadata = working.NewValue.Metadata; title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); From cd679707eddc4aa2a4ff911e4da1221526bc3a2a Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 17:16:11 +0100 Subject: [PATCH 088/628] Prevent channel duplicates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 19c3be0d7b..33b0c0e9e1 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -447,7 +447,7 @@ namespace osu.Game.Online.Chat public void MarkChannelAsRead(Message message) { - var channel = JoinedChannels.First(c => c.Id == message.ChannelId); + var channel = JoinedChannels.Single(c => c.Id == message.ChannelId); var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; req.Failure += e => Logger.Error(e, "Failed to mark channel as read"); From 50e357a79930b0980fb67fddafc21c65712a0c49 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 17:42:02 +0100 Subject: [PATCH 089/628] Change method parameters, add detailed error message and method docs --- osu.Game/Online/Chat/ChannelManager.cs | 16 +++++++++++++--- osu.Game/Overlays/ChatOverlay.cs | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 33b0c0e9e1..9f263477d0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -445,12 +445,22 @@ namespace osu.Game.Online.Chat return tcs.Task; } - public void MarkChannelAsRead(Message message) + /// + /// Marks the as read + /// (see for more information) + /// + /// The channel that will be marked as read + /// The message where it will be read up to. If was provided, the latest message of the will be read. + public void MarkChannelAsRead(Channel channel, Message message = null) { - var channel = JoinedChannels.Single(c => c.Id == message.ChannelId); + if (message == null) + message = channel.Messages.Last(); + var req = new MarkChannelAsReadRequest(channel, message); + req.Success += () => channel.LastReadId = message.Id; - req.Failure += e => Logger.Error(e, "Failed to mark channel as read"); + req.Failure += e => Logger.Error(e, $"Failed to mark channel {channel.ToString()} up to '{message.ToString()}' as read"); + api.Queue(req); } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index b64d3a1893..45d311df28 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -282,7 +282,7 @@ namespace osu.Game.Overlays // mark channel as read when channel switched if (e.NewValue.Messages.Any()) - channelManager.MarkChannelAsRead(e.NewValue.Messages.Last()); + channelManager.MarkChannelAsRead(e.NewValue); } private float startDragChatHeight; From d9c57baa89cab9430f3a9577666d0a8708096444 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 17:48:03 +0100 Subject: [PATCH 090/628] Add test case for mismatch of channels --- osu.Game/Online/Chat/ChannelManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9f263477d0..b30d1ffa60 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -455,6 +456,8 @@ namespace osu.Game.Online.Chat { if (message == null) message = channel.Messages.Last(); + else + Debug.Assert(channel.Id == message.Id, "Provided channel and message owner channel aren't equal."); var req = new MarkChannelAsReadRequest(channel, message); From f8a11e50b677c4f3172efbbeae05eee81e713608 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 18:00:34 +0100 Subject: [PATCH 091/628] Remove redundant ToString() calls as string interpolation does this automatically.. --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index b30d1ffa60..5aab43dbd9 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -462,7 +462,7 @@ namespace osu.Game.Online.Chat var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; - req.Failure += e => Logger.Error(e, $"Failed to mark channel {channel.ToString()} up to '{message.ToString()}' as read"); + req.Failure += e => Logger.Error(e, $"Failed to mark channel {channel} up to '{message}' as read"); api.Queue(req); } From 2ea1367a881cab6e5e9eed787971a6f5ca22f989 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 19:47:35 +0100 Subject: [PATCH 092/628] Remove message parameter and make it mark the entire channel as read --- osu.Game/Online/Chat/ChannelManager.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 5aab43dbd9..4071be0aaf 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -448,17 +448,11 @@ namespace osu.Game.Online.Chat /// /// Marks the as read - /// (see for more information) /// /// The channel that will be marked as read - /// The message where it will be read up to. If was provided, the latest message of the will be read. - public void MarkChannelAsRead(Channel channel, Message message = null) + public void MarkChannelAsRead(Channel channel) { - if (message == null) - message = channel.Messages.Last(); - else - Debug.Assert(channel.Id == message.Id, "Provided channel and message owner channel aren't equal."); - + var message = channel.Messages.Last(); var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; From ccaf4e48a169644bafbfeafe006e9c71d57a5beb Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 11 Jan 2020 20:04:58 +0100 Subject: [PATCH 093/628] Remove using directive --- osu.Game/Online/Chat/ChannelManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 4071be0aaf..35a48b7ec8 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; From 730cc92bf36ddf5c7a2eb53d5c7042b422708de5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 22:43:07 +0300 Subject: [PATCH 094/628] Fade out instead of insta hiding on menu suspending --- osu.Game/Screens/Menu/MainMenu.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 72b61eb05c..2de31cf399 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -236,7 +236,7 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.EnteringMode; - songTicker.Hide(); + songTicker.FadeOut(100, Easing.OutQuint); songTicker.AllowUpdates = false; this.FadeOut(FADE_OUT_DURATION, Easing.InSine); From f43602518a6b013bdcb0e8cd9bc3309463f4d53c Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 11 Jan 2020 11:43:51 -0800 Subject: [PATCH 095/628] Add global action for toggling now playing overlay --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 4 ++++ osu.Game/OsuGame.cs | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index e37567c72c..7763577a14 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -24,6 +24,7 @@ namespace osu.Game.Input.Bindings public IEnumerable GlobalKeyBindings => new[] { + new KeyBinding(InputKey.F6, GlobalAction.ToggleNowPlaying), new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), new KeyBinding(InputKey.F10, GlobalAction.ToggleGameplayMouseButtons), @@ -137,5 +138,8 @@ namespace osu.Game.Input.Bindings [Description("Play / pause")] MusicPlay, + + [Description("Toggle now playing overlay")] + ToggleNowPlaying, } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 84aba4af52..9df854d178 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -61,6 +61,8 @@ namespace osu.Game private NotificationOverlay notifications; + private NowPlayingOverlay nowPlaying; + private DirectOverlay direct; private SocialOverlay social; @@ -624,7 +626,7 @@ namespace osu.Game Origin = Anchor.TopRight, }, rightFloatingOverlayContent.Add, true); - loadComponentSingleFile(new NowPlayingOverlay + loadComponentSingleFile(nowPlaying = new NowPlayingOverlay { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, @@ -822,6 +824,10 @@ namespace osu.Game switch (action) { + case GlobalAction.ToggleNowPlaying: + nowPlaying.ToggleVisibility(); + return true; + case GlobalAction.ToggleChat: chatOverlay.ToggleVisibility(); return true; From f1b4fbb844082a910481373c74114b59519ad62c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 12 Jan 2020 17:38:15 +0300 Subject: [PATCH 096/628] Make gradient in NewsArticleCover be effected by hover --- osu.Game/Overlays/News/NewsArticleCover.cs | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/News/NewsArticleCover.cs b/osu.Game/Overlays/News/NewsArticleCover.cs index e484309a18..f61b30b381 100644 --- a/osu.Game/Overlays/News/NewsArticleCover.cs +++ b/osu.Game/Overlays/News/NewsArticleCover.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK.Graphics; @@ -19,6 +20,10 @@ namespace osu.Game.Overlays.News { public class NewsArticleCover : Container { + private const int hover_duration = 300; + + private readonly Box gradient; + public NewsArticleCover(ArticleInfo info) { RelativeSizeAxes = Axes.X; @@ -47,11 +52,11 @@ namespace osu.Game.Overlays.News Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, }, - new Box + gradient = new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.6f)), - Alpha = 1f, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.7f)), + Alpha = 0 }, new DateContainer(info.Time) { @@ -90,6 +95,18 @@ namespace osu.Game.Overlays.News bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); } + protected override bool OnHover(HoverEvent e) + { + gradient.FadeIn(hover_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + gradient.FadeOut(hover_duration, Easing.OutQuint); + } + [LongRunningLoad] private class NewsBackground : Sprite { From 8cc2d70df0fb725e09891caf912adb335841e31d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 12 Jan 2020 16:24:14 +0100 Subject: [PATCH 097/628] Reduce API calls by checking what message was last marked as read --- osu.Game/Online/Chat/ChannelManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 35a48b7ec8..b741bd9433 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -451,6 +451,9 @@ namespace osu.Game.Online.Chat /// The channel that will be marked as read public void MarkChannelAsRead(Channel channel) { + if (channel.LastMessageId == channel.LastReadId) + return; + var message = channel.Messages.Last(); var req = new MarkChannelAsReadRequest(channel, message); From aa2645502cf182cc8241814f89ad0a39f6b4cbf3 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 12 Jan 2020 20:43:48 +0100 Subject: [PATCH 098/628] Fix adjusted value always being 0 --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index a147527f6c..52a5b101d4 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -118,17 +118,9 @@ namespace osu.Game.Screens.Select.Details mod.ApplyToDifficulty(adjustedDifficulty); } - //mania specific - if ((Beatmap?.Ruleset?.ID ?? 0) == 3) - { - firstValue.Title = "Key Amount"; - firstValue.Value = ((int)MathF.Round(baseDifficulty?.CircleSize ?? 0), (int)MathF.Round(adjustedDifficulty?.CircleSize ?? 0)); - } - else - { - firstValue.Title = "Circle Size"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); - } + // Account for mania differences + firstValue.Title = (Beatmap?.Ruleset?.ID ?? 0) == 3 ? "Key Amount" : "Circle Size"; + firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null); From b5ac707c6cf9be7671adbaa95677ad43ce7d9379 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 12 Jan 2020 21:09:48 +0100 Subject: [PATCH 099/628] Remove unnecessary directive --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 52a5b101d4..b7f60a8370 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using System; using osu.Game.Beatmaps; using osu.Framework.Bindables; using System.Collections.Generic; From c190c68659236e0e5b2d57945b7a52ee7d936a7f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Jan 2020 12:22:44 +0900 Subject: [PATCH 100/628] Add safety for channel with no messages --- osu.Game/Online/Chat/ChannelManager.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index b741bd9433..4b5ec1cad0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -454,7 +454,11 @@ namespace osu.Game.Online.Chat if (channel.LastMessageId == channel.LastReadId) return; - var message = channel.Messages.Last(); + var message = channel.Messages.LastOrDefault(); + + if (message == null) + return; + var req = new MarkChannelAsReadRequest(channel, message); req.Success += () => channel.LastReadId = message.Id; From af167eb719964794663983e32f2fbac80ba4f693 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 13 Jan 2020 23:28:26 +0700 Subject: [PATCH 101/628] Remove duplicate condition in TournamentFont --- osu.Game.Tournament/TournamentFont.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentFont.cs b/osu.Game.Tournament/TournamentFont.cs index f9e60ff2bc..32f0264562 100644 --- a/osu.Game.Tournament/TournamentFont.cs +++ b/osu.Game.Tournament/TournamentFont.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament string weightString = weight.ToString(); // Only exo has an explicit "regular" weight, other fonts do not - if (weight == FontWeight.Regular && family != GetFamilyString(TournamentTypeface.Aquatico) && family != GetFamilyString(TournamentTypeface.Aquatico)) + if (weight == FontWeight.Regular && family != GetFamilyString(TournamentTypeface.Aquatico)) weightString = string.Empty; return weightString; From 619fe29871b7e2797b9e0c15003842bb70e4059f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 01:39:45 +0900 Subject: [PATCH 102/628] Make reverse arrow animate faster via divisor specification Adds MinimumBeatLength to BeatSyncedContainer to make sure things don't get out of hand. --- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 3 +++ osu.Game/Graphics/Containers/BeatSyncedContainer.cs | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 2b9a3aa197..2c6e5b7c18 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -20,6 +20,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { this.repeatPoint = repeatPoint; + Divisor = 2; + MinimumBeatLength = 200; + Anchor = Anchor.Centre; Origin = Anchor.Centre; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index b9ef279f5c..be9aefa359 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -38,6 +38,11 @@ namespace osu.Game.Graphics.Containers /// public int Divisor { get; set; } = 1; + /// + /// An optional minimum beat length. Any beat length below this will be multiplied by two until valid. + /// + public double MinimumBeatLength { get; set; } + /// /// Default length of a beat in milliseconds. Used whenever there is no beatmap or track playing. /// @@ -89,6 +94,9 @@ namespace osu.Game.Graphics.Containers double beatLength = timingPoint.BeatLength / Divisor; + while (beatLength < MinimumBeatLength) + beatLength *= 2; + int beatIndex = (int)((currentTrackTime - timingPoint.Time) / beatLength) - (effectPoint.OmitFirstBarLine ? 1 : 0); // The beats before the start of the first control point are off by 1, this should do the trick From c5085aea24ae4b08890baac8e894ce208d71af7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 01:45:10 +0900 Subject: [PATCH 103/628] Use Child, not InternalChild --- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 2c6e5b7c18..ee7cdefa13 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - InternalChild = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.ChevronRight, @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { if (Clock.CurrentTime < repeatPoint.StartTime) - InternalChild.ScaleTo(1.3f).ScaleTo(1f, Math.Min(timingPoint.BeatLength, repeatPoint.StartTime - Clock.CurrentTime), Easing.Out); + Child.ScaleTo(1.3f).ScaleTo(1f, Math.Min(timingPoint.BeatLength, repeatPoint.StartTime - Clock.CurrentTime), Easing.Out); } } } From 210d06b75ed27209d6d8721a8d3b131004a57bb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 01:45:32 +0900 Subject: [PATCH 104/628] Remove default value --- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index ee7cdefa13..37bbfbe806 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.ChevronRight, Size = new Vector2(0.35f) - }, confineMode: ConfineMode.NoScaling) + }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From ab4f31639d9e2ccfd8ac4cc61091c024aa0c6827 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 01:47:44 +0900 Subject: [PATCH 105/628] Remove weird time clause --- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 37bbfbe806..0403fe8196 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { if (Clock.CurrentTime < repeatPoint.StartTime) - Child.ScaleTo(1.3f).ScaleTo(1f, Math.Min(timingPoint.BeatLength, repeatPoint.StartTime - Clock.CurrentTime), Easing.Out); + Child.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out); } } } From fe09e34f1bf8a9ed9d7479c0792ac871ae3b5020 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 01:48:20 +0900 Subject: [PATCH 106/628] Remove limiting clause --- .../Objects/Drawables/Pieces/ReverseArrowPiece.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs index 0403fe8196..08dd97b0d8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ReverseArrowPiece.cs @@ -42,10 +42,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces }; } - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) - { - if (Clock.CurrentTime < repeatPoint.StartTime) - Child.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out); - } + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) => + Child.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out); } } From 90e4def4bd0d782f24b4d987639f33a1388fe621 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 14 Jan 2020 07:07:21 +0300 Subject: [PATCH 107/628] Remove online stuff out of the selector --- .../TestSceneRankingsSpotlightSelector.cs | 18 ++++++-- .../Overlays/Rankings/SpotlightSelector.cs | 45 +++++++------------ 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 9320213844..0862b3251a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Rankings; namespace osu.Game.Tests.Visual.Online @@ -14,15 +15,26 @@ namespace osu.Game.Tests.Visual.Online typeof(SpotlightSelector), }; - protected override bool UseOnlineAPI => true; - public TestSceneRankingsSpotlightSelector() { SpotlightSelector selector; Add(selector = new SpotlightSelector()); - AddStep("Fetch spotlights", selector.FetchSpotlights); + var spotlights = new APISpotlight[] + { + new APISpotlight { Name = "Spotlight 1" }, + new APISpotlight { Name = "Spotlight 2" }, + new APISpotlight { Name = "Spotlight 3" }, + }; + + AddStep("Load spotlights", () => selector.Spotlights = spotlights); + AddStep("Load info", () => selector.UpdateInfo(new APISpotlight + { + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now, + ParticipantCount = 15155151, + }, 18)); } } } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index fb61555c20..a275f4ed50 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -9,11 +9,10 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osuTK; using System; +using System.Collections.Generic; namespace osu.Game.Overlays.Rankings { @@ -21,15 +20,19 @@ namespace osu.Game.Overlays.Rankings { private readonly Box background; private readonly SpotlightsDropdown dropdown; - private readonly DimmedLoadingLayer loading; - - [Resolved] - private IAPIProvider api { get; set; } public readonly Bindable SelectedSpotlight = new Bindable(); + public IEnumerable Spotlights + { + get => dropdown.Items; + set => dropdown.Items = value; + } + private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; + private readonly InfoColumn mapCountColumn; + private readonly InfoColumn participants; public SpotlightSelector() { @@ -66,11 +69,12 @@ namespace osu.Game.Overlays.Rankings { startDateColumn = new InfoColumn(@"Start Date"), endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participants = new InfoColumn(@"Participants"), } } } }, - loading = new DimmedLoadingLayer(), }; } @@ -80,29 +84,12 @@ namespace osu.Game.Overlays.Rankings background.Colour = colours.GreySeafoam; } - protected override void LoadComplete() + public void UpdateInfo(APISpotlight spotlight, int mapCount) { - base.LoadComplete(); - SelectedSpotlight.BindValueChanged(onSelectionChanged); - } - - public void FetchSpotlights() - { - loading.Show(); - - var request = new GetSpotlightsRequest(); - request.Success += response => - { - dropdown.Items = response.Spotlights; - loading.Hide(); - }; - api.Queue(request); - } - - private void onSelectionChanged(ValueChangedEvent spotlight) - { - startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); - endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + startDateColumn.Value = dateToString(spotlight.StartDate); + endDateColumn.Value = dateToString(spotlight.EndDate); + mapCountColumn.Value = mapCount.ToString(); + participants.Value = spotlight.ParticipantCount?.ToString("N0"); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); From 18ebd309788124c12ae3d5bf8388f97e4822939c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 14 Jan 2020 07:20:03 +0300 Subject: [PATCH 108/628] CI fix --- .../Visual/Online/TestSceneRankingsSpotlightSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 0862b3251a..1a62cb6dad 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online Add(selector = new SpotlightSelector()); - var spotlights = new APISpotlight[] + var spotlights = new[] { new APISpotlight { Name = "Spotlight 1" }, new APISpotlight { Name = "Spotlight 2" }, From c196e83e75f495f533f82e867d7d8cd3e9165738 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 13 Jan 2020 20:48:39 -0800 Subject: [PATCH 109/628] Allow changing volume in song select with arrow keys when pressing alt --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index bf2382c4ae..da01ac5f95 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -436,7 +436,7 @@ namespace osu.Game.Screens.Select break; } - if (direction == 0) + if (direction == 0 || e.AltPressed) return base.OnKeyDown(e); SelectNext(direction, skipDifficulties); From 7349c023d1b9696559d5190469024544d064204a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:01:51 +0900 Subject: [PATCH 110/628] Cleanup spotlight selection --- .../TestSceneRankingsSpotlightSelector.cs | 4 +-- .../API/Requests/Responses/APISpotlight.cs | 2 +- .../Overlays/Rankings/SpotlightSelector.cs | 30 ++++++++++++++----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 1a62cb6dad..d714d5fb7d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -29,12 +29,12 @@ namespace osu.Game.Tests.Visual.Online }; AddStep("Load spotlights", () => selector.Spotlights = spotlights); - AddStep("Load info", () => selector.UpdateInfo(new APISpotlight + AddStep("Load info", () => selector.Current.Value = new APISpotlight { StartDate = DateTimeOffset.Now, EndDate = DateTimeOffset.Now, ParticipantCount = 15155151, - }, 18)); + }); } } } diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 63c47e7812..2191ed4743 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset EndDate; [JsonProperty(@"participant_count")] - public int? ParticipantCount; + public int ParticipantCount; public override string ToString() => Name; } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index a275f4ed50..def7469b16 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -13,15 +13,22 @@ using osu.Game.Online.API.Requests.Responses; using osuTK; using System; using System.Collections.Generic; +using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : Container + public class SpotlightSelector : Container, IHasCurrentValue { private readonly Box background; private readonly SpotlightsDropdown dropdown; - public readonly Bindable SelectedSpotlight = new Bindable(); + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } public IEnumerable Spotlights { @@ -55,7 +62,7 @@ namespace osu.Game.Overlays.Rankings Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, - Current = SelectedSpotlight, + Current = Current, Depth = -float.MaxValue }, new FillFlowContainer @@ -84,12 +91,19 @@ namespace osu.Game.Overlays.Rankings background.Colour = colours.GreySeafoam; } - public void UpdateInfo(APISpotlight spotlight, int mapCount) + protected override void LoadComplete() { - startDateColumn.Value = dateToString(spotlight.StartDate); - endDateColumn.Value = dateToString(spotlight.EndDate); - mapCountColumn.Value = mapCount.ToString(); - participants.Value = spotlight.ParticipantCount?.ToString("N0"); + base.LoadComplete(); + + Current.BindValueChanged(onCurrentChanged); + } + + private void onCurrentChanged(ValueChangedEvent spotlight) + { + startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); + endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + // mapCountColumn.Value = spotlight.NewValue.ParticipantCount.ToString(); + participants.Value = spotlight.NewValue.ParticipantCount.ToString(); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); From 20466d79df37e8671badf7bd12f7dc66b0bcea10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Jan 2020 14:18:28 +0900 Subject: [PATCH 111/628] Update netcore version --- .idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml index 1fd10e0e1a..d85a0ae44c 100644 --- a/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml @@ -1,6 +1,6 @@ -