From 11dad7bf746820b56fa426f63f8582062de52a6d Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 10 Oct 2018 16:46:02 +0200 Subject: [PATCH 001/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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/157] 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 c69e88eb97b90c73b3e2dcd2bebe18c8aa4b8540 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 21 Dec 2019 13:32:25 +0300 Subject: [PATCH 012/157] 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 013/157] 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 014/157] 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 015/157] 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 016/157] 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 017/157] 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 018/157] 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 019/157] 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 020/157] 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 021/157] 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 022/157] 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 ee332e0d424b0a8a76efc28b413208e14f8b1f6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 2 Jan 2020 11:46:18 +0900 Subject: [PATCH 023/157] 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 024/157] 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 e0f66928e6e76dfeef068327a4296d1482baff97 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 7 Jan 2020 01:07:50 +0300 Subject: [PATCH 025/157] 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 6adf5ba3813482e40cf3e0c391d136e7e9c596e9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 7 Jan 2020 12:29:21 +0300 Subject: [PATCH 026/157] 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 027/157] 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 6500cc967fff845a8e65cd3fc1a7a666be43669e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 06:58:35 +0300 Subject: [PATCH 028/157] 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 029/157] 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 030/157] 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 031/157] 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 d25ef1966d32bda80e258da550a6c87768ca0eeb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 17:48:09 +0300 Subject: [PATCH 032/157] 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 033/157] 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 bd33687f533a969d7bd855054b50f840614ef754 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 18:27:22 +0300 Subject: [PATCH 034/157] 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 730cc92bf36ddf5c7a2eb53d5c7042b422708de5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 11 Jan 2020 22:43:07 +0300 Subject: [PATCH 035/157] 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 d57f55f053d2da94b7816ba16d5a603102147e67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Jan 2020 19:09:49 +0900 Subject: [PATCH 036/157] Apply remaining changes required to restore previous functionality --- .../Edit/ManiaBlueprintContainer.cs | 6 + .../Edit/ManiaHitObjectComposer.cs | 2 +- .../Edit/OsuBlueprintContainer.cs | 8 +- .../Edit/OsuHitObjectComposer.cs | 2 +- .../Editor/TestSceneBlueprintContainer.cs | 4 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- .../Compose/Components/BlueprintContainer.cs | 136 ++++------------- .../Components/ComposeBlueprintContainer.cs | 137 ++++++++++++++++++ .../Edit/Compose/Components/DragBox.cs | 8 +- .../Compose/Components/SelectionHandler.cs | 2 +- .../Timeline/TimelineHitObjectDisplay.cs | 30 +++- 11 files changed, 221 insertions(+), 116 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs index 9cb4e54234..5f66ae7491 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.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.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Objects.Drawables; @@ -11,6 +12,11 @@ namespace osu.Game.Rulesets.Mania.Edit { public class ManiaBlueprintContainer : ComposeBlueprintContainer { + public ManiaBlueprintContainer(IEnumerable drawableHitObjects) + : base(drawableHitObjects) + { + } + public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) { switch (hitObject) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 824c92184a..62b609610f 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania.Edit return drawableRuleset; } - protected override ComposeBlueprintContainer CreateBlueprintContainer() => new ManiaBlueprintContainer(); + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new ManiaBlueprintContainer(drawableRuleset.Playfield.AllHitObjects); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index a6a7d9bcc0..fc856d9810 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.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.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; @@ -13,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuBlueprintContainer : ComposeBlueprintContainer { - public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); + protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) { @@ -31,5 +32,10 @@ namespace osu.Game.Rulesets.Osu.Edit return base.CreateBlueprintFor(hitObject); } + + public OsuBlueprintContainer(IEnumerable drawableHitObjects) + : base(drawableHitObjects) + { + } } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 28f7768aac..b01488e7c2 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit new SpinnerCompositionTool() }; - protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(); + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(HitObjects); protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable selectedHitObjects) { diff --git a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs index 67b0b61545..a230e5221f 100644 --- a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs +++ b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs @@ -1,7 +1,9 @@ // 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 NUnit.Framework; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Tests.Visual; @@ -12,7 +14,7 @@ namespace osu.Game.Tests.Editor [SetUp] public void Setup() => Schedule(() => { - Child = new ComposeBlueprintContainer(); + Child = new ComposeBlueprintContainer(new List()); }); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 536c7767b7..52c0701f4f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Edit private IBeatmapProcessor beatmapProcessor; private DrawableEditRulesetWrapper drawableRulesetWrapper; - private BlueprintContainer blueprintContainer; + private ComposeBlueprintContainer blueprintContainer; private Container distanceSnapGridContainer; private DistanceSnapGrid distanceSnapGrid; private readonly List layerContainers = new List(); diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index a8fb87c1b0..7944476100 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -14,7 +14,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osuTK; @@ -30,12 +29,11 @@ namespace osu.Game.Screens.Edit.Compose.Components { public event Action> SelectionChanged; - private DragBox dragBox; + protected DragBox DragBox; + private SelectionBlueprintContainer selectionBlueprints; - private Container placementBlueprintContainer; - private PlacementBlueprint currentPlacement; + private SelectionHandler selectionHandler; - private InputManager inputManager; [Resolved] private IAdjustableClock adjustableClock { get; set; } @@ -43,6 +41,9 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private EditorBeatmap beatmap { get; set; } + [Resolved(canBeNull: true)] + private IDistanceSnapProvider snapProvider { get; set; } + protected BlueprintContainer() { RelativeSizeAxes = Axes.Both; @@ -51,13 +52,15 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Creates a which outlines s and handles movement of selections. /// - public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); + protected virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); /// /// Creates a for a specific . /// /// The to create the overlay for. - public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; + protected virtual SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => null; + + protected virtual DragBox CreateDragBox(Action performSelect) => new DragBox(performSelect); [BackgroundDependencyLoader] private void load() @@ -65,46 +68,24 @@ namespace osu.Game.Screens.Edit.Compose.Components selectionHandler = CreateSelectionHandler(); selectionHandler.DeselectAll = deselectAll; - InternalChildren = new[] + AddRangeInternal(new[] { - dragBox = new DragBox(select), + DragBox = CreateDragBox(select), selectionHandler, selectionBlueprints = new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }, - placementBlueprintContainer = new Container { RelativeSizeAxes = Axes.Both }, - dragBox.CreateProxy() - }; + DragBox.CreateProxy().With(p => p.Depth = int.MinValue) + }); foreach (var obj in beatmap.HitObjects) - addBlueprintFor(obj); + AddBlueprintFor(obj); } protected override void LoadComplete() { base.LoadComplete(); - beatmap.HitObjectAdded += addBlueprintFor; + beatmap.HitObjectAdded += AddBlueprintFor; beatmap.HitObjectRemoved += removeBlueprintFor; - - inputManager = GetContainingInputManager(); - } - - private HitObjectCompositionTool currentTool; - - /// - /// The current placement tool. - /// - public HitObjectCompositionTool CurrentTool - { - get => currentTool; - set - { - if (currentTool == value) - return; - - currentTool = value; - - refreshTool(); - } } protected override bool OnMouseDown(MouseDownEvent e) @@ -148,17 +129,6 @@ namespace osu.Game.Screens.Edit.Compose.Components return e.Button == MouseButton.Left; } - protected override bool OnMouseMove(MouseMoveEvent e) - { - if (currentPlacement != null) - { - updatePlacementPosition(e.ScreenSpaceMousePosition); - return true; - } - - return base.OnMouseMove(e); - } - protected override bool OnDragStart(DragStartEvent e) { if (e.Button == MouseButton.Right) @@ -166,8 +136,10 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!beginSelectionMovement()) { - dragBox.UpdateDrag(e); - dragBox.FadeIn(250, Easing.OutQuint); + if (!DragBox.UpdateDrag(e)) + return false; + + DragBox.FadeIn(250, Easing.OutQuint); } return true; @@ -179,7 +151,10 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; if (!moveCurrentSelection(e)) - dragBox.UpdateDrag(e); + { + if (!DragBox.UpdateDrag(e)) + return false; + } return true; } @@ -191,7 +166,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!finishSelectionMovement()) { - dragBox.FadeOut(250, Easing.OutQuint); + DragBox.FadeOut(250, Easing.OutQuint); selectionHandler.UpdateVisibility(); } @@ -229,30 +204,8 @@ namespace osu.Game.Screens.Edit.Compose.Components public bool OnReleased(PlatformAction action) => false; - protected override void Update() - { - base.Update(); - - if (currentPlacement != null) - { - if (composer.CursorInPlacementArea) - currentPlacement.State = PlacementState.Shown; - else if (currentPlacement?.PlacementBegun == false) - currentPlacement.State = PlacementState.Hidden; - } - } - #region Blueprint Addition/Removal - private void addBlueprintFor(HitObject hitObject) - { - var drawable = composer.HitObjects.FirstOrDefault(d => d.HitObject == hitObject); - if (drawable == null) - return; - - addBlueprintFor(drawable); - } - private void removeBlueprintFor(HitObject hitObject) { var blueprint = selectionBlueprints.Single(m => m.DrawableObject.HitObject == hitObject); @@ -267,10 +220,8 @@ namespace osu.Game.Screens.Edit.Compose.Components selectionBlueprints.Remove(blueprint); } - private void addBlueprintFor(DrawableHitObject hitObject) + protected virtual void AddBlueprintFor(HitObject hitObject) { - refreshTool(); - var blueprint = CreateBlueprintFor(hitObject); if (blueprint == null) return; @@ -283,37 +234,6 @@ namespace osu.Game.Screens.Edit.Compose.Components #endregion - #region Placement - - /// - /// Refreshes the current placement tool. - /// - private void refreshTool() - { - placementBlueprintContainer.Clear(); - currentPlacement = null; - - var blueprint = CurrentTool?.CreatePlacementBlueprint(); - - if (blueprint != null) - { - placementBlueprintContainer.Child = currentPlacement = blueprint; - - // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame - updatePlacementPosition(inputManager.CurrentState.Mouse.Position); - } - } - - private void updatePlacementPosition(Vector2 screenSpacePosition) - { - Vector2 snappedGridPosition = composer.GetSnappedPosition(ToLocalSpace(screenSpacePosition), 0).position; - Vector2 snappedScreenSpacePosition = ToScreenSpace(snappedGridPosition); - - currentPlacement.UpdatePosition(snappedScreenSpacePosition); - } - - #endregion - #region Selection /// @@ -449,7 +369,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // The final movement position, relative to screenSpaceMovementStartPosition Vector2 movePosition = startPosition + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; - (Vector2 snappedPosition, double snappedTime) = composer.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); + (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); // Move the hitobjects if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) @@ -486,7 +406,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (beatmap != null) { - beatmap.HitObjectAdded -= addBlueprintFor; + beatmap.HitObjectAdded -= AddBlueprintFor; beatmap.HitObjectRemoved -= removeBlueprintFor; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 9267006e4c..1576def38e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -1,6 +1,19 @@ // 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Framework.Input.Events; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Edit.Tools; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; + namespace osu.Game.Screens.Edit.Compose.Components { /// @@ -8,5 +21,129 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public class ComposeBlueprintContainer : BlueprintContainer { + [Resolved] + private HitObjectComposer composer { get; set; } + + private PlacementBlueprint currentPlacement; + + private readonly Container placementBlueprintContainer; + + private InputManager inputManager; + + private readonly IEnumerable drawableHitObjects; + + public ComposeBlueprintContainer(IEnumerable drawableHitObjects) + { + this.drawableHitObjects = drawableHitObjects; + + placementBlueprintContainer = new Container + { + RelativeSizeAxes = Axes.Both + }; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(placementBlueprintContainer); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + } + + #region Placement + + /// + /// Refreshes the current placement tool. + /// + private void refreshTool() + { + placementBlueprintContainer.Clear(); + currentPlacement = null; + + var blueprint = CurrentTool?.CreatePlacementBlueprint(); + + if (blueprint != null) + { + placementBlueprintContainer.Child = currentPlacement = blueprint; + + // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame + updatePlacementPosition(inputManager.CurrentState.Mouse.Position); + } + } + + private void updatePlacementPosition(Vector2 screenSpacePosition) + { + Vector2 snappedGridPosition = composer.GetSnappedPosition(ToLocalSpace(screenSpacePosition), 0).position; + Vector2 snappedScreenSpacePosition = ToScreenSpace(snappedGridPosition); + + currentPlacement.UpdatePosition(snappedScreenSpacePosition); + } + + #endregion + + protected override bool OnMouseMove(MouseMoveEvent e) + { + if (currentPlacement != null) + { + updatePlacementPosition(e.ScreenSpaceMousePosition); + return true; + } + + return base.OnMouseMove(e); + } + + protected override void Update() + { + base.Update(); + + if (currentPlacement != null) + { + if (composer.CursorInPlacementArea) + currentPlacement.State = PlacementState.Shown; + else if (currentPlacement?.PlacementBegun == false) + currentPlacement.State = PlacementState.Hidden; + } + } + + protected sealed override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) + { + var drawable = drawableHitObjects.FirstOrDefault(d => d.HitObject == hitObject); + if (drawable == null) + return null; + + return CreateBlueprintFor(drawable); + } + + public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; + + protected override void AddBlueprintFor(HitObject hitObject) + { + refreshTool(); + base.AddBlueprintFor(hitObject); + } + + private HitObjectCompositionTool currentTool; + + /// + /// The current placement tool. + /// + public HitObjectCompositionTool CurrentTool + { + get => currentTool; + set + { + if (currentTool == value) + return; + + currentTool = value; + + refreshTool(); + } + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs index 2a510e74fd..f522ca356f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs @@ -50,7 +50,12 @@ namespace osu.Game.Screens.Edit.Compose.Components }; } - public void UpdateDrag(MouseButtonEvent e) + /// + /// Handle a forwarded mouse event. + /// + /// The mouse event. + /// Whether the event should be handled and blocking. + public virtual bool UpdateDrag(MouseButtonEvent e) { var dragPosition = e.ScreenSpaceMousePosition; var dragStartPosition = e.ScreenSpaceMouseDownPosition; @@ -67,6 +72,7 @@ namespace osu.Game.Screens.Edit.Compose.Components box.Size = bottomRight - topLeft; performSelection?.Invoke(dragRectangle); + return true; } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index e2d7855eb5..bff94e66ed 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private Drawable outline; - [Resolved] + [Resolved(CanBeNull = true)] private IPlacementHandler placementHandler { get; set; } public SelectionHandler() diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 12909f257d..f521d08ada 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -1,11 +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 System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -26,7 +29,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline this.beatmap = beatmap; - AddInternal(content = new TimelinePart()); + AddInternal(content = new TimelinePart { RelativeSizeAxes = Axes.Both }); } [BackgroundDependencyLoader] @@ -44,6 +47,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }; } + protected override void LoadComplete() + { + base.LoadComplete(); + DragBox.Alpha = 0; + } + private void remove(HitObject h) { foreach (var d in content.OfType().Where(c => c.HitObject == h)) @@ -57,6 +66,25 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline content.Add(new TimelineHitObjectRepresentation(h) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }); } + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + + return false; // tempoerary until we correctly handle selections. + } + + protected override DragBox CreateDragBox(Action performSelect) => new NoDragDragBox(performSelect); + + internal class NoDragDragBox : DragBox + { + public NoDragDragBox(Action performSelect) + : base(performSelect) + { + } + + public override bool UpdateDrag(MouseButtonEvent e) => false; + } + private class TimelineHitObjectRepresentation : CompositeDrawable { public const float THICKNESS = 3; From 5f178b77554d1fbd158b66bdd441f588c590c152 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 16 Jan 2020 11:54:03 +0900 Subject: [PATCH 037/157] General refactorings --- .../Edit/OsuBlueprintContainer.cs | 10 +++---- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 +-- .../Compose/Components/BlueprintContainer.cs | 30 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index fc856d9810..30682616e6 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuBlueprintContainer : ComposeBlueprintContainer { + public OsuBlueprintContainer(IEnumerable drawableHitObjects) + : base(drawableHitObjects) + { + } + protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) @@ -32,10 +37,5 @@ namespace osu.Game.Rulesets.Osu.Edit return base.CreateBlueprintFor(hitObject); } - - public OsuBlueprintContainer(IEnumerable drawableHitObjects) - : base(drawableHitObjects) - { - } } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 52c0701f4f..5eba31d149 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -147,8 +147,6 @@ namespace osu.Game.Rulesets.Edit blueprintContainer.SelectionChanged += selectionChanged; } - protected abstract ComposeBlueprintContainer CreateBlueprintContainer(); - protected override void LoadComplete() { base.LoadComplete(); @@ -235,6 +233,8 @@ namespace osu.Game.Rulesets.Edit protected abstract IReadOnlyList CompositionTools { get; } + protected abstract ComposeBlueprintContainer CreateBlueprintContainer(); + protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null); public void BeginPlacement(HitObject hitObject) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 7944476100..c356f1d4e0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { public event Action> SelectionChanged; - protected DragBox DragBox; + protected DragBox DragBox { get; private set; } private SelectionBlueprintContainer selectionBlueprints; @@ -49,19 +49,6 @@ namespace osu.Game.Screens.Edit.Compose.Components RelativeSizeAxes = Axes.Both; } - /// - /// Creates a which outlines s and handles movement of selections. - /// - protected virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); - - /// - /// Creates a for a specific . - /// - /// The to create the overlay for. - protected virtual SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => null; - - protected virtual DragBox CreateDragBox(Action performSelect) => new DragBox(performSelect); - [BackgroundDependencyLoader] private void load() { @@ -73,7 +60,7 @@ namespace osu.Game.Screens.Edit.Compose.Components DragBox = CreateDragBox(select), selectionHandler, selectionBlueprints = new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }, - DragBox.CreateProxy().With(p => p.Depth = int.MinValue) + DragBox.CreateProxy().With(p => p.Depth = float.MinValue) }); foreach (var obj in beatmap.HitObjects) @@ -88,6 +75,19 @@ namespace osu.Game.Screens.Edit.Compose.Components beatmap.HitObjectRemoved += removeBlueprintFor; } + /// + /// Creates a which outlines s and handles movement of selections. + /// + protected virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler(); + + /// + /// Creates a for a specific . + /// + /// The to create the overlay for. + protected virtual SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => null; + + protected virtual DragBox CreateDragBox(Action performSelect) => new DragBox(performSelect); + protected override bool OnMouseDown(MouseDownEvent e) { beginClickSelection(e); From 9535b3eeba97df727471c4f947323cf20f172563 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 16 Jan 2020 12:00:36 +0900 Subject: [PATCH 038/157] Fix possible nullref on blueprint removal --- osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index c356f1d4e0..81b0fb247f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -208,7 +208,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void removeBlueprintFor(HitObject hitObject) { - var blueprint = selectionBlueprints.Single(m => m.DrawableObject.HitObject == hitObject); + var blueprint = selectionBlueprints.SingleOrDefault(m => m.DrawableObject.HitObject == hitObject); if (blueprint == null) return; From 2bc7458abf98113f38d43212201193caa01cb54f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 17 Jan 2020 13:27:47 +0900 Subject: [PATCH 039/157] Add mod setting (de)serialization support --- .../Online/TestAPIModSerialization.cs | 82 +++++++++++++++++++ .../Configuration/SettingSourceAttribute.cs | 26 ++++-- osu.Game/Online/API/APIMod.cs | 56 +++++++++++++ .../Online/API/Requests/Responses/APIMod.cs | 14 ---- osu.Game/Online/Multiplayer/PlaylistItem.cs | 11 ++- 5 files changed, 162 insertions(+), 27 deletions(-) create mode 100644 osu.Game.Tests/Online/TestAPIModSerialization.cs create mode 100644 osu.Game/Online/API/APIMod.cs delete mode 100644 osu.Game/Online/API/Requests/Responses/APIMod.cs diff --git a/osu.Game.Tests/Online/TestAPIModSerialization.cs b/osu.Game.Tests/Online/TestAPIModSerialization.cs new file mode 100644 index 0000000000..845f57136a --- /dev/null +++ b/osu.Game.Tests/Online/TestAPIModSerialization.cs @@ -0,0 +1,82 @@ +// 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 Newtonsoft.Json; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Online.API; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Tests.Online +{ + [TestFixture] + public class TestAPIModSerialization + { + [Test] + public void TestAcronymIsPreserved() + { + var apiMod = new APIMod(new TestMod()); + + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(apiMod)); + + Assert.That(deserialized.Acronym, Is.EqualTo(apiMod.Acronym)); + } + + [Test] + public void TestRawSettingIsPreserved() + { + var apiMod = new APIMod(new TestMod { TestSetting = { Value = 2 } }); + + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(apiMod)); + + Assert.That(deserialized.Settings, Contains.Key("test_setting").With.ContainValue(2.0)); + } + + [Test] + public void TestConvertedModHasCorrectSetting() + { + var apiMod = new APIMod(new TestMod { TestSetting = { Value = 2 } }); + + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(apiMod)); + var converted = (TestMod)deserialized.ToMod(new TestRuleset()); + + Assert.That(converted.TestSetting.Value, Is.EqualTo(2)); + } + + private class TestRuleset : Ruleset + { + public override IEnumerable GetModsFor(ModType type) => new[] { new TestMod() }; + + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => throw new System.NotImplementedException(); + + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new System.NotImplementedException(); + + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new System.NotImplementedException(); + + public override string Description { get; } + public override string ShortName { get; } + } + + private class TestMod : Mod + { + public override string Name => "Test Mod"; + public override string Acronym => "TM"; + public override double ScoreMultiplier => 1; + + [SettingSource("Test")] + public BindableNumber TestSetting { get; } = new BindableDouble + { + MinValue = 0, + MaxValue = 10, + Default = 5, + Precision = 0.01, + }; + } + } +} diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 056fa8bcc0..f859dccc80 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -35,16 +35,11 @@ namespace osu.Game.Configuration { public static IEnumerable CreateSettingsControls(this object obj) { - foreach (var property in obj.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) + foreach (var (attr, property) in obj.GetSettingsSourceProperties()) { - var attr = property.GetCustomAttribute(true); + object value = property.GetValue(obj); - if (attr == null) - continue; - - var prop = property.GetValue(obj); - - switch (prop) + switch (value) { case BindableNumber bNumber: yield return new SettingsSlider @@ -102,9 +97,22 @@ namespace osu.Game.Configuration break; default: - throw new InvalidOperationException($"{nameof(SettingSourceAttribute)} was attached to an unsupported type ({prop})"); + throw new InvalidOperationException($"{nameof(SettingSourceAttribute)} was attached to an unsupported type ({value})"); } } } + + public static IEnumerable<(SettingSourceAttribute, PropertyInfo)> GetSettingsSourceProperties(this object obj) + { + foreach (var property in obj.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) + { + var attr = property.GetCustomAttribute(true); + + if (attr == null) + continue; + + yield return (attr, property); + } + } } } diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs new file mode 100644 index 0000000000..30336d16a3 --- /dev/null +++ b/osu.Game/Online/API/APIMod.cs @@ -0,0 +1,56 @@ +// 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 Humanizer; +using Newtonsoft.Json; +using osu.Framework.Bindables; +using osu.Game.Configuration; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Online.API +{ + public class APIMod : IMod + { + [JsonProperty("acronym")] + public string Acronym { get; set; } + + [JsonProperty("settings")] + public Dictionary Settings { get; set; } = new Dictionary(); + + [JsonConstructor] + private APIMod() + { + } + + public APIMod(Mod mod) + { + Acronym = mod.Acronym; + + foreach (var (_, property) in mod.GetSettingsSourceProperties()) + Settings.Add(property.Name.Underscore(), property.GetValue(mod)); + } + + public Mod ToMod(Ruleset ruleset) + { + Mod resultMod = ruleset.GetAllMods().FirstOrDefault(m => m.Acronym == Acronym); + + if (resultMod == null) + return null; // Todo: Maybe throw exception? + + foreach (var (_, property) in resultMod.GetSettingsSourceProperties()) + { + if (!Settings.TryGetValue(property.Name.Underscore(), out object settingValue)) + continue; + + ((IBindable)property.GetValue(resultMod)).Parse(settingValue); + } + + return resultMod; + } + + public bool Equals(IMod other) => Acronym == other?.Acronym; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIMod.cs b/osu.Game/Online/API/Requests/Responses/APIMod.cs deleted file mode 100644 index b9da4f49ee..0000000000 --- a/osu.Game/Online/API/Requests/Responses/APIMod.cs +++ /dev/null @@ -1,14 +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 osu.Game.Rulesets.Mods; - -namespace osu.Game.Online.API.Requests.Responses -{ - public class APIMod : IMod - { - public string Acronym { get; set; } - - public bool Equals(IMod other) => Acronym == other?.Acronym; - } -} diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs index d13e8b31e6..5f8edc607b 100644 --- a/osu.Game/Online/Multiplayer/PlaylistItem.cs +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Game.Beatmaps; +using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -50,7 +51,7 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("allowed_mods")] private APIMod[] allowedMods { - get => AllowedMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + get => AllowedMods.Select(m => new APIMod(m)).ToArray(); set => allowedModsBacking = value; } @@ -59,7 +60,7 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("required_mods")] private APIMod[] requiredMods { - get => RequiredMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray(); + get => RequiredMods.Select(m => new APIMod(m)).ToArray(); set => requiredModsBacking = value; } @@ -72,10 +73,12 @@ namespace osu.Game.Online.Multiplayer Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); Ruleset = rulesets.GetRuleset(RulesetID); + Ruleset rulesetInstance = Ruleset.CreateInstance(); + if (allowedModsBacking != null) { AllowedMods.Clear(); - AllowedMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => allowedModsBacking.Any(m => m.Acronym == mod.Acronym))); + AllowedMods.AddRange(allowedModsBacking.Select(m => m.ToMod(rulesetInstance))); allowedModsBacking = null; } @@ -83,7 +86,7 @@ namespace osu.Game.Online.Multiplayer if (requiredModsBacking != null) { RequiredMods.Clear(); - RequiredMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => requiredModsBacking.Any(m => m.Acronym == mod.Acronym))); + RequiredMods.AddRange(requiredModsBacking.Select(m => m.ToMod(rulesetInstance))); requiredModsBacking = null; } From 4fa2c5c8c1fdcb9b51b629832bedd25f992a5284 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 17 Jan 2020 18:52:13 +0900 Subject: [PATCH 040/157] Resolve unassigned properties --- osu.Game.Tests/Online/TestAPIModSerialization.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Online/TestAPIModSerialization.cs b/osu.Game.Tests/Online/TestAPIModSerialization.cs index 845f57136a..d9318aa822 100644 --- a/osu.Game.Tests/Online/TestAPIModSerialization.cs +++ b/osu.Game.Tests/Online/TestAPIModSerialization.cs @@ -59,8 +59,8 @@ namespace osu.Game.Tests.Online public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => throw new System.NotImplementedException(); - public override string Description { get; } - public override string ShortName { get; } + public override string Description { get; } = string.Empty; + public override string ShortName { get; } = string.Empty; } private class TestMod : Mod From cd5290b03007d24d42c54d64558cd5b9f0528115 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Jan 2020 13:50:27 +0900 Subject: [PATCH 041/157] Enforce using get-only auto property where possible --- .../Screens/Ladder/Components/ProgressionPath.cs | 4 ++-- osu.Game/Screens/Ranking/ResultModeButton.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 2 +- .../Storyboards/Drawables/DrawableStoryboardAnimation.cs | 2 +- osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs | 2 +- osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs | 2 +- osu.sln.DotSettings | 5 +++-- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs b/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs index 84a329085a..cb73985b11 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs @@ -10,8 +10,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { public class ProgressionPath : Path { - public DrawableTournamentMatch Source { get; private set; } - public DrawableTournamentMatch Destination { get; private set; } + public DrawableTournamentMatch Source { get; } + public DrawableTournamentMatch Destination { get; } public ProgressionPath(DrawableTournamentMatch source, DrawableTournamentMatch destination) { diff --git a/osu.Game/Screens/Ranking/ResultModeButton.cs b/osu.Game/Screens/Ranking/ResultModeButton.cs index 38636b0c3b..d7eb5db125 100644 --- a/osu.Game/Screens/Ranking/ResultModeButton.cs +++ b/osu.Game/Screens/Ranking/ResultModeButton.cs @@ -92,6 +92,6 @@ namespace osu.Game.Screens.Ranking protected override void OnDeactivated() => colouredPart.FadeColour(inactiveColour, 200, Easing.OutQuint); - public string TooltipText { get; private set; } + public string TooltipText { get; } } } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 451708c1cf..b0d5be8140 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -363,7 +363,7 @@ namespace osu.Game.Screens.Select public class InfoLabel : Container, IHasTooltip { - public string TooltipText { get; private set; } + public string TooltipText { get; } public InfoLabel(BeatmapStatistic statistic) { diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 7a84ac009a..94d7395ecf 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -14,7 +14,7 @@ namespace osu.Game.Storyboards.Drawables { public class DrawableStoryboard : Container { - public Storyboard Storyboard { get; private set; } + public Storyboard Storyboard { get; } protected override Container Content { get; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index ced3b9c1b6..eabb78bac5 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -15,7 +15,7 @@ namespace osu.Game.Storyboards.Drawables { public class DrawableStoryboardAnimation : TextureAnimation, IFlippable, IVectorScalable { - public StoryboardAnimation Animation { get; private set; } + public StoryboardAnimation Animation { get; } private bool flipH; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index fd2d441f34..39f5418902 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs @@ -10,7 +10,7 @@ namespace osu.Game.Storyboards.Drawables { public class DrawableStoryboardLayer : LifetimeManagementContainer { - public StoryboardLayer Layer { get; private set; } + public StoryboardLayer Layer { get; } public bool Enabled; public override bool IsPresent => Enabled && base.IsPresent; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index c0da0e9c0e..d8d3248659 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -15,7 +15,7 @@ namespace osu.Game.Storyboards.Drawables { public class DrawableStoryboardSprite : Sprite, IFlippable, IVectorScalable { - public StoryboardSprite Sprite { get; private set; } + public StoryboardSprite Sprite { get; } private bool flipH; diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 12571be31d..15ea20084d 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -19,8 +19,8 @@ HINT DO_NOT_SHOW HINT - HINT - HINT + WARNING + WARNING WARNING WARNING WARNING @@ -765,6 +765,7 @@ See the LICENCE file in the repository root for full licence text. <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True True True From a27e2c574d003f72a956b892d195e1d416d6d6f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Jan 2020 13:53:46 +0900 Subject: [PATCH 042/157] Update fastlane and plugins --- Gemfile.lock | 74 +++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ab594aee74..e3954c2681 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.1) + CFPropertyList (3.0.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) @@ -18,8 +18,8 @@ GEM unf (>= 0.0.5, < 1.0.0) dotenv (2.7.5) emoji_regex (1.0.1) - excon (0.67.0) - faraday (0.15.4) + excon (0.71.1) + faraday (0.17.3) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) faraday (>= 0.7.4) @@ -27,7 +27,7 @@ GEM faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) fastimage (2.1.7) - fastlane (2.133.0) + fastlane (2.140.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) babosa (>= 1.0.2, < 2.0.0) @@ -36,13 +36,13 @@ GEM commander-fastlane (>= 4.4.6, < 5.0.0) dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 2.0) - excon (>= 0.45.0, < 1.0.0) - faraday (< 0.16.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 0.17) faraday-cookie_jar (~> 0.0.6) - faraday_middleware (< 0.16.0) + faraday_middleware (~> 0.13.1) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.21.2, < 0.24.0) + google-api-client (>= 0.29.2, < 0.37.0) google-cloud-storage (>= 1.15.0, < 2.0.0) highline (>= 1.7.2, < 2.0.0) json (< 3.0.0) @@ -61,56 +61,58 @@ GEM tty-screen (>= 0.6.3, < 1.0.0) tty-spinner (>= 0.8.0, < 1.0.0) word_wrap (~> 1.0.0) - xcodeproj (>= 1.8.1, < 2.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) fastlane-plugin-clean_testflight_testers (0.3.0) - fastlane-plugin-souyuz (0.8.1) - souyuz (>= 0.8.1) + fastlane-plugin-souyuz (0.9.1) + souyuz (= 0.9.1) fastlane-plugin-xamarin (0.6.3) gh_inspector (1.1.3) - google-api-client (0.23.9) + google-api-client (0.36.4) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.5, < 0.7.0) + googleauth (~> 0.9) httpclient (>= 2.8.1, < 3.0) - mime-types (~> 3.0) + mini_mime (~> 1.0) representable (~> 3.0) retriable (>= 2.0, < 4.0) - signet (~> 0.9) - google-cloud-core (1.3.1) + signet (~> 0.12) + google-cloud-core (1.5.0) google-cloud-env (~> 1.0) - google-cloud-env (1.2.1) + google-cloud-errors (~> 1.0) + google-cloud-env (1.3.0) faraday (~> 0.11) - google-cloud-storage (1.16.0) + google-cloud-errors (1.0.0) + google-cloud-storage (1.25.1) + addressable (~> 2.5) digest-crc (~> 0.4) - google-api-client (~> 0.23) + google-api-client (~> 0.33) google-cloud-core (~> 1.2) - googleauth (>= 0.6.2, < 0.10.0) - googleauth (0.6.7) + googleauth (~> 0.9) + mini_mime (~> 1.0) + googleauth (0.10.0) faraday (~> 0.12) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) - signet (~> 0.7) + signet (~> 0.12) highline (1.7.10) http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) - json (2.2.0) + json (2.3.0) jwt (2.1.0) - memoist (0.16.0) - mime-types (3.3) - mime-types-data (~> 3.2015) - mime-types-data (3.2019.1009) - mini_magick (4.9.5) + memoist (0.16.2) + mini_magick (4.10.1) + mini_mime (1.0.2) mini_portile2 (2.4.0) - multi_json (1.13.1) + multi_json (1.14.1) multi_xml (0.6.0) multipart-post (2.0.0) nanaimo (0.2.6) naturally (2.2.0) - nokogiri (1.10.4) + nokogiri (1.10.7) mini_portile2 (~> 2.4.0) os (1.0.1) plist (3.5.0) @@ -128,12 +130,12 @@ GEM faraday (~> 0.9) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) - simctl (1.6.6) + simctl (1.6.7) CFPropertyList naturally slack-notifier (2.3.2) - souyuz (0.8.1) - fastlane (>= 2.29.0) + souyuz (0.9.1) + fastlane (>= 1.103.0) highline (~> 1.7) nokogiri (~> 1.7) terminal-notifier (2.0.0) @@ -141,15 +143,15 @@ GEM unicode-display_width (~> 1.1, >= 1.1.1) tty-cursor (0.7.0) tty-screen (0.7.0) - tty-spinner (0.9.1) + tty-spinner (0.9.2) tty-cursor (~> 0.7) uber (0.1.0) unf (0.1.4) unf_ext unf_ext (0.0.7.6) - unicode-display_width (1.6.0) + unicode-display_width (1.6.1) word_wrap (1.0.0) - xcodeproj (1.12.0) + xcodeproj (1.14.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) From bfb056c612029c78fcb2676645a5fb1cda97884d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 20 Jan 2020 18:17:21 +0900 Subject: [PATCH 043/157] Apply input method signature refactorings --- .../Edit/Blueprints/ManiaPlacementBlueprint.cs | 4 ++-- .../Edit/Blueprints/ManiaSelectionBlueprint.cs | 6 ++---- .../Components/PathControlPointPiece.cs | 8 +------- .../Sliders/SliderPlacementBlueprint.cs | 4 ++-- .../Sliders/SliderSelectionBlueprint.cs | 7 ++----- .../Components/DrawableTournamentMatch.cs | 5 ++--- .../Screens/Ladder/LadderDragContainer.cs | 3 +-- .../Containers/OsuFocusedOverlayContainer.cs | 4 ++-- .../Graphics/Containers/OsuScrollContainer.cs | 18 +++++++++--------- osu.Game/Graphics/Cursor/MenuCursor.cs | 4 ++-- .../Graphics/UserInterface/DialogButton.cs | 4 ++-- .../UserInterface/OsuAnimatedButton.cs | 4 ++-- osu.Game/Graphics/UserInterface/OsuButton.cs | 4 ++-- .../Graphics/UserInterface/OsuSliderBar.cs | 4 ++-- .../RetrievalFailurePlaceholder.cs | 4 ++-- .../Online/Placeholders/LoginPlaceholder.cs | 4 ++-- osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs | 7 ++----- osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 8 +++----- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 16 +++++----------- osu.Game/Overlays/Mods/ModButton.cs | 4 +--- osu.Game/Overlays/Music/PlaylistItem.cs | 4 ++-- osu.Game/Overlays/Music/PlaylistList.cs | 16 ++++++++-------- osu.Game/Overlays/NowPlayingOverlay.cs | 7 +++---- .../Timelines/Summary/Parts/MarkerPart.cs | 8 +++++--- .../Compose/Components/BeatDivisorControl.cs | 7 +++---- .../Compose/Components/BlueprintContainer.cs | 15 +++++---------- .../Compose/Components/Timeline/Timeline.cs | 4 ++-- osu.Game/Screens/Menu/Button.cs | 4 ++-- osu.Game/Screens/Menu/OsuLogo.cs | 5 ++--- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 4 +++- osu.Game/Screens/Play/HUD/HoldForMenuButton.cs | 3 +-- osu.Game/Screens/Play/KeyCounterMouse.cs | 4 ++-- osu.Game/Screens/Play/SkipOverlay.cs | 7 +++---- osu.Game/Screens/Select/FooterButton.cs | 4 ++-- .../Select/Options/BeatmapOptionsButton.cs | 4 ++-- 36 files changed, 95 insertions(+), 127 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs index b28d8bb0e6..7a3b42914e 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs @@ -54,10 +54,10 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { EndPlacement(); - return base.OnMouseUp(e); + base.OnMouseUp(e); } public override void UpdatePosition(Vector2 screenSpacePosition) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs index 3bd7fb2d49..ff3dbe614a 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs @@ -55,14 +55,12 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints return base.OnMouseDown(e); } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { - var result = base.OnDrag(e); + base.OnDrag(e); ScreenSpaceDragPosition = e.ScreenSpaceMousePosition; DragPosition = DrawableObject.ToLocalSpace(e.ScreenSpaceMousePosition); - - return result; } public override void Show() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 6a0730db91..af4da5e853 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -135,13 +135,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components return false; } - protected override bool OnMouseUp(MouseUpEvent e) => RequestSelection != null; - protected override bool OnClick(ClickEvent e) => RequestSelection != null; protected override bool OnDragStart(DragStartEvent e) => e.Button == MouseButton.Left; - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { if (ControlPoint == slider.Path.ControlPoints[0]) { @@ -158,12 +156,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } else ControlPoint.Position.Value += e.Delta; - - return true; } - protected override bool OnDragEnd(DragEndEvent e) => true; - /// /// Updates the state of the circular control point marker. /// diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 2497e428fc..90512849d4 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -106,11 +106,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (state == PlacementState.Body && e.Button == MouseButton.Right) endCurve(); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnDoubleClick(DoubleClickEvent e) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 3165c441fb..4fdead512a 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -90,19 +90,16 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected override bool OnDragStart(DragStartEvent e) => placementControlPointIndex != null; - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { Debug.Assert(placementControlPointIndex != null); HitObject.Path.ControlPoints[placementControlPointIndex.Value].Position.Value = e.MousePosition - HitObject.Position; - - return true; } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { placementControlPointIndex = null; - return true; } private BindableList controlPoints => HitObject.Path.ControlPoints; diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs index dde280ccd8..c4b670f059 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs @@ -289,16 +289,15 @@ namespace osu.Game.Tournament.Screens.Ladder.Components return true; } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { - if (base.OnDrag(e)) return true; + base.OnDrag(e); Selected = true; this.MoveToOffset(e.Delta); var pos = Position; Match.Position.Value = new Point((int)pos.X, (int)pos.Y); - return true; } public void Remove() diff --git a/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs b/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs index 0c450a66b4..bdaa1ae7fd 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs @@ -22,10 +22,9 @@ namespace osu.Game.Tournament.Screens.Ladder protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false; - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { this.MoveTo(target += e.Delta, 1000, Easing.OutQuint); - return true; } private const float min_scale = 0.6f; diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index facf70b47a..7c2c1e5c67 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -76,12 +76,12 @@ namespace osu.Game.Graphics.Containers return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (closeOnMouseUp && !base.ReceivePositionalInputAt(e.ScreenSpaceMousePosition)) Hide(); - return base.OnMouseUp(e); + base.OnMouseUp(e); } public virtual bool OnPressed(GlobalAction action) diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs index cfd459da5e..6d531887ed 100644 --- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs +++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs @@ -50,15 +50,15 @@ namespace osu.Game.Graphics.Containers return base.OnMouseDown(e); } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { if (rightMouseDragging) { scrollFromMouseEvent(e); - return true; + return; } - return base.OnDrag(e); + base.OnDrag(e); } protected override bool OnDragStart(DragStartEvent e) @@ -72,15 +72,15 @@ namespace osu.Game.Graphics.Containers return base.OnDragStart(e); } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { if (rightMouseDragging) { rightMouseDragging = false; - return true; + return; } - return base.OnDragEnd(e); + base.OnDragEnd(e); } protected override bool OnScroll(ScrollEvent e) @@ -162,13 +162,13 @@ namespace osu.Game.Graphics.Containers return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { - if (e.Button != MouseButton.Left) return false; + if (e.Button != MouseButton.Left) return; box.FadeColour(Color4.White, 100); - return base.OnMouseUp(e); + base.OnMouseUp(e); } } } diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 170ea63059..580177d17a 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -92,7 +92,7 @@ namespace osu.Game.Graphics.Cursor return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (!e.IsPressed(MouseButton.Left) && !e.IsPressed(MouseButton.Right)) { @@ -107,7 +107,7 @@ namespace osu.Game.Graphics.Cursor dragRotationState = DragRotationState.NotDragging; } - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override void PopIn() diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index aed07e56ee..9b53ee7b2d 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -232,11 +232,11 @@ namespace osu.Game.Graphics.UserInterface return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (Selected.Value) colourContainer.ResizeWidthTo(hover_width, click_duration, Easing.In); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs index 660bd7979f..cfcf034d1c 100644 --- a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs @@ -107,10 +107,10 @@ namespace osu.Game.Graphics.UserInterface return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { Content.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } } } diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index c6a9aa1c97..9cf8f02024 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -129,10 +129,10 @@ namespace osu.Game.Graphics.UserInterface return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { Content.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected virtual SpriteText CreateText() => new OsuSpriteText diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 958390d5d2..2112aac6a3 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -128,10 +128,10 @@ namespace osu.Game.Graphics.UserInterface return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { Nub.Current.Value = false; - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override void OnUserChange(T value) diff --git a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs index 15d7dabe65..d109f28e72 100644 --- a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs +++ b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs @@ -55,10 +55,10 @@ namespace osu.Game.Online.Leaderboards return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { icon.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } } } diff --git a/osu.Game/Online/Placeholders/LoginPlaceholder.cs b/osu.Game/Online/Placeholders/LoginPlaceholder.cs index ffc6623229..591eb976e2 100644 --- a/osu.Game/Online/Placeholders/LoginPlaceholder.cs +++ b/osu.Game/Online/Placeholders/LoginPlaceholder.cs @@ -31,10 +31,10 @@ namespace osu.Game.Online.Placeholders return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { this.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs index 266e68f17e..09dc06b95f 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs @@ -141,16 +141,13 @@ namespace osu.Game.Overlays.Chat.Tabs updateState(); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { switch (e.Button) { case MouseButton.Middle: CloseButton.Click(); - return true; - - default: - return false; + break; } } diff --git a/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs b/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs index bde930d4fb..178afda5ac 100644 --- a/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs +++ b/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs @@ -34,10 +34,10 @@ namespace osu.Game.Overlays.Chat.Tabs return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { icon.ScaleTo(0.75f, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 45d311df28..2c0fa49b5d 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -299,7 +299,7 @@ namespace osu.Game.Overlays return true; } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { if (isDragging) { @@ -311,14 +311,12 @@ namespace osu.Game.Overlays ChatHeight.Value = targetChatHeight; } - - return true; } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { isDragging = false; - return base.OnDragEnd(e); + base.OnDragEnd(e); } private void selectTab(int index) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8317951c8a..a35fa016a9 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -177,17 +177,19 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { // don't do anything until the last button is released. if (!HasFocus || e.HasAnyButtonPressed) - return base.OnMouseUp(e); + { + base.OnMouseUp(e); + return; + } if (bindTarget.IsHovered) finalise(); else updateBindTarget(); - return true; } protected override bool OnScroll(ScrollEvent e) @@ -313,14 +315,6 @@ namespace osu.Game.Overlays.KeyBinding Size = new Vector2(80, 20); } - protected override bool OnMouseUp(MouseUpEvent e) - { - base.OnMouseUp(e); - - // without this, the mouse up triggers a finalise (and deselection) of the current binding target. - return true; - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 77ef08f52d..e574828cd2 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -158,7 +158,7 @@ namespace osu.Game.Overlays.Mods return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { scaleContainer.ScaleTo(1, 500, Easing.OutElastic); @@ -172,8 +172,6 @@ namespace osu.Game.Overlays.Mods break; } } - - return true; } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 29b6ae00f3..d40f391982 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -43,10 +43,10 @@ namespace osu.Game.Overlays.Music return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { IsDraggable = false; - return base.OnMouseUp(e); + base.OnMouseUp(e); } private bool selected; diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 3cd04ac809..7bdcab6dff 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -136,29 +136,29 @@ namespace osu.Game.Overlays.Music return draggedItem != null || base.OnDragStart(e); } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { nativeDragPosition = e.ScreenSpaceMousePosition; - if (draggedItem == null) - return base.OnDrag(e); - return true; + if (draggedItem == null) + base.OnDrag(e); } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { nativeDragPosition = e.ScreenSpaceMousePosition; if (draggedItem == null) - return base.OnDragEnd(e); + { + base.OnDragEnd(e); + return; + } if (dragDestination != null) musicController.ChangeBeatmapSetPosition(draggedItem.BeatmapSetInfo, dragDestination.Value); draggedItem = null; dragDestination = null; - - return true; } protected override void Update() diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index a8ba7fa427..042e95c6d7 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -385,7 +385,7 @@ namespace osu.Game.Overlays return true; } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { Vector2 change = e.MousePosition - e.MouseDownPosition; @@ -393,13 +393,12 @@ namespace osu.Game.Overlays change *= change.Length <= 0 ? 0 : MathF.Pow(change.Length, 0.7f) / change.Length; this.MoveTo(change); - return true; } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { this.MoveTo(Vector2.Zero, 800, Easing.OutElastic); - return base.OnDragEnd(e); + base.OnDragEnd(e); } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 79ada40a89..d03cc8a0e8 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -32,12 +32,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } protected override bool OnDragStart(DragStartEvent e) => true; - protected override bool OnDragEnd(DragEndEvent e) => true; - protected override bool OnDrag(DragEvent e) + protected override void OnDragEnd(DragEndEvent e) + { + } + + protected override void OnDrag(DragEvent e) { seekToPosition(e.ScreenSpaceMousePosition); - return true; } protected override bool OnMouseDown(MouseDownEvent e) diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 42773ef687..8201ec2710 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -262,10 +262,10 @@ namespace osu.Game.Screens.Edit.Compose.Components return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { marker.Active = false; - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) @@ -274,10 +274,9 @@ namespace osu.Game.Screens.Edit.Compose.Components return true; } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { handleMouseInput(e.ScreenSpaceMousePosition); - return true; } private void handleMouseInput(Vector2 screenSpaceMousePosition) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index cafaddc39e..0679174fc8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -129,11 +129,10 @@ namespace osu.Game.Screens.Edit.Compose.Components return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { // Special case for when a drag happened instead of a click Schedule(() => endClickSelection()); - return e.Button == MouseButton.Left; } protected override bool OnMouseMove(MouseMoveEvent e) @@ -161,29 +160,25 @@ namespace osu.Game.Screens.Edit.Compose.Components return true; } - protected override bool OnDrag(DragEvent e) + protected override void OnDrag(DragEvent e) { if (e.Button == MouseButton.Right) - return false; + return; if (!moveCurrentSelection(e)) dragBox.UpdateDrag(e); - - return true; } - protected override bool OnDragEnd(DragEndEvent e) + protected override void OnDragEnd(DragEndEvent e) { if (e.Button == MouseButton.Right) - return false; + return; if (!finishSelectionMovement()) { dragBox.FadeOut(250, Easing.OutQuint); selectionHandler.UpdateVisibility(); } - - return true; } protected override bool OnKeyDown(KeyDownEvent e) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index b4f3b1f610..b8acc1ab44 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -143,10 +143,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return false; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { endUserDrag(); - return base.OnMouseUp(e); + base.OnMouseUp(e); } private void beginUserDrag() diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index fac6b69e1f..6708ce0ba0 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -194,10 +194,10 @@ namespace osu.Game.Screens.Menu return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { boxHoverLayer.FadeTo(0, 1000, Easing.OutQuint); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 33b6ee8025..be2f29cbe9 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -353,12 +353,11 @@ namespace osu.Game.Screens.Menu return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { - if (e.Button != MouseButton.Left) return false; + if (e.Button != MouseButton.Left) return; logoBounceContainer.ScaleTo(1f, 500, Easing.OutElastic); - return true; } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index adfbe977a4..b968f96414 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -163,7 +163,9 @@ namespace osu.Game.Screens.Play // Don't let mouse down events through the overlay or people can click circles while paused. protected override bool OnMouseDown(MouseDownEvent e) => true; - protected override bool OnMouseUp(MouseUpEvent e) => true; + protected override void OnMouseUp(MouseUpEvent e) + { + } protected override bool OnMouseMove(MouseMoveEvent e) => true; diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index 7946e6d322..5d7b2a084d 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -278,11 +278,10 @@ namespace osu.Game.Screens.Play.HUD return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (!e.HasAnyButtonPressed) AbortConfirm(); - return true; } } } diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs index 828441de6e..e55525c5e8 100644 --- a/osu.Game/Screens/Play/KeyCounterMouse.cs +++ b/osu.Game/Screens/Play/KeyCounterMouse.cs @@ -45,10 +45,10 @@ namespace osu.Game.Screens.Play return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { if (e.Button == Button) IsLit = false; - return base.OnMouseUp(e); + base.OnMouseUp(e); } } } diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 772d326c7f..c6324b6db5 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -202,10 +202,9 @@ namespace osu.Game.Screens.Play return true; } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { Show(); - return true; } public override void Hide() => State = Visibility.Hidden; @@ -311,10 +310,10 @@ namespace osu.Game.Screens.Play return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { aspect.ScaleTo(1, 1000, Easing.OutElastic); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index b77da36748..4dcab60548 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -118,10 +118,10 @@ namespace osu.Game.Screens.Select return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { box.FadeOut(Footer.TRANSITION_LENGTH, Easing.OutQuint); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index ff9beafb23..4e4653cb57 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -60,10 +60,10 @@ namespace osu.Game.Screens.Select.Options return base.OnMouseDown(e); } - protected override bool OnMouseUp(MouseUpEvent e) + protected override void OnMouseUp(MouseUpEvent e) { flash.FadeTo(0, 1000, Easing.OutQuint); - return base.OnMouseUp(e); + base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) From 1b1003bd731bf3797b5c47ed9eb6eacea7db595a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 20 Jan 2020 18:31:25 +0900 Subject: [PATCH 044/157] Refactor --- .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 4 ---- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 4 ---- 2 files changed, 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index d03cc8a0e8..5d638d7919 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -33,10 +33,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override bool OnDragStart(DragStartEvent e) => true; - protected override void OnDragEnd(DragEndEvent e) - { - } - protected override void OnDrag(DragEvent e) { seekToPosition(e.ScreenSpaceMousePosition); diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index b968f96414..f0fec41e46 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -163,10 +163,6 @@ namespace osu.Game.Screens.Play // Don't let mouse down events through the overlay or people can click circles while paused. protected override bool OnMouseDown(MouseDownEvent e) => true; - protected override void OnMouseUp(MouseUpEvent e) - { - } - protected override bool OnMouseMove(MouseMoveEvent e) => true; protected void AddButton(string text, Color4 colour, Action action) From 40f502c6d13e163cf2d93ebedf5b2ae6ab38d57d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 20 Jan 2020 19:35:37 +0900 Subject: [PATCH 045/157] Apply input method signature refactorings --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 9 ++++++--- .../Edit/Compose/Components/BlueprintContainer.cs | 2 -- osu.Game/Screens/Play/KeyCounterKeyboard.cs | 4 ++-- osu.Game/Screens/Select/FooterButtonRandom.cs | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8317951c8a..02ddd1505e 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -216,12 +216,15 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnKeyUp(KeyUpEvent e) + protected override void OnKeyUp(KeyUpEvent e) { - if (!HasFocus) return base.OnKeyUp(e); + if (!HasFocus) + { + base.OnKeyUp(e); + return; + } finalise(); - return true; } protected override bool OnJoystickPress(JoystickPressEvent e) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index cafaddc39e..43e8cd96f8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -201,8 +201,6 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; } - protected override bool OnKeyUp(KeyUpEvent e) => false; - public bool OnPressed(PlatformAction action) { switch (action.ActionType) diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs index 29188b6b59..187dcc1264 100644 --- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs +++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs @@ -27,10 +27,10 @@ namespace osu.Game.Screens.Play return base.OnKeyDown(e); } - protected override bool OnKeyUp(KeyUpEvent e) + protected override void OnKeyUp(KeyUpEvent e) { if (e.Key == Key) IsLit = false; - return base.OnKeyUp(e); + base.OnKeyUp(e); } } } diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index 14c9eb2035..9bc5181f6f 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -44,11 +44,11 @@ namespace osu.Game.Screens.Select return base.OnKeyDown(e); } - protected override bool OnKeyUp(KeyUpEvent e) + protected override void OnKeyUp(KeyUpEvent e) { secondaryActive = e.ShiftPressed; updateText(); - return base.OnKeyUp(e); + base.OnKeyUp(e); } private void updateText() From b62e3addf378ad05bbb3733d22ad347c594f3e82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 20 Jan 2020 20:30:25 +0900 Subject: [PATCH 046/157] Apply input method signature refactorings --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8317951c8a..cbaa9fb718 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -235,13 +235,15 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnJoystickRelease(JoystickReleaseEvent e) + protected override void OnJoystickRelease(JoystickReleaseEvent e) { if (!HasFocus) - return base.OnJoystickRelease(e); + { + base.OnJoystickRelease(e); + return; + } finalise(); - return true; } private void clear() From 1becbb072efa33543373fa14bad51b9aab287078 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Jan 2020 23:26:21 +0900 Subject: [PATCH 047/157] Remove broken test --- .../Editor/TestSceneBlueprintContainer.cs | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs diff --git a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs b/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs deleted file mode 100644 index a230e5221f..0000000000 --- a/osu.Game.Tests/Editor/TestSceneBlueprintContainer.cs +++ /dev/null @@ -1,20 +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.Collections.Generic; -using NUnit.Framework; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Screens.Edit.Compose.Components; -using osu.Game.Tests.Visual; - -namespace osu.Game.Tests.Editor -{ - public class TestSceneBlueprintContainer : EditorClockTestScene - { - [SetUp] - public void Setup() => Schedule(() => - { - Child = new ComposeBlueprintContainer(new List()); - }); - } -} From 740bdee125ca7b8ed7bd32c21026b31b19a36333 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Jan 2020 23:59:21 +0900 Subject: [PATCH 048/157] Apply remaining uncaught changes --- osu.Game/Audio/SampleInfo.cs | 2 +- osu.Game/Graphics/UserInterface/HoverSounds.cs | 2 +- osu.Game/Graphics/UserInterface/ScoreCounter.cs | 6 +----- osu.Game/Storyboards/StoryboardSprite.cs | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index 66c07209f3..2406b0bef2 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -19,6 +19,6 @@ namespace osu.Game.Audio public IEnumerable LookupNames => new[] { sampleName }; - public int Volume { get; set; } = 100; + public int Volume { get; } = 100; } } diff --git a/osu.Game/Graphics/UserInterface/HoverSounds.cs b/osu.Game/Graphics/UserInterface/HoverSounds.cs index fcd8940348..40899e7e95 100644 --- a/osu.Game/Graphics/UserInterface/HoverSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverSounds.cs @@ -24,7 +24,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Length of debounce for hover sound playback, in milliseconds. Default is 50ms. /// - public double HoverDebounceTime { get; set; } = 50; + public double HoverDebounceTime { get; } = 50; protected readonly HoverSampleSet SampleSet; diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index 24d8009f40..01d8edaecf 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -16,11 +16,7 @@ namespace osu.Game.Graphics.UserInterface /// /// How many leading zeroes the counter has. /// - public uint LeadingZeroes - { - get; - protected set; - } + public uint LeadingZeroes { get; } /// /// Displays score. diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index 22e1929419..f411ad04f3 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -16,7 +16,7 @@ namespace osu.Game.Storyboards private readonly List loops = new List(); private readonly List triggers = new List(); - public string Path { get; set; } + public string Path { get; } public bool IsDrawable => HasCommands; public Anchor Origin; From 41295bc27cb5100376a9007230d84e299bb18156 Mon Sep 17 00:00:00 2001 From: ProTheory8 Date: Mon, 20 Jan 2020 16:06:36 +0000 Subject: [PATCH 049/157] Difficulty Adjust mod customisation menu opens automatically now --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 1 + osu.Game/Rulesets/Mods/Mod.cs | 6 ++++++ osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 2 ++ 3 files changed, 9 insertions(+) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 7f07ce620c..cdc4a42b33 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -474,6 +474,7 @@ namespace osu.Game.Overlays.Mods { if (State.Value == Visibility.Visible) sampleOn?.Play(); DeselectTypes(selectedMod.IncompatibleMods, true); + if (selectedMod.RequiresConfiguration) ModSettingsContainer.Alpha = 1; } else { diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index e168171186..9ee19a433b 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -60,6 +60,12 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual bool Ranked => false; + /// + /// Returns true if this mod requires configuration. If true, opens mod customisation menu every time user enables mod. + /// + [JsonIgnore] + public virtual bool RequiresConfiguration => false; + /// /// The mods this mod cannot be enabled with. /// diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index b74bf01d1b..d74e2ce2bc 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -24,6 +24,8 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1.0; + public override bool RequiresConfiguration => true; + public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; [SettingSource("Drain Rate", "Override a beatmap's set HP.")] From 02f26e4a4d02a1aba90aa88829d694631aba4cce Mon Sep 17 00:00:00 2001 From: ProTheory8 <59506423+ProTheory8@users.noreply.github.com> Date: Tue, 21 Jan 2020 08:44:22 +0500 Subject: [PATCH 050/157] Update comment Co-Authored-By: Salman Ahmed --- osu.Game/Rulesets/Mods/Mod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 9ee19a433b..46c0c1da07 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mods public virtual bool Ranked => false; /// - /// Returns true if this mod requires configuration. If true, opens mod customisation menu every time user enables mod. + /// Whether this mod requires configuration to apply changes to the game. /// [JsonIgnore] public virtual bool RequiresConfiguration => false; From bd96cf94a6284f1d6b9be30e054fda5cfa6c4c62 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 00:53:59 +0900 Subject: [PATCH 051/157] Begin refactoring SelectionBlueprint to handle non-drawable HitObjects --- .../Blueprints/ManiaSelectionBlueprint.cs | 2 +- .../Edit/ManiaBlueprintContainer.cs | 2 +- .../Edit/ManiaSelectionHandler.cs | 5 +- .../Edit/Masks/ManiaSelectionBlueprint.cs | 2 +- .../Edit/Blueprints/OsuSelectionBlueprint.cs | 4 +- .../Edit/OsuBlueprintContainer.cs | 2 +- .../Edit/OverlaySelectionBlueprint.cs | 32 ++++++++++++ osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 35 +++++-------- .../Timelines/Summary/Parts/TimelinePart.cs | 20 +++++--- .../Compose/Components/BlueprintContainer.cs | 38 ++++---------- .../Components/ComposeBlueprintContainer.cs | 2 +- .../Compose/Components/MoveSelectionEvent.cs | 8 +-- .../Compose/Components/SelectionHandler.cs | 4 +- .../Timeline/TimelineHitObjectDisplay.cs | 51 ++++++------------- .../Visual/SelectionBlueprintTestScene.cs | 2 +- 15 files changed, 102 insertions(+), 107 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs index 3bd7fb2d49..63e3d0fcc1 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public class ManiaSelectionBlueprint : SelectionBlueprint + public class ManiaSelectionBlueprint : OverlaySelectionBlueprint { public Vector2 ScreenSpaceDragPosition { get; private set; } public Vector2 DragPosition { get; private set; } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs index 5f66ae7491..d744036b4c 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Edit { } - public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) + public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) { switch (hitObject) { diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs index 618af3e772..f33fd3c640 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Timing; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.UI; @@ -72,8 +73,10 @@ namespace osu.Game.Rulesets.Mania.Edit if (scrollingInfo.Direction.Value == ScrollingDirection.Down) delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight; - foreach (var b in SelectedBlueprints) + foreach (var selectionBlueprint in SelectedBlueprints) { + var b = (OverlaySelectionBlueprint)selectionBlueprint; + var hitObject = b.DrawableObject; var objectParent = (HitObjectContainer)hitObject.Parent; diff --git a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs index ff8882124f..433db79ae0 100644 --- a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Edit.Masks { - public abstract class ManiaSelectionBlueprint : SelectionBlueprint + public abstract class ManiaSelectionBlueprint : OverlaySelectionBlueprint { protected ManiaSelectionBlueprint(DrawableHitObject drawableObject) : base(drawableObject) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index a864257274..b0e13808a5 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -7,10 +7,10 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Edit.Blueprints { - public abstract class OsuSelectionBlueprint : SelectionBlueprint + public abstract class OsuSelectionBlueprint : OverlaySelectionBlueprint where T : OsuHitObject { - protected T HitObject => (T)DrawableObject.HitObject; + protected new T HitObject => (T)DrawableObject.HitObject; protected OsuSelectionBlueprint(DrawableHitObject drawableObject) : base(drawableObject) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index 30682616e6..330f34b85c 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Edit protected override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); - public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) + public override OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) { switch (hitObject) { diff --git a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs new file mode 100644 index 0000000000..4c3898aa04 --- /dev/null +++ b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs @@ -0,0 +1,32 @@ +// 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.Primitives; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Edit +{ + public abstract class OverlaySelectionBlueprint : SelectionBlueprint + { + /// + /// The which this applies to. + /// + public readonly DrawableHitObject DrawableObject; + + protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected; + + protected OverlaySelectionBlueprint(DrawableHitObject drawableObject) + : base(drawableObject.HitObject) + { + DrawableObject = drawableObject; + } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); + + public override Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; + + public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; + } +} diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index bf99f83e0b..d8952a3932 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.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; @@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Edit /// public abstract class SelectionBlueprint : CompositeDrawable, IStateful { + public readonly HitObject HitObject; + /// /// Invoked when this has been selected. /// @@ -30,22 +32,15 @@ namespace osu.Game.Rulesets.Edit /// public event Action Deselected; - /// - /// The which this applies to. - /// - public readonly DrawableHitObject DrawableObject; - - protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected; public override bool HandlePositionalInput => ShouldBeAlive; public override bool RemoveWhenNotAlive => false; [Resolved(CanBeNull = true)] private HitObjectComposer composer { get; set; } - protected SelectionBlueprint(DrawableHitObject drawableObject) + protected SelectionBlueprint(HitObject hitObject) { - DrawableObject = drawableObject; - + this.HitObject = hitObject; RelativeSizeAxes = Axes.Both; AlwaysPresent = true; @@ -87,37 +82,35 @@ namespace osu.Game.Rulesets.Edit protected override bool ShouldBeConsideredForInput(Drawable child) => State == SelectionState.Selected; /// - /// Selects this , causing it to become visible. + /// Selects this , causing it to become visible. /// public void Select() => State = SelectionState.Selected; /// - /// Deselects this , causing it to become invisible. + /// Deselects this , causing it to become invisible. /// public void Deselect() => State = SelectionState.NotSelected; public bool IsSelected => State == SelectionState.Selected; /// - /// Updates the , invoking and re-processing the beatmap. + /// Updates the , invoking and re-processing the beatmap. /// - protected void UpdateHitObject() => composer?.UpdateHitObject(DrawableObject.HitObject); - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); + protected void UpdateHitObject() => composer?.UpdateHitObject(HitObject); /// - /// The s to be displayed in the context menu for this . + /// The s to be displayed in the context menu for this . /// public virtual MenuItem[] ContextMenuItems => Array.Empty(); /// - /// The screen-space point that causes this to be selected. + /// The screen-space point that causes this to be selected. /// - public virtual Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; + public virtual Vector2 SelectionPoint => ScreenSpaceDrawQuad.Centre; /// - /// The screen-space quad that outlines this for selections. + /// The screen-space quad that outlines this for selections. /// - public virtual Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; + public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; } } 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 119635ccd5..4a7c3f26bc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -11,20 +11,24 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { + public class TimelinePart : TimelinePart + { + } + /// /// Represents a part of the summary timeline.. /// - public class TimelinePart : Container + public class TimelinePart : Container where T : Drawable { protected readonly IBindable Beatmap = new Bindable(); - private readonly Container timeline; + private readonly Container content; - protected override Container Content => timeline; + protected override Container Content => content; - public TimelinePart() + public TimelinePart(Container content = null) { - AddInternal(timeline = new Container { RelativeSizeAxes = Axes.Both }); + AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); Beatmap.ValueChanged += b => { @@ -44,17 +48,17 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts // the track may not be loaded completely (only has a length once it is). if (!Beatmap.Value.Track.IsLoaded) { - timeline.RelativeChildSize = Vector2.One; + content.RelativeChildSize = Vector2.One; Schedule(updateRelativeChildSize); return; } - timeline.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); + content.RelativeChildSize = new Vector2((float)Math.Max(1, Beatmap.Value.Track.Length), 1); } protected virtual void LoadBeatmap(WorkingBeatmap beatmap) { - timeline.Clear(); + content.Clear(); } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 81b0fb247f..e945955db6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { DragBox = CreateDragBox(select), selectionHandler, - selectionBlueprints = new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }, + selectionBlueprints = CreateSelectionBlueprintContainer(), DragBox.CreateProxy().With(p => p.Depth = float.MinValue) }); @@ -67,6 +67,8 @@ namespace osu.Game.Screens.Edit.Compose.Components AddBlueprintFor(obj); } + protected virtual SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; + protected override void LoadComplete() { base.LoadComplete(); @@ -118,7 +120,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (clickedBlueprint == null) return false; - adjustableClock?.Seek(clickedBlueprint.DrawableObject.HitObject.StartTime); + adjustableClock?.Seek(clickedBlueprint.HitObject.StartTime); return true; } @@ -208,7 +210,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void removeBlueprintFor(HitObject hitObject) { - var blueprint = selectionBlueprints.SingleOrDefault(m => m.DrawableObject.HitObject == hitObject); + var blueprint = selectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject); if (blueprint == null) return; @@ -346,8 +348,8 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; // Movement is tracked from the blueprint of the earliest hitobject, since it only makes sense to distance snap from that hitobject - movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.DrawableObject.HitObject.StartTime).First(); - screenSpaceMovementStartPosition = movementBlueprint.DrawableObject.ToScreenSpace(movementBlueprint.DrawableObject.OriginPosition); + movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.HitObject.StartTime).First(); + screenSpaceMovementStartPosition = movementBlueprint.SelectionPoint; // todo: unsure if correct return true; } @@ -365,14 +367,14 @@ namespace osu.Game.Screens.Edit.Compose.Components Debug.Assert(screenSpaceMovementStartPosition != null); Vector2 startPosition = screenSpaceMovementStartPosition.Value; - HitObject draggedObject = movementBlueprint.DrawableObject.HitObject; + HitObject draggedObject = movementBlueprint.HitObject; // The final movement position, relative to screenSpaceMovementStartPosition Vector2 movePosition = startPosition + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); // Move the hitobjects - if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) + if (!selectionHandler.HandleMovement(new MoveSelectionEvent((OverlaySelectionBlueprint)movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) return true; // Apply the start time at the newly snapped-to position @@ -411,29 +413,9 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - private class SelectionBlueprintContainer : Container + protected class SelectionBlueprintContainer : Container { public IEnumerable AliveBlueprints => AliveInternalChildren.Cast(); - - protected override int Compare(Drawable x, Drawable y) - { - if (!(x is SelectionBlueprint xBlueprint) || !(y is SelectionBlueprint yBlueprint)) - return base.Compare(x, y); - - return Compare(xBlueprint, yBlueprint); - } - - public int Compare(SelectionBlueprint x, SelectionBlueprint y) - { - // dpeth is used to denote selected status (we always want selected blueprints to handle input first). - int d = x.Depth.CompareTo(y.Depth); - if (d != 0) - return d; - - // Put earlier hitobjects towards the end of the list, so they handle input first - int i = y.DrawableObject.HitObject.StartTime.CompareTo(x.DrawableObject.HitObject.StartTime); - return i == 0 ? CompareReverseChildID(x, y) : i; - } } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 1576def38e..3c41dead5d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return CreateBlueprintFor(drawable); } - public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; + public virtual OverlaySelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null; protected override void AddBlueprintFor(HitObject hitObject) { diff --git a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs index fe0a47aec8..8662347aeb 100644 --- a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs +++ b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs @@ -7,14 +7,14 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components { /// - /// An event which occurs when a is moved. + /// An event which occurs when a is moved. /// public class MoveSelectionEvent { /// - /// The that triggered this . + /// The that triggered this . /// - public readonly SelectionBlueprint Blueprint; + public readonly OverlaySelectionBlueprint Blueprint; /// /// The starting screen-space position of the hitobject. @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public readonly Vector2 InstantDelta; - public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) + public MoveSelectionEvent(OverlaySelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) { Blueprint = blueprint; ScreenSpaceStartPosition = screenSpaceStartPosition; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index bff94e66ed..907a22b9ce 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Compose.Components public IEnumerable SelectedBlueprints => selectedBlueprints; private readonly List selectedBlueprints; - public IEnumerable SelectedHitObjects => selectedBlueprints.Select(b => b.DrawableObject.HitObject); + public IEnumerable SelectedHitObjects => selectedBlueprints.Select(b => b.HitObject); private Drawable outline; @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void deleteSelected() { foreach (var h in selectedBlueprints.ToList()) - placementHandler.Delete(h.DrawableObject.HitObject); + placementHandler.Delete(h.HitObject); } #endregion diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index f521d08ada..e1acaa34cb 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -2,13 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; @@ -19,32 +18,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { 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 { RelativeSizeAxes = Axes.Both }); } - [BackgroundDependencyLoader] - private void load() - { - foreach (var h in beatmap.HitObjects) - add(h); + protected override SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; - beatmap.HitObjectAdded += add; - beatmap.HitObjectRemoved += remove; - beatmap.StartTimeChanged += h => + protected class TimelineSelectionBlueprintContainer : SelectionBlueprintContainer + { + protected override Container Content { get; } + + public TimelineSelectionBlueprintContainer() { - remove(h); - add(h); - }; + AddInternal(new TimelinePart(Content = new Container { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both }); + } } protected override void LoadComplete() @@ -53,24 +41,19 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline DragBox.Alpha = 0; } - private void remove(HitObject h) + protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) { - foreach (var d in content.OfType().Where(c => c.HitObject == h)) - d.Expire(); - } + //var yOffset = content.Count(d => d.X == h.StartTime); + var yOffset = 0; - private void add(HitObject h) - { - var yOffset = content.Count(d => d.X == h.StartTime); - - content.Add(new TimelineHitObjectRepresentation(h) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }); + return new TimelineHitObjectRepresentation(hitObject) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }; } protected override bool OnMouseDown(MouseDownEvent e) { base.OnMouseDown(e); - return false; // tempoerary until we correctly handle selections. + return false; // temporary until we correctly handle selections. } protected override DragBox CreateDragBox(Action performSelect) => new NoDragDragBox(performSelect); @@ -85,15 +68,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public override bool UpdateDrag(MouseButtonEvent e) => false; } - private class TimelineHitObjectRepresentation : CompositeDrawable + private class TimelineHitObjectRepresentation : SelectionBlueprint { public const float THICKNESS = 3; - public readonly HitObject HitObject; - public TimelineHitObjectRepresentation(HitObject hitObject) + : base(hitObject) { - HitObject = hitObject; Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; diff --git a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs index 3233ee160d..6565f98666 100644 --- a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs +++ b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual }); } - protected void AddBlueprint(SelectionBlueprint blueprint) + protected void AddBlueprint(OverlaySelectionBlueprint blueprint) { Add(blueprint.With(d => { From 61d7b63914c2c806f1ae6eab113f01a7193036d1 Mon Sep 17 00:00:00 2001 From: ProTheory8 <59506423+ProTheory8@users.noreply.github.com> Date: Tue, 21 Jan 2020 09:30:11 +0500 Subject: [PATCH 052/157] Readability Improvement --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index cdc4a42b33..38f5d54714 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -473,7 +473,9 @@ namespace osu.Game.Overlays.Mods if (selectedMod != null) { if (State.Value == Visibility.Visible) sampleOn?.Play(); + DeselectTypes(selectedMod.IncompatibleMods, true); + if (selectedMod.RequiresConfiguration) ModSettingsContainer.Alpha = 1; } else From 53fe0ce79086351260002e3162baccf63840c17d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 14:20:52 +0900 Subject: [PATCH 053/157] Use AliveChildren --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index e945955db6..438be6ab54 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -258,7 +258,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!allowDeselection && selectionHandler.SelectedBlueprints.Any(s => s.IsHovered)) return; - foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveBlueprints) + foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveChildren) { if (blueprint.IsHovered) { @@ -415,7 +415,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected class SelectionBlueprintContainer : Container { - public IEnumerable AliveBlueprints => AliveInternalChildren.Cast(); + //todo: remove } } } From 8f16c1cb049813cce2e1dabc07aa52e44e894038 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 14:21:00 +0900 Subject: [PATCH 054/157] Add non-hiding selection state --- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 10 +++++++--- .../Components/Timeline/TimelineHitObjectDisplay.cs | 8 +++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index d8952a3932..d50a9dce16 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Edit RelativeSizeAxes = Axes.Both; AlwaysPresent = true; - Alpha = 0; + OnDeselected(); } private SelectionState state; @@ -64,12 +64,12 @@ namespace osu.Game.Rulesets.Edit switch (state) { case SelectionState.Selected: - Show(); + OnSelected(); Selected?.Invoke(this); break; case SelectionState.NotSelected: - Hide(); + OnDeselected(); Deselected?.Invoke(this); break; } @@ -78,6 +78,10 @@ namespace osu.Game.Rulesets.Edit } } + protected virtual void OnDeselected() => Hide(); + + protected virtual void OnSelected() => Show(); + // When not selected, input is only required for the blueprint itself to receive IsHovering protected override bool ShouldBeConsideredForInput(Drawable child) => State == SelectionState.Selected; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index e1acaa34cb..5d1c4eeeae 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -70,6 +70,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private class TimelineHitObjectRepresentation : SelectionBlueprint { + private Circle circle; + public const float THICKNESS = 3; public TimelineHitObjectRepresentation(HitObject hitObject) @@ -104,7 +106,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }); } - AddInternal(new Circle + AddInternal(circle = new Circle { Size = new Vector2(16), Anchor = Anchor.CentreLeft, @@ -116,6 +118,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline BorderThickness = THICKNESS, }); } + + protected override void OnSelected() => circle.BorderColour = Color4.Orange; + + protected override void OnDeselected() => circle.BorderColour = Color4.Black; } } } From 195068ba9a9f6d35708159b2276ec74e70568456 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:35:36 +0900 Subject: [PATCH 055/157] Cache EditorBeatmap in test --- osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index 29575cb42e..e9372bd134 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -40,6 +40,8 @@ namespace osu.Game.Tests.Visual.Editor var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap); + Dependencies.Cache(editorBeatmap); + Children = new Drawable[] { new FillFlowContainer From 24a466ab249e6a88790a9f067f34ce44388e4521 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:36:21 +0900 Subject: [PATCH 056/157] Avoid null by calling initial OnDeselected later --- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index d50a9dce16..1c82a8287b 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -40,11 +40,15 @@ namespace osu.Game.Rulesets.Edit protected SelectionBlueprint(HitObject hitObject) { - this.HitObject = hitObject; + HitObject = hitObject; RelativeSizeAxes = Axes.Both; + } - AlwaysPresent = true; + [BackgroundDependencyLoader] + private void load() + { OnDeselected(); + AlwaysPresent = true; } private SelectionState state; @@ -116,5 +120,7 @@ namespace osu.Game.Rulesets.Edit /// The screen-space quad that outlines this for selections. /// public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; + + public Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Parent.ToLocalSpace(screenSpacePosition) - Position; } } From 79351976d5bc3eed44859e1a2f357d0f1b59f8e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:37:05 +0900 Subject: [PATCH 057/157] Allow timeline content to get more localised dependencies --- osu.Game/Screens/Edit/EditorScreenWithTimeline.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index aa8d99b517..8967f24185 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Edit private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); - private TimelineArea timelineArea; + private Container timelineContainer; [BackgroundDependencyLoader(true)] private void load([CanBeNull] BindableBeatDivisor beatDivisor) @@ -62,11 +62,10 @@ namespace osu.Game.Screens.Edit { new Drawable[] { - new Container + timelineContainer = new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timelineArea = CreateTimelineArea() }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -100,14 +99,16 @@ namespace osu.Game.Screens.Edit mainContent.Add(content); content.FadeInFromZero(300, Easing.OutQuint); - LoadComponentAsync(CreateTimelineContent(), timelineArea.Add); + LoadComponentAsync(new TimelineArea + { + RelativeSizeAxes = Axes.Both, + Child = CreateTimelineContent() + }, timelineContainer.Add); }); } protected abstract Drawable CreateMainContent(); protected virtual Drawable CreateTimelineContent() => new Container(); - - protected TimelineArea CreateTimelineArea() => new TimelineArea { RelativeSizeAxes = Axes.Both }; } } From 353b74b04a81331a9343e5cd0f3ba41ba129a64e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:37:35 +0900 Subject: [PATCH 058/157] Handle selection events in timeline --- .../Components/Timeline/TimelineHitObjectDisplay.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 5d1c4eeeae..32efdd42a3 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -49,15 +49,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return new TimelineHitObjectRepresentation(hitObject) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }; } - protected override bool OnMouseDown(MouseDownEvent e) - { - base.OnMouseDown(e); - - return false; // temporary until we correctly handle selections. - } - - protected override DragBox CreateDragBox(Action performSelect) => new NoDragDragBox(performSelect); - internal class NoDragDragBox : DragBox { public NoDragDragBox(Action performSelect) @@ -74,6 +65,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public const float THICKNESS = 3; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); + public TimelineHitObjectRepresentation(HitObject hitObject) : base(hitObject) { From 6dd50572d242993a9c1a174ea4e5cf4344c0996a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:37:43 +0900 Subject: [PATCH 059/157] Break mania more --- osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs index f33fd3c640..9069a636a8 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Edit // When scrolling downwards the anchor position is at the bottom of the screen, however the movement event assumes the anchor is at the top of the screen. // This causes the delta to assume a positive hitobject position, and which can be corrected for by subtracting the parent height. if (scrollingInfo.Direction.Value == ScrollingDirection.Down) - delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight; + delta -= moveEvent.Blueprint.Parent.DrawHeight; // todo: probably wrong foreach (var selectionBlueprint in SelectedBlueprints) { From 6187b2e77cad79cb899af96adb66d400081bf9fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 18:00:36 +0900 Subject: [PATCH 060/157] Implement IDistanceSnapProvider in timeline for now --- .../Compose/Components/Timeline/Timeline.cs | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index b4f3b1f610..c866fb38c8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -10,11 +10,15 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; +using osu.Game.Rulesets.Edit; +using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class Timeline : ZoomableScrollContainer + [Cached(typeof(IDistanceSnapProvider))] + public class Timeline : ZoomableScrollContainer, IDistanceSnapProvider { public readonly Bindable WaveformVisible = new Bindable(); public readonly IBindable Beatmap = new Bindable(); @@ -162,5 +166,51 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (trackWasPlaying) adjustableClock.Start(); } + + [Resolved] + private BindableBeatDivisor beatDivisor { get; set; } + + [Resolved] + private EditorBeatmap beatmap { get; set; } + + public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => (position, time); + + public float GetBeatSnapDistanceAt(double referenceTime) + { + DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(referenceTime); + return (float)(100 * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatDivisor.Value); + } + + public float DurationToDistance(double referenceTime, double duration) + { + double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime)); + } + + public double DistanceToDuration(double referenceTime, float distance) + { + double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength; + } + + public double GetSnappedDurationFromDistance(double referenceTime, float distance) + => beatSnap(referenceTime, DistanceToDuration(referenceTime, distance)); + + public float GetSnappedDistanceFromDistance(double referenceTime, float distance) + => DurationToDistance(referenceTime, beatSnap(referenceTime, DistanceToDuration(referenceTime, distance))); + + /// + /// Snaps a duration to the closest beat of a timing point applicable at the reference time. + /// + /// The time of the timing point which resides in. + /// The duration to snap. + /// A value that represents snapped to the closest beat of the timing point. + private double beatSnap(double referenceTime, double duration) + { + double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + + // A 1ms offset prevents rounding errors due to minute variations in duration + return (int)((duration + 1) / beatLength) * beatLength; + } } } From a888d148b653477e11ea7b5a292faf5a2c63b39d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 18:01:10 +0900 Subject: [PATCH 061/157] Remove remaining cast --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 +- .../Screens/Edit/Compose/Components/MoveSelectionEvent.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 438be6ab54..b792065b43 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -374,7 +374,7 @@ namespace osu.Game.Screens.Edit.Compose.Components (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); // Move the hitobjects - if (!selectionHandler.HandleMovement(new MoveSelectionEvent((OverlaySelectionBlueprint)movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) + if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) return true; // Apply the start time at the newly snapped-to position diff --git a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs index 8662347aeb..48cb702c78 100644 --- a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs +++ b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs @@ -12,9 +12,9 @@ namespace osu.Game.Screens.Edit.Compose.Components public class MoveSelectionEvent { /// - /// The that triggered this . + /// The that triggered this . /// - public readonly OverlaySelectionBlueprint Blueprint; + public readonly SelectionBlueprint Blueprint; /// /// The starting screen-space position of the hitobject. @@ -34,13 +34,13 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public readonly Vector2 InstantDelta; - public MoveSelectionEvent(OverlaySelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) + public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) { Blueprint = blueprint; ScreenSpaceStartPosition = screenSpaceStartPosition; ScreenSpacePosition = screenSpacePosition; - InstantDelta = Blueprint.DrawableObject.Parent.ToLocalSpace(ScreenSpacePosition) - Blueprint.DrawableObject.Position; + InstantDelta = Blueprint.GetInstantDelta(ScreenSpacePosition); } } } From f582c42bbd3a248c98d47bcc27470a94c7e7b6d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 18:56:09 +0900 Subject: [PATCH 062/157] Perform deletion directly via EditorBeatmap --- osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 907a22b9ce..9d9685af8a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private Drawable outline; [Resolved(CanBeNull = true)] - private IPlacementHandler placementHandler { get; set; } + private EditorBeatmap editorBeatmap { get; set; } public SelectionHandler() { @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void deleteSelected() { foreach (var h in selectedBlueprints.ToList()) - placementHandler.Delete(h.HitObject); + editorBeatmap.Remove(h.HitObject); } #endregion From b8d2012fc3fa5a02315ff9f394e6f3eda2d320be Mon Sep 17 00:00:00 2001 From: ProTheory8 Date: Tue, 21 Jan 2020 10:26:51 +0000 Subject: [PATCH 063/157] Added test --- .../UserInterface/TestSceneModSettings.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index 8dcb7dcbf8..c7744129cb 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -25,6 +25,8 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Mod testCustomisableMod = new TestModCustomisable1(); + private readonly Mod testCustomisableAutoOpenMod = new TestModCustomisable3(); + [Test] public void TestButtonShowsOnCustomisableMod() { @@ -53,6 +55,16 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value); } + [Test] + public void TestCustomisationOpensOnModSelect() + { + createModSelect(); + + AddStep("open", () => modSelect.Show()); + AddStep("select mod", () => modSelect.SelectMod(testCustomisableAutoOpenMod)); + AddAssert("Customisation opened", () => modSelect.ModSettingsContainer.Alpha == 1); + } + private void createModSelect() { AddStep("create mod select", () => @@ -98,7 +110,8 @@ namespace osu.Game.Tests.Visual.UserInterface return new Mod[] { new TestModCustomisable1(), - new TestModCustomisable2() + new TestModCustomisable2(), + new TestModCustomisable3() }; } @@ -130,6 +143,15 @@ namespace osu.Game.Tests.Visual.UserInterface public override string Acronym => "CM2"; } + private class TestModCustomisable3 : TestModCustomisable + { + public override string Name => "Customisable Mod 3"; + + public override string Acronym => "CM3"; + + public override bool RequiresConfiguration => true; + } + private abstract class TestModCustomisable : Mod, IApplicableMod { public override double ScoreMultiplier => 1.0; From 1ce78afa9872008ceed0a428366eedb4da9472d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 19:51:44 +0900 Subject: [PATCH 064/157] Disable y offset for now --- .../Compose/Components/Timeline/TimelineHitObjectDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 32efdd42a3..d83336b21b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -44,9 +44,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) { //var yOffset = content.Count(d => d.X == h.StartTime); - var yOffset = 0; + //var yOffset = 0; - return new TimelineHitObjectRepresentation(hitObject) { Y = -yOffset * TimelineHitObjectRepresentation.THICKNESS }; + return new TimelineHitObjectRepresentation(hitObject); } internal class NoDragDragBox : DragBox From c88bdbd4a0264f766de60f88af736d1da4b6a998 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 20:46:39 +0900 Subject: [PATCH 065/157] Share selected hitobjects across multiple blueprint containers --- .../Compose/Components/BlueprintContainer.cs | 18 ++++++++++++++++++ .../Compose/Components/SelectionHandler.cs | 7 ++++++- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index b792065b43..c5414542e4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; @@ -41,6 +42,8 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private EditorBeatmap beatmap { get; set; } + private readonly BindableList selectedHitObjects = new BindableList(); + [Resolved(canBeNull: true)] private IDistanceSnapProvider snapProvider { get; set; } @@ -65,6 +68,19 @@ namespace osu.Game.Screens.Edit.Compose.Components foreach (var obj in beatmap.HitObjects) AddBlueprintFor(obj); + + selectedHitObjects.BindTo(beatmap.SelectedHitObjects); + selectedHitObjects.ItemsAdded += objects => + { + foreach (var o in objects) + selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); + }; + + selectedHitObjects.ItemsRemoved += objects => + { + foreach (var o in objects) + selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); + }; } protected virtual SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; @@ -315,6 +331,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { selectionHandler.HandleSelected(blueprint); selectionBlueprints.ChangeChildDepth(blueprint, 1); + beatmap.SelectedHitObjects.Add(blueprint.HitObject); SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects); } @@ -323,6 +340,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { selectionHandler.HandleDeselected(blueprint); selectionBlueprints.ChangeChildDepth(blueprint, 0); + beatmap.SelectedHitObjects.Remove(blueprint.HitObject); SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects); } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 9d9685af8a..6ca110e518 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -102,7 +102,11 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Handle a blueprint becoming selected. /// /// The blueprint. - internal void HandleSelected(SelectionBlueprint blueprint) => selectedBlueprints.Add(blueprint); + internal void HandleSelected(SelectionBlueprint blueprint) + { + selectedBlueprints.Add(blueprint); + editorBeatmap.SelectedHitObjects.Add(blueprint.HitObject); + } /// /// Handle a blueprint becoming deselected. @@ -111,6 +115,7 @@ namespace osu.Game.Screens.Edit.Compose.Components internal void HandleDeselected(SelectionBlueprint blueprint) { selectedBlueprints.Remove(blueprint); + editorBeatmap.SelectedHitObjects.Remove(blueprint.HitObject); // We don't want to update visibility if > 0, since we may be deselecting blueprints during drag-selection if (selectedBlueprints.Count == 0) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 6ed74dfdb0..2ff7563a88 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -29,6 +29,8 @@ namespace osu.Game.Screens.Edit /// public event Action StartTimeChanged; + public BindableList SelectedHitObjects { get; } = new BindableList(); + public readonly IBeatmap PlayableBeatmap; private readonly Dictionary> startTimeBindables = new Dictionary>(); From a963d652bc1caee47081b5d4a8dc0ae93134a246 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 20:54:50 +0900 Subject: [PATCH 066/157] Mark readonly --- .../Compose/Components/Timeline/TimelineHitObjectDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index d83336b21b..b2ff9eee12 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -61,7 +61,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private class TimelineHitObjectRepresentation : SelectionBlueprint { - private Circle circle; + private readonly Circle circle; public const float THICKNESS = 3; From 83fa4a9bb34d74e362cd7e684f0879c9d385a812 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 22:24:04 +0900 Subject: [PATCH 067/157] Move circle size to a constant --- .../Compose/Components/Timeline/TimelineHitObjectDisplay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index b2ff9eee12..7932813bbc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -65,6 +65,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public const float THICKNESS = 3; + private const float circle_size = 16; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); public TimelineHitObjectRepresentation(HitObject hitObject) @@ -101,7 +103,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline AddInternal(circle = new Circle { - Size = new Vector2(16), + Size = new Vector2(circle_size), Anchor = Anchor.CentreLeft, Origin = Anchor.Centre, RelativePositionAxes = Axes.X, From 9de4424aec08a26e5d179d5015e4fef93de25990 Mon Sep 17 00:00:00 2001 From: ProTheory8 Date: Tue, 21 Jan 2020 14:32:53 +0000 Subject: [PATCH 068/157] Removed TestModCustomisable3 --- .../Visual/UserInterface/TestSceneModSettings.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index c7744129cb..e2ce2341e5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Mod testCustomisableMod = new TestModCustomisable1(); - private readonly Mod testCustomisableAutoOpenMod = new TestModCustomisable3(); + private readonly Mod testCustomisableAutoOpenMod = new TestModCustomisable2(); [Test] public void TestButtonShowsOnCustomisableMod() @@ -61,6 +61,7 @@ namespace osu.Game.Tests.Visual.UserInterface createModSelect(); AddStep("open", () => modSelect.Show()); + AddAssert("Customisation closed", () => modSelect.ModSettingsContainer.Alpha == 0); AddStep("select mod", () => modSelect.SelectMod(testCustomisableAutoOpenMod)); AddAssert("Customisation opened", () => modSelect.ModSettingsContainer.Alpha == 1); } @@ -110,8 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface return new Mod[] { new TestModCustomisable1(), - new TestModCustomisable2(), - new TestModCustomisable3() + new TestModCustomisable2() }; } @@ -141,13 +141,6 @@ namespace osu.Game.Tests.Visual.UserInterface public override string Name => "Customisable Mod 2"; public override string Acronym => "CM2"; - } - - private class TestModCustomisable3 : TestModCustomisable - { - public override string Name => "Customisable Mod 3"; - - public override string Acronym => "CM3"; public override bool RequiresConfiguration => true; } From 98aaf3864953f31a942184bdc6adce5e3781e782 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 23:58:51 +0900 Subject: [PATCH 069/157] Fix playfield movement regressing --- osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs | 2 ++ osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs index 4c3898aa04..b4ae3f3fba 100644 --- a/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/OverlaySelectionBlueprint.cs @@ -28,5 +28,7 @@ namespace osu.Game.Rulesets.Edit public override Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; + + public override Vector2 GetInstantDelta(Vector2 screenSpacePosition) => DrawableObject.Parent.ToLocalSpace(screenSpacePosition) - DrawableObject.Position; } } diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 1c82a8287b..9998254f76 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -121,6 +121,6 @@ namespace osu.Game.Rulesets.Edit /// public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; - public Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Parent.ToLocalSpace(screenSpacePosition) - Position; + public virtual Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Parent.ToLocalSpace(screenSpacePosition) - Position; } } From e3a2b20f631532dece1d51a4eabd89cc4c05bdff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 01:32:11 +0900 Subject: [PATCH 070/157] Fix SelectionHandler visibility on remote selection --- osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 6ca110e518..0aced5f957 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -106,6 +106,8 @@ namespace osu.Game.Screens.Edit.Compose.Components { selectedBlueprints.Add(blueprint); editorBeatmap.SelectedHitObjects.Add(blueprint.HitObject); + + UpdateVisibility(); } /// @@ -144,8 +146,6 @@ namespace osu.Game.Screens.Edit.Compose.Components DeselectAll?.Invoke(); blueprint.Select(); } - - UpdateVisibility(); } private void deleteSelected() From 03b6a3ddc3fabdffc6fb7c8a76dc6999ba7c2cca Mon Sep 17 00:00:00 2001 From: raouls555 <30951475+raouls555@users.noreply.github.com> Date: Tue, 21 Jan 2020 23:22:08 +0100 Subject: [PATCH 071/157] Allow parsing hex colour codes with alpha --- osu.Game/Graphics/OsuColour.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 6767104576..53a40f5613 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -36,6 +36,20 @@ namespace osu.Game.Graphics Convert.ToByte(hex.Substring(2, 2), 16), Convert.ToByte(hex.Substring(4, 2), 16), 255); + + case 4: + return new Color4( + (byte)(Convert.ToByte(hex.Substring(0, 1), 16) * 17), + (byte)(Convert.ToByte(hex.Substring(1, 1), 16) * 17), + (byte)(Convert.ToByte(hex.Substring(2, 1), 16) * 17), + (byte)(Convert.ToByte(hex.Substring(3, 1), 16) * 17)); + + case 8: + return new Color4( + Convert.ToByte(hex.Substring(0, 2), 16), + Convert.ToByte(hex.Substring(2, 2), 16), + Convert.ToByte(hex.Substring(4, 2), 16), + Convert.ToByte(hex.Substring(6, 2), 16)); } } From 7b2f58eb305bd27c8183c9f0405b97c07569708a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 22 Jan 2020 13:22:34 +0900 Subject: [PATCH 072/157] Apply OnRelease method signature refactorings --- osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs | 5 ++++- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 14 +++++++------- .../Objects/Drawables/DrawableHoldNote.cs | 10 ++++------ .../Objects/Drawables/DrawableHoldNoteHead.cs | 4 +++- .../Objects/Drawables/DrawableHoldNoteTail.cs | 4 +++- .../Objects/Drawables/DrawableNote.cs | 4 +++- osu.Game.Rulesets.Mania/UI/Column.cs | 4 +++- .../UI/Components/ColumnBackground.cs | 3 +-- .../UI/Components/ColumnKeyArea.cs | 3 +-- .../Components/PathControlPointVisualiser.cs | 4 +++- .../Objects/Drawables/DrawableHitCircle.cs | 4 +++- .../UI/Cursor/OsuCursorContainer.cs | 4 +--- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 4 +++- .../Objects/Drawables/DrawableHit.cs | 5 +++-- .../Objects/Drawables/DrawableTaikoHitObject.cs | 5 ++++- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 4 +++- .../Containers/OsuFocusedOverlayContainer.cs | 4 +++- osu.Game/Graphics/ScreenshotManager.cs | 4 +++- osu.Game/Graphics/UserInterface/BackButton.cs | 4 +++- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 4 +++- osu.Game/Input/IdleTracker.cs | 2 +- osu.Game/OsuGame.cs | 4 +++- osu.Game/Overlays/MusicController.cs | 4 +++- osu.Game/Overlays/Volume/VolumeControlReceptor.cs | 5 ++++- osu.Game/Rulesets/UI/RulesetInputManager.cs | 6 +++++- .../UI/Scrolling/DrawableScrollingRuleset.cs | 4 +++- .../Edit/Compose/Components/BlueprintContainer.cs | 4 +++- .../Edit/Compose/Components/SelectionHandler.cs | 4 +++- osu.Game/Screens/Edit/Editor.cs | 4 +++- osu.Game/Screens/Menu/ButtonSystem.cs | 4 +++- osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 5 +---- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 10 +--------- osu.Game/Screens/Play/HUD/HoldForMenuButton.cs | 6 ++---- osu.Game/Screens/Play/HotkeyExitOverlay.cs | 5 ++--- osu.Game/Screens/Play/HotkeyRetryOverlay.cs | 5 ++--- osu.Game/Screens/Play/KeyCounterAction.cs | 5 ++--- osu.Game/Screens/Play/SkipOverlay.cs | 4 +++- osu.Game/Screens/Select/SongSelect.cs | 4 +++- 38 files changed, 108 insertions(+), 74 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs index a47efcc10a..4c72b9fd3e 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs @@ -36,7 +36,10 @@ namespace osu.Game.Rulesets.Catch.Mods //disable keyboard controls public bool OnPressed(CatchAction action) => true; - public bool OnReleased(CatchAction action) => true; + + public void OnReleased(CatchAction action) + { + } protected override bool OnMouseMove(MouseMoveEvent e) { diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 0c8c483048..1de0b6bfa3 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -103,7 +103,9 @@ namespace osu.Game.Rulesets.Catch.UI MovableCatcher.X = state.CatcherX.Value; } - public bool OnReleased(CatchAction action) => false; + public void OnReleased(CatchAction action) + { + } public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj); @@ -341,24 +343,22 @@ namespace osu.Game.Rulesets.Catch.UI return false; } - public bool OnReleased(CatchAction action) + public void OnReleased(CatchAction action) { switch (action) { case CatchAction.MoveLeft: currentDirection++; - return true; + break; case CatchAction.MoveRight: currentDirection--; - return true; + break; case CatchAction.Dash: Dashing = false; - return true; + break; } - - return false; } /// diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 155adb958b..14a7c5fda3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -171,17 +171,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.Hitting = true; } - public bool OnReleased(ManiaAction action) + public void OnReleased(ManiaAction action) { if (AllJudged) - return false; + return; if (action != Action.Value) - return false; + return; // Make sure a hold was started if (HoldStartTime == null) - return false; + return; Tail.UpdateResult(); endHold(); @@ -189,8 +189,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // If the key has been released too early, the user should not receive full score for the release if (!Tail.IsHit) HasBroken = true; - - return true; } private void endHold() diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs index a5d03bf765..390c64c5e2 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs @@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public override bool OnPressed(ManiaAction action) => false; // Handled by the hold note - public override bool OnReleased(ManiaAction action) => false; // Handled by the hold note + public override void OnReleased(ManiaAction action) + { + } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs index a660144dd1..568b07c958 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs @@ -59,6 +59,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public override bool OnPressed(ManiaAction action) => false; // Handled by the hold note - public override bool OnReleased(ManiaAction action) => false; // Handled by the hold note + public override void OnReleased(ManiaAction action) + { + } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 8f353ae138..85613d3afb 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -77,6 +77,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return UpdateResult(true); } - public virtual bool OnReleased(ManiaAction action) => false; + public virtual void OnReleased(ManiaAction action) + { + } } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 3d2a070b0f..63c573d344 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -191,7 +191,9 @@ namespace osu.Game.Rulesets.Mania.UI return true; } - public bool OnReleased(ManiaAction action) => false; + public void OnReleased(ManiaAction action) + { + } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) // This probably shouldn't exist as is, but the columns in the stage are separated by a 1px border diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs index 57241da564..75cc351310 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs @@ -98,11 +98,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components return false; } - public bool OnReleased(ManiaAction action) + public void OnReleased(ManiaAction action) { if (action == this.action.Value) backgroundOverlay.FadeTo(0, 250, Easing.OutQuint); - return false; } } } diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs index 85880222d7..60fc2713b3 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs @@ -115,11 +115,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components return false; } - public bool OnReleased(ManiaAction action) + public void OnReleased(ManiaAction action) { if (action == this.action.Value) keyIcon.ScaleTo(1f, 125, Easing.OutQuint); - return false; } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 6f583d7983..e293eba9d7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -108,7 +108,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components return false; } - public bool OnReleased(PlatformAction action) => action.ActionMethod == PlatformActionMethod.Delete; + public void OnReleased(PlatformAction action) + { + } private void selectPiece(PathControlPointPiece piece, MouseButtonEvent e) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index f74f2d7bc5..3162f4b379 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -205,7 +205,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables return false; } - public bool OnReleased(OsuAction action) => false; + public void OnReleased(OsuAction action) + { + } } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 6433ced624..a463542e64 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor return false; } - public bool OnReleased(OsuAction action) + public void OnReleased(OsuAction action) { switch (action) { @@ -120,8 +120,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor updateExpandedState(); break; } - - return false; } public override bool HandlePositionalInput => true; // OverlayContainer will set this false when we go hidden, but we always want to receive input. diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index 3b18e41f30..ca3030db3e 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -107,7 +107,9 @@ namespace osu.Game.Rulesets.Osu.UI return false; } - public bool OnReleased(OsuAction action) => false; + public void OnReleased(OsuAction action) + { + } public void Appear() => Schedule(() => { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 4b25ff0ecc..85dfc8d5e0 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -77,11 +77,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return result; } - public override bool OnReleased(TaikoAction action) + public override void OnReleased(TaikoAction action) { if (action == HitAction) HitAction = null; - return base.OnReleased(action); + + base.OnReleased(action); } protected override void Update() diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index b9d31ff906..5f892dd2fa 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -77,7 +77,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public Drawable CreateProxiedContent() => proxiedContent.CreateProxy(); public abstract bool OnPressed(TaikoAction action); - public virtual bool OnReleased(TaikoAction action) => false; + + public virtual void OnReleased(TaikoAction action) + { + } public override double LifetimeStart { diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 5234ae1f69..d26ccfe867 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -187,7 +187,9 @@ namespace osu.Game.Rulesets.Taiko.UI return false; } - public bool OnReleased(TaikoAction action) => false; + public void OnReleased(TaikoAction action) + { + } } } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index facf70b47a..652b693b86 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -99,7 +99,9 @@ namespace osu.Game.Graphics.Containers return false; } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } protected override void UpdateState(ValueChangedEvent state) { diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index b9151b7393..7f20c30048 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -67,7 +67,9 @@ namespace osu.Game.Graphics return false; } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } private volatile int screenShotTasks; diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index 23565e8742..88ba7ede6e 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -67,7 +67,9 @@ namespace osu.Game.Graphics.UserInterface return false; } - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + public void OnReleased(GlobalAction action) + { + } } } } diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 0b183c0ec9..e59353a480 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -80,7 +80,9 @@ namespace osu.Game.Graphics.UserInterface return false; } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } public override bool RequestsFocus => HoldFocus; } diff --git a/osu.Game/Input/IdleTracker.cs b/osu.Game/Input/IdleTracker.cs index 39ccf9fe1c..63a6348b57 100644 --- a/osu.Game/Input/IdleTracker.cs +++ b/osu.Game/Input/IdleTracker.cs @@ -50,7 +50,7 @@ namespace osu.Game.Input public bool OnPressed(PlatformAction action) => updateLastInteractionTime(); - public bool OnReleased(PlatformAction action) => updateLastInteractionTime(); + public void OnReleased(PlatformAction action) => updateLastInteractionTime(); protected override bool Handle(UIEvent e) { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9df854d178..ff46c6d849 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -881,7 +881,9 @@ namespace osu.Game #endregion - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } private Container overlayContent; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 3c0f6468bc..19f06e99f1 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -326,7 +326,9 @@ namespace osu.Game.Overlays return false; } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } public class MusicControllerToast : Toast { diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 9cd3aac2cb..76fad945cc 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -16,6 +16,9 @@ namespace osu.Game.Overlays.Volume public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false; public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false; - public bool OnReleased(GlobalAction action) => false; + + public void OnReleased(GlobalAction action) + { + } } } diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 5cc213be41..41b2739fc5 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -139,7 +139,11 @@ namespace osu.Game.Rulesets.UI public bool OnPressed(T action) => Target.Children.OfType>().Any(c => c.OnPressed(action, Clock.Rate >= 0)); - public bool OnReleased(T action) => Target.Children.OfType>().Any(c => c.OnReleased(action, Clock.Rate >= 0)); + public void OnReleased(T action) + { + foreach (var c in Target.Children.OfType>()) + c.OnReleased(action, Clock.Rate >= 0); + } } #endregion diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index fda1d7c723..8bcdfff2fd 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -201,7 +201,9 @@ namespace osu.Game.Rulesets.UI.Scrolling throw new ArgumentException($"{nameof(Playfield)} must be a {nameof(ScrollingPlayfield)} when using {nameof(DrawableScrollingRuleset)}."); } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } private class LocalScrollingInfo : IScrollingInfo { diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index cafaddc39e..11fbd8ce04 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -215,7 +215,9 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; } - public bool OnReleased(PlatformAction action) => false; + public void OnReleased(PlatformAction action) + { + } protected override void Update() { diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index e2d7855eb5..1473a1a2da 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -87,7 +87,9 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; } - public bool OnReleased(PlatformAction action) => action.ActionMethod == PlatformActionMethod.Delete; + public void OnReleased(PlatformAction action) + { + } #endregion diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e212b429b9..e5cb319fb9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -253,7 +253,9 @@ namespace osu.Game.Screens.Edit return false; } - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; + public void OnReleased(GlobalAction action) + { + } public override void OnResuming(IScreen last) { diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index ed8e4c70f9..d94f8aa11a 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -211,7 +211,9 @@ namespace osu.Game.Screens.Menu } } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } private bool goBack() { diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs index aaa3a77e74..db2faeb60a 100644 --- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -24,16 +24,13 @@ namespace osu.Game.Screens.Menu return false; } - public bool OnReleased(GlobalAction action) + public void OnReleased(GlobalAction action) { if (action == GlobalAction.Back) { if (!Fired) AbortConfirm(); - return true; } - - return false; } } } diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index adfbe977a4..0c94e04cf6 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -247,16 +247,8 @@ namespace osu.Game.Screens.Play return false; } - public bool OnReleased(GlobalAction action) + public void OnReleased(GlobalAction action) { - switch (action) - { - case GlobalAction.Back: - case GlobalAction.Select: - return true; - } - - return false; } private void buttonSelectionChanged(DialogButton button, bool isSelected) diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index 7946e6d322..f209d5ea6c 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -259,16 +259,14 @@ namespace osu.Game.Screens.Play.HUD return false; } - public bool OnReleased(GlobalAction action) + public void OnReleased(GlobalAction action) { switch (action) { case GlobalAction.Back: AbortConfirm(); - return true; + break; } - - return false; } protected override bool OnMouseDown(MouseDownEvent e) diff --git a/osu.Game/Screens/Play/HotkeyExitOverlay.cs b/osu.Game/Screens/Play/HotkeyExitOverlay.cs index c18aecda55..8d7e2481bf 100644 --- a/osu.Game/Screens/Play/HotkeyExitOverlay.cs +++ b/osu.Game/Screens/Play/HotkeyExitOverlay.cs @@ -17,12 +17,11 @@ namespace osu.Game.Screens.Play return true; } - public bool OnReleased(GlobalAction action) + public void OnReleased(GlobalAction action) { - if (action != GlobalAction.QuickExit) return false; + if (action != GlobalAction.QuickExit) return; AbortConfirm(); - return true; } } } diff --git a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs index f1b851f2d5..58fd941f36 100644 --- a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs +++ b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs @@ -17,12 +17,11 @@ namespace osu.Game.Screens.Play return true; } - public bool OnReleased(GlobalAction action) + public void OnReleased(GlobalAction action) { - if (action != GlobalAction.QuickRetry) return false; + if (action != GlobalAction.QuickRetry) return; AbortConfirm(); - return true; } } } diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs index 33d675358c..00eddcc776 100644 --- a/osu.Game/Screens/Play/KeyCounterAction.cs +++ b/osu.Game/Screens/Play/KeyCounterAction.cs @@ -27,15 +27,14 @@ namespace osu.Game.Screens.Play return false; } - public bool OnReleased(T action, bool forwards) + public void OnReleased(T action, bool forwards) { if (!EqualityComparer.Default.Equals(action, Action)) - return false; + return; IsLit = false; if (!forwards) Decrement(); - return false; } } } diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 772d326c7f..d06e72bfa0 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -143,7 +143,9 @@ namespace osu.Game.Screens.Play return false; } - public bool OnReleased(GlobalAction action) => false; + public void OnReleased(GlobalAction action) + { + } private class FadeContainer : Container, IStateful { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8f7ad2022d..bf57def700 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -681,7 +681,9 @@ namespace osu.Game.Screens.Select return false; } - public bool OnReleased(GlobalAction action) => action == GlobalAction.Select; + public void OnReleased(GlobalAction action) + { + } protected override bool OnKeyDown(KeyDownEvent e) { From 03b61e4a5a5e3338400882776b99be6a221e6679 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 22 Jan 2020 20:00:36 +0900 Subject: [PATCH 073/157] Throw exception rather than returning nulls --- osu.Game/Online/API/APIMod.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIMod.cs b/osu.Game/Online/API/APIMod.cs index 30336d16a3..46a8db31b7 100644 --- a/osu.Game/Online/API/APIMod.cs +++ b/osu.Game/Online/API/APIMod.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 System.Linq; using Humanizer; @@ -38,7 +39,7 @@ namespace osu.Game.Online.API Mod resultMod = ruleset.GetAllMods().FirstOrDefault(m => m.Acronym == Acronym); if (resultMod == null) - return null; // Todo: Maybe throw exception? + throw new InvalidOperationException($"There is no mod in the ruleset ({ruleset.ShortName}) matching the acronym {Acronym}."); foreach (var (_, property) in resultMod.GetSettingsSourceProperties()) { From e2c4cffc9a23860bbebfd13405ffc33fc52e986c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 22:57:09 +0900 Subject: [PATCH 074/157] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 9c0da1e9fd..2ccba60424 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f41c5fee7f..9b431e6425 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index bb4a59a601..4dc7403553 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 8ea354571cd48f010c6d0ca68f99fd5f2128e35e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 23:04:37 +0900 Subject: [PATCH 075/157] Update naming --- osu.Game/OsuGameBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0819642d2d..07c9d37a86 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -330,7 +330,7 @@ namespace osu.Game private class OsuUserInputManager : UserInputManager { - protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button) + protected override MouseButtonEventManager CreateButtonEventManagerFor(MouseButton button) { switch (button) { @@ -338,7 +338,7 @@ namespace osu.Game return new RightMouseManager(button); } - return base.CreateButtonManagerFor(button); + return base.CreateButtonEventManagerFor(button); } private class RightMouseManager : MouseButtonEventManager From c0935b9b86e9977c100090944c1d5528449eb379 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 23:13:21 +0900 Subject: [PATCH 076/157] Update naming in tournament --- osu.Game.Tournament/TournamentGameBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 17d7dc0245..1c94856a4e 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -303,7 +303,7 @@ namespace osu.Game.Tournament private class TournamentInputManager : UserInputManager { - protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button) + protected override MouseButtonEventManager CreateButtonEventManagerFor(MouseButton button) { switch (button) { @@ -311,7 +311,7 @@ namespace osu.Game.Tournament return new RightMouseManager(button); } - return base.CreateButtonManagerFor(button); + return base.CreateButtonEventManagerFor(button); } private class RightMouseManager : MouseButtonEventManager From a6775d1bd3a0432e5e2b3b907d3bb14851fc26fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 14:58:15 +0900 Subject: [PATCH 077/157] Implement custom drag box and allow drag seeking once again --- .../Edit/Compose/Components/DragBox.cs | 36 ++++++++++--------- .../Timeline/TimelineHitObjectDisplay.cs | 35 ++++++++++++++++-- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs index f522ca356f..adbab1767b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs @@ -17,9 +17,9 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public class DragBox : CompositeDrawable { - private readonly Action performSelection; + protected readonly Action PerformSelection; - private Drawable box; + protected Drawable Box; /// /// Creates a new . @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// A delegate that performs drag selection. public DragBox(Action performSelection) { - this.performSelection = performSelection; + PerformSelection = performSelection; RelativeSizeAxes = Axes.Both; AlwaysPresent = true; @@ -37,19 +37,21 @@ namespace osu.Game.Screens.Edit.Compose.Components [BackgroundDependencyLoader] private void load() { - InternalChild = box = new Container - { - Masking = true, - BorderColour = Color4.White, - BorderThickness = SelectionHandler.BORDER_RADIUS, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.1f - } - }; + InternalChild = Box = CreateBox(); } + protected virtual Drawable CreateBox() => new Container + { + Masking = true, + BorderColour = Color4.White, + BorderThickness = SelectionHandler.BORDER_RADIUS, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.1f + } + }; + /// /// Handle a forwarded mouse event. /// @@ -68,10 +70,10 @@ namespace osu.Game.Screens.Edit.Compose.Components var topLeft = ToLocalSpace(dragRectangle.TopLeft); var bottomRight = ToLocalSpace(dragRectangle.BottomRight); - box.Position = topLeft; - box.Size = bottomRight - topLeft; + Box.Position = topLeft; + Box.Size = bottomRight - topLeft; - performSelection?.Invoke(dragRectangle); + PerformSelection?.Invoke(dragRectangle); return true; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 7932813bbc..e68b088d78 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -21,6 +21,17 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public TimelineHitObjectDisplay(EditorBeatmap beatmap) { RelativeSizeAxes = Axes.Both; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Height = 0.4f; + + AddInternal(new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + Alpha = 0.1f, + }); } protected override SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; @@ -49,14 +60,32 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return new TimelineHitObjectRepresentation(hitObject); } - internal class NoDragDragBox : DragBox + protected override DragBox CreateDragBox(Action performSelect) => new CustomDragBox(performSelect); + + internal class CustomDragBox : DragBox { - public NoDragDragBox(Action performSelect) + public CustomDragBox(Action performSelect) : base(performSelect) { } - public override bool UpdateDrag(MouseButtonEvent e) => false; + protected override Drawable CreateBox() => new Box + { + RelativeSizeAxes = Axes.Y, + Alpha = 0.3f + }; + + public override bool UpdateDrag(MouseButtonEvent e) + { + float selection1 = e.MouseDownPosition.X; + float selection2 = e.MousePosition.X; + + Box.X = Math.Min(selection1, selection2); + Box.Width = Math.Abs(selection1 - selection2); + + PerformSelection?.Invoke(Box.ScreenSpaceDrawQuad.AABBFloat); + return true; + } } private class TimelineHitObjectRepresentation : SelectionBlueprint From 482409e776cd9def6f45af0106b1fd5367aff221 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 15:31:58 +0900 Subject: [PATCH 078/157] Colour extension bars of long objects --- .../Timeline/TimelineHitObjectDisplay.cs | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index e68b088d78..b09c1a5597 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -92,6 +92,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { private readonly Circle circle; + private Container extensionBar; + public const float THICKNESS = 3; private const float circle_size = 16; @@ -109,11 +111,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline X = (float)hitObject.StartTime; RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; if (hitObject is IHasEndTime) { - AddInternal(new Container + AddInternal(extensionBar = new Container { CornerRadius = 2, Masking = true, @@ -143,9 +147,32 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }); } - protected override void OnSelected() => circle.BorderColour = Color4.Orange; + protected override void OnSelected() + { + circle.BorderColour = Color4.Orange; + if (extensionBar != null) + extensionBar.Colour = Color4.Orange; + } - protected override void OnDeselected() => circle.BorderColour = Color4.Black; + protected override void OnDeselected() + { + circle.BorderColour = Color4.Black; + if (extensionBar != null) + extensionBar.Colour = Color4.Black; + } + + public override Quad SelectionQuad + { + get + { + // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. + var circleQuad = circle.ScreenSpaceDrawQuad; + var actualQuad = ScreenSpaceDrawQuad; + + return new Quad(circleQuad.TopLeft, Vector2.ComponentMax(actualQuad.TopRight, circleQuad.TopRight), + circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); + } + } } } } From c4395b1cea45b242e2f19816a92b9aa4df2c727a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 15:42:49 +0900 Subject: [PATCH 079/157] Clean up nested class implementations --- .../Timeline/TimelineHitObjectDisplay.cs | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index b09c1a5597..397c74b193 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -36,33 +36,32 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; - protected class TimelineSelectionBlueprintContainer : SelectionBlueprintContainer - { - protected override Container Content { get; } - - public TimelineSelectionBlueprintContainer() - { - AddInternal(new TimelinePart(Content = new Container { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both }); - } - } - protected override void LoadComplete() { base.LoadComplete(); DragBox.Alpha = 0; } - protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) + protected override bool OnDrag(DragEvent e) { - //var yOffset = content.Count(d => d.X == h.StartTime); - //var yOffset = 0; - - return new TimelineHitObjectRepresentation(hitObject); + lastDragEvent = e; + return base.OnDrag(e); } + protected override void Update() + { + if (IsDragged && lastDragEvent != null) + // trigger every frame so drags continue to update selection while playback is scrolling the timeline. + DragBox.UpdateDrag(lastDragEvent); + + base.Update(); + } + + protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectRepresentation(hitObject); + protected override DragBox CreateDragBox(Action performSelect) => new CustomDragBox(performSelect); - internal class CustomDragBox : DragBox + private class CustomDragBox : DragBox { public CustomDragBox(Action performSelect) : base(performSelect) @@ -88,11 +87,21 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } + protected class TimelineSelectionBlueprintContainer : SelectionBlueprintContainer + { + protected override Container Content { get; } + + public TimelineSelectionBlueprintContainer() + { + AddInternal(new TimelinePart(Content = new Container { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both }); + } + } + private class TimelineHitObjectRepresentation : SelectionBlueprint { private readonly Circle circle; - private Container extensionBar; + private readonly Container extensionBar; public const float THICKNESS = 3; From a8ec4907c410dedb4d8c71bc5348db3c096d73ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 15:58:03 +0900 Subject: [PATCH 080/157] Fix selections while scrolling timeline --- .../Components/Timeline/TimelineHitObjectDisplay.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 397c74b193..d50616a66f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -63,6 +63,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private class CustomDragBox : DragBox { + private Vector2 lastMouseDown; + private float localMouseDown; + public CustomDragBox(Action performSelect) : base(performSelect) { @@ -76,7 +79,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public override bool UpdateDrag(MouseButtonEvent e) { - float selection1 = e.MouseDownPosition.X; + // store the original position of the mouse down, as we may be scrolled during selection. + if (lastMouseDown != e.ScreenSpaceMouseDownPosition) + { + lastMouseDown = e.ScreenSpaceMouseDownPosition; + localMouseDown = e.MouseDownPosition.X; + } + + float selection1 = localMouseDown; float selection2 = e.MousePosition.X; Box.X = Math.Min(selection1, selection2); From 89d90fdfa054620811404ab60c694d6cb12098c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 16:33:23 +0900 Subject: [PATCH 081/157] Fix drag not updating until mouse is moved while scrolling timeline --- .../Components/Timeline/TimelineHitObjectDisplay.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index d50616a66f..f812095a35 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -18,6 +18,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { internal class TimelineHitObjectDisplay : BlueprintContainer { + private DragEvent lastDragEvent; + public TimelineHitObjectDisplay(EditorBeatmap beatmap) { RelativeSizeAxes = Axes.Both; @@ -50,9 +52,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override void Update() { - if (IsDragged && lastDragEvent != null) - // trigger every frame so drags continue to update selection while playback is scrolling the timeline. - DragBox.UpdateDrag(lastDragEvent); + // trigger every frame so drags continue to update selection while playback is scrolling the timeline. + if (IsDragged) + OnDrag(lastDragEvent); base.Update(); } From 63cef8b8b7189bb4c9215c26e90d532ffd5d83ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 16:58:33 +0900 Subject: [PATCH 082/157] Rename nested classes to be more appropriate --- .../Components/Timeline/TimelineHitObjectDisplay.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index f812095a35..10b470e4b7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -59,16 +59,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline base.Update(); } - protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectRepresentation(hitObject); + protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject); - protected override DragBox CreateDragBox(Action performSelect) => new CustomDragBox(performSelect); + protected override DragBox CreateDragBox(Action performSelect) => new TimelineDragBox(performSelect); - private class CustomDragBox : DragBox + private class TimelineDragBox : DragBox { private Vector2 lastMouseDown; private float localMouseDown; - public CustomDragBox(Action performSelect) + public TimelineDragBox(Action performSelect) : base(performSelect) { } @@ -109,7 +109,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - private class TimelineHitObjectRepresentation : SelectionBlueprint + private class TimelineHitObjectBlueprint : SelectionBlueprint { private readonly Circle circle; @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); - public TimelineHitObjectRepresentation(HitObject hitObject) + public TimelineHitObjectBlueprint(HitObject hitObject) : base(hitObject) { Anchor = Anchor.CentreLeft; From f0d810fe2098a94a15ad34e439a98ca36e42b59b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 17:11:37 +0900 Subject: [PATCH 083/157] Follow start time and duration changes --- .../Timeline/TimelineHitObjectDisplay.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 10b470e4b7..a11958c8c9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; +using JetBrains.Annotations; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; @@ -115,6 +117,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private readonly Container extensionBar; + [UsedImplicitly] + private readonly Bindable startTime; + public const float THICKNESS = 3; private const float circle_size = 16; @@ -127,9 +132,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; - Width = (float)(hitObject.GetEndTime() - hitObject.StartTime); - - X = (float)hitObject.StartTime; + startTime = hitObject.StartTimeBindable.GetBoundCopy(); + startTime.BindValueChanged(time => X = (float)time.NewValue, true); RelativePositionAxes = Axes.X; @@ -168,6 +172,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }); } + protected override void Update() + { + base.Update(); + + // no bindable so we perform this every update + Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); + } + protected override void OnSelected() { circle.BorderColour = Color4.Orange; From cb6e7425aebc9789ac80af0a21f29fd25bad2205 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 17:54:11 +0900 Subject: [PATCH 084/157] Make dragbox stateful to fix blueprint movement --- .../Compose/Components/BlueprintContainer.cs | 29 +++++++++---------- .../Edit/Compose/Components/DragBox.cs | 26 +++++++++++++++-- .../Timeline/TimelineHitObjectDisplay.cs | 8 ++++- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index c5414542e4..583627f78e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -152,15 +152,16 @@ namespace osu.Game.Screens.Edit.Compose.Components if (e.Button == MouseButton.Right) return false; - if (!beginSelectionMovement()) - { - if (!DragBox.UpdateDrag(e)) - return false; + if (beginSelectionMovement()) + return true; - DragBox.FadeIn(250, Easing.OutQuint); + if (DragBox.HandleDrag(e)) + { + DragBox.Show(); + return true; } - return true; + return false; } protected override bool OnDrag(DragEvent e) @@ -168,13 +169,10 @@ namespace osu.Game.Screens.Edit.Compose.Components if (e.Button == MouseButton.Right) return false; - if (!moveCurrentSelection(e)) - { - if (!DragBox.UpdateDrag(e)) - return false; - } + if (DragBox.State == Visibility.Visible) + return DragBox.HandleDrag(e); - return true; + return moveCurrentSelection(e); } protected override bool OnDragEnd(DragEndEvent e) @@ -182,13 +180,14 @@ namespace osu.Game.Screens.Edit.Compose.Components if (e.Button == MouseButton.Right) return false; - if (!finishSelectionMovement()) + if (DragBox.State == Visibility.Visible) { - DragBox.FadeOut(250, Easing.OutQuint); + DragBox.Hide(); selectionHandler.UpdateVisibility(); + return true; } - return true; + return finishSelectionMovement(); } protected override bool OnKeyDown(KeyDownEvent e) diff --git a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs index adbab1767b..c5f1bd1575 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,7 +16,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A box that displays the drag selection and provides selection events for users to handle. /// - public class DragBox : CompositeDrawable + public class DragBox : CompositeDrawable, IStateful { protected readonly Action PerformSelection; @@ -57,7 +58,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The mouse event. /// Whether the event should be handled and blocking. - public virtual bool UpdateDrag(MouseButtonEvent e) + public virtual bool HandleDrag(MouseButtonEvent e) { var dragPosition = e.ScreenSpaceMousePosition; var dragStartPosition = e.ScreenSpaceMouseDownPosition; @@ -76,5 +77,26 @@ namespace osu.Game.Screens.Edit.Compose.Components PerformSelection?.Invoke(dragRectangle); return true; } + + private Visibility state; + + public Visibility State + { + get => state; + set + { + if (value == state) return; + + state = value; + this.FadeTo(state == Visibility.Hidden ? 0 : 1, 250, Easing.OutQuint); + StateChanged?.Invoke(state); + } + } + + public override void Hide() => State = Visibility.Hidden; + + public override void Show() => State = Visibility.Visible; + + public event Action StateChanged; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index a11958c8c9..7101fac310 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -52,6 +52,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return base.OnDrag(e); } + protected override bool OnDragEnd(DragEndEvent e) + { + lastDragEvent = null; + return base.OnDragEnd(e); + } + protected override void Update() { // trigger every frame so drags continue to update selection while playback is scrolling the timeline. @@ -81,7 +87,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Alpha = 0.3f }; - public override bool UpdateDrag(MouseButtonEvent e) + public override bool HandleDrag(MouseButtonEvent e) { // store the original position of the mouse down, as we may be scrolled during selection. if (lastMouseDown != e.ScreenSpaceMouseDownPosition) From 53bdf72592ba86418da460560515553e63401437 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 21:37:06 +0900 Subject: [PATCH 085/157] Allow basic timeline selection temporal movement --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- .../Components/Timeline/TimelineHitObjectDisplay.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index c866fb38c8..21eb4b08b0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorBeatmap beatmap { get; set; } - public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => (position, time); + public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => (position, (position.X / Content.DrawWidth) * track.Length); public float GetBeatSnapDistanceAt(double referenceTime) { diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs index 7101fac310..5e6403bb05 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs @@ -67,6 +67,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline base.Update(); } + protected override SelectionHandler CreateSelectionHandler() => new TimelineSelectionHandler(); + + internal class TimelineSelectionHandler : SelectionHandler + { + public override bool HandleMovement(MoveSelectionEvent moveEvent) => true; + } + protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject); protected override DragBox CreateDragBox(Action performSelect) => new TimelineDragBox(performSelect); @@ -212,6 +219,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); } } + + public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; } } } From aa1a226ab7522b3207d3c3a949fbec1a905be345 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 21:37:57 +0900 Subject: [PATCH 086/157] Remove unused ScreenSpaceStartPosition field --- .../Edit/Compose/Components/BlueprintContainer.cs | 2 +- .../Edit/Compose/Components/MoveSelectionEvent.cs | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 583627f78e..58cd4d0974 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Edit.Compose.Components (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); // Move the hitobjects - if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, startPosition, ToScreenSpace(snappedPosition)))) + if (!selectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprint, ToScreenSpace(snappedPosition)))) return true; // Apply the start time at the newly snapped-to position diff --git a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs index 48cb702c78..0792d0f80e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs +++ b/osu.Game/Screens/Edit/Compose/Components/MoveSelectionEvent.cs @@ -16,11 +16,6 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public readonly SelectionBlueprint Blueprint; - /// - /// The starting screen-space position of the hitobject. - /// - public readonly Vector2 ScreenSpaceStartPosition; - /// /// The expected screen-space position of the hitobject at the current cursor position. /// @@ -29,15 +24,11 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The distance between and the hitobject's current position, in the coordinate-space of the hitobject's parent. /// - /// - /// This does not use and does not represent the cumulative movement distance. - /// public readonly Vector2 InstantDelta; - public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpaceStartPosition, Vector2 screenSpacePosition) + public MoveSelectionEvent(SelectionBlueprint blueprint, Vector2 screenSpacePosition) { Blueprint = blueprint; - ScreenSpaceStartPosition = screenSpaceStartPosition; ScreenSpacePosition = screenSpacePosition; InstantDelta = Blueprint.GetInstantDelta(ScreenSpacePosition); From c76f76e5aa441c526278345a706f34487e6c1eaa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 21:43:02 +0900 Subject: [PATCH 087/157] Fix being able to drag out of the blueprint intending to be moved --- .../Compose/Components/BlueprintContainer.cs | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 58cd4d0974..ef4a06879e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -109,6 +109,9 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { beginClickSelection(e); + + prepareSelectionMovement(); + return e.Button == MouseButton.Left; } @@ -144,6 +147,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { // Special case for when a drag happened instead of a click Schedule(() => endClickSelection()); + + finishSelectionMovement(); + return e.Button == MouseButton.Left; } @@ -152,7 +158,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (e.Button == MouseButton.Right) return false; - if (beginSelectionMovement()) + if (movementBlueprint != null) return true; if (DragBox.HandleDrag(e)) @@ -184,10 +190,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { DragBox.Hide(); selectionHandler.UpdateVisibility(); - return true; } - return finishSelectionMovement(); + return true; } protected override bool OnKeyDown(KeyDownEvent e) @@ -348,14 +353,14 @@ namespace osu.Game.Screens.Edit.Compose.Components #region Selection Movement - private Vector2? screenSpaceMovementStartPosition; + private Vector2? movementBlueprintOriginalPosition; private SelectionBlueprint movementBlueprint; /// /// Attempts to begin the movement of any selected blueprints. /// /// Whether movement began. - private bool beginSelectionMovement() + private bool prepareSelectionMovement() { Debug.Assert(movementBlueprint == null); @@ -366,7 +371,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest hitobject, since it only makes sense to distance snap from that hitobject movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.HitObject.StartTime).First(); - screenSpaceMovementStartPosition = movementBlueprint.SelectionPoint; // todo: unsure if correct + movementBlueprintOriginalPosition = movementBlueprint.SelectionPoint; // todo: unsure if correct return true; } @@ -381,13 +386,13 @@ namespace osu.Game.Screens.Edit.Compose.Components if (movementBlueprint == null) return false; - Debug.Assert(screenSpaceMovementStartPosition != null); + Debug.Assert(movementBlueprintOriginalPosition != null); - Vector2 startPosition = screenSpaceMovementStartPosition.Value; HitObject draggedObject = movementBlueprint.HitObject; // The final movement position, relative to screenSpaceMovementStartPosition - Vector2 movePosition = startPosition + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; + Vector2 movePosition = movementBlueprintOriginalPosition.Value + e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; + (Vector2 snappedPosition, double snappedTime) = snapProvider.GetSnappedPosition(ToLocalSpace(movePosition), draggedObject.StartTime); // Move the hitobjects @@ -411,7 +416,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (movementBlueprint == null) return false; - screenSpaceMovementStartPosition = null; + movementBlueprintOriginalPosition = null; movementBlueprint = null; return true; From 9d2a46df892587185343b8ebb7723823df750c33 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Jan 2020 21:46:24 +0900 Subject: [PATCH 088/157] Add beat snapping to timeline movement --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 21eb4b08b0..98fb754931 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -173,7 +173,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorBeatmap beatmap { get; set; } - public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => (position, (position.X / Content.DrawWidth) * track.Length); + public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) + { + var targetTime = (position.X / Content.DrawWidth) * track.Length; + return (position, beatSnap(targetTime, targetTime)); + } public float GetBeatSnapDistanceAt(double referenceTime) { From 477e1b7d278a9b1b490a43d4291c5c0af00b05f5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 12:17:46 +0900 Subject: [PATCH 089/157] Rename TimelineHitObjectDisplay to TimelineBlueprintContainer --- .../Visual/Editor/TestSceneEditorComposeTimeline.cs | 4 ++-- ...elineHitObjectDisplay.cs => TimelineBlueprintContainer.cs} | 4 ++-- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game/Screens/Edit/Compose/Components/Timeline/{TimelineHitObjectDisplay.cs => TimelineBlueprintContainer.cs} (98%) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index e9372bd134..78cdeb3ac8 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Editor public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), - typeof(TimelineHitObjectDisplay), + typeof(TimelineBlueprintContainer), typeof(Timeline), typeof(TimelineButton), typeof(CentreMarker) @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Editor }, new TimelineArea { - Child = new TimelineHitObjectDisplay(editorBeatmap), + Child = new TimelineBlueprintContainer(editorBeatmap), Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs similarity index 98% rename from osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs rename to osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 5e6403bb05..c5603c0f67 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -18,11 +18,11 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - internal class TimelineHitObjectDisplay : BlueprintContainer + internal class TimelineBlueprintContainer : BlueprintContainer { private DragEvent lastDragEvent; - public TimelineHitObjectDisplay(EditorBeatmap beatmap) + public TimelineBlueprintContainer(EditorBeatmap beatmap) { RelativeSizeAxes = Axes.Both; Anchor = Anchor.Centre; diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 1a6aae294a..20e1ef95d3 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -32,6 +32,6 @@ namespace osu.Game.Screens.Edit.Compose return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(composer)); } - protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineHitObjectDisplay(EditorBeatmap); + protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineBlueprintContainer(EditorBeatmap); } } From cb09c2e1449ee26285d14a27a9f40c3fb0f937d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 12:29:32 +0900 Subject: [PATCH 090/157] Add support for dragging outside visible extents --- .../Edit/Compose/Components/Timeline/Timeline.cs | 1 + .../Timeline/TimelineBlueprintContainer.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 98fb754931..804c2f1e65 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -18,6 +18,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { [Cached(typeof(IDistanceSnapProvider))] + [Cached] public class Timeline : ZoomableScrollContainer, IDistanceSnapProvider { public readonly Bindable WaveformVisible = new Bindable(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index c5603c0f67..16e1793c8c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -3,6 +3,7 @@ using System; using JetBrains.Annotations; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -20,6 +21,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { internal class TimelineBlueprintContainer : BlueprintContainer { + [Resolved(CanBeNull = true)] + private Timeline timeline { get; set; } + private DragEvent lastDragEvent; public TimelineBlueprintContainer(EditorBeatmap beatmap) @@ -48,6 +52,18 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override bool OnDrag(DragEvent e) { + if (timeline != null) + { + var timelineQuad = timeline.ScreenSpaceDrawQuad; + var mouseX = e.ScreenSpaceMousePosition.X; + + // scroll if in a drag and dragging outside visible extents + if (mouseX > timelineQuad.TopRight.X) + timeline.ScrollBy((float)((mouseX - timelineQuad.TopRight.X) / 10 * Clock.ElapsedFrameTime)); + else if (mouseX < timelineQuad.TopLeft.X) + timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime)); + } + lastDragEvent = e; return base.OnDrag(e); } From 56c044c44ac6cc6ea460fef8883d99fb9a88aadc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 13:33:55 +0900 Subject: [PATCH 091/157] Move beat snapping to its own interface --- ...tSceneHitObjectComposerDistanceSnapping.cs | 9 +++- .../Visual/Editor/TestSceneComposeScreen.cs | 2 + .../Editor/TestSceneEditorComposeTimeline.cs | 4 +- .../Editor/TestSceneHitObjectComposer.cs | 1 + osu.Game/Rulesets/Edit/HitObjectComposer.cs | 26 +++-------- osu.Game/Rulesets/Edit/IBeatSnapProvider.cs | 30 ++++++++++++ .../Compose/Components/Timeline/Timeline.cs | 46 ++++--------------- osu.Game/Screens/Edit/Editor.cs | 15 +++++- osu.Game/Screens/Edit/EditorBeatmap.cs | 20 +++++++- 9 files changed, 90 insertions(+), 63 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/IBeatSnapProvider.cs diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs index 2d336bd19c..e825df5a3f 100644 --- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Edit; @@ -19,7 +20,13 @@ namespace osu.Game.Tests.Editor private TestHitObjectComposer composer; [Cached(typeof(EditorBeatmap))] - private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + [Cached(typeof(IBeatSnapProvider))] + private readonly EditorBeatmap editorBeatmap; + + public TestSceneHitObjectComposerDistanceSnapping() + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap(), BeatDivisor); + } [SetUp] public void Setup() => Schedule(() => diff --git a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs index 3562689482..a8830824c0 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Screens.Edit; @@ -14,6 +15,7 @@ namespace osu.Game.Tests.Visual.Editor public class TestSceneComposeScreen : EditorClockTestScene { [Cached(typeof(EditorBeatmap))] + [Cached(typeof(IBeatSnapProvider))] private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap { diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index 78cdeb3ac8..5b0408268f 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -38,9 +39,10 @@ namespace osu.Game.Tests.Visual.Editor { Beatmap.Value = new WaveformTestBeatmap(audio); - var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap); + var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor); Dependencies.Cache(editorBeatmap); + Dependencies.CacheAs(editorBeatmap); Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs index c001c83877..e41c2427fb 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs @@ -66,6 +66,7 @@ namespace osu.Game.Tests.Visual.Editor Dependencies.CacheAs(clock); Dependencies.CacheAs(clock); Dependencies.CacheAs(editorBeatmap); + Dependencies.CacheAs(editorBeatmap); Child = new OsuHitObjectComposer(new OsuRuleset()); } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 5eba31d149..50042d1e3b 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Edit private IAdjustableClock adjustableClock { get; set; } [Resolved] - private BindableBeatDivisor beatDivisor { get; set; } + private IBeatSnapProvider beatSnapProvider { get; set; } private IBeatmapProcessor beatmapProcessor; @@ -259,40 +259,26 @@ namespace osu.Game.Rulesets.Edit public override float GetBeatSnapDistanceAt(double referenceTime) { DifficultyControlPoint difficultyPoint = EditorBeatmap.ControlPointInfo.DifficultyPointAt(referenceTime); - return (float)(100 * EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatDivisor.Value); + return (float)(100 * EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatSnapProvider.BeatDivisor); } public override float DurationToDistance(double referenceTime, double duration) { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime)); } public override double DistanceToDuration(double referenceTime, float distance) { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength; } public override double GetSnappedDurationFromDistance(double referenceTime, float distance) - => beatSnap(referenceTime, DistanceToDuration(referenceTime, distance)); + => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor); public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnap(referenceTime, DistanceToDuration(referenceTime, distance))); - - /// - /// Snaps a duration to the closest beat of a timing point applicable at the reference time. - /// - /// The time of the timing point which resides in. - /// The duration to snap. - /// A value that represents snapped to the closest beat of the timing point. - private double beatSnap(double referenceTime, double duration) - { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; - - // A 1ms offset prevents rounding errors due to minute variations in duration - return (int)((duration + 1) / beatLength) * beatLength; - } + => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor)); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs new file mode 100644 index 0000000000..ed6e08d054 --- /dev/null +++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs @@ -0,0 +1,30 @@ +// 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.Rulesets.Edit +{ + public interface IBeatSnapProvider + { + /// + /// Snaps a duration to the closest beat of a timing point applicable at the reference time. + /// + /// The time of the timing point which resides in. + /// The duration to snap. + /// The divisor to use for snapping purposes. + /// A value that represents snapped to the closest beat of the timing point. + double SnapTime(double referenceTime, double duration, int beatDivisor); + + /// + /// Get the most appropriate beat length at a given time. + /// + /// A reference time used for lookup. + /// The divisor to use for snapping purposes. + /// The most appropriate beat length. + double GetBeatLengthAtTime(double referenceTime, int beatDivisor); + + /// + /// Returns the current beat divisor. + /// + int BeatDivisor { get; } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 804c2f1e65..ec6f0bb923 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.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; @@ -10,7 +11,6 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Rulesets.Edit; using osuTK; @@ -169,53 +169,25 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } [Resolved] - private BindableBeatDivisor beatDivisor { get; set; } + private EditorBeatmap beatmap { get; set; } [Resolved] - private EditorBeatmap beatmap { get; set; } + private IBeatSnapProvider beatSnapProvider { get; set; } public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) { var targetTime = (position.X / Content.DrawWidth) * track.Length; - return (position, beatSnap(targetTime, targetTime)); + return (position, beatSnapProvider.SnapTime(targetTime, targetTime, beatSnapProvider.BeatDivisor)); } - public float GetBeatSnapDistanceAt(double referenceTime) - { - DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(referenceTime); - return (float)(100 * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatDivisor.Value); - } + public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); - public float DurationToDistance(double referenceTime, double duration) - { - double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; - return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime)); - } + public float DurationToDistance(double referenceTime, double duration) => throw new NotImplementedException(); - public double DistanceToDuration(double referenceTime, float distance) - { - double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; - return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength; - } + public double DistanceToDuration(double referenceTime, float distance) => throw new NotImplementedException(); - public double GetSnappedDurationFromDistance(double referenceTime, float distance) - => beatSnap(referenceTime, DistanceToDuration(referenceTime, distance)); + public double GetSnappedDurationFromDistance(double referenceTime, float distance) => throw new NotImplementedException(); - public float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnap(referenceTime, DistanceToDuration(referenceTime, distance))); - - /// - /// Snaps a duration to the closest beat of a timing point applicable at the reference time. - /// - /// The time of the timing point which resides in. - /// The duration to snap. - /// A value that represents snapped to the closest beat of the timing point. - private double beatSnap(double referenceTime, double duration) - { - double beatLength = beatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; - - // A 1ms offset prevents rounding errors due to minute variations in duration - return (int)((duration + 1) / beatLength) * beatLength; - } + public float GetSnappedDistanceFromDistance(double referenceTime, float distance) => throw new NotImplementedException(); } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e212b429b9..26660c427c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -26,6 +26,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; @@ -34,7 +35,8 @@ using osu.Game.Users; namespace osu.Game.Screens.Edit { - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler + [Cached(typeof(IBeatSnapProvider))] + public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IBeatSnapProvider { public override float BackgroundParallaxAmount => 0.1f; @@ -77,11 +79,14 @@ namespace osu.Game.Screens.Edit clock.ChangeSource(sourceClock); playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - editorBeatmap = new EditorBeatmap(playableBeatmap); + editorBeatmap = new EditorBeatmap(playableBeatmap, beatDivisor); dependencies.CacheAs(clock); dependencies.CacheAs(clock); + + // todo: remove caching of this and consume via editorBeatmap? dependencies.Cache(beatDivisor); + dependencies.CacheAs(editorBeatmap); EditorMenuBar menuBar; @@ -345,5 +350,11 @@ namespace osu.Game.Screens.Edit saveBeatmap(); beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } + + public double SnapTime(double referenceTime, double duration, int beatDivisor) => editorBeatmap.SnapTime(referenceTime, duration, beatDivisor); + + public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => editorBeatmap.GetBeatLengthAtTime(referenceTime, beatDivisor); + + public int BeatDivisor => beatDivisor.Value; } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 2ff7563a88..b7dd94b6c5 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -8,11 +8,12 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Edit { - public class EditorBeatmap : IBeatmap + public class EditorBeatmap : IBeatmap, IBeatSnapProvider { /// /// Invoked when a is added to this . @@ -33,11 +34,14 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; + private readonly BindableBeatDivisor beatDivisor; + private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap) + public EditorBeatmap(IBeatmap playableBeatmap, BindableBeatDivisor beatDivisor = null) { PlayableBeatmap = playableBeatmap; + this.beatDivisor = beatDivisor; foreach (var obj in HitObjects) trackStartTime(obj); @@ -123,5 +127,17 @@ namespace osu.Game.Screens.Edit return list.Count - 1; } + + public double SnapTime(double referenceTime, double duration, int beatDivisor) + { + double beatLength = GetBeatLengthAtTime(referenceTime, beatDivisor); + + // A 1ms offset prevents rounding errors due to minute variations in duration + return (int)((duration + 1) / beatLength) * beatLength; + } + + public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; + + public int BeatDivisor => beatDivisor?.Value ?? 1; } } From 098d643955fc7fd05a35f1106451b1fb12290ea4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 14:39:56 +0900 Subject: [PATCH 092/157] Move beat snapping to its own interface --- ...tSceneHitObjectComposerDistanceSnapping.cs | 9 +++++- .../Visual/Editor/TestSceneComposeScreen.cs | 2 ++ .../Editor/TestSceneHitObjectComposer.cs | 1 + osu.Game/Rulesets/Edit/HitObjectComposer.cs | 26 ++++------------ osu.Game/Rulesets/Edit/IBeatSnapProvider.cs | 30 +++++++++++++++++++ osu.Game/Screens/Edit/Editor.cs | 15 ++++++++-- osu.Game/Screens/Edit/EditorBeatmap.cs | 20 +++++++++++-- 7 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/IBeatSnapProvider.cs diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs index 2d336bd19c..e825df5a3f 100644 --- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Testing; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Edit; @@ -19,7 +20,13 @@ namespace osu.Game.Tests.Editor private TestHitObjectComposer composer; [Cached(typeof(EditorBeatmap))] - private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + [Cached(typeof(IBeatSnapProvider))] + private readonly EditorBeatmap editorBeatmap; + + public TestSceneHitObjectComposerDistanceSnapping() + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap(), BeatDivisor); + } [SetUp] public void Setup() => Schedule(() => diff --git a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs index 3562689482..a8830824c0 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Screens.Edit; @@ -14,6 +15,7 @@ namespace osu.Game.Tests.Visual.Editor public class TestSceneComposeScreen : EditorClockTestScene { [Cached(typeof(EditorBeatmap))] + [Cached(typeof(IBeatSnapProvider))] private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap { diff --git a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs index c001c83877..e41c2427fb 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs @@ -66,6 +66,7 @@ namespace osu.Game.Tests.Visual.Editor Dependencies.CacheAs(clock); Dependencies.CacheAs(clock); Dependencies.CacheAs(editorBeatmap); + Dependencies.CacheAs(editorBeatmap); Child = new OsuHitObjectComposer(new OsuRuleset()); } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index bfaa7e8872..e1ce294581 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Edit private IAdjustableClock adjustableClock { get; set; } [Resolved] - private BindableBeatDivisor beatDivisor { get; set; } + private IBeatSnapProvider beatSnapProvider { get; set; } private IBeatmapProcessor beatmapProcessor; @@ -257,40 +257,26 @@ namespace osu.Game.Rulesets.Edit public override float GetBeatSnapDistanceAt(double referenceTime) { DifficultyControlPoint difficultyPoint = EditorBeatmap.ControlPointInfo.DifficultyPointAt(referenceTime); - return (float)(100 * EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatDivisor.Value); + return (float)(100 * EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / beatSnapProvider.BeatDivisor); } public override float DurationToDistance(double referenceTime, double duration) { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime)); } public override double DistanceToDuration(double referenceTime, float distance) { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength; } public override double GetSnappedDurationFromDistance(double referenceTime, float distance) - => beatSnap(referenceTime, DistanceToDuration(referenceTime, distance)); + => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor); public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnap(referenceTime, DistanceToDuration(referenceTime, distance))); - - /// - /// Snaps a duration to the closest beat of a timing point applicable at the reference time. - /// - /// The time of the timing point which resides in. - /// The duration to snap. - /// A value that represents snapped to the closest beat of the timing point. - private double beatSnap(double referenceTime, double duration) - { - double beatLength = EditorBeatmap.ControlPointInfo.TimingPointAt(referenceTime).BeatLength / beatDivisor.Value; - - // A 1ms offset prevents rounding errors due to minute variations in duration - return (int)((duration + 1) / beatLength) * beatLength; - } + => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor)); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs new file mode 100644 index 0000000000..ed6e08d054 --- /dev/null +++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs @@ -0,0 +1,30 @@ +// 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.Rulesets.Edit +{ + public interface IBeatSnapProvider + { + /// + /// Snaps a duration to the closest beat of a timing point applicable at the reference time. + /// + /// The time of the timing point which resides in. + /// The duration to snap. + /// The divisor to use for snapping purposes. + /// A value that represents snapped to the closest beat of the timing point. + double SnapTime(double referenceTime, double duration, int beatDivisor); + + /// + /// Get the most appropriate beat length at a given time. + /// + /// A reference time used for lookup. + /// The divisor to use for snapping purposes. + /// The most appropriate beat length. + double GetBeatLengthAtTime(double referenceTime, int beatDivisor); + + /// + /// Returns the current beat divisor. + /// + int BeatDivisor { get; } + } +} diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e5cb319fb9..820915e8e3 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -26,6 +26,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Graphics.Cursor; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; @@ -34,7 +35,8 @@ using osu.Game.Users; namespace osu.Game.Screens.Edit { - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler + [Cached(typeof(IBeatSnapProvider))] + public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IBeatSnapProvider { public override float BackgroundParallaxAmount => 0.1f; @@ -77,11 +79,14 @@ namespace osu.Game.Screens.Edit clock.ChangeSource(sourceClock); playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - editorBeatmap = new EditorBeatmap(playableBeatmap); + editorBeatmap = new EditorBeatmap(playableBeatmap, beatDivisor); dependencies.CacheAs(clock); dependencies.CacheAs(clock); + + // todo: remove caching of this and consume via editorBeatmap? dependencies.Cache(beatDivisor); + dependencies.CacheAs(editorBeatmap); EditorMenuBar menuBar; @@ -347,5 +352,11 @@ namespace osu.Game.Screens.Edit saveBeatmap(); beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } + + public double SnapTime(double referenceTime, double duration, int beatDivisor) => editorBeatmap.SnapTime(referenceTime, duration, beatDivisor); + + public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => editorBeatmap.GetBeatLengthAtTime(referenceTime, beatDivisor); + + public int BeatDivisor => beatDivisor.Value; } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 6ed74dfdb0..7c037c435f 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -8,11 +8,12 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Edit { - public class EditorBeatmap : IBeatmap + public class EditorBeatmap : IBeatmap, IBeatSnapProvider { /// /// Invoked when a is added to this . @@ -31,11 +32,14 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; + private readonly BindableBeatDivisor beatDivisor; + private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap) + public EditorBeatmap(IBeatmap playableBeatmap, BindableBeatDivisor beatDivisor = null) { PlayableBeatmap = playableBeatmap; + this.beatDivisor = beatDivisor; foreach (var obj in HitObjects) trackStartTime(obj); @@ -121,5 +125,17 @@ namespace osu.Game.Screens.Edit return list.Count - 1; } + + public double SnapTime(double referenceTime, double duration, int beatDivisor) + { + double beatLength = GetBeatLengthAtTime(referenceTime, beatDivisor); + + // A 1ms offset prevents rounding errors due to minute variations in duration + return (int)((duration + 1) / beatLength) * beatLength; + } + + public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; + + public int BeatDivisor => beatDivisor?.Value ?? 1; } } From ccf911884be0e8a822b4ed4215413cd103752758 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 15:31:56 +0900 Subject: [PATCH 093/157] Remove passed in BaetDivisor --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 8 ++++---- osu.Game/Rulesets/Edit/IBeatSnapProvider.cs | 6 ++---- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Screens/Edit/EditorBeatmap.cs | 6 +++--- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e1ce294581..dbd29a167c 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -262,21 +262,21 @@ namespace osu.Game.Rulesets.Edit public override float DurationToDistance(double referenceTime, double duration) { - double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime); return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceTime)); } public override double DistanceToDuration(double referenceTime, float distance) { - double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime, beatSnapProvider.BeatDivisor); + double beatLength = beatSnapProvider.GetBeatLengthAtTime(referenceTime); return distance / GetBeatSnapDistanceAt(referenceTime) * beatLength; } public override double GetSnappedDurationFromDistance(double referenceTime, float distance) - => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor); + => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance)); public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance), beatSnapProvider.BeatDivisor)); + => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance))); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs index ed6e08d054..e1daafaebe 100644 --- a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs @@ -10,17 +10,15 @@ namespace osu.Game.Rulesets.Edit /// /// The time of the timing point which resides in. /// The duration to snap. - /// The divisor to use for snapping purposes. /// A value that represents snapped to the closest beat of the timing point. - double SnapTime(double referenceTime, double duration, int beatDivisor); + double SnapTime(double referenceTime, double duration); /// /// Get the most appropriate beat length at a given time. /// /// A reference time used for lookup. - /// The divisor to use for snapping purposes. /// The most appropriate beat length. - double GetBeatLengthAtTime(double referenceTime, int beatDivisor); + double GetBeatLengthAtTime(double referenceTime); /// /// Returns the current beat divisor. diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 820915e8e3..8d66cef16e 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -353,9 +353,9 @@ namespace osu.Game.Screens.Edit beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } - public double SnapTime(double referenceTime, double duration, int beatDivisor) => editorBeatmap.SnapTime(referenceTime, duration, beatDivisor); + public double SnapTime(double referenceTime, double duration) => editorBeatmap.SnapTime(referenceTime, duration); - public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => editorBeatmap.GetBeatLengthAtTime(referenceTime, beatDivisor); + public double GetBeatLengthAtTime(double referenceTime) => editorBeatmap.GetBeatLengthAtTime(referenceTime); public int BeatDivisor => beatDivisor.Value; } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 7c037c435f..a67a0ff0f1 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -126,15 +126,15 @@ namespace osu.Game.Screens.Edit return list.Count - 1; } - public double SnapTime(double referenceTime, double duration, int beatDivisor) + public double SnapTime(double referenceTime, double duration) { - double beatLength = GetBeatLengthAtTime(referenceTime, beatDivisor); + double beatLength = GetBeatLengthAtTime(referenceTime); // A 1ms offset prevents rounding errors due to minute variations in duration return (int)((duration + 1) / beatLength) * beatLength; } - public double GetBeatLengthAtTime(double referenceTime, int beatDivisor) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; + public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; public int BeatDivisor => beatDivisor?.Value ?? 1; } From d3262a5667757ef047722c69634d3250d614f6a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Jan 2020 17:35:36 +0900 Subject: [PATCH 094/157] Cache EditorBeatmap in test --- osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index 29575cb42e..e9372bd134 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -40,6 +40,8 @@ namespace osu.Game.Tests.Visual.Editor var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap); + Dependencies.Cache(editorBeatmap); + Children = new Drawable[] { new FillFlowContainer From 9d90799447027b3d74a92363514aed5a6b1911f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 16:20:42 +0900 Subject: [PATCH 095/157] Remove useless container --- .../Edit/Compose/Components/BlueprintContainer.cs | 10 +++------- .../Components/Timeline/TimelineBlueprintContainer.cs | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 4ef8877795..23f62e4eaf 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected DragBox DragBox { get; private set; } - private SelectionBlueprintContainer selectionBlueprints; + private Container selectionBlueprints; private SelectionHandler selectionHandler; @@ -83,7 +83,8 @@ namespace osu.Game.Screens.Edit.Compose.Components }; } - protected virtual SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; + protected virtual Container CreateSelectionBlueprintContainer() => + new Container { RelativeSizeAxes = Axes.Both }; protected override void LoadComplete() { @@ -430,10 +431,5 @@ namespace osu.Game.Screens.Edit.Compose.Components beatmap.HitObjectRemoved -= removeBlueprintFor; } } - - protected class SelectionBlueprintContainer : Container - { - //todo: remove - } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index b0d3e2dcde..9fef2998bd 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }); } - protected override SelectionBlueprintContainer CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; + protected override Container CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; protected override void LoadComplete() { @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - protected class TimelineSelectionBlueprintContainer : SelectionBlueprintContainer + protected class TimelineSelectionBlueprintContainer : Container { protected override Container Content { get; } From 5cadbb1ffb057f71f086b6a6053a65e15807001a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 16:22:43 +0900 Subject: [PATCH 096/157] Move timeline blueprint to own class --- .../Timeline/TimelineBlueprintContainer.cs | 102 --------------- .../Timeline/TimelineHitObjectBlueprint.cs | 116 ++++++++++++++++++ 2 files changed, 116 insertions(+), 102 deletions(-) create mode 100644 osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 9fef2998bd..c1458480a6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using JetBrains.Annotations; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; @@ -12,7 +10,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; using osuTK; using osuTK.Graphics; @@ -139,104 +136,5 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline AddInternal(new TimelinePart(Content = new Container { RelativeSizeAxes = Axes.Both }) { RelativeSizeAxes = Axes.Both }); } } - - private class TimelineHitObjectBlueprint : SelectionBlueprint - { - private readonly Circle circle; - - private readonly Container extensionBar; - - [UsedImplicitly] - private readonly Bindable startTime; - - public const float THICKNESS = 3; - - private const float circle_size = 16; - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); - - public TimelineHitObjectBlueprint(HitObject hitObject) - : base(hitObject) - { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; - - startTime = hitObject.StartTimeBindable.GetBoundCopy(); - startTime.BindValueChanged(time => X = (float)time.NewValue, true); - - RelativePositionAxes = Axes.X; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - if (hitObject is IHasEndTime) - { - AddInternal(extensionBar = new Container - { - CornerRadius = 2, - Masking = true, - Size = new Vector2(1, THICKNESS), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.X, - Colour = Color4.Black, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - } - }); - } - - AddInternal(circle = new Circle - { - Size = new Vector2(circle_size), - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.X, - AlwaysPresent = true, - Colour = Color4.White, - BorderColour = Color4.Black, - BorderThickness = THICKNESS, - }); - } - - protected override void Update() - { - base.Update(); - - // no bindable so we perform this every update - Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); - } - - protected override void OnSelected() - { - circle.BorderColour = Color4.Orange; - if (extensionBar != null) - extensionBar.Colour = Color4.Orange; - } - - protected override void OnDeselected() - { - circle.BorderColour = Color4.Black; - if (extensionBar != null) - extensionBar.Colour = Color4.Black; - } - - public override Quad SelectionQuad - { - get - { - // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. - var circleQuad = circle.ScreenSpaceDrawQuad; - var actualQuad = ScreenSpaceDrawQuad; - - return new Quad(circleQuad.TopLeft, Vector2.ComponentMax(actualQuad.TopRight, circleQuad.TopRight), - circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); - } - } - - public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; - } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs new file mode 100644 index 0000000000..2ed5471444 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -0,0 +1,116 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Edit.Compose.Components.Timeline +{ + public class TimelineHitObjectBlueprint : SelectionBlueprint + { + private readonly Circle circle; + + private readonly Container extensionBar; + + [UsedImplicitly] + private readonly Bindable startTime; + + public const float THICKNESS = 3; + + private const float circle_size = 16; + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); + + public TimelineHitObjectBlueprint(HitObject hitObject) + : base(hitObject) + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + startTime = hitObject.StartTimeBindable.GetBoundCopy(); + startTime.BindValueChanged(time => X = (float)time.NewValue, true); + + RelativePositionAxes = Axes.X; + + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + if (hitObject is IHasEndTime) + { + AddInternal(extensionBar = new Container + { + CornerRadius = 2, + Masking = true, + Size = new Vector2(1, THICKNESS), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.X, + Colour = Color4.Black, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + } + }); + } + + AddInternal(circle = new Circle + { + Size = new Vector2(circle_size), + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.X, + AlwaysPresent = true, + Colour = Color4.White, + BorderColour = Color4.Black, + BorderThickness = THICKNESS, + }); + } + + protected override void Update() + { + base.Update(); + + // no bindable so we perform this every update + Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); + } + + protected override void OnSelected() + { + circle.BorderColour = Color4.Orange; + if (extensionBar != null) + extensionBar.Colour = Color4.Orange; + } + + protected override void OnDeselected() + { + circle.BorderColour = Color4.Black; + if (extensionBar != null) + extensionBar.Colour = Color4.Black; + } + + public override Quad SelectionQuad + { + get + { + // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. + var circleQuad = circle.ScreenSpaceDrawQuad; + var actualQuad = ScreenSpaceDrawQuad; + + return new Quad(circleQuad.TopLeft, Vector2.ComponentMax(actualQuad.TopRight, circleQuad.TopRight), + circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); + } + } + + public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; + } +} From 5646f7777e77bd6c7a5414debef4bfd9c7c769cd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 16:23:42 +0900 Subject: [PATCH 097/157] Add comment about custom SelectionHandler --- .../Components/Timeline/TimelineBlueprintContainer.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index c1458480a6..6bfd323c13 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -82,15 +82,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override SelectionHandler CreateSelectionHandler() => new TimelineSelectionHandler(); - internal class TimelineSelectionHandler : SelectionHandler - { - public override bool HandleMovement(MoveSelectionEvent moveEvent) => true; - } - protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject); protected override DragBox CreateDragBox(Action performSelect) => new TimelineDragBox(performSelect); + internal class TimelineSelectionHandler : SelectionHandler + { + // for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation + public override bool HandleMovement(MoveSelectionEvent moveEvent) => true; + } + private class TimelineDragBox : DragBox { private Vector2 lastMouseDown; From 32fb87acecdad9722ab9c7acf1d235df2f342fad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 16:45:30 +0900 Subject: [PATCH 098/157] Update country names --- osu.Game.Tournament/Resources/countries.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Resources/countries.json b/osu.Game.Tournament/Resources/countries.json index ec2ca2bf37..7306a8bec5 100644 --- a/osu.Game.Tournament/Resources/countries.json +++ b/osu.Game.Tournament/Resources/countries.json @@ -541,7 +541,7 @@ }, { "FlagName": "MK", - "FullName": "Macedonia", + "FullName": "North Macedonia", "Acronym": "MKD" }, { @@ -811,7 +811,7 @@ }, { "FlagName": "CV", - "FullName": "Cape Verde", + "FullName": "Cabo Verde", "Acronym": "CPV" }, { @@ -821,7 +821,7 @@ }, { "FlagName": "SZ", - "FullName": "Swaziland", + "FullName": "Eswatini", "Acronym": "SWZ" }, { From 667fdb907cb56e6ad5fb5d4f616e1c8a23d85710 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 23 Jan 2020 12:21:16 +0300 Subject: [PATCH 099/157] Call the method directly rather that trigger a bindable --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 99f79cd940..1193de52d7 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Comments { this.type = type; this.id = id; - Sort.TriggerChange(); + refetchComments(); } private void refetchComments() From 0c3120d965914062e5dd14619bee56abb031ccb0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 23 Jan 2020 12:59:53 +0300 Subject: [PATCH 100/157] Fix possible crash due to not loaded api --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 1193de52d7..9f1d9d9488 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(_ => refetchComments()); + Sort.BindValueChanged(_ => refetchComments(), true); base.LoadComplete(); } @@ -129,6 +129,10 @@ namespace osu.Game.Overlays.Comments { this.type = type; this.id = id; + + if (!IsLoaded) + return; + refetchComments(); } From f8cb8985161d313490b33fe420cc0b3f931d33bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Jan 2020 20:03:52 +0900 Subject: [PATCH 101/157] Improve song select display on ultrawide displays (or when UI scale is set low) --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 117 ++++++++++++++------ 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index b0d5be8140..cf49cf0228 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Select { private const float shear_width = 36.75f; - private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGED_CONTAINER_SIZE.Y, 0); + private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0); private readonly IBindable ruleset = new Bindable(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bf57def700..bcb828a666 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Select { public abstract class SongSelect : OsuScreen, IKeyBindingHandler { - public static readonly Vector2 WEDGED_CONTAINER_SIZE = new Vector2(0.5f, 245); + public static readonly float WEDGE_HEIGHT = 245; protected const float BACKGROUND_BLUR = 20; private const float left_area_padding = 20; @@ -88,13 +88,15 @@ namespace osu.Game.Screens.Select [Resolved(canBeNull: true)] private MusicController music { get; set; } + private const float panel_overflow = 1.2f; + [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). transferRulesetValue(); - AddRangeInternal(new Drawable[] + AddRangeInternal(new[] { new ParallaxContainer { @@ -107,27 +109,61 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = -150 }, - Size = new Vector2(WEDGED_CONTAINER_SIZE.X, 1), + Size = new Vector2(0.5f, 1), } } }, - new Container + new GridContainer // used for max width implementation { - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.Both, - Size = new Vector2(WEDGED_CONTAINER_SIZE.X, 1), - Padding = new MarginPadding + ColumnDimensions = new[] { - Bottom = Footer.HEIGHT, - Top = WEDGED_CONTAINER_SIZE.Y + left_area_padding, - Left = left_area_padding, - Right = left_area_padding * 2, + new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 650), }, - Child = BeatmapDetails = new BeatmapDetailArea + Content = new[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 10, Right = 5 }, + new Drawable[] + { + new Container + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + + Children = new Drawable[] + { + beatmapInfoWedge = new BeatmapInfoWedge + { + Height = WEDGE_HEIGHT, + RelativeSizeAxes = Axes.X, + Margin = new MarginPadding + { + Top = left_area_padding, + Right = left_area_padding, + }, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Bottom = Footer.HEIGHT, + Top = WEDGE_HEIGHT + left_area_padding, + Left = left_area_padding, + Right = left_area_padding * 2, + }, + Children = new Drawable[] + { + BeatmapDetails = new BeatmapDetailArea + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 10, Right = 5 }, + }, + } + }, + } + }, + }, } }, new Container @@ -136,13 +172,13 @@ namespace osu.Game.Screens.Select Masking = true, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Width = 2, //avoid horizontal masking so the panels don't clip when screen stack is pushed. + Width = panel_overflow, //avoid horizontal masking so the panels don't clip when screen stack is pushed. Child = new Container { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Width = 0.5f, + Width = 1 / panel_overflow, Children = new Drawable[] { new Container @@ -153,15 +189,33 @@ namespace osu.Game.Screens.Select Top = FilterControl.HEIGHT, Bottom = Footer.HEIGHT }, - Child = Carousel = new BeatmapCarousel + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1 - WEDGED_CONTAINER_SIZE.X, 1), - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - SelectionChanged = updateSelectedBeatmap, - BeatmapSetsChanged = carouselBeatmapsLoaded, - }, + new GridContainer // used for max width implementation + { + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 850), + }, + Content = new[] + { + new Drawable[] + { + null, + Carousel = new BeatmapCarousel + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + SelectionChanged = updateSelectedBeatmap, + BeatmapSetsChanged = carouselBeatmapsLoaded, + }, + } + } + }, + } }, FilterControl = new FilterControl { @@ -173,21 +227,12 @@ namespace osu.Game.Screens.Select } }, }, - beatmapInfoWedge = new BeatmapInfoWedge - { - Size = WEDGED_CONTAINER_SIZE, - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding - { - Top = left_area_padding, - Right = left_area_padding, - }, - }, new ResetScrollContainer(() => Carousel.ScrollToSelected()) { RelativeSizeAxes = Axes.Y, Width = 250, - } + }, + beatmapInfoWedge.CreateProxy() }); if (ShowFooter) From 6493f24547bd1eae1ecbfce3edb13f4ac0612d80 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 23 Jan 2020 15:56:01 +0300 Subject: [PATCH 102/157] Add TotalCommentsCounter to CommentsContainer --- osu.Game/Overlays/Comments/CommentsContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 9f1d9d9488..433af5fb4e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -38,6 +38,7 @@ namespace osu.Game.Overlays.Comments private readonly FillFlowContainer content; private readonly DeletedChildrenPlaceholder deletedChildrenPlaceholder; private readonly CommentsShowMoreButton moreButton; + private readonly TotalCommentsCounter commentCounter; public CommentsContainer() { @@ -56,6 +57,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { + commentCounter = new TotalCommentsCounter(), new CommentsHeader { Sort = { BindTarget = Sort }, @@ -133,6 +135,7 @@ namespace osu.Game.Overlays.Comments if (!IsLoaded) return; + commentCounter.Current.Value = 0; refetchComments(); } @@ -199,6 +202,8 @@ namespace osu.Game.Overlays.Comments moreButton.IsLoading = false; } + commentCounter.Current.Value = response.Total; + moreButton.FadeTo(response.HasMore ? 1 : 0); }, loadCancellation.Token); } From 316a764f6f85a91f42b1d11b6bb8b03b47392e73 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Thu, 23 Jan 2020 16:23:53 +0100 Subject: [PATCH 103/157] Minor cleanups for Legacy Storyboard/Beatmap decoder --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 12 ++++++------ osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 5 ++++- .../Beatmaps/Formats/LegacyStoryboardDecoder.cs | 14 +++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 447d52d980..a8ec351817 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -239,11 +239,11 @@ namespace osu.Game.Beatmaps.Formats break; case @"Source": - beatmap.BeatmapInfo.Metadata.Source = pair.Value; + metadata.Source = pair.Value; break; case @"Tags": - beatmap.BeatmapInfo.Metadata.Tags = pair.Value; + metadata.Tags = pair.Value; break; case @"BeatmapID": @@ -300,13 +300,13 @@ namespace osu.Game.Beatmaps.Formats switch (type) { case LegacyEventType.Background: - string bgFilename = split[2].Trim('"'); - beatmap.BeatmapInfo.Metadata.BackgroundFile = bgFilename.ToStandardisedPath(); + string bgFilename = split[2]; + beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(bgFilename); ; break; case LegacyEventType.Video: - string videoFilename = split[2].Trim('"'); - beatmap.BeatmapInfo.Metadata.VideoFile = videoFilename.ToStandardisedPath(); + string videoFilename = split[2]; + beatmap.BeatmapInfo.Metadata.VideoFile = CleanFilename(videoFilename); break; case LegacyEventType.Break: diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index f55e24245b..0ec80eee41 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using osu.Framework.Extensions; using osu.Framework.Logging; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; @@ -115,7 +116,7 @@ namespace osu.Game.Beatmaps.Formats protected KeyValuePair SplitKeyVal(string line, char separator = ':') { - var split = line.Trim().Split(new[] { separator }, 2); + var split = line.Split(separator, 2); return new KeyValuePair ( @@ -124,6 +125,8 @@ namespace osu.Game.Beatmaps.Formats ); } + protected string CleanFilename(string path) => path.Trim('"').ToStandardisedPath(); + protected enum Section { None, diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index c46634e72f..cbf0f8dfbd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -7,7 +7,6 @@ using System.Globalization; using System.IO; using osuTK; using osuTK.Graphics; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Game.IO; using osu.Game.Storyboards; @@ -65,12 +64,14 @@ namespace osu.Game.Beatmaps.Formats private void handleEvents(string line) { var depth = 0; + var lineSpan = line.AsSpan(); - while (line.StartsWith(" ", StringComparison.Ordinal) || line.StartsWith("_", StringComparison.Ordinal)) + while (lineSpan.StartsWith(" ", StringComparison.Ordinal) || lineSpan.StartsWith("_", StringComparison.Ordinal)) { + lineSpan = lineSpan.Slice(1); ++depth; - line = line.Substring(1); } + line = line.Substring(depth); decodeVariables(ref line); @@ -89,7 +90,7 @@ namespace osu.Game.Beatmaps.Formats { var layer = parseLayer(split[1]); var origin = parseOrigin(split[2]); - var path = cleanFilename(split[3]); + var path = CleanFilename(split[3]); var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y)); @@ -101,7 +102,7 @@ namespace osu.Game.Beatmaps.Formats { var layer = parseLayer(split[1]); var origin = parseOrigin(split[2]); - var path = cleanFilename(split[3]); + var path = CleanFilename(split[3]); var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); var frameCount = int.Parse(split[6]); @@ -116,7 +117,7 @@ namespace osu.Game.Beatmaps.Formats { var time = double.Parse(split[1], CultureInfo.InvariantCulture); var layer = parseLayer(split[2]); - var path = cleanFilename(split[3]); + var path = CleanFilename(split[3]); var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; storyboard.GetLayer(layer).Add(new StoryboardSampleInfo(path, time, (int)volume)); break; @@ -332,6 +333,5 @@ namespace osu.Game.Beatmaps.Formats } } - private string cleanFilename(string path) => path.Trim('"').ToStandardisedPath(); } } From 6658bdb223c15661bf7836d66165dacef2d07eec Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Thu, 23 Jan 2020 16:34:43 +0100 Subject: [PATCH 104/157] Fix CodeFactor issues --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index a8ec351817..965fcc03a3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -301,7 +301,7 @@ namespace osu.Game.Beatmaps.Formats { case LegacyEventType.Background: string bgFilename = split[2]; - beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(bgFilename); ; + beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(bgFilename); break; case LegacyEventType.Video: diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index cbf0f8dfbd..a7d0360f0d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -332,6 +332,5 @@ namespace osu.Game.Beatmaps.Formats break; } } - } } From 5863576ce49721bb0cad638dfdeedb997c95fa48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 11:42:33 +0900 Subject: [PATCH 105/157] Add comment as to why counter is zeroes only in Show method --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 433af5fb4e..d252083411 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -135,7 +135,9 @@ namespace osu.Game.Overlays.Comments if (!IsLoaded) return; + // only reset when changing ID/type. other refetch ops are generally just changing sort order. commentCounter.Current.Value = 0; + refetchComments(); } From 851b89128559aee63f81b6dbccfa0f50e0f5dc66 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 11:52:32 +0900 Subject: [PATCH 106/157] Fix incorrect insert logic --- .../Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index d18f6f3743..f06f6938a2 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.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.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -33,7 +34,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private const int drawable_judgement_size = 8; private const int spacing = 2; - private int runningDepth; + public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); public JudgementFlow() { @@ -47,7 +48,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public void Push(Color4 colour) { - Insert(runningDepth--, new DrawableResult(colour, drawable_judgement_size)); + Add(new DrawableResult(colour, drawable_judgement_size)); if (Children.Count > max_available_judgements) Children.FirstOrDefault(c => !c.IsRemoved)?.Remove(); From eb5abcab8c129a47f11a56f178e32f50d4a6c8aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 11:54:48 +0900 Subject: [PATCH 107/157] Rename and simplify circle logic --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index f06f6938a2..657235bfd4 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public override void OnNewJudgement(JudgementResult judgement) => judgementsFlow.Push(GetColourForHitResult(HitWindows.ResultFor(judgement.TimeOffset))); - private class JudgementFlow : FillFlowContainer + private class JudgementFlow : FillFlowContainer { private const int max_available_judgements = 20; private const int drawable_judgement_size = 8; @@ -48,46 +48,43 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public void Push(Color4 colour) { - Add(new DrawableResult(colour, drawable_judgement_size)); + Add(new HitErrorCircle(colour, drawable_judgement_size)); if (Children.Count > max_available_judgements) Children.FirstOrDefault(c => !c.IsRemoved)?.Remove(); } } - private class DrawableResult : Container + private class HitErrorCircle : Container { public bool IsRemoved { get; private set; } - private readonly CircularContainer content; + private readonly Circle circle; - public DrawableResult(Color4 colour, int size) + public HitErrorCircle(Color4 colour, int size) { Size = new Vector2(size); - Child = content = new CircularContainer + Child = circle = new Circle { RelativeSizeAxes = Axes.Both, - Masking = true, Alpha = 0, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colour - }, + 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); + + circle.FadeInFromZero(animation_duration, Easing.OutQuint); + circle.MoveToY(-DrawSize.Y); + circle.MoveToY(0, animation_duration, Easing.OutQuint); } public void Remove() { IsRemoved = true; + this.FadeOut(animation_duration, Easing.OutQuint).Expire(); } } From e4702ffe9ef809a966fdc519c4039ce9ee076f06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 13:10:02 +0900 Subject: [PATCH 108/157] Fix editor rate adjustment polluting global beatmap rate --- .../Screens/Edit/Components/PlaybackControl.cs | 17 +++++++++++++---- osu.Game/Screens/Edit/Editor.cs | 9 ++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 62d6c4648b..66df68418a 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -5,6 +5,8 @@ using System.Linq; using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,13 +27,13 @@ namespace osu.Game.Screens.Edit.Components private IAdjustableClock adjustableClock; + private readonly BindableNumber tempo = new BindableDouble(1); + [BackgroundDependencyLoader] private void load(IAdjustableClock adjustableClock) { this.adjustableClock = adjustableClock; - PlaybackTabControl tabs; - Children = new Drawable[] { playButton = new IconButton @@ -58,11 +60,18 @@ namespace osu.Game.Screens.Edit.Components RelativeSizeAxes = Axes.Both, Height = 0.5f, Padding = new MarginPadding { Left = 45 }, - Child = tabs = new PlaybackTabControl(), + Child = new PlaybackTabControl { Current = tempo }, } }; - tabs.Current.ValueChanged += tempo => Beatmap.Value.Track.Tempo.Value = tempo.NewValue; + Track?.AddAdjustment(AdjustableProperty.Tempo, tempo); + } + + protected override void Dispose(bool isDisposing) + { + Track?.RemoveAdjustment(AdjustableProperty.Tempo, tempo); + + base.Dispose(isDisposing); } protected override bool OnKeyDown(KeyDownEvent e) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8d66cef16e..eae94a3c8e 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -46,6 +46,8 @@ namespace osu.Game.Screens.Edit public override bool DisallowExternalBeatmapRulesetChanges => true; + public override bool AllowRateAdjustments => false; + [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -262,12 +264,6 @@ namespace osu.Game.Screens.Edit { } - public override void OnResuming(IScreen last) - { - base.OnResuming(last); - Beatmap.Value.Track?.Stop(); - } - public override void OnEntering(IScreen last) { base.OnEntering(last); @@ -291,7 +287,6 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.ResetSpeedAdjustments(); Beatmap.Value.Track?.Stop(); if (seekToStart) From 0e9ab8c76b843fcb35bd06d7ffd1c423549ba5f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 13:39:47 +0900 Subject: [PATCH 109/157] Rename test scene to match --- ...mposeTimeline.cs => TestSceneTimelineBlueprintContainer.cs} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename osu.Game.Tests/Visual/Editor/{TestSceneEditorComposeTimeline.cs => TestSceneTimelineBlueprintContainer.cs} (97%) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs similarity index 97% rename from osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs rename to osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs index 5b0408268f..34bf671eba 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs @@ -23,12 +23,11 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editor { [TestFixture] - public class TestSceneEditorComposeTimeline : EditorClockTestScene + public class TestSceneTimelineBlueprintContainer : EditorClockTestScene { public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), - typeof(TimelineBlueprintContainer), typeof(Timeline), typeof(TimelineButton), typeof(CentreMarker) From 997b49f6dc872f0104a9680665b5dbb92c67c91f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 14:21:22 +0900 Subject: [PATCH 110/157] Change display to always show progress bar, only hiding seeking handle instead --- .../Visual/Gameplay/TestSceneSongProgress.cs | 3 +++ osu.Game/Screens/Play/HUDOverlay.cs | 1 - osu.Game/Screens/Play/SongProgress.cs | 8 +++---- osu.Game/Screens/Play/SongProgressBar.cs | 23 ++++++++++++++++++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 0996b5b0c7..ff14846b68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -6,6 +6,9 @@ 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.Testing; using osu.Framework.Utils; using osu.Framework.Timing; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 236bdc8442..a5f8051557 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -131,7 +131,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; } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 1368158938..aa745f5ba2 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -46,7 +46,6 @@ namespace osu.Game.Screens.Play public override bool HandlePositionalInput => AllowSeeking.Value; private double firstHitTime => objects.First().StartTime; - private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1; private IEnumerable objects; @@ -92,7 +91,6 @@ namespace osu.Game.Screens.Play }, bar = new SongProgressBar(bottom_bar_height, graph_height, handle_size) { - Alpha = 0, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, OnSeek = time => RequestSeek?.Invoke(time), @@ -105,6 +103,9 @@ namespace osu.Game.Screens.Play { base.LoadComplete(); + if (clock != null) + gameplayClock = clock; + config.BindWith(OsuSetting.ShowProgressGraph, ShowGraph); graph.FillColour = bar.FillColour = colours.BlueLighter; @@ -151,8 +152,7 @@ namespace osu.Game.Screens.Play private void updateBarVisibility() { - 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); + bar.ShowHandle = AllowSeeking.Value; updateInfoMargin(); } diff --git a/osu.Game/Screens/Play/SongProgressBar.cs b/osu.Game/Screens/Play/SongProgressBar.cs index 817b703fca..5052b32335 100644 --- a/osu.Game/Screens/Play/SongProgressBar.cs +++ b/osu.Game/Screens/Play/SongProgressBar.cs @@ -21,6 +21,22 @@ namespace osu.Game.Screens.Play private readonly Container handleBase; private readonly Container handleContainer; + private bool showHandle; + + public bool ShowHandle + { + get => showHandle; + set + { + if (value == showHandle) + return; + + showHandle = value; + + handleBase.FadeTo(showHandle ? 1 : 0, 200); + } + } + public Color4 FillColour { set => fill.Colour = value; @@ -75,6 +91,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Width = 2, + Alpha = 0, Colour = Color4.White, Position = new Vector2(2, 0), Children = new Drawable[] @@ -128,7 +145,11 @@ namespace osu.Game.Screens.Play protected override void OnUserChange(double value) { scheduledSeek?.Cancel(); - scheduledSeek = Schedule(() => OnSeek?.Invoke(value)); + scheduledSeek = Schedule(() => + { + if (showHandle) + OnSeek?.Invoke(value); + }); } } } From 2187dbd0c28b43684842593aa6f4f3b9427294d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 14:37:37 +0900 Subject: [PATCH 111/157] Rename steps in test for clarity --- osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index ff14846b68..b9b13d7bd8 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.Value = true); + AddStep("allow seeking", () => progress.AllowSeeking.Value = true); AddStep("hide graph", () => progress.ShowGraph.Value = false); - AddStep("hide Bar", () => progress.AllowSeeking.Value = false); - AddStep("show bar", () => progress.AllowSeeking.Value = true); + AddStep("disallow seeking", () => progress.AllowSeeking.Value = false); + AddStep("allow seeking", () => progress.AllowSeeking.Value = true); AddStep("show graph", () => progress.ShowGraph.Value = true); AddStep("stop", clock.Stop); } From c0a233e8bb7d8a8ce8c2a6b67b6be72c09a8d57b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 15:00:10 +0900 Subject: [PATCH 112/157] Align background wedge with carousel --- osu.Game/Screens/Select/SongSelect.cs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bcb828a666..30cb66b301 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -105,11 +105,26 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.Both, Children = new[] { - new WedgeBackground + new GridContainer // used for max width implementation { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = -150 }, - Size = new Vector2(0.5f, 1), + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 850), + }, + Content = new[] + { + new Drawable[] + { + new WedgeBackground + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = -150 }, + }, + null + } + } } } }, From fdde4a6858301129ac787b4fc4990a421e09cf28 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 15:34:15 +0900 Subject: [PATCH 113/157] Tidy up song select hierarchy to be more readable --- osu.Game/Screens/Select/SongSelect.cs | 219 ++++++++++++-------------- 1 file changed, 100 insertions(+), 119 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 30cb66b301..1a29f336ea 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -88,22 +88,22 @@ namespace osu.Game.Screens.Select [Resolved(canBeNull: true)] private MusicController music { get; set; } - private const float panel_overflow = 1.2f; - [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). transferRulesetValue(); - AddRangeInternal(new[] + AddRangeInternal(new Drawable[] { - new ParallaxContainer + new ResetScrollContainer(() => Carousel.ScrollToSelected()) { - Masking = true, - ParallaxAmount = 0.005f, - RelativeSizeAxes = Axes.Both, - Children = new[] + RelativeSizeAxes = Axes.Y, + Width = 250, + }, + new VerticalMaskingContainer + { + Children = new Drawable[] { new GridContainer // used for max width implementation { @@ -117,44 +117,14 @@ namespace osu.Game.Screens.Select { new Drawable[] { - new WedgeBackground + new ParallaxContainer { + ParallaxAmount = 0.005f, RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = -150 }, - }, - null - } - } - } - } - }, - new GridContainer // used for max width implementation - { - RelativeSizeAxes = Axes.Both, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 650), - }, - Content = new[] - { - new Drawable[] - { - new Container - { - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, - - Children = new Drawable[] - { - beatmapInfoWedge = new BeatmapInfoWedge - { - Height = WEDGE_HEIGHT, - RelativeSizeAxes = Axes.X, - Margin = new MarginPadding + Child = new WedgeBackground { - Top = left_area_padding, - Right = left_area_padding, + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = -150 }, }, }, new Container @@ -162,92 +132,80 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { - Bottom = Footer.HEIGHT, - Top = WEDGE_HEIGHT + left_area_padding, - Left = left_area_padding, - Right = left_area_padding * 2, + Top = FilterControl.HEIGHT, + Bottom = Footer.HEIGHT }, + Child = Carousel = new BeatmapCarousel + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + SelectionChanged = updateSelectedBeatmap, + BeatmapSetsChanged = carouselBeatmapsLoaded, + }, + } + }, + } + }, + FilterControl = new FilterControl + { + RelativeSizeAxes = Axes.X, + Height = FilterControl.HEIGHT, + FilterChanged = ApplyFilterToCarousel, + Background = { Width = 2 }, + }, + new GridContainer // used for max width implementation + { + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 650), + }, + Content = new[] + { + new Drawable[] + { + new Container + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - BeatmapDetails = new BeatmapDetailArea + beatmapInfoWedge = new BeatmapInfoWedge + { + Height = WEDGE_HEIGHT, + RelativeSizeAxes = Axes.X, + Margin = new MarginPadding + { + Top = left_area_padding, + Right = left_area_padding, + }, + }, + new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 10, Right = 5 }, + Padding = new MarginPadding + { + Bottom = Footer.HEIGHT, + Top = WEDGE_HEIGHT + left_area_padding, + Left = left_area_padding, + Right = left_area_padding * 2, + }, + Child = BeatmapDetails = new BeatmapDetailArea + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 10, Right = 5 }, + }, }, } }, - } - }, - }, + }, + } + } } }, - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = panel_overflow, //avoid horizontal masking so the panels don't clip when screen stack is pushed. - Child = new Container - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = 1 / panel_overflow, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Top = FilterControl.HEIGHT, - Bottom = Footer.HEIGHT - }, - Children = new Drawable[] - { - new GridContainer // used for max width implementation - { - RelativeSizeAxes = Axes.Both, - ColumnDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.Relative, 0.5f, maxSize: 850), - }, - Content = new[] - { - new Drawable[] - { - null, - Carousel = new BeatmapCarousel - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Both, - SelectionChanged = updateSelectedBeatmap, - BeatmapSetsChanged = carouselBeatmapsLoaded, - }, - } - } - }, - } - }, - FilterControl = new FilterControl - { - RelativeSizeAxes = Axes.X, - Height = FilterControl.HEIGHT, - FilterChanged = ApplyFilterToCarousel, - Background = { Width = 2 }, - }, - } - }, - }, - new ResetScrollContainer(() => Carousel.ScrollToSelected()) - { - RelativeSizeAxes = Axes.Y, - Width = 250, - }, - beatmapInfoWedge.CreateProxy() }); if (ShowFooter) @@ -765,6 +723,29 @@ namespace osu.Game.Screens.Select return base.OnKeyDown(e); } + private class VerticalMaskingContainer : Container + { + private const float panel_overflow = 1.2f; + + protected override Container Content { get; } + + public VerticalMaskingContainer() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + Width = panel_overflow; //avoid horizontal masking so the panels don't clip when screen stack is pushed. + InternalChild = Content = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 1 / panel_overflow, + }; + } + } + private class ResetScrollContainer : Container { private readonly Action onHoverAction; From f9a54dfb1dc59a9e85cec3ccb1c63e46361ea911 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 16:23:41 +0900 Subject: [PATCH 114/157] Tidy up implementation and show on returning with new song --- osu.Game/Screens/Menu/MainMenu.cs | 50 +++++++++++++---------------- osu.Game/Screens/Menu/SongTicker.cs | 7 ++-- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 2de31cf399..27b87e4fa5 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -78,27 +78,6 @@ namespace osu.Game.Screens.Menu holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); - AddInternal(songTicker = new SongTicker - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = 15, Top = 5 } - }); - - if (host.CanExit) - { - AddInternal(exitConfirmOverlay = new ExitConfirmOverlay - { - Action = () => - { - if (holdDelay.Value > 0) - confirmAndExit(); - else - this.Exit(); - } - }); - } - AddRangeInternal(new Drawable[] { buttonsContainer = new ParallaxContainer @@ -117,8 +96,28 @@ namespace osu.Game.Screens.Menu } }, sideFlashes = new MenuSideFlashes(), + songTicker = new SongTicker + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = 15, Top = 5 } + } }); + if (host.CanExit) + { + AddInternal(exitConfirmOverlay = new ExitConfirmOverlay + { + Action = () => + { + if (holdDelay.Value > 0) + confirmAndExit(); + else + this.Exit(); + } + }); + } + buttons.StateChanged += state => { switch (state) @@ -236,9 +235,6 @@ namespace osu.Game.Screens.Menu buttons.State = ButtonSystemState.EnteringMode; - songTicker.FadeOut(100, Easing.OutQuint); - songTicker.AllowUpdates = false; - this.FadeOut(FADE_OUT_DURATION, Easing.InSine); buttonsContainer.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine); @@ -249,8 +245,6 @@ namespace osu.Game.Screens.Menu { base.OnResuming(last); - songTicker.AllowUpdates = true; - (Background as BackgroundScreenDefault)?.Next(); //we may have consumed our preloaded instance, so let's make another. @@ -277,8 +271,10 @@ namespace osu.Game.Screens.Menu } buttons.State = ButtonSystemState.Exit; - this.FadeOut(3000); + songTicker.Hide(); + + this.FadeOut(3000); return base.OnExiting(next); } diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index f858d162d2..c3569b7ccb 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.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 osu.Framework.Allocation; @@ -17,8 +17,6 @@ namespace osu.Game.Screens.Menu { private const int fade_duration = 800; - public bool AllowUpdates { get; set; } = true; - [Resolved] private Bindable beatmap { get; set; } @@ -58,8 +56,7 @@ namespace osu.Game.Screens.Menu private void onBeatmapChanged(ValueChangedEvent working) { - if (!AllowUpdates) - return; + var metadata = beatmap.Value.Metadata; var metadata = working.NewValue.Metadata; From 6f44f8a1ad0a64a142043ea97eb806836519df76 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 16:27:49 +0900 Subject: [PATCH 115/157] Ensure only run once when not current screen --- osu.Game/Screens/Menu/SongTicker.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index c3569b7ccb..4323d639c4 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.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 osu.Framework.Allocation; @@ -22,6 +22,8 @@ namespace osu.Game.Screens.Menu private readonly OsuSpriteText title, artist; + public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; + public SongTicker() { AutoSizeAxes = Axes.Both; @@ -51,19 +53,20 @@ namespace osu.Game.Screens.Menu protected override void LoadComplete() { base.LoadComplete(); - beatmap.BindValueChanged(onBeatmapChanged); + + beatmap.BindValueChanged(_ => Scheduler.AddOnce(show), true); } - private void onBeatmapChanged(ValueChangedEvent working) + private void show() { var metadata = beatmap.Value.Metadata; - 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); + this.FadeInFromZero(fade_duration) + .Delay(4000) + .Then().FadeOut(fade_duration); } } } From 7495cfa0a95dc4e8e54af3b11c9d299422114d7f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 16:32:31 +0900 Subject: [PATCH 116/157] Add a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene You have to have a test scene --- .../Visual/Menus/TestSceneSongTicker.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs new file mode 100644 index 0000000000..d7f23f5cc0 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs @@ -0,0 +1,36 @@ +// 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.Overlays; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual.Menus +{ + public class TestSceneSongTicker : OsuTestScene + { + [Cached] + private MusicController musicController = new MusicController(); + + public TestSceneSongTicker() + { + AddRange(new Drawable[] + { + musicController, + new SongTicker + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new NowPlayingOverlay + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + State = { Value = Visibility.Visible } + } + }); + } + } +} From 827f48c29bc8a512a1807b9e010899a0f7172c8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 16:32:39 +0900 Subject: [PATCH 117/157] Adjust fade --- osu.Game/Screens/Menu/SongTicker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index 4323d639c4..c4943e77d5 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Menu title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)); artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)); - this.FadeInFromZero(fade_duration) + this.FadeInFromZero(fade_duration / 2f) .Delay(4000) .Then().FadeOut(fade_duration); } From f9e93e2a6ae041f0a956f82aaa0768e9cb601a12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 24 Jan 2020 16:34:13 +0900 Subject: [PATCH 118/157] Fix regressed input handling order --- osu.Game/Screens/Menu/MainMenu.cs | 33 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 27b87e4fa5..b03febce31 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -78,7 +78,21 @@ namespace osu.Game.Screens.Menu holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay); loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed); - AddRangeInternal(new Drawable[] + if (host.CanExit) + { + AddInternal(exitConfirmOverlay = new ExitConfirmOverlay + { + Action = () => + { + if (holdDelay.Value > 0) + confirmAndExit(); + else + this.Exit(); + } + }); + } + + AddRangeInternal(new[] { buttonsContainer = new ParallaxContainer { @@ -101,23 +115,10 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Margin = new MarginPadding { Right = 15, Top = 5 } - } + }, + exitConfirmOverlay.CreateProxy() }); - if (host.CanExit) - { - AddInternal(exitConfirmOverlay = new ExitConfirmOverlay - { - Action = () => - { - if (holdDelay.Value > 0) - confirmAndExit(); - else - this.Exit(); - } - }); - } - buttons.StateChanged += state => { switch (state) From 28727bbafd1c7e5e3fb3bd2aabf73d47e900f24e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 17:30:37 +0900 Subject: [PATCH 119/157] Fix crash when deselecting via ctrl+click --- .../Edit/Compose/Components/BlueprintContainer.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 23f62e4eaf..165fc93b9e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -110,7 +110,6 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { beginClickSelection(e); - prepareSelectionMovement(); return e.Button == MouseButton.Left; @@ -356,21 +355,19 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Attempts to begin the movement of any selected blueprints. /// - /// Whether movement began. - private bool prepareSelectionMovement() + private void prepareSelectionMovement() { - Debug.Assert(movementBlueprint == null); + if (!selectionHandler.SelectedBlueprints.Any()) + return; // Any selected blueprint that is hovered can begin the movement of the group, however only the earliest hitobject is used for movement // A special case is added for when a click selection occurred before the drag if (!clickSelectionBegan && !selectionHandler.SelectedBlueprints.Any(b => b.IsHovered)) - return false; + return; // Movement is tracked from the blueprint of the earliest hitobject, since it only makes sense to distance snap from that hitobject movementBlueprint = selectionHandler.SelectedBlueprints.OrderBy(b => b.HitObject.StartTime).First(); movementBlueprintOriginalPosition = movementBlueprint.SelectionPoint; // todo: unsure if correct - - return true; } /// From 6fc6a376ee285700940fcfbebac3da349e312d99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 17:50:09 +0900 Subject: [PATCH 120/157] Fix incorrect slider selection point --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 4fdead512a..c18b3b0ff3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 SelectionPoint => HeadBlueprint.SelectionPoint; + public override Vector2 SelectionPoint => ((DrawableSlider)DrawableObject).HeadCircle.ScreenSpaceDrawQuad.Centre; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos); From 811ddb02a4bca157bcb17b5fee4adbeb11415fd0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 17:50:36 +0900 Subject: [PATCH 121/157] General refactoring --- .../Blueprints/Sliders/SliderCircleSelectionBlueprint.cs | 1 + .../Visual/Editor/TestSceneTimelineBlueprintContainer.cs | 2 +- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 6 +++--- .../Components/Timeline/TimelineBlueprintContainer.cs | 6 +++--- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs index f09279ed73..a0392fe536 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleSelectionBlueprint.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders : base(slider) { this.position = position; + InternalChild = CirclePiece = new HitCirclePiece(); Select(); diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs index 34bf671eba..e7b2508ac7 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Editor }, new TimelineArea { - Child = new TimelineBlueprintContainer(editorBeatmap), + Child = new TimelineBlueprintContainer(), Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 165fc93b9e..6b21f56567 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -83,9 +83,6 @@ namespace osu.Game.Screens.Edit.Compose.Components }; } - protected virtual Container CreateSelectionBlueprintContainer() => - new Container { RelativeSizeAxes = Axes.Both }; - protected override void LoadComplete() { base.LoadComplete(); @@ -94,6 +91,9 @@ namespace osu.Game.Screens.Edit.Compose.Components beatmap.HitObjectRemoved += removeBlueprintFor; } + protected virtual Container CreateSelectionBlueprintContainer() => + new Container { RelativeSizeAxes = Axes.Both }; + /// /// Creates a which outlines s and handles movement of selections. /// diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 6bfd323c13..3b9cb1df24 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private DragEvent lastDragEvent; - public TimelineBlueprintContainer(EditorBeatmap beatmap) + public TimelineBlueprintContainer() { RelativeSizeAxes = Axes.Both; Anchor = Anchor.Centre; @@ -39,14 +39,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }); } - protected override Container CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; - protected override void LoadComplete() { base.LoadComplete(); DragBox.Alpha = 0; } + protected override Container CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; + protected override void OnDrag(DragEvent e) { if (timeline != null) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 20e1ef95d3..cdea200e10 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -32,6 +32,6 @@ namespace osu.Game.Screens.Edit.Compose return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(composer)); } - protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineBlueprintContainer(EditorBeatmap); + protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineBlueprintContainer(); } } From 027778acc1dff50fcfd04ff116f0b94daf732a25 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 17:51:24 +0900 Subject: [PATCH 122/157] Fix slider circles not being selected by default --- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 39 ++++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 9998254f76..a972d28480 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -41,14 +41,15 @@ namespace osu.Game.Rulesets.Edit protected SelectionBlueprint(HitObject hitObject) { HitObject = hitObject; + RelativeSizeAxes = Axes.Both; + AlwaysPresent = true; } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { - OnDeselected(); - AlwaysPresent = true; + base.LoadComplete(); + updateState(); } private SelectionState state; @@ -65,23 +66,29 @@ namespace osu.Game.Rulesets.Edit state = value; - switch (state) - { - case SelectionState.Selected: - OnSelected(); - Selected?.Invoke(this); - break; - - case SelectionState.NotSelected: - OnDeselected(); - Deselected?.Invoke(this); - break; - } + if (IsLoaded) + updateState(); StateChanged?.Invoke(state); } } + private void updateState() + { + switch (state) + { + case SelectionState.Selected: + OnSelected(); + Selected?.Invoke(this); + break; + + case SelectionState.NotSelected: + OnDeselected(); + Deselected?.Invoke(this); + break; + } + } + protected virtual void OnDeselected() => Hide(); protected virtual void OnSelected() => Show(); From db4cd51d020cc768d5131d5e1f47456d47cead94 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 24 Jan 2020 12:24:35 +0300 Subject: [PATCH 123/157] Implement OverlayColourProvider --- osu.Game/Graphics/OsuColour.cs | 51 ----------- osu.Game/Overlays/BeatmapSetOverlay.cs | 1 + osu.Game/Overlays/ChangelogOverlay.cs | 5 ++ osu.Game/Overlays/DirectOverlay.cs | 1 + osu.Game/Overlays/FullscreenOverlay.cs | 17 +++- osu.Game/Overlays/NewsOverlay.cs | 5 ++ osu.Game/Overlays/OverlayColourProvider.cs | 90 +++++++++++++++++++ osu.Game/Overlays/RankingsOverlay.cs | 1 + .../SearchableList/SearchableListOverlay.cs | 8 +- osu.Game/Overlays/SocialOverlay.cs | 1 + osu.Game/Overlays/UserProfileOverlay.cs | 5 ++ 11 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 osu.Game/Overlays/OverlayColourProvider.cs diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 53a40f5613..c8298543a1 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Beatmaps; -using osuTK; using osuTK.Graphics; namespace osu.Game.Graphics @@ -78,46 +77,6 @@ namespace osu.Game.Graphics } } - public Color4 ForOverlayElement(OverlayColourScheme colourScheme, float saturation, float lightness, float opacity = 1) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, opacity)); - - // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 - private static float getBaseHue(OverlayColourScheme colourScheme) - { - float hue; - - switch (colourScheme) - { - default: - throw new ArgumentException($@"{colourScheme} colour scheme does not provide a hue value in {nameof(getBaseHue)}."); - - case OverlayColourScheme.Red: - hue = 0; - break; - - case OverlayColourScheme.Pink: - hue = 333; - break; - - case OverlayColourScheme.Orange: - hue = 46; - break; - - case OverlayColourScheme.Green: - hue = 115; - break; - - case OverlayColourScheme.Purple: - hue = 255; - break; - - case OverlayColourScheme.Blue: - hue = 200; - break; - } - - return hue / 360f; - } - // See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less public readonly Color4 PurpleLighter = FromHex(@"eeeeff"); public readonly Color4 PurpleLight = FromHex(@"aa88ff"); @@ -220,14 +179,4 @@ namespace osu.Game.Graphics public readonly Color4 ContextMenuGray = FromHex(@"223034"); } - - public enum OverlayColourScheme - { - Red, - Pink, - Orange, - Green, - Purple, - Blue - } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 50fb2782d4..e4e928df18 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public BeatmapSetOverlay() + : base(OverlayColourScheme.Blue) { OsuScrollContainer scroll; Info info; diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 15b0079277..e2186df64c 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -36,6 +36,11 @@ namespace osu.Game.Overlays private List streams; + public ChangelogOverlay() + : base(OverlayColourScheme.Purple) + { + } + [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colour) { diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 9daf55c796..c718ca7a1e 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -84,6 +84,7 @@ namespace osu.Game.Overlays } public DirectOverlay() + : base(OverlayColourScheme.Blue) { // osu!direct colours are not part of the standard palette diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 0911ee84de..662188cbfd 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -18,8 +18,12 @@ namespace osu.Game.Overlays [Resolved] protected IAPIProvider API { get; private set; } - protected FullscreenOverlay() + private readonly OverlayColourScheme colourScheme; + + protected FullscreenOverlay(OverlayColourScheme colourScheme) { + this.colourScheme = colourScheme; + Waves.FirstWaveColour = OsuColour.Gray(0.4f); Waves.SecondWaveColour = OsuColour.Gray(0.3f); Waves.ThirdWaveColour = OsuColour.Gray(0.2f); @@ -41,6 +45,17 @@ namespace osu.Game.Overlays }; } + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + + [BackgroundDependencyLoader] + private void load() + { + dependencies.Cache(new OverlayColourProvider(colourScheme)); + } + public override void Show() { if (State.Value == Visibility.Visible) diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index e7471cb21d..6dde300556 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -21,6 +21,11 @@ namespace osu.Game.Overlays public readonly Bindable Current = new Bindable(null); + public NewsOverlay() + : base(OverlayColourScheme.Purple) + { + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs new file mode 100644 index 0000000000..1223b8d064 --- /dev/null +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -0,0 +1,90 @@ +// 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 osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public class OverlayColourProvider + { + private readonly OverlayColourScheme colourScheme; + + public OverlayColourProvider(OverlayColourScheme colourScheme) + { + this.colourScheme = colourScheme; + } + + private Color4 convert(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + + // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 + private static float getBaseHue(OverlayColourScheme colourScheme) + { + float hue; + + switch (colourScheme) + { + default: + throw new ArgumentException($@"{colourScheme} colour scheme does not provide a hue value in {nameof(getBaseHue)}."); + + case OverlayColourScheme.Red: + hue = 0; + break; + + case OverlayColourScheme.Pink: + hue = 333; + break; + + case OverlayColourScheme.Orange: + hue = 46; + break; + + case OverlayColourScheme.Green: + hue = 115; + break; + + case OverlayColourScheme.Purple: + hue = 255; + break; + + case OverlayColourScheme.Blue: + hue = 200; + break; + } + + return hue / 360f; + } + + public Color4 Highlight1 => convert(1, 0.7f); + public Color4 Content1 => convert(0.4f, 1); + public Color4 Content2 => convert(0.4f, 0.9f); + public Color4 Link1 => convert(0.4f, 0.8f); + public Color4 Link2 => convert(0.4f, 0.75f); + public Color4 Link3 => convert(0.4f, 0.7f); + public Color4 Link4 => convert(0.4f, 0.5f); + public Color4 Dark1 => convert(0.2f, 0.35f); + public Color4 Dark2 => convert(0.2f, 0.3f); + public Color4 Dark3 => convert(0.2f, 0.25f); + public Color4 Dark4 => convert(0.2f, 0.20f); + public Color4 Dark5 => convert(0.2f, 0.15f); + public Color4 Dark6 => convert(0.2f, 0.1f); + public Color4 Foreground1 => convert(0.1f, 0.6f); + public Color4 Background1 => convert(0.1f, 0.4f); + public Color4 Background2 => convert(0.1f, 0.3f); + public Color4 Background3 => convert(0.1f, 0.25f); + public Color4 Background4 => convert(0.1f, 0.2f); + public Color4 Background5 => convert(0.1f, 0.15f); + public Color4 Background6 => convert(0.1f, 0.1f); + } + + public enum OverlayColourScheme + { + Red, + Pink, + Orange, + Green, + Purple, + Blue + } +} diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index c8874ef891..2297925e5c 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -36,6 +36,7 @@ namespace osu.Game.Overlays private IAPIProvider api { get; set; } public RankingsOverlay() + : base(OverlayColourScheme.Green) { Children = new Drawable[] { diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs index 5975e94ffc..0783c64c20 100644 --- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs +++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs @@ -16,6 +16,11 @@ namespace osu.Game.Overlays.SearchableList public abstract class SearchableListOverlay : FullscreenOverlay { public const float WIDTH_PADDING = 80; + + protected SearchableListOverlay(OverlayColourScheme colourScheme) + : base(colourScheme) + { + } } public abstract class SearchableListOverlay : SearchableListOverlay @@ -35,7 +40,8 @@ namespace osu.Game.Overlays.SearchableList protected abstract SearchableListHeader CreateHeader(); protected abstract SearchableListFilterControl CreateFilterControl(); - protected SearchableListOverlay() + protected SearchableListOverlay(OverlayColourScheme colourScheme) + : base(colourScheme) { Children = new Drawable[] { diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 0c99962def..27bef7145b 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -52,6 +52,7 @@ namespace osu.Game.Overlays } public SocialOverlay() + : base(OverlayColourScheme.Pink) { Waves.FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); Waves.SecondWaveColour = OsuColour.FromHex(@"b04384"); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index a34fc619a8..07c0dbed43 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -29,6 +29,11 @@ namespace osu.Game.Overlays public const float CONTENT_X_MARGIN = 70; + public UserProfileOverlay() + : base(OverlayColourScheme.Green) + { + } + public void ShowUser(long userId) => ShowUser(new User { Id = userId }); public void ShowUser(User user, bool fetchOnline = true) From e03a085d7071228941d0f1f20fd90d57806fc32c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 24 Jan 2020 12:33:34 +0300 Subject: [PATCH 124/157] Make overlay elements use OverlayColourProvider --- .../Overlays/BreadcrumbControlOverlayHeader.cs | 10 ++-------- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 -- osu.Game/Overlays/News/NewsHeader.cs | 1 - osu.Game/Overlays/OverlayColourProvider.cs | 2 +- osu.Game/Overlays/OverlayHeader.cs | 14 +++++--------- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 - osu.Game/Overlays/TabControlOverlayHeader.cs | 9 ++------- 7 files changed, 10 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index 2e50c19729..c3f35b4313 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays @@ -15,15 +14,10 @@ namespace osu.Game.Overlays protected override TabControl CreateTabControl() => BreadcrumbControl = new OverlayHeaderBreadcrumbControl(); - protected BreadcrumbControlOverlayHeader(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - BreadcrumbControl.AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.75f); + BreadcrumbControl.AccentColour = colourProvider.Highlight1; } public class OverlayHeaderBreadcrumbControl : BreadcrumbControl diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index d5e0890b4d..70a45f2667 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; @@ -26,7 +25,6 @@ namespace osu.Game.Overlays.Changelog private const string listing_string = "listing"; public ChangelogHeader() - : base(OverlayColourScheme.Purple) { BreadcrumbControl.AddItem(listing_string); BreadcrumbControl.Current.ValueChanged += e => diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 03dc64b3bd..457c5a19ba 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -23,7 +23,6 @@ namespace osu.Game.Overlays.News public Action ShowFrontPage; public NewsHeader() - : base(OverlayColourScheme.Purple) { BreadcrumbControl.AddItem(front_page_string); diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index 1223b8d064..e92a231bc1 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -66,7 +66,7 @@ namespace osu.Game.Overlays public Color4 Dark1 => convert(0.2f, 0.35f); public Color4 Dark2 => convert(0.2f, 0.3f); public Color4 Dark3 => convert(0.2f, 0.25f); - public Color4 Dark4 => convert(0.2f, 0.20f); + public Color4 Dark4 => convert(0.2f, 0.2f); public Color4 Dark5 => convert(0.2f, 0.15f); public Color4 Dark6 => convert(0.2f, 0.1f); public Color4 Foreground1 => convert(0.1f, 0.6f); diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index c9547bb5b8..2578f6a3bd 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -25,12 +25,8 @@ namespace osu.Game.Overlays set => background.Height = value; } - protected OverlayColourScheme ColourScheme { get; } - - protected OverlayHeader(OverlayColourScheme colourScheme) + protected OverlayHeader() { - ColourScheme = colourScheme; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -89,11 +85,11 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - titleBackground.Colour = colours.ForOverlayElement(ColourScheme, 0.2f, 0.15f); - title.AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); - controlBackground.Colour = colours.ForOverlayElement(ColourScheme, 0.2f, 0.2f); + titleBackground.Colour = colourProvider.Dark5; + title.AccentColour = colourProvider.Highlight1; + controlBackground.Colour = colourProvider.Dark4; } protected abstract Drawable CreateBackground(); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index b550d7d823..f8eb03770a 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -24,7 +24,6 @@ namespace osu.Game.Overlays.Profile private DetailHeaderContainer detailHeaderContainer; public ProfileHeader() - : base(OverlayColourScheme.Green) { BackgroundHeight = 150; diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index 8f3aa896ee..0c55b8383b 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -16,15 +16,10 @@ namespace osu.Game.Overlays protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl(); - protected TabControlOverlayHeader(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - TabControl.AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.75f); + TabControl.AccentColour = colourProvider.Highlight1; } public class OverlayHeaderTabControl : OverlayTabControl From 59ff3aa800648663d6c30a7db6632380866d9290 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 24 Jan 2020 12:42:48 +0300 Subject: [PATCH 125/157] Fix tests --- osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs | 1 + osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs index fe8437be17..e60adcee34 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs @@ -41,6 +41,7 @@ namespace osu.Game.Tests.Visual.Online private class TestFullscreenOverlay : FullscreenOverlay { public TestFullscreenOverlay() + : base(OverlayColourScheme.Pink) { Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 63b46c991f..f825e4f1e9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -31,6 +31,9 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileHeaderButton) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + [Resolved] private IAPIProvider api { get; set; } From d9af43da4c231e21f03ddadd2a541aa3d1a55132 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 24 Jan 2020 12:55:51 +0300 Subject: [PATCH 126/157] Remove unused usings --- osu.Game/Overlays/News/NewsHeader.cs | 1 - osu.Game/Overlays/OverlayHeader.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 457c5a19ba..1152d9044b 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using System; diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 2578f6a3bd..bc58a17401 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osuTK.Graphics; From 9e0e7be8d09b2c8d449a7ebb138e8c4e90a8c6bb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 18:57:17 +0900 Subject: [PATCH 127/157] Modernise filter implementation --- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 2 +- osu.Game/Screens/Select/FilterControl.cs | 10 +++++++--- osu.Game/Screens/Select/FilterCriteria.cs | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index d50154485a..2ffb73f226 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Select.Carousel match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(Beatmap.Metadata.Artist) || criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode); - match &= Beatmap.StarDifficulty >= criteria.DisplayStarsMinimum && Beatmap.StarDifficulty <= criteria.DisplayStarsMaximum; + match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(Beatmap.StarDifficulty); if (match) { diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 88a48a54fc..c851b201d7 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -42,11 +42,15 @@ namespace osu.Game.Screens.Select Group = groupMode.Value, Sort = sortMode.Value, AllowConvertedBeatmaps = showConverted.Value, - Ruleset = ruleset.Value - DisplayStarsMinimum = minimumStars, - DisplayStarsMaximum = maximumStars, + Ruleset = ruleset.Value, }; + if (!minimumStars.IsDefault) + criteria.UserStarDifficulty.Min = minimumStars.Value; + + if (!maximumStars.IsDefault) + criteria.UserStarDifficulty.Max = maximumStars.Value; + FilterQueryParser.ApplyQueries(criteria, query); return criteria; } diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index fb41c1d09a..27d9adc386 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -25,13 +25,12 @@ namespace osu.Game.Screens.Select public OptionalRange OnlineStatus; public OptionalTextFilter Creator; public OptionalTextFilter Artist; + public OptionalRange UserStarDifficulty; public string[] SearchTerms = Array.Empty(); public RulesetInfo Ruleset; public bool AllowConvertedBeatmaps; - public double DisplayStarsMinimum; - public double DisplayStarsMaximum; private string searchText; From 62fa619ad43fc9161f9a733ff2a9d6d057817b75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:08:14 +0900 Subject: [PATCH 128/157] Display "no limit" for maximum stars --- .../Settings/Sections/Gameplay/SongSelectSettings.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index a5f56ae76e..78f12c0695 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay KeyboardStep = 0.1f, Keywords = new[] { "star", "difficulty" } }, - new SettingsSlider + new SettingsSlider { LabelText = "up to", Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum), @@ -49,6 +49,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }; } + private class MaximumStarsSlider : StarSlider + { + public override string TooltipText => Current.IsDefault ? "no limit" : base.TooltipText; + } + private class StarSlider : OsuSliderBar { public override string TooltipText => Current.Value.ToString(@"0.## stars"); From 2643b6fca3b1d3695bcb53731c81b9cc4dfb2e73 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:12:48 +0900 Subject: [PATCH 129/157] Add additional keywods --- .../Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index 78f12c0695..b01aa1e297 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -32,14 +32,14 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Display beatmaps from", Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum), KeyboardStep = 0.1f, - Keywords = new[] { "star", "difficulty" } + Keywords = new[] { "minimum", "star", "difficulty" } }, new SettingsSlider { LabelText = "up to", Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum), KeyboardStep = 0.1f, - Keywords = new[] { "star", "difficulty" } + Keywords = new[] { "maximum", "star", "difficulty" } }, new SettingsEnumDropdown { From ed66ee3ba6904beb011a885e3266dd47f6d81aae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:12:56 +0900 Subject: [PATCH 130/157] Allow 10.0 stars to be selectable --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 7e4ab58e36..4155381790 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -24,7 +24,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ShowConvertedBeatmaps, true); Set(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1); - Set(OsuSetting.DisplayStarsMaximum, 10.0, 0, 10, 0.1); + Set(OsuSetting.DisplayStarsMaximum, 10.1, 0, 10.1, 0.1); Set(OsuSetting.SongSelectGroupingMode, GroupMode.All); Set(OsuSetting.SongSelectSortingMode, SortMode.Title); From 45a25214ab401b73c5f55e8aa6aefa614fe8c8db Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:39:21 +0900 Subject: [PATCH 131/157] Make upper and lower bounds inclusive --- osu.Game/Screens/Select/FilterCriteria.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index 27d9adc386..9fa57af01d 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -25,7 +25,12 @@ namespace osu.Game.Screens.Select public OptionalRange OnlineStatus; public OptionalTextFilter Creator; public OptionalTextFilter Artist; - public OptionalRange UserStarDifficulty; + + public OptionalRange UserStarDifficulty = new OptionalRange + { + IsLowerInclusive = true, + IsUpperInclusive = true + }; public string[] SearchTerms = Array.Empty(); From bb390b4470df1e5c6536da9740edc6698bfd2354 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:40:20 +0900 Subject: [PATCH 132/157] Add test --- .../SongSelect/TestSceneBeatmapCarousel.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 132b104afb..71ae47dc66 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -437,6 +437,53 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selection was random", () => eagerSelectedIDs.Count > 1); } + [Test] + public void TestFilteringByUserStarDifficulty() + { + BeatmapSetInfo set = null; + + loadBeatmaps(new List()); + + AddStep("add mixed difficulty set", () => + { + set = createTestBeatmapSet(1); + set.Beatmaps.Clear(); + + for (int i = 1; i <= 15; i++) + { + set.Beatmaps.Add(new BeatmapInfo + { + Version = $"Stars: {i}", + StarDifficulty = i, + }); + } + + carousel.UpdateBeatmapSet(set); + }); + + AddStep("select added set", () => carousel.SelectBeatmap(set.Beatmaps[0], false)); + + AddStep("filter [5..]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 5 } })); + AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask); + checkVisibleItemCount(true, 11); + + AddStep("filter to [0..7]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Max = 7 } })); + AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask); + checkVisibleItemCount(true, 7); + + AddStep("filter to [5..7]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 5, Max = 7 } })); + AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask); + checkVisibleItemCount(true, 3); + + AddStep("filter [2..2]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 2, Max = 2 } })); + AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask); + checkVisibleItemCount(true, 1); + + AddStep("filter to [0..]", () => carousel.Filter(new FilterCriteria { UserStarDifficulty = { Min = 0 } })); + AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask); + checkVisibleItemCount(true, 15); + } + private void loadBeatmaps(List beatmapSets = null) { createCarousel(); From 75d0fd0bab1ca0a00308bca0f459cb242024ed37 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:43:23 +0900 Subject: [PATCH 133/157] Rename class --- .../Settings/Sections/Gameplay/SongSelectSettings.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index b01aa1e297..de67d55184 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Show converted beatmaps", Bindable = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), }, - new SettingsSlider + new SettingsSlider { LabelText = "Display beatmaps from", Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum), @@ -49,12 +49,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }; } - private class MaximumStarsSlider : StarSlider + private class MaximumStarsSlider : StarsSlider { public override string TooltipText => Current.IsDefault ? "no limit" : base.TooltipText; } - private class StarSlider : OsuSliderBar + private class StarsSlider : OsuSliderBar { public override string TooltipText => Current.Value.ToString(@"0.## stars"); } From d1684a3c92513e7e0af59d3452a98afffaff79aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 24 Jan 2020 19:50:16 +0900 Subject: [PATCH 134/157] Duplicate keywords for better UX --- .../Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index de67d55184..e03c247b6c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -32,14 +32,14 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Display beatmaps from", Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum), KeyboardStep = 0.1f, - Keywords = new[] { "minimum", "star", "difficulty" } + Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsSlider { LabelText = "up to", Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum), KeyboardStep = 0.1f, - Keywords = new[] { "maximum", "star", "difficulty" } + Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsEnumDropdown { From bc75290655b222d073fc58ea99cd2525dfb72656 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 25 Jan 2020 00:11:20 +0900 Subject: [PATCH 135/157] Ensure min and max stars are correctly ordered --- .../Settings/Sections/Gameplay/SongSelectSettings.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index e03c247b6c..0c42247993 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -1,7 +1,9 @@ // 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.Game.Configuration; using osu.Game.Graphics.UserInterface; @@ -10,11 +12,20 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { public class SongSelectSettings : SettingsSubsection { + private Bindable minStars; + private Bindable maxStars; + protected override string Header => "Song Select"; [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + minStars = config.GetBindable(OsuSetting.DisplayStarsMinimum); + maxStars = config.GetBindable(OsuSetting.DisplayStarsMaximum); + + minStars.ValueChanged += min => maxStars.Value = Math.Max(min.NewValue, maxStars.Value); + maxStars.ValueChanged += max => minStars.Value = Math.Min(max.NewValue, minStars.Value); + Children = new Drawable[] { new SettingsCheckbox From 219e14baa2e0f7a9a63be5a78f418c5e826d6c71 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Fri, 24 Jan 2020 17:05:27 +0100 Subject: [PATCH 136/157] Address review and fix InspectCode --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 ++---- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 965fcc03a3..009da0656b 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -300,13 +300,11 @@ namespace osu.Game.Beatmaps.Formats switch (type) { case LegacyEventType.Background: - string bgFilename = split[2]; - beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(bgFilename); + beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[2]); break; case LegacyEventType.Video: - string videoFilename = split[2]; - beatmap.BeatmapInfo.Metadata.VideoFile = CleanFilename(videoFilename); + beatmap.BeatmapInfo.Metadata.VideoFile = CleanFilename(split[2]); break; case LegacyEventType.Break: diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index a7d0360f0d..9ba4d7b05e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -71,6 +71,7 @@ namespace osu.Game.Beatmaps.Formats lineSpan = lineSpan.Slice(1); ++depth; } + line = line.Substring(depth); decodeVariables(ref line); From fa595e07a65907e66cb2e37b31c7e76ab5cb62f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 25 Jan 2020 12:44:48 +0900 Subject: [PATCH 137/157] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 2ccba60424..5497a82a7a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9b431e6425..0ea558bbc7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 4dc7403553..a215bc65e8 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 73e822e08db765e1a3fbc1f1fdea8bab88d029df Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 25 Jan 2020 06:46:54 +0300 Subject: [PATCH 138/157] Make waves colour dependent on overlay colour scheme --- osu.Game/Overlays/ChangelogOverlay.cs | 5 ----- osu.Game/Overlays/DirectOverlay.cs | 7 ------- osu.Game/Overlays/FullscreenOverlay.cs | 14 +++++++------- osu.Game/Overlays/RankingsOverlay.cs | 15 ++------------- osu.Game/Overlays/SocialOverlay.cs | 5 ----- 5 files changed, 9 insertions(+), 37 deletions(-) diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index e2186df64c..412e29735a 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -44,11 +44,6 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colour) { - Waves.FirstWaveColour = colour.GreyVioletLight; - Waves.SecondWaveColour = colour.GreyViolet; - Waves.ThirdWaveColour = colour.GreyVioletDark; - Waves.FourthWaveColour = colour.GreyVioletDarker; - Children = new Drawable[] { new Box diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index c718ca7a1e..e4cef319fe 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -86,13 +86,6 @@ namespace osu.Game.Overlays public DirectOverlay() : base(OverlayColourScheme.Blue) { - // osu!direct colours are not part of the standard palette - - Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2"); - Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2"); - Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); - Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); - ScrollFlow.Children = new Drawable[] { resultCountsContainer = new FillFlowContainer diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 662188cbfd..c391947ccb 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -6,7 +6,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osuTK.Graphics; @@ -24,11 +23,6 @@ namespace osu.Game.Overlays { this.colourScheme = colourScheme; - Waves.FirstWaveColour = OsuColour.Gray(0.4f); - Waves.SecondWaveColour = OsuColour.Gray(0.3f); - Waves.ThirdWaveColour = OsuColour.Gray(0.2f); - Waves.FourthWaveColour = OsuColour.Gray(0.1f); - RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; Width = 0.85f; @@ -53,7 +47,13 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - dependencies.Cache(new OverlayColourProvider(colourScheme)); + OverlayColourProvider colourProvider; + dependencies.Cache(colourProvider = new OverlayColourProvider(colourScheme)); + + Waves.FirstWaveColour = colourProvider.Highlight1; + Waves.SecondWaveColour = colourProvider.Link4; + Waves.ThirdWaveColour = colourProvider.Dark3; + Waves.FourthWaveColour = colourProvider.Dark1; } public override void Show() diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 2297925e5c..1ab18b8c15 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays private readonly Bindable ruleset = new Bindable(); private readonly BasicScrollContainer scrollFlow; - private readonly Box background; private readonly Container tableContainer; private readonly DimmedLoadingLayer loading; @@ -40,9 +39,10 @@ namespace osu.Game.Overlays { Children = new Drawable[] { - background = new Box + new Box { RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.1f), }, scrollFlow = new BasicScrollContainer { @@ -86,17 +86,6 @@ namespace osu.Game.Overlays }; } - [BackgroundDependencyLoader] - private void load(OsuColour colour) - { - Waves.FirstWaveColour = colour.Green; - Waves.SecondWaveColour = colour.GreenLight; - Waves.ThirdWaveColour = colour.GreenDark; - Waves.FourthWaveColour = colour.GreenDarker; - - background.Colour = OsuColour.Gray(0.1f); - } - protected override void LoadComplete() { Country.BindValueChanged(_ => diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 27bef7145b..9a523bc1bc 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -54,11 +54,6 @@ namespace osu.Game.Overlays public SocialOverlay() : base(OverlayColourScheme.Pink) { - Waves.FirstWaveColour = OsuColour.FromHex(@"cb5fa0"); - Waves.SecondWaveColour = OsuColour.FromHex(@"b04384"); - Waves.ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); - Waves.FourthWaveColour = OsuColour.FromHex(@"6d214d"); - Add(loading = new LoadingAnimation()); Filter.Search.Current.ValueChanged += text => From 9a960a60e37fe69cb6140ca9fdb78f949b077b8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 25 Jan 2020 17:08:24 +0900 Subject: [PATCH 139/157] Remove build target from Fastfile --- fastlane/Fastfile | 1 - 1 file changed, 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 28a83fbbae..510b53054b 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -111,7 +111,6 @@ platform :ios do souyuz( platform: "ios", - build_target: "osu_iOS", plist_path: "../osu.iOS/Info.plist" ) end From 8aec9e450089d874caf812153c7dd7025621018a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 25 Jan 2020 11:41:26 +0300 Subject: [PATCH 140/157] Fix NullReferenceException on main menu for mobile game hsots --- 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 b03febce31..cb5ceefb0f 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Menu Origin = Anchor.TopRight, Margin = new MarginPadding { Right = 15, Top = 5 } }, - exitConfirmOverlay.CreateProxy() + exitConfirmOverlay?.CreateProxy() ?? Drawable.Empty() }); buttons.StateChanged += state => From d2a032ca8d84453fc35cf54123dfda7dd8070c39 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sat, 25 Jan 2020 22:16:21 +0100 Subject: [PATCH 141/157] Move reverse-order comparer to ChannelTabControl --- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 14 -------------- osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 6a7998d5fb..1bfbee4a60 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -10,7 +10,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -84,14 +83,6 @@ namespace osu.Game.Graphics.UserInterface set => strip.Colour = value; } - protected override TabFillFlowContainer CreateTabFlow() => new OsuTabFillFlowContainer - { - Direction = FillDirection.Full, - RelativeSizeAxes = Axes.Both, - Depth = -1, - Masking = true - }; - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -283,10 +274,5 @@ namespace osu.Game.Graphics.UserInterface } } } - - private class OsuTabFillFlowContainer : TabFillFlowContainer - { - protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - } } } diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs index 2e4d8ce729..104495ae01 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs @@ -9,6 +9,7 @@ using osuTK; using System; using System.Linq; using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.Chat.Tabs { @@ -113,5 +114,18 @@ namespace osu.Game.Overlays.Chat.Tabs OnRequestLeave?.Invoke(tab.Value); } + + protected override TabFillFlowContainer CreateTabFlow() => new ChannelTabFillFlowContainer + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.Both, + Depth = -1, + Masking = true + }; + + private class ChannelTabFillFlowContainer : TabFillFlowContainer + { + protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); + } } } From eabb5a870175e6f59fb86b9039c7a77d6cd832ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Jan 2020 17:40:38 +0900 Subject: [PATCH 142/157] Use ToString instead of Substring --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 9ba4d7b05e..35576e0f33 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -72,7 +72,7 @@ namespace osu.Game.Beatmaps.Formats ++depth; } - line = line.Substring(depth); + line = lineSpan.ToString(); decodeVariables(ref line); From bd7c137394e5f2f7c4377d575b83b6df8f09f43e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Jan 2020 18:31:01 +0900 Subject: [PATCH 143/157] Remap osu!mania dual stage key bindings to be more ergonomic --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 02c2158383..b7b523a94d 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -237,19 +237,19 @@ namespace osu.Game.Rulesets.Mania { LeftKeys = new[] { - InputKey.Number1, - InputKey.Number2, - InputKey.Number3, - InputKey.Number4, + InputKey.Q, + InputKey.W, + InputKey.E, + InputKey.R, }, RightKeys = new[] { - InputKey.Z, InputKey.X, InputKey.C, - InputKey.V + InputKey.V, + InputKey.B }, - SpecialKey = InputKey.Tilde, + SpecialKey = InputKey.S, SpecialAction = ManiaAction.Special1, NormalActionStart = ManiaAction.Key1 }.GenerateKeyBindingsFor(keys, out var nextNormal); @@ -265,12 +265,12 @@ namespace osu.Game.Rulesets.Mania }, RightKeys = new[] { - InputKey.O, - InputKey.P, - InputKey.BracketLeft, - InputKey.BracketRight + InputKey.K, + InputKey.L, + InputKey.Semicolon, + InputKey.Quote }, - SpecialKey = InputKey.BackSlash, + SpecialKey = InputKey.I, SpecialAction = ManiaAction.Special2, NormalActionStart = nextNormal }.GenerateKeyBindingsFor(keys, out _); From 406bc23fdeea4955de909fb4d1cd30371e032ba7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 12:38:20 +0300 Subject: [PATCH 144/157] Rename incorrect colours --- osu.Game/Overlays/FullscreenOverlay.cs | 2 +- osu.Game/Overlays/OverlayColourProvider.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index c391947ccb..8a8a53e042 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -51,7 +51,7 @@ namespace osu.Game.Overlays dependencies.Cache(colourProvider = new OverlayColourProvider(colourScheme)); Waves.FirstWaveColour = colourProvider.Highlight1; - Waves.SecondWaveColour = colourProvider.Link4; + Waves.SecondWaveColour = colourProvider.Light4; Waves.ThirdWaveColour = colourProvider.Dark3; Waves.FourthWaveColour = colourProvider.Dark1; } diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index e92a231bc1..dd756d4b3f 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -59,10 +59,10 @@ namespace osu.Game.Overlays public Color4 Highlight1 => convert(1, 0.7f); public Color4 Content1 => convert(0.4f, 1); public Color4 Content2 => convert(0.4f, 0.9f); - public Color4 Link1 => convert(0.4f, 0.8f); - public Color4 Link2 => convert(0.4f, 0.75f); - public Color4 Link3 => convert(0.4f, 0.7f); - public Color4 Link4 => convert(0.4f, 0.5f); + public Color4 Light1 => convert(0.4f, 0.8f); + public Color4 Light2 => convert(0.4f, 0.75f); + public Color4 Light3 => convert(0.4f, 0.7f); + public Color4 Light4 => convert(0.4f, 0.5f); public Color4 Dark1 => convert(0.2f, 0.35f); public Color4 Dark2 => convert(0.2f, 0.3f); public Color4 Dark3 => convert(0.2f, 0.25f); From 6dee287a82c28a5bdfcc097c9d74f98370b9c691 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 12:39:15 +0300 Subject: [PATCH 145/157] Move private methods below public --- osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index dd756d4b3f..b548522538 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,6 +16,27 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } + public Color4 Highlight1 => convert(1, 0.7f); + public Color4 Content1 => convert(0.4f, 1); + public Color4 Content2 => convert(0.4f, 0.9f); + public Color4 Light1 => convert(0.4f, 0.8f); + public Color4 Light2 => convert(0.4f, 0.75f); + public Color4 Light3 => convert(0.4f, 0.7f); + public Color4 Light4 => convert(0.4f, 0.5f); + public Color4 Dark1 => convert(0.2f, 0.35f); + public Color4 Dark2 => convert(0.2f, 0.3f); + public Color4 Dark3 => convert(0.2f, 0.25f); + public Color4 Dark4 => convert(0.2f, 0.2f); + public Color4 Dark5 => convert(0.2f, 0.15f); + public Color4 Dark6 => convert(0.2f, 0.1f); + public Color4 Foreground1 => convert(0.1f, 0.6f); + public Color4 Background1 => convert(0.1f, 0.4f); + public Color4 Background2 => convert(0.1f, 0.3f); + public Color4 Background3 => convert(0.1f, 0.25f); + public Color4 Background4 => convert(0.1f, 0.2f); + public Color4 Background5 => convert(0.1f, 0.15f); + public Color4 Background6 => convert(0.1f, 0.1f); + private Color4 convert(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 @@ -55,27 +76,6 @@ namespace osu.Game.Overlays return hue / 360f; } - - public Color4 Highlight1 => convert(1, 0.7f); - public Color4 Content1 => convert(0.4f, 1); - public Color4 Content2 => convert(0.4f, 0.9f); - public Color4 Light1 => convert(0.4f, 0.8f); - public Color4 Light2 => convert(0.4f, 0.75f); - public Color4 Light3 => convert(0.4f, 0.7f); - public Color4 Light4 => convert(0.4f, 0.5f); - public Color4 Dark1 => convert(0.2f, 0.35f); - public Color4 Dark2 => convert(0.2f, 0.3f); - public Color4 Dark3 => convert(0.2f, 0.25f); - public Color4 Dark4 => convert(0.2f, 0.2f); - public Color4 Dark5 => convert(0.2f, 0.15f); - public Color4 Dark6 => convert(0.2f, 0.1f); - public Color4 Foreground1 => convert(0.1f, 0.6f); - public Color4 Background1 => convert(0.1f, 0.4f); - public Color4 Background2 => convert(0.1f, 0.3f); - public Color4 Background3 => convert(0.1f, 0.25f); - public Color4 Background4 => convert(0.1f, 0.2f); - public Color4 Background5 => convert(0.1f, 0.15f); - public Color4 Background6 => convert(0.1f, 0.1f); } public enum OverlayColourScheme From 750a4476d8cb91e5984552a53d3f7cccba7de1d1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 12:41:21 +0300 Subject: [PATCH 146/157] Simplify getBaseHue function --- osu.Game/Overlays/OverlayColourProvider.cs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index b548522538..1221de480e 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -42,39 +42,29 @@ namespace osu.Game.Overlays // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) { - float hue; - switch (colourScheme) { default: throw new ArgumentException($@"{colourScheme} colour scheme does not provide a hue value in {nameof(getBaseHue)}."); case OverlayColourScheme.Red: - hue = 0; - break; + return 0; case OverlayColourScheme.Pink: - hue = 333; - break; + return 333 / 360f; case OverlayColourScheme.Orange: - hue = 46; - break; + return 46 / 360f; case OverlayColourScheme.Green: - hue = 115; - break; + return 115 / 360f; case OverlayColourScheme.Purple: - hue = 255; - break; + return 255 / 360f; case OverlayColourScheme.Blue: - hue = 200; - break; + return 200 / 360f; } - - return hue / 360f; } } From 8e470678c7d124fab495d4c15be304f598be87aa Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 12:42:23 +0300 Subject: [PATCH 147/157] Rename convert() to getColour() --- osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index 1221de480e..9816f313ad 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,28 +16,28 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } - public Color4 Highlight1 => convert(1, 0.7f); - public Color4 Content1 => convert(0.4f, 1); - public Color4 Content2 => convert(0.4f, 0.9f); - public Color4 Light1 => convert(0.4f, 0.8f); - public Color4 Light2 => convert(0.4f, 0.75f); - public Color4 Light3 => convert(0.4f, 0.7f); - public Color4 Light4 => convert(0.4f, 0.5f); - public Color4 Dark1 => convert(0.2f, 0.35f); - public Color4 Dark2 => convert(0.2f, 0.3f); - public Color4 Dark3 => convert(0.2f, 0.25f); - public Color4 Dark4 => convert(0.2f, 0.2f); - public Color4 Dark5 => convert(0.2f, 0.15f); - public Color4 Dark6 => convert(0.2f, 0.1f); - public Color4 Foreground1 => convert(0.1f, 0.6f); - public Color4 Background1 => convert(0.1f, 0.4f); - public Color4 Background2 => convert(0.1f, 0.3f); - public Color4 Background3 => convert(0.1f, 0.25f); - public Color4 Background4 => convert(0.1f, 0.2f); - public Color4 Background5 => convert(0.1f, 0.15f); - public Color4 Background6 => convert(0.1f, 0.1f); + public Color4 Highlight1 => getColour(1, 0.7f); + public Color4 Content1 => getColour(0.4f, 1); + public Color4 Content2 => getColour(0.4f, 0.9f); + public Color4 Light1 => getColour(0.4f, 0.8f); + public Color4 Light2 => getColour(0.4f, 0.75f); + public Color4 Light3 => getColour(0.4f, 0.7f); + public Color4 Light4 => getColour(0.4f, 0.5f); + public Color4 Dark1 => getColour(0.2f, 0.35f); + public Color4 Dark2 => getColour(0.2f, 0.3f); + public Color4 Dark3 => getColour(0.2f, 0.25f); + public Color4 Dark4 => getColour(0.2f, 0.2f); + public Color4 Dark5 => getColour(0.2f, 0.15f); + public Color4 Dark6 => getColour(0.2f, 0.1f); + public Color4 Foreground1 => getColour(0.1f, 0.6f); + public Color4 Background1 => getColour(0.1f, 0.4f); + public Color4 Background2 => getColour(0.1f, 0.3f); + public Color4 Background3 => getColour(0.1f, 0.25f); + public Color4 Background4 => getColour(0.1f, 0.2f); + public Color4 Background5 => getColour(0.1f, 0.15f); + public Color4 Background6 => getColour(0.1f, 0.1f); - private Color4 convert(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) From 852e622f02056bf296f0b3ae5721c659df0b1d7c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 13:12:35 +0300 Subject: [PATCH 148/157] Fix broken BreadcrumbControl --- osu.Game/Graphics/UserInterface/BreadcrumbControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index e2438cc4cd..4dfb2769dc 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -34,8 +34,8 @@ namespace osu.Game.Graphics.UserInterface var tIndex = TabContainer.IndexOf(t); var tabIndex = TabContainer.IndexOf(TabMap[index.NewValue]); - t.State = tIndex < tabIndex ? Visibility.Hidden : Visibility.Visible; - t.Chevron.FadeTo(tIndex <= tabIndex ? 0f : 1f, 500, Easing.OutQuint); + t.State = tIndex > tabIndex ? Visibility.Hidden : Visibility.Visible; + t.Chevron.FadeTo(tIndex >= tabIndex ? 0f : 1f, 500, Easing.OutQuint); } }; } From 1305634c5263a9e628d4cbd0879d246181225aee Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 14:02:05 +0300 Subject: [PATCH 149/157] Simplify colour provider caching --- osu.Game/Overlays/FullscreenOverlay.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 8a8a53e042..b7e6eb2ff7 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -17,11 +17,12 @@ namespace osu.Game.Overlays [Resolved] protected IAPIProvider API { get; private set; } - private readonly OverlayColourScheme colourScheme; + [Cached] + private OverlayColourProvider colourProvider; protected FullscreenOverlay(OverlayColourScheme colourScheme) { - this.colourScheme = colourScheme; + colourProvider = new OverlayColourProvider(colourScheme); RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; @@ -39,17 +40,9 @@ namespace osu.Game.Overlays }; } - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - [BackgroundDependencyLoader] private void load() { - OverlayColourProvider colourProvider; - dependencies.Cache(colourProvider = new OverlayColourProvider(colourScheme)); - Waves.FirstWaveColour = colourProvider.Highlight1; Waves.SecondWaveColour = colourProvider.Light4; Waves.ThirdWaveColour = colourProvider.Dark3; From 49c5d5b23d27d188183930920bc3628cdcf43e65 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 14:06:05 +0300 Subject: [PATCH 150/157] Make colour provider readonly --- osu.Game/Overlays/FullscreenOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index b7e6eb2ff7..e02f03301b 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays protected IAPIProvider API { get; private set; } [Cached] - private OverlayColourProvider colourProvider; + private readonly OverlayColourProvider colourProvider; protected FullscreenOverlay(OverlayColourScheme colourScheme) { From 97c80529d5ac0abeb848c56af603cc5033d72d45 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Jan 2020 21:47:40 +0900 Subject: [PATCH 151/157] Adjust wave colours slightly --- osu.Game/Overlays/FullscreenOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index e02f03301b..959f6749d2 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -43,10 +43,10 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - Waves.FirstWaveColour = colourProvider.Highlight1; - Waves.SecondWaveColour = colourProvider.Light4; - Waves.ThirdWaveColour = colourProvider.Dark3; - Waves.FourthWaveColour = colourProvider.Dark1; + Waves.FirstWaveColour = colourProvider.Light4; + Waves.SecondWaveColour = colourProvider.Light3; + Waves.ThirdWaveColour = colourProvider.Dark4; + Waves.FourthWaveColour = colourProvider.Dark3; } public override void Show() From a6124ae499eddbe22c799fc8b1de46f74c560f79 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 27 Jan 2020 08:24:15 +0800 Subject: [PATCH 152/157] fix typo on ScoreProcessor xmldoc --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 8ccc2af93b..8eafaa88ec 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Scoring public readonly Bindable Rank = new Bindable(ScoreRank.X); /// - /// THe highest combo achieved by this score. + /// The highest combo achieved by this score. /// public readonly BindableInt HighestCombo = new BindableInt(); From 15fd8596c238348c45b5ff367b8d6b5fcfc97f21 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 27 Jan 2020 12:16:00 +0900 Subject: [PATCH 153/157] Fix cursor not hiding for screenshots --- osu.Game/Graphics/ScreenshotManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 7f20c30048..3ad36577b5 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -90,7 +90,7 @@ namespace osu.Game.Graphics { ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() => { - if (framesWaited++ < frames_to_wait) + if (framesWaited++ >= frames_to_wait) // ReSharper disable once AccessToDisposedClosure framesWaitedEvent.Set(); }, 10, true); From 431b1489b9e859fcb79ea6dfd0709c33fb3d7478 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 27 Jan 2020 13:16:36 +0900 Subject: [PATCH 154/157] Add test --- .../TestSceneBreadcrumbControl.cs | 27 +++++++++++++++++-- .../UserInterface/BreadcrumbControl.cs | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs index 19eebc89b6..3967b62c95 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs @@ -1,9 +1,11 @@ // 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 NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -12,11 +14,11 @@ namespace osu.Game.Tests.Visual.UserInterface [TestFixture] public class TestSceneBreadcrumbControl : OsuTestScene { - private readonly BreadcrumbControl breadcrumbs; + private readonly TestBreadcrumbControl breadcrumbs; public TestSceneBreadcrumbControl() { - Add(breadcrumbs = new BreadcrumbControl + Add(breadcrumbs = new TestBreadcrumbControl { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -25,8 +27,13 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddStep(@"first", () => breadcrumbs.Current.Value = BreadcrumbTab.Click); + assertVisible(1); + AddStep(@"second", () => breadcrumbs.Current.Value = BreadcrumbTab.The); + assertVisible(2); + AddStep(@"third", () => breadcrumbs.Current.Value = BreadcrumbTab.Circles); + assertVisible(3); } [BackgroundDependencyLoader] @@ -35,11 +42,27 @@ namespace osu.Game.Tests.Visual.UserInterface breadcrumbs.StripColour = colours.Blue; } + private void assertVisible(int count) => AddAssert($"first {count} item(s) visible", () => + { + for (int i = 0; i < count; i++) + { + if (breadcrumbs.GetDrawable((BreadcrumbTab)i).State != Visibility.Visible) + return false; + } + + return true; + }); + private enum BreadcrumbTab { Click, The, Circles, } + + private class TestBreadcrumbControl : BreadcrumbControl + { + public BreadcrumbTabItem GetDrawable(BreadcrumbTab tab) => (BreadcrumbTabItem)TabContainer.First(t => t.Value == tab); + } } } diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 4dfb2769dc..84429bf5bd 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -40,7 +40,7 @@ namespace osu.Game.Graphics.UserInterface }; } - protected class BreadcrumbTabItem : OsuTabItem, IStateful + public class BreadcrumbTabItem : OsuTabItem, IStateful { protected virtual float ChevronSize => 10; From 834e82d543074cdfb45480c31d1c83a4d62f727c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 14:50:24 +0900 Subject: [PATCH 155/157] Add comprehensive tests for changelog overlay Includes failing case --- .../Online/TestSceneChangelogOverlay.cs | 57 +++++++++++++------ osu.Game/Overlays/ChangelogOverlay.cs | 16 +++--- osu.sln.DotSettings | 1 + 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs index 658f678b10..7a8570c09b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneChangelogOverlay : OsuTestScene { - private ChangelogOverlay changelog; + private TestChangelogOverlay changelog; public override IReadOnlyList RequiredTypes => new[] { @@ -29,23 +29,40 @@ namespace osu.Game.Tests.Visual.Online protected override bool UseOnlineAPI => true; - protected override void LoadComplete() + [SetUp] + public void SetUp() => Schedule(() => { - base.LoadComplete(); + Child = changelog = new TestChangelogOverlay(); + }); - Add(changelog = new ChangelogOverlay()); - AddStep(@"Show", changelog.Show); - AddStep(@"Hide", changelog.Hide); + [Test] + public void ShowWithNoFetch() + { + AddStep(@"Show", () => changelog.Show()); + AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0); + AddAssert(@"listing displayed", () => changelog.Current.Value == null); + AddAssert(@"no stream selected", () => changelog.Header.Streams.Current.Value == null); + } - AddWaitStep("wait for hide", 3); + [Test] + public void ShowWithListing() + { + AddStep(@"Show with listing", () => changelog.ShowListing()); + AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0); + AddAssert(@"listing displayed", () => changelog.Current.Value == null); + AddAssert(@"no stream selected", () => changelog.Header.Streams.Current.Value == null); + } + [Test] + public void ShowWithBuild() + { AddStep(@"Show with Lazer 2018.712.0", () => { changelog.ShowBuild(new APIChangelogBuild { Version = "2018.712.0", DisplayVersion = "2018.712.0", - UpdateStream = new APIUpdateStream { Name = OsuGameBase.CLIENT_STREAM_NAME }, + UpdateStream = new APIUpdateStream { Id = 7, Name = OsuGameBase.CLIENT_STREAM_NAME }, ChangelogEntries = new List { new APIChangelogEntry @@ -56,19 +73,16 @@ namespace osu.Game.Tests.Visual.Online } } }); - changelog.Show(); }); - AddWaitStep("wait for show", 3); - AddStep(@"Hide", changelog.Hide); - AddWaitStep("wait for hide", 3); - - AddStep(@"Show with listing", () => - { - changelog.ShowListing(); - changelog.Show(); - }); + AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0); + AddAssert(@"correct build displayed", () => changelog.Current.Value.Version == "2018.712.0"); + AddAssert(@"correct stream selected", () => changelog.Header.Streams.Current.Value.Id == 7); + } + [Test] + public void TestHTMLUnescaping() + { AddStep(@"Ensure HTML string unescaping", () => { changelog.ShowBuild(new APIChangelogBuild @@ -97,5 +111,12 @@ namespace osu.Game.Tests.Visual.Online }); }); } + + private class TestChangelogOverlay : ChangelogOverlay + { + public new List Streams => base.Streams; + + public new ChangelogHeader Header => base.Header; + } } } diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 412e29735a..2ce26276d5 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.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; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays { public readonly Bindable Current = new Bindable(); - private ChangelogHeader header; + protected ChangelogHeader Header; private Container content; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays private List builds; - private List streams; + protected List Streams; public ChangelogOverlay() : base(OverlayColourScheme.Purple) @@ -62,7 +62,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new ChangelogHeader + Header = new ChangelogHeader { ListingSelected = ShowListing, }, @@ -78,7 +78,7 @@ namespace osu.Game.Overlays sampleBack = audio.Samples.Get(@"UI/generic-select-soft"); - header.Current.BindTo(Current); + Header.Current.BindTo(Current); Current.BindValueChanged(e => { @@ -117,7 +117,7 @@ namespace osu.Game.Overlays performAfterFetch(() => { var build = builds.Find(b => b.Version == version && b.UpdateStream.Name == updateStream) - ?? streams.Find(s => s.Name == updateStream)?.LatestBuild; + ?? Streams.Find(s => s.Name == updateStream)?.LatestBuild; if (build != null) ShowBuild(build); @@ -179,9 +179,9 @@ namespace osu.Game.Overlays res.Streams.ForEach(s => s.LatestBuild.UpdateStream = res.Streams.Find(s2 => s2.Id == s.LatestBuild.UpdateStream.Id)); builds = res.Builds; - streams = res.Streams; + Streams = res.Streams; - header.Streams.Populate(res.Streams); + Header.Streams.Populate(res.Streams); tcs.SetResult(true); }); diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 15ea20084d..6d131bf423 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -298,6 +298,7 @@ GL GLSL HID + HTML HUD ID IL From 292a82ac273f2f2df092aa7b4368e5e7ff9ef5c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 14:52:21 +0900 Subject: [PATCH 156/157] Fix incorrect propagation of stream/build on initial display with build --- .../Overlays/Changelog/ChangelogHeader.cs | 19 +++++++++++++++++-- .../Changelog/UpdateStreamBadgeArea.cs | 2 -- osu.Game/Overlays/ChangelogOverlay.cs | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 70a45f2667..7755c0f64b 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -37,7 +38,7 @@ namespace osu.Game.Overlays.Changelog Streams.Current.ValueChanged += e => { - if (e.NewValue?.LatestBuild != null && e.NewValue != Current.Value?.UpdateStream) + if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Current.Value?.UpdateStream)) Current.Value = e.NewValue.LatestBuild; }; } @@ -54,7 +55,7 @@ namespace osu.Game.Overlays.Changelog BreadcrumbControl.AddItem(e.NewValue.ToString()); BreadcrumbControl.Current.Value = e.NewValue.ToString(); - Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == e.NewValue.UpdateStream.Name); + updateCurrentStream(); title.Version = e.NewValue.UpdateStream.DisplayName; } @@ -80,6 +81,20 @@ namespace osu.Game.Overlays.Changelog protected override ScreenTitle CreateTitle() => title = new ChangelogHeaderTitle(); + public void Populate(List streams) + { + Streams.Populate(streams); + updateCurrentStream(); + } + + private void updateCurrentStream() + { + if (Current.Value == null) + return; + + Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Current.Value.UpdateStream.Name); + } + public class HeaderBackground : Sprite { public HeaderBackground() diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs index 2b48811bd6..ca57ba24e2 100644 --- a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs +++ b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs @@ -29,8 +29,6 @@ namespace osu.Game.Overlays.Changelog public void Populate(List streams) { - Current.Value = null; - foreach (APIUpdateStream updateStream in streams) AddItem(updateStream); } diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 2ce26276d5..90ba206077 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.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; @@ -181,7 +181,7 @@ namespace osu.Game.Overlays builds = res.Builds; Streams = res.Streams; - Header.Streams.Populate(res.Streams); + Header.Populate(res.Streams); tcs.SetResult(true); }); From 5609c92aafa89a99ff79943c4dd2481c421897f0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2020 07:50:21 +0000 Subject: [PATCH 157/157] Bump DiscordRichPresence from 1.0.121 to 1.0.147 Bumps [DiscordRichPresence](https://github.com/Lachee/discord-rpc-csharp) from 1.0.121 to 1.0.147. - [Release notes](https://github.com/Lachee/discord-rpc-csharp/releases) - [Commits](https://github.com/Lachee/discord-rpc-csharp/commits) Signed-off-by: dependabot-preview[bot] --- osu.Desktop/osu.Desktop.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index da47ad8223..b9294088f4 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -29,7 +29,7 @@ - +