private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game) { beatmapSet = database.GetWithChildren <BeatmapSetInfo>(beatmapSet.BeatmapSetID); beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); var beatmap = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged }; //for the time being, let's completely load the difficulty panels in the background. //this likely won't scale so well, but allows us to completely async the loading flow. Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate { carousel.AddGroup(group); if (Beatmap == null) { carousel.SelectBeatmap(beatmapSet.Beatmaps.First()); } else { var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo)); if (panel != null) { carousel.SelectGroup(group, panel); } } })); }
private void filterChanged() { filterTask?.Cancel(); filterTask = Scheduler.AddDelayed(() => { filterTask = null; var search = filter.Search; BeatmapGroup newSelection = null; foreach (var beatmapGroup in carousel) { var set = beatmapGroup.BeatmapSet; bool match = string.IsNullOrEmpty(search) || (set.Metadata.Artist ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.ArtistUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.Title ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.TitleUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1; if (match) { beatmapGroup.State = BeatmapGroupState.Collapsed; if (newSelection == null || beatmapGroup.BeatmapSet.OnlineBeatmapSetID == Beatmap.BeatmapSetInfo.OnlineBeatmapSetID) { newSelection = beatmapGroup; } } else { beatmapGroup.State = BeatmapGroupState.Hidden; } } if (newSelection != null) { carousel.SelectBeatmap(newSelection.BeatmapSet.Beatmaps[0], false); } }, 250); }
private void removeGroup(BeatmapGroup group) { if (group == null) { return; } if (selectedGroup == group) { if (getVisibleGroups().Count() == 1) { selectNullBeatmap(); } else { SelectNext(); } } groups.Remove(group); panels.Remove(group.Header); foreach (var p in group.BeatmapPanels) { panels.Remove(p); } scrollableContent.Remove(group.Header); scrollableContent.RemoveRange(group.BeatmapPanels); computeYPositions(); }
/// <summary> /// selection has been changed as the result of interaction with the carousel. /// </summary> private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) { if (!beatmap.Equals(Beatmap?.BeatmapInfo)) { Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } ensurePlayingSelected(); }
private void filterChanged(bool debounce = true, bool eagerSelection = true) { filterTask?.Cancel(); filterTask = Scheduler.AddDelayed(() => { filterTask = null; var search = filter.Search; BeatmapGroup newSelection = null; carousel.Sort(filter.Sort); foreach (var beatmapGroup in carousel) { var set = beatmapGroup.BeatmapSet; bool hasCurrentMode = set.Beatmaps.Any(bm => bm.Mode == playMode); bool match = hasCurrentMode; match &= string.IsNullOrEmpty(search) || (set.Metadata.Artist ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.ArtistUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.Title ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1 || (set.Metadata.TitleUnicode ?? "").IndexOf(search, StringComparison.InvariantCultureIgnoreCase) != -1; if (match) { if (newSelection == null || beatmapGroup.BeatmapSet.OnlineBeatmapSetID == Beatmap.BeatmapSetInfo.OnlineBeatmapSetID) { if (newSelection != null) { newSelection.State = BeatmapGroupState.Collapsed; } newSelection = beatmapGroup; } else { beatmapGroup.State = BeatmapGroupState.Collapsed; } } else { beatmapGroup.State = BeatmapGroupState.Hidden; } } if (newSelection != null) { if (newSelection.BeatmapPanels.Any(b => b.Beatmap.ID == Beatmap.BeatmapInfo.ID)) { carousel.SelectBeatmap(Beatmap.BeatmapInfo, false); } else if (eagerSelection) { carousel.SelectBeatmap(newSelection.BeatmapSet.Beatmaps[0], false); } } }, debounce ? 250 : 0); }
private void addGroup(BeatmapGroup group) { // prevent duplicates by concurrent independent actions trying to add a group if (groups.Any(g => g.BeatmapSet.ID == group.BeatmapSet.ID)) { return; } groups.Add(group); panels.Add(group.Header); panels.AddRange(group.BeatmapPanels); }
public void AddGroup(BeatmapGroup group) { group.State = BeatmapGroupState.Collapsed; groups.Add(group); panels.Add(group.Header); foreach (BeatmapPanel panel in group.BeatmapPanels) { panels.Add(panel); } computeYPositions(); }
private void selectBeatmap(BeatmapGroup group, BeatmapInfo beatmap) { if (selectedBeatmapGroup == group) { return; } if (selectedBeatmapGroup != null) { selectedBeatmapGroup.State = BeatmapGroupState.Collapsed; } selectedBeatmapGroup = group; }
public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) { // todo: this method should be smarter as to not recreate panels that haven't changed, etc. var oldGroup = groups.Find(b => b.BeatmapSet.ID == beatmapSet.ID); var newGroup = createGroup(beatmapSet); int index = groups.IndexOf(oldGroup); if (index >= 0) { groups.RemoveAt(index); } if (newGroup != null) { if (index >= 0) { groups.Insert(index, newGroup); } else { addGroup(newGroup); } } bool hadSelection = selectedGroup == oldGroup; if (hadSelection && newGroup == null) { selectedGroup = null; } Filter(null, false); //check if we can/need to maintain our current selection. if (hadSelection && newGroup != null) { var newSelection = newGroup.BeatmapPanels.Find(p => p.Beatmap.ID == selectedPanel?.Beatmap.ID); if (newSelection == null && oldGroup != null && selectedPanel != null) { newSelection = newGroup.BeatmapPanels[Math.Min(newGroup.BeatmapPanels.Count - 1, oldGroup.BeatmapPanels.IndexOf(selectedPanel))]; } selectGroup(newGroup, newSelection); } }
public void SelectGroup(BeatmapGroup group, BeatmapPanel panel) { if (SelectedGroup != null && SelectedGroup != group) { SelectedGroup.State = BeatmapGroupState.Collapsed; } SelectedGroup = group; panel.State = PanelSelectedState.Selected; SelectedPanel = panel; float selectedY = computeYPositions(); ScrollTo(selectedY); }
private void addBeatmapSet(BeatmapSetInfo beatmapSet, Framework.Game game, bool select = false) { beatmapSet = database.GetWithChildren <BeatmapSetInfo>(beatmapSet.ID); beatmapSet.Beatmaps.ForEach(b => { database.GetChildren(b); if (b.Metadata == null) { b.Metadata = beatmapSet.Metadata; } }); foreach (var b in beatmapSet.Beatmaps) { b.ComputeDifficulty(database); } beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.StarDifficulty).ToList(); var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database); var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged, StartRequested = b => footer.StartButton.TriggerClick() }; //for the time being, let's completely load the difficulty panels in the background. //this likely won't scale so well, but allows us to completely async the loading flow. Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate { beatmapGroups.Add(group); carousel.AddGroup(group); if (Beatmap == null || select) { carousel.SelectBeatmap(beatmapSet.Beatmaps.First()); } else { var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo)); if (panel != null) { carousel.SelectGroup(group, panel); } } })); }
public void UpdateBeatmap(BeatmapInfo beatmap) { // todo: this method should not run more than once for the same BeatmapSetInfo. var set = manager.QueryBeatmapSet(s => s.ID == beatmap.BeatmapSetInfoID); // todo: this method should be smarter as to not recreate panels that haven't changed, etc. var group = groups.Find(b => b.BeatmapSet.ID == set.ID); int i = groups.IndexOf(group); if (i >= 0) { groups.RemoveAt(i); } var newGroup = createGroup(set); if (newGroup != null) { if (i >= 0) { groups.Insert(i, newGroup); } else { groups.Add(newGroup); } } bool hadSelection = selectedGroup == group; if (hadSelection && newGroup == null) { selectedGroup = null; } Filter(null, false); //check if we can/need to maintain our current selection. if (hadSelection && newGroup != null) { var newSelection = newGroup.BeatmapPanels.Find(p => p.Beatmap.ID == selectedPanel?.Beatmap.ID) ?? newGroup.BeatmapPanels[Math.Min(newGroup.BeatmapPanels.Count - 1, group.BeatmapPanels.IndexOf(selectedPanel))]; selectGroup(newGroup, newSelection); } }
public void AddGroup(BeatmapGroup group) { group.State = BeatmapGroupState.Collapsed; groups.Add(group); group.Header.Depth = -scrollableContent.Children.Count(); scrollableContent.Add(group.Header); foreach (BeatmapPanel panel in group.BeatmapPanels) { panel.Depth = -scrollableContent.Children.Count(); scrollableContent.Add(panel); } computeYPositions(); }
private void addBeatmapSet(BeatmapSetInfo beatmapSet) { beatmapSet = database.GetWithChildren <BeatmapSetInfo>(beatmapSet.BeatmapSetID); beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); Schedule(() => { var group = new BeatmapGroup(beatmapSet) { SelectionChanged = selectBeatmap }; setList.Add(group); if (setList.Children.Count() == 1) { group.State = BeatmapGroupState.Expanded; } }); }
/// <summary> /// selection has been changed as the result of interaction with the carousel. /// </summary> private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) { if (!beatmap.Equals(Beatmap?.BeatmapInfo)) { if (beatmap.BeatmapSetID == Beatmap?.BeatmapInfo.BeatmapSetID) { sampleChangeDifficulty.Play(); } else { sampleChangeBeatmap.Play(); } Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } ensurePlayingSelected(); }
public void SelectNext(int direction = 1, bool skipDifficulties = true) { if (groups.All(g => g.State == BeatmapGroupState.Hidden)) { selectedGroup = null; selectedPanel = null; SelectionChanged?.Invoke(null); return; } if (!skipDifficulties && selectedGroup != null) { int i = selectedGroup.BeatmapPanels.IndexOf(selectedPanel) + direction; if (i >= 0 && i < selectedGroup.BeatmapPanels.Count) { //changing difficulty panel, not set. selectGroup(selectedGroup, selectedGroup.BeatmapPanels[i]); return; } } int startIndex = Math.Max(0, groups.IndexOf(selectedGroup)); int index = startIndex; 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); } return; } } while (index != startIndex); }
private void removeGroup(BeatmapGroup group) { groups.Remove(group); panels.Remove(group.Header); foreach (var p in group.BeatmapPanels) { panels.Remove(p); } scrollableContent.Remove(group.Header); scrollableContent.RemoveRange(group.BeatmapPanels); if (selectedGroup == group) { SelectNext(); } computeYPositions(); }
public void SelectGroup(BeatmapGroup group, BeatmapPanel panel) { if (SelectedGroup != null && SelectedGroup != group) { SelectedGroup.State = BeatmapGroupState.Collapsed; foreach (BeatmapPanel p in group.BeatmapPanels) { p.MoveToY(group.Header.Position.Y); } } SelectedGroup = group; panel.State = PanelSelectedState.Selected; SelectedPanel = panel; float selectedY = computeYPositions(); ScrollTo(selectedY); }
private void selectGroup(BeatmapGroup group, BeatmapPanel panel = null, bool animated = true) { try { if (panel == null) { panel = group.BeatmapPanels.First(); } if (selectedPanel == panel) { return; } Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group"); if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden) { selectedGroup.State = BeatmapGroupState.Collapsed; } group.State = BeatmapGroupState.Expanded; group.SelectedPanel = panel; panel.State = PanelSelectedState.Selected; if (selectedPanel == panel) { return; } selectedPanel = panel; selectedGroup = group; SelectionChanged?.Invoke(panel.Beatmap); } finally { float selectedY = computeYPositions(animated); ScrollTo(selectedY, animated); } }
private void addBeatmapSet(BeatmapSetInfo beatmapSet) { beatmapSet = database.GetWithChildren <BeatmapSetInfo>(beatmapSet.BeatmapSetID); beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged }; group.Preload(Game, g => { beatmapSetFlow.Add(group); if (Beatmap == null) { if (beatmapSetFlow.Children.Count() == 1) { group.State = BeatmapGroupState.Expanded; return; } } else { if (selectedBeatmapInfo?.Equals(Beatmap.BeatmapInfo) != true) { var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo)); if (panel != null) { panel.State = PanelSelectedState.Selected; return; } } } group.State = BeatmapGroupState.Collapsed; }); }
private void addBeatmapSet(BeatmapSetInfo beatmapSet, Framework.Game game, bool select = false) { beatmapSet = database.GetWithChildren <BeatmapSetInfo>(beatmapSet.ID); beatmapSet.Beatmaps.ForEach(b => { database.GetChildren(b); if (b.Metadata == null) { b.Metadata = beatmapSet.Metadata; } }); var group = new BeatmapGroup(beatmapSet, database) { SelectionChanged = selectionChanged, StartRequested = b => raiseSelect() }; //for the time being, let's completely load the difficulty panels in the background. //this likely won't scale so well, but allows us to completely async the loading flow. Task.WhenAll(group.BeatmapPanels.Select(panel => panel.LoadAsync(game))).ContinueWith(task => Schedule(delegate { beatmapGroups.Add(group); group.State = BeatmapGroupState.Collapsed; carousel.AddGroup(group); filterChanged(false, false); if (Beatmap == null || select) { carousel.SelectBeatmap(beatmapSet.Beatmaps.First()); } else { carousel.SelectBeatmap(Beatmap.BeatmapInfo); } })); }
/// <summary> /// selection has been changed as the result of interaction with the carousel. /// </summary> private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) { selectedBeatmapInfo = beatmap; if (!beatmap.Equals(Beatmap?.BeatmapInfo)) { Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } ensurePlayingSelected(); if (selectedBeatmapGroup == group) { return; } if (selectedBeatmapGroup != null) { selectedBeatmapGroup.State = BeatmapGroupState.Collapsed; } selectedBeatmapGroup = group; }
/// <summary> /// selection has been changed as the result of interaction with the carousel. /// </summary> private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) { bool beatmapSetChange = false; if (!beatmap.Equals(Beatmap?.BeatmapInfo)) { if (beatmap.BeatmapSetInfoID == Beatmap?.BeatmapInfo.BeatmapSetInfoID) sampleChangeDifficulty.Play(); else { sampleChangeBeatmap.Play(); beatmapSetChange = true; } Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } ensurePlayingSelected(beatmapSetChange); }
private void addGroup(BeatmapGroup group) { groups.Add(group); panels.Add(group.Header); panels.AddRange(group.BeatmapPanels); }
private void selectNullBeatmap() { selectedGroup = null; selectedPanel = null; SelectionChanged?.Invoke(null); }
private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game) { beatmapSet = database.GetWithChildren<BeatmapSetInfo>(beatmapSet.ID); beatmapSet.Beatmaps.ForEach(b => { database.GetChildren(b); if (b.Metadata == null) b.Metadata = beatmapSet.Metadata; }); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database); var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged, StartRequested = b => start() }; //for the time being, let's completely load the difficulty panels in the background. //this likely won't scale so well, but allows us to completely async the loading flow. Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate { carousel.AddGroup(group); if (Beatmap == null) carousel.SelectBeatmap(beatmapSet.Beatmaps.First()); else { var panel = group.BeatmapPanels.FirstOrDefault(p => p.Beatmap.Equals(Beatmap.BeatmapInfo)); if (panel != null) carousel.SelectGroup(group, panel); } })); }