From f58c554d19751c6ed7587799f6e7f1d790042711 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Dec 2017 20:22:10 +0900 Subject: [PATCH 01/13] Add per-difficulty filtering support Filters based on selected ruleset --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 6 +- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 2 + osu.Game/Screens/Select/BeatmapCarousel.cs | 66 ++++++++++++++------- osu.Game/Screens/Select/FilterCriteria.cs | 10 +++- osu.sln.DotSettings | 1 + 5 files changed, 60 insertions(+), 25 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 163dd7fbe9..59ff7b06e5 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -40,6 +40,7 @@ namespace osu.Game.Beatmaps.Drawables public BeatmapSetInfo BeatmapSet; private BeatmapGroupState state; + public BeatmapGroupState State { get { return state; } @@ -52,7 +53,8 @@ namespace osu.Game.Beatmaps.Drawables case BeatmapGroupState.Expanded: Header.State = PanelSelectedState.Selected; foreach (BeatmapPanel panel in BeatmapPanels) - panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : PanelSelectedState.NotSelected; + panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : + !panel.Filtered ? PanelSelectedState.NotSelected : PanelSelectedState.Hidden; break; case BeatmapGroupState.Collapsed: Header.State = PanelSelectedState.NotSelected; @@ -108,7 +110,7 @@ namespace osu.Game.Beatmaps.Drawables //we want to make sure one of our children is selected in the case none have been selected yet. if (SelectedPanel == null) - BeatmapPanels.First().State = PanelSelectedState.Selected; + BeatmapPanels.First(p => !p.Filtered).State = PanelSelectedState.Selected; } private void panelGainedSelection(BeatmapPanel panel) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index e6bf08eb9f..c94f4fdc57 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -61,6 +61,8 @@ namespace osu.Game.Beatmaps.Drawables return base.OnClick(state); } + public bool Filtered { get; set; } + protected override void ApplyState(PanelSelectedState last = PanelSelectedState.Hidden) { if (!IsLoaded) return; diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 578b02d90a..fb6761eb8d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Select var newSelection = newGroup.BeatmapPanels.Find(p => p.Beatmap.ID == selectedPanel?.Beatmap.ID); - if(newSelection == null && oldGroup != null && selectedPanel != null) + if (newSelection == null && oldGroup != null && selectedPanel != null) newSelection = newGroup.BeatmapPanels[Math.Min(newGroup.BeatmapPanels.Count - 1, oldGroup.BeatmapPanels.IndexOf(selectedPanel))]; selectGroup(newGroup, newSelection); @@ -178,42 +178,62 @@ namespace osu.Game.Screens.Select SelectionChanged?.Invoke(null); } + /// + /// Increment selection in the carousel in a chosen direction. + /// + /// The direction to increment. Negative is backwards. + /// Whether to skip individual difficulties and only increment over full groups. public void SelectNext(int direction = 1, bool skipDifficulties = true) { + // todo: we may want to refactor and remove this as an optimisation in the future. if (groups.All(g => g.State == BeatmapGroupState.Hidden)) { selectNullBeatmap(); return; } - if (!skipDifficulties && selectedGroup != null) - { - int i = selectedGroup.BeatmapPanels.IndexOf(selectedPanel) + direction; + int originalIndex = Math.Max(0, groups.IndexOf(selectedGroup)); + int currentIndex = originalIndex; - if (i >= 0 && i < selectedGroup.BeatmapPanels.Count) - { - //changing difficulty panel, not set. - selectGroup(selectedGroup, selectedGroup.BeatmapPanels[i]); - return; - } - } + // local function to increment the index in the required direction, wrapping over extremities. + int incrementIndex() => currentIndex = (currentIndex + direction + groups.Count) % groups.Count; - int startIndex = Math.Max(0, groups.IndexOf(selectedGroup)); - int index = startIndex; + // in the case we are skipping difficulties, we want to increment the index once before starting to find out new target + // (we don't care about the currently selected group). + if (skipDifficulties) + incrementIndex(); do { - index = (index + direction + groups.Count) % groups.Count; - if (groups[index].State != BeatmapGroupState.Hidden) - { - if (skipDifficulties) - SelectBeatmap(groups[index].SelectedPanel != null ? groups[index].SelectedPanel.Beatmap : groups[index].BeatmapPanels.First().Beatmap); - else - SelectBeatmap(direction == 1 ? groups[index].BeatmapPanels.First().Beatmap : groups[index].BeatmapPanels.Last().Beatmap); + var group = groups[currentIndex]; + if (group.State == BeatmapGroupState.Hidden) continue; + + // we are only interested in non-filtered panels. + IEnumerable validPanels = group.BeatmapPanels.Where(p => !p.Filtered); + + // if we are considering difficulties, we need to do a few extrea steps. + if (!skipDifficulties) + { + // we want to reverse the panel order if we are searching backwards. + if (direction < 0) + validPanels = validPanels.Reverse(); + + // if we are currently on the selected panel, let's try to find a valid difficulty before leaving to the next group. + // the first valid difficulty is found by skipping to the selected panel and then one further. + if (currentIndex == originalIndex) + validPanels = validPanels.SkipWhile(p => p != selectedPanel).Skip(1); + } + + var next = validPanels.FirstOrDefault(); + + // at this point, we can perform the selection change if we have a valid new target, else continue to increment in the specified direction. + if (next != null) + { + selectGroup(group, next); return; } - } while (index != startIndex); + } while (incrementIndex() != originalIndex); } private IEnumerable getVisibleGroups() => groups.Where(selectGroup => selectGroup.State != BeatmapGroupState.Hidden); @@ -416,6 +436,8 @@ namespace osu.Game.Screens.Select foreach (BeatmapPanel panel in group.BeatmapPanels) { + if (panel.Filtered) continue; + if (panel == selectedPanel) selectedY = currentY + panel.DrawHeight / 2 - DrawHeight / 2; @@ -460,7 +482,7 @@ namespace osu.Game.Screens.Select try { if (panel == null) - panel = group.BeatmapPanels.First(); + panel = group.BeatmapPanels.First(p => !p.Filtered); if (selectedPanel == panel) return; diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index c1355bfa63..96778291a1 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Rulesets; using osu.Game.Screens.Select.Filter; @@ -18,19 +19,26 @@ namespace osu.Game.Screens.Select public RulesetInfo Ruleset; public bool AllowConvertedBeatmaps; + private bool canConvert(BeatmapInfo beatmapInfo) => beatmapInfo.RulesetID == Ruleset.ID || beatmapInfo.RulesetID == 0 && Ruleset.ID > 0 && AllowConvertedBeatmaps; + public void Filter(List groups) { foreach (var g in groups) { var set = g.BeatmapSet; - bool hasCurrentMode = AllowConvertedBeatmaps || set.Beatmaps.Any(bm => bm.RulesetID == (Ruleset?.ID ?? 0)); + // we only support converts from osu! mode to other modes for now. + // in the future this will have to change, at which point this condition will become a touch more complicated. + bool hasCurrentMode = set.Beatmaps.Any(canConvert); bool match = hasCurrentMode; if (!string.IsNullOrEmpty(SearchText)) match &= set.Metadata.SearchableTerms.Any(term => term.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0); + foreach (var panel in g.BeatmapPanels) + panel.Filtered = !canConvert(panel.Beatmap); + switch (g.State) { case BeatmapGroupState.Hidden: diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 76929dcbb3..2f52881d6d 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -602,6 +602,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-frame <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="_" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> From 970e55fc4a07064437f0cf878de2a160d62520f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Dec 2017 20:49:27 +0900 Subject: [PATCH 02/13] Update difficulty icons on headers to match filtered difficulties --- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 3 ++- osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs | 17 +++++++++++++++-- osu.Game/Screens/Select/FilterCriteria.cs | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index c94f4fdc57..d8ba1e9195 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -61,7 +62,7 @@ namespace osu.Game.Beatmaps.Drawables return base.OnClick(state); } - public bool Filtered { get; set; } + public BindableBool Filtered = new BindableBool(); protected override void ApplyState(PanelSelectedState last = PanelSelectedState.Hidden) { diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs index 85daefea57..9bb7b5c737 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs @@ -7,6 +7,7 @@ using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -157,8 +158,7 @@ namespace osu.Game.Beatmaps.Drawables if (panels == null) throw new ArgumentNullException(nameof(panels)); - foreach (var p in panels) - difficultyIcons.Add(new DifficultyIcon(p.Beatmap)); + difficultyIcons.AddRange(panels.Select(p => new FilterableDifficultyIcon(p))); } public MenuItem[] ContextMenuItems @@ -178,5 +178,18 @@ namespace osu.Game.Beatmaps.Drawables return items.ToArray(); } } + + public class FilterableDifficultyIcon : DifficultyIcon + { + private readonly BindableBool filtered = new BindableBool(); + + public FilterableDifficultyIcon(BeatmapPanel panel) + : base(panel.Beatmap) + { + filtered.BindTo(panel.Filtered); + filtered.ValueChanged += v => this.FadeTo(v ? 0.1f : 1, 100); + filtered.TriggerChange(); + } + } } } diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index 96778291a1..f410c69212 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Select match &= set.Metadata.SearchableTerms.Any(term => term.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0); foreach (var panel in g.BeatmapPanels) - panel.Filtered = !canConvert(panel.Beatmap); + panel.Filtered.Value = !canConvert(panel.Beatmap); switch (g.State) { From fb92b3551e8f3a2705293d7032e2702adbadd618 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Dec 2017 21:12:06 +0900 Subject: [PATCH 03/13] Correct panel y positions when filtered panels are present --- osu.Game/Screens/Select/BeatmapCarousel.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index fb6761eb8d..aa41cad67e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -436,18 +436,16 @@ namespace osu.Game.Screens.Select foreach (BeatmapPanel panel in group.BeatmapPanels) { - if (panel.Filtered) continue; - if (panel == selectedPanel) selectedY = currentY + panel.DrawHeight / 2 - DrawHeight / 2; panel.MoveToX(-50, 500, Easing.OutExpo); //on first display we want to begin hidden under our group's header. - if (panel.Alpha == 0) + if (panel.Filtered || panel.Alpha == 0) panel.MoveToY(headerY); - movePanel(panel, true, animated, ref currentY); + movePanel(panel, !panel.Filtered, animated, ref currentY); } } else From b10240d7ef41f1a41edbfa6d0717a907823be6ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Dec 2017 21:31:26 +0900 Subject: [PATCH 04/13] Handle the case where the selected panel is no longer a valid selection better --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 45 +++++++++++---------- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 +++-- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 59ff7b06e5..e0536584bd 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -47,31 +47,34 @@ namespace osu.Game.Beatmaps.Drawables set { state = value; - - switch (value) - { - case BeatmapGroupState.Expanded: - Header.State = PanelSelectedState.Selected; - foreach (BeatmapPanel panel in BeatmapPanels) - panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : - !panel.Filtered ? PanelSelectedState.NotSelected : PanelSelectedState.Hidden; - break; - case BeatmapGroupState.Collapsed: - Header.State = PanelSelectedState.NotSelected; - foreach (BeatmapPanel panel in BeatmapPanels) - panel.State = PanelSelectedState.Hidden; - break; - case BeatmapGroupState.Hidden: - Header.State = PanelSelectedState.Hidden; - foreach (BeatmapPanel panel in BeatmapPanels) - panel.State = PanelSelectedState.Hidden; - break; - } - + UpdateState(); StateChanged?.Invoke(state); } } + public void UpdateState() + { + switch (state) + { + case BeatmapGroupState.Expanded: + Header.State = PanelSelectedState.Selected; + foreach (BeatmapPanel panel in BeatmapPanels) + panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : + !panel.Filtered ? PanelSelectedState.NotSelected : PanelSelectedState.Hidden; + break; + case BeatmapGroupState.Collapsed: + Header.State = PanelSelectedState.NotSelected; + foreach (BeatmapPanel panel in BeatmapPanels) + panel.State = PanelSelectedState.Hidden; + break; + case BeatmapGroupState.Hidden: + Header.State = PanelSelectedState.Hidden; + foreach (BeatmapPanel panel in BeatmapPanels) + panel.State = PanelSelectedState.Hidden; + break; + } + } + public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapManager manager) { if (beatmapSet == null) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index aa41cad67e..f6b832d0f7 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -327,6 +327,8 @@ namespace osu.Game.Screens.Select computeYPositions(); + selectedGroup?.UpdateState(); + if (selectedGroup == null || selectedGroup.State == BeatmapGroupState.Hidden) SelectNext(); else @@ -441,11 +443,13 @@ namespace osu.Game.Screens.Select panel.MoveToX(-50, 500, Easing.OutExpo); + bool isHidden = panel.State == PanelSelectedState.Hidden; + //on first display we want to begin hidden under our group's header. - if (panel.Filtered || panel.Alpha == 0) + if (isHidden || panel.Alpha == 0) panel.MoveToY(headerY); - movePanel(panel, !panel.Filtered, animated, ref currentY); + movePanel(panel, !isHidden, animated, ref currentY); } } else @@ -479,7 +483,7 @@ namespace osu.Game.Screens.Select { try { - if (panel == null) + if (panel == null || panel.Filtered == true) panel = group.BeatmapPanels.First(p => !p.Filtered); if (selectedPanel == panel) return; From 8dea999908ab034ba6e6825ac66707bf61ef7cca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Dec 2017 21:35:47 +0900 Subject: [PATCH 05/13] Order difficulty icons by ruleset --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index e0536584bd..8b2670f39c 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -93,7 +93,7 @@ namespace osu.Game.Beatmaps.Drawables RelativeSizeAxes = Axes.X, }; - BeatmapPanels = BeatmapSet.Beatmaps.Where(b => !b.Hidden).OrderBy(b => b.StarDifficulty).Select(b => new BeatmapPanel(b) + BeatmapPanels = BeatmapSet.Beatmaps.Where(b => !b.Hidden).OrderBy(b => b.RulesetID).ThenBy(b => b.StarDifficulty).Select(b => new BeatmapPanel(b) { Alpha = 0, GainedSelection = panelGainedSelection, From 69653c7f4fa166f60faac99123ed3a557cbb2b38 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Dec 2017 13:07:34 +0900 Subject: [PATCH 06/13] Don't use nested ternary if --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 8b2670f39c..9eb84421d4 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -59,8 +59,12 @@ namespace osu.Game.Beatmaps.Drawables case BeatmapGroupState.Expanded: Header.State = PanelSelectedState.Selected; foreach (BeatmapPanel panel in BeatmapPanels) - panel.State = panel == SelectedPanel ? PanelSelectedState.Selected : - !panel.Filtered ? PanelSelectedState.NotSelected : PanelSelectedState.Hidden; + if (panel == SelectedPanel) + panel.State = PanelSelectedState.Selected; + else if (panel.Filtered) + panel.State = PanelSelectedState.Hidden; + else + panel.State = PanelSelectedState.NotSelected; break; case BeatmapGroupState.Collapsed: Header.State = PanelSelectedState.NotSelected; From d11bf379d8b8c72d2bcc4ca09b828f77e1054293 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 12 Dec 2017 11:04:11 +0100 Subject: [PATCH 07/13] no longer select beatmapsets on import/download let's save some ears and eyes for now --- osu.Game/Screens/Select/SongSelect.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index cf08ab273e..fffd05e7b5 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -309,14 +309,7 @@ namespace osu.Game.Screens.Select carousel.Filter(criteria, debounce); } - private void onBeatmapSetAdded(BeatmapSetInfo s) - { - Schedule(() => - { - carousel.UpdateBeatmapSet(s); - carousel.SelectBeatmap(s.Beatmaps.First()); - }); - } + private void onBeatmapSetAdded(BeatmapSetInfo s) => Schedule(() => carousel.UpdateBeatmapSet(s)); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Schedule(() => removeBeatmapSet(s)); From 9fed97267872346de7c68e79804d6c35e3ad30bd Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 12 Dec 2017 11:15:34 +0100 Subject: [PATCH 08/13] removed unnecessary using --- osu.Game/Screens/Select/SongSelect.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index fffd05e7b5..7fb6a82981 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using System.Threading; using OpenTK; using OpenTK.Input; From c6eaaf658e7fae1c1e32f3d26624ec33ac0d0602 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 12 Dec 2017 13:24:18 +0100 Subject: [PATCH 09/13] fix BeatmapInfoWedge not counting Circles/Sliders correctly --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 10 +++++----- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index bb5700976d..d67f7f6948 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -5,7 +5,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; @@ -18,6 +17,7 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects.Legacy.Osu; namespace osu.Game.Rulesets.Osu { @@ -37,14 +37,14 @@ namespace osu.Game.Rulesets.Osu { new BeatmapStatistic { - Name = @"Circle count", - Content = beatmap.Beatmap.HitObjects.Count(h => h is HitCircle).ToString(), + Name = @"Circle Count", + Content = beatmap.Beatmap.HitObjects.Count(h => h is ConvertHit).ToString(), Icon = FontAwesome.fa_dot_circle_o }, new BeatmapStatistic { - Name = @"Slider count", - Content = beatmap.Beatmap.HitObjects.Count(h => h is Slider).ToString(), + Name = @"Slider Count", + Content = beatmap.Beatmap.HitObjects.Count(h => h is ConvertSlider).ToString(), Icon = FontAwesome.fa_circle_o } }; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 479cacc52b..9527f50802 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Objects.Legacy { - internal abstract class ConvertSlider : HitObject, IHasCurve + public abstract class ConvertSlider : HitObject, IHasCurve { /// /// Scoring distance with a speed-adjusted beat length of 1 second. diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index 0c1000965c..04c67ff1e4 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Hit-type, used for parsing Beatmaps. /// - internal sealed class ConvertHit : HitObject, IHasPosition, IHasCombo + public sealed class ConvertHit : HitObject, IHasPosition, IHasCombo { public Vector2 Position { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index 75a6d80560..3c15eaf14b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Slider-type, used for parsing Beatmaps. /// - internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo + public sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo { public Vector2 Position { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index 2b2dbe0765..eff0f1a2cb 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Spinner-type, used for parsing Beatmaps. /// - internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition + public sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition { public double EndTime { get; set; } From 1d206f7ec69f0b980b88fed402596f8716961190 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 12 Dec 2017 14:44:12 +0100 Subject: [PATCH 10/13] add visual tests for BeatmapInfoWedge --- .../Visual/TestCaseBeatmapInfoWedge.cs | 69 +++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + 2 files changed, 70 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs new file mode 100644 index 0000000000..0168cedc86 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -0,0 +1,69 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Screens.Select; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseBeatmapInfoWedge : OsuTestCase + { + private BeatmapManager beatmaps; + private readonly Random random; + private readonly BeatmapInfoWedge infoWedge; + private readonly Bindable beatmap = new Bindable(); + + public TestCaseBeatmapInfoWedge() + { + random = new Random(0123); + + Add(infoWedge = new BeatmapInfoWedge + { + Size = new Vector2(0.5f, 245), + RelativeSizeAxes = Axes.X, + Margin = new MarginPadding + { + Top = 20, + }, + }); + + AddStep("show", () => + { + Content.FadeInFromZero(250); + infoWedge.State = Visibility.Visible; + infoWedge.UpdateBeatmap(beatmap); + }); + AddStep("hide", () => + { + infoWedge.State = Visibility.Hidden; + Content.FadeOut(100); + }); + AddStep("random beatmap", randomBeatmap); + AddStep("null beatmap", () => infoWedge.UpdateBeatmap(beatmap.Default)); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game, BeatmapManager beatmaps) + { + this.beatmaps = beatmaps; + beatmap.BindTo(game.Beatmap); + } + + private void randomBeatmap() + { + var sets = beatmaps.GetAllUsableBeatmapSets(); + if (sets.Count == 0) + return; + + var b = sets[random.Next(0, sets.Count)].Beatmaps[0]; + beatmap.Value = beatmaps.GetWorkingBeatmap(b); + infoWedge.UpdateBeatmap(beatmap); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 12d47591ec..1542269f00 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -90,6 +90,7 @@ + From d4cd8354196626689fdeaeb1332e3aa51ba8a174 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 13 Dec 2017 16:32:32 +0100 Subject: [PATCH 11/13] correctly count HitObjects for their type also legacy classes are internal again --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 37 ++++++++++++------- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 2 +- .../Objects/Legacy/Osu/ConvertSlider.cs | 2 +- .../Objects/Legacy/Osu/ConvertSpinner.cs | 2 +- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index d67f7f6948..48516a8cef 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -17,7 +17,8 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects.Legacy.Osu; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Osu { @@ -33,21 +34,29 @@ namespace osu.Game.Rulesets.Osu new KeyBinding(InputKey.MouseRight, OsuAction.RightButton), }; - public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] + public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) { - new BeatmapStatistic + IEnumerable hitObjects = beatmap.Beatmap.HitObjects; + IEnumerable durationObjects = hitObjects.Where(d => d is IHasEndTime); + IEnumerable circles = hitObjects.Except(durationObjects); + IEnumerable sliders = hitObjects.Where(s => s is IHasCurve); + + return new[] { - Name = @"Circle Count", - Content = beatmap.Beatmap.HitObjects.Count(h => h is ConvertHit).ToString(), - Icon = FontAwesome.fa_dot_circle_o - }, - new BeatmapStatistic - { - Name = @"Slider Count", - Content = beatmap.Beatmap.HitObjects.Count(h => h is ConvertSlider).ToString(), - Icon = FontAwesome.fa_circle_o - } - }; + new BeatmapStatistic + { + Name = @"Circle Count", + Content = circles.Count().ToString(), + Icon = FontAwesome.fa_circle_o + }, + new BeatmapStatistic + { + Name = @"Slider Count", + Content = sliders.Count().ToString(), + Icon = FontAwesome.fa_circle + } + }; + } public override IEnumerable GetModsFor(ModType type) { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 9527f50802..479cacc52b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Objects.Legacy { - public abstract class ConvertSlider : HitObject, IHasCurve + internal abstract class ConvertSlider : HitObject, IHasCurve { /// /// Scoring distance with a speed-adjusted beat length of 1 second. diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index 04c67ff1e4..0c1000965c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Hit-type, used for parsing Beatmaps. /// - public sealed class ConvertHit : HitObject, IHasPosition, IHasCombo + internal sealed class ConvertHit : HitObject, IHasPosition, IHasCombo { public Vector2 Position { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index 3c15eaf14b..75a6d80560 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Slider-type, used for parsing Beatmaps. /// - public sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo + internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo { public Vector2 Position { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index eff0f1a2cb..2b2dbe0765 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu /// /// Legacy osu! Spinner-type, used for parsing Beatmaps. /// - public sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition + internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition { public double EndTime { get; set; } From 345b67ac85973641f76535d44a5627e045b343a3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Dec 2017 12:46:02 +0900 Subject: [PATCH 12/13] Remove unnecessary .Except --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 48516a8cef..85a46f3aaa 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -37,8 +37,7 @@ namespace osu.Game.Rulesets.Osu public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) { IEnumerable hitObjects = beatmap.Beatmap.HitObjects; - IEnumerable durationObjects = hitObjects.Where(d => d is IHasEndTime); - IEnumerable circles = hitObjects.Except(durationObjects); + IEnumerable circles = hitObjects.Where(d => !(d is IHasEndTime)); IEnumerable sliders = hitObjects.Where(s => s is IHasCurve); return new[] From 65a6946a9ad9d65bf1a43fa42e2ef96500f30637 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Dec 2017 12:47:47 +0900 Subject: [PATCH 13/13] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 8480ab5009..dd7dba7212 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8480ab5009b2b4a7810a817a12433959424d5339 +Subproject commit dd7dba7212845b780fa50e0aa12b1aaa7155cddb