1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 15:47:26 +08:00

Move filtering to BeatmapCarousel (but actual logic is now in FilterCriteria.

This commit is contained in:
Dean Herbert 2017-03-17 19:54:51 +09:00
parent 4b97304603
commit 907236e475
No known key found for this signature in database
GPG Key ID: 46D71BF4958ABB49
9 changed files with 131 additions and 104 deletions

View File

@ -10,7 +10,7 @@ using osu.Game.Database;
namespace osu.Game.Beatmaps.Drawables
{
internal class BeatmapGroup : IStateful<BeatmapGroupState>
public class BeatmapGroup : IStateful<BeatmapGroupState>
{
public BeatmapPanel SelectedPanel;

View File

@ -18,7 +18,7 @@ using osu.Game.Graphics.Sprites;
namespace osu.Game.Beatmaps.Drawables
{
internal class BeatmapPanel : Panel
public class BeatmapPanel : Panel
{
public BeatmapInfo Beatmap;
private Sprite background;

View File

@ -17,7 +17,7 @@ using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
internal class BeatmapSetHeader : Panel
public class BeatmapSetHeader : Panel
{
public Action<BeatmapSetHeader> GainedSelection;
private SpriteText title, artist;

View File

@ -12,7 +12,7 @@ using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Beatmaps.Drawables
{
internal class Panel : Container, IStateful<PanelSelectedState>
public class Panel : Container, IStateful<PanelSelectedState>
{
public const float MAX_HEIGHT = 80;
@ -117,7 +117,7 @@ namespace osu.Game.Beatmaps.Drawables
}
}
internal enum PanelSelectedState
public enum PanelSelectedState
{
Hidden,
NotSelected,

View File

@ -17,7 +17,7 @@ using osu.Framework.MathUtils;
using System.Diagnostics;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Game.Screens.Select.Filter;
using osu.Framework.Threading;
namespace osu.Game.Screens.Select
{
@ -40,19 +40,20 @@ namespace osu.Game.Screens.Select
panels.Clear();
groups.Clear();
IEnumerable<BeatmapGroup> newGroups = null;
List<BeatmapGroup> newGroups = null;
Task.Run(() =>
{
newGroups = value.Select(createGroup).ToList();
criteria.Filter(newGroups);
}).ContinueWith(t =>
{
Schedule(() =>
{
foreach (var g in newGroups)
addGroup(g);
computeYPositions();
computeYPositions();
BeatmapsChanged?.Invoke();
});
});
@ -173,36 +174,42 @@ namespace osu.Game.Screens.Select
selectGroup(group, panel);
}
public void Sort(SortMode mode)
private FilterCriteria criteria = new FilterCriteria();
private ScheduledDelegate filterTask;
public void Filter(FilterCriteria newCriteria = null, bool debounce = true)
{
List<BeatmapGroup> sortedGroups = new List<BeatmapGroup>(groups);
switch (mode)
if (!IsLoaded) return;
criteria = newCriteria ?? criteria ?? new FilterCriteria();
Action perform = delegate
{
case SortMode.Artist:
sortedGroups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Artist, y.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Title:
sortedGroups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Title, y.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Author:
sortedGroups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Author, y.BeatmapSet.Metadata.Author, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Difficulty:
sortedGroups.Sort((x, y) => x.BeatmapSet.MaxStarDifficulty.CompareTo(y.BeatmapSet.MaxStarDifficulty));
break;
default:
Sort(SortMode.Artist); // Temporary
break;
}
filterTask = null;
scrollableContent.Clear(false);
panels.Clear();
groups.Clear();
criteria.Filter(groups);
foreach (var g in sortedGroups)
addGroup(g);
var filtered = new List<BeatmapGroup>(groups);
computeYPositions();
scrollableContent.Clear(false);
panels.Clear();
groups.Clear();
foreach (var g in filtered)
addGroup(g);
computeYPositions();
if (selectedGroup.State == BeatmapGroupState.Hidden)
SelectNext();
};
filterTask?.Cancel();
if (debounce)
filterTask = Scheduler.AddDelayed(perform, 250);
else
perform();
}
public IEnumerator<BeatmapGroup> GetEnumerator() => groups.GetEnumerator();

View File

@ -5,6 +5,7 @@ using System;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
@ -15,14 +16,13 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Filter;
using Container = osu.Framework.Graphics.Containers.Container;
using osu.Framework.Input;
using osu.Game.Modes;
namespace osu.Game.Screens.Select
{
public class FilterControl : Container
{
public Action FilterChanged;
public string Search => searchTextBox.Text;
public Action<FilterCriteria> FilterChanged;
private OsuTabControl<SortMode> sortTabs;
@ -30,16 +30,16 @@ namespace osu.Game.Screens.Select
private SortMode sort = SortMode.Title;
public SortMode Sort
{
get { return sort; }
{
get { return sort; }
set
{
if (sort != value)
{
sort = value;
FilterChanged?.Invoke();
FilterChanged?.Invoke(Criteria);
}
}
}
}
private GroupMode group = GroupMode.All;
@ -51,11 +51,19 @@ namespace osu.Game.Screens.Select
if (group != value)
{
group = value;
FilterChanged?.Invoke();
FilterChanged?.Invoke(Criteria);
}
}
}
public FilterCriteria Criteria => new FilterCriteria
{
Group = group,
Sort = sort,
SearchText = searchTextBox.Text,
Mode = playMode
};
public Action Exit;
private SearchTextBox searchTextBox;
@ -88,7 +96,7 @@ namespace osu.Game.Screens.Select
OnChange = (sender, newText) =>
{
if (newText)
FilterChanged?.Invoke();
FilterChanged?.Invoke(Criteria);
},
Exit = () => Exit?.Invoke(),
},
@ -152,16 +160,21 @@ namespace osu.Game.Screens.Select
searchTextBox.HoldFocus = false;
searchTextBox.TriggerFocusLost();
}
public void Activate()
{
searchTextBox.HoldFocus = true;
}
private readonly Bindable<PlayMode> playMode = new Bindable<PlayMode>();
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, OsuGame osu)
{
sortTabs.AccentColour = colours.GreenLight;
if (osu != null)
playMode.BindTo(osu.PlayMode);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Modes;
using osu.Game.Screens.Select.Filter;
namespace osu.Game.Screens.Select
{
public class FilterCriteria
{
public GroupMode Group;
public SortMode Sort;
public string SearchText;
public PlayMode Mode;
public void Filter(List<BeatmapGroup> groups)
{
foreach (var g in groups)
{
var set = g.BeatmapSet;
bool hasCurrentMode = set.Beatmaps.Any(bm => bm.Mode == Mode);
bool match = hasCurrentMode;
match &= string.IsNullOrEmpty(SearchText)
|| (set.Metadata.Artist ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|| (set.Metadata.ArtistUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|| (set.Metadata.Title ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1
|| (set.Metadata.TitleUnicode ?? string.Empty).IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1;
switch (g.State)
{
case BeatmapGroupState.Hidden:
if (match) g.State = BeatmapGroupState.Collapsed;
break;
default:
if (!match) g.State = BeatmapGroupState.Hidden;
break;
}
}
switch (Sort)
{
default:
case SortMode.Artist:
groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Artist, y.BeatmapSet.Metadata.Artist, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Title:
groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Title, y.BeatmapSet.Metadata.Title, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Author:
groups.Sort((x, y) => string.Compare(x.BeatmapSet.Metadata.Author, y.BeatmapSet.Metadata.Author, StringComparison.InvariantCultureIgnoreCase));
break;
case SortMode.Difficulty:
groups.Sort((x, y) => x.BeatmapSet.MaxStarDifficulty.CompareTo(y.BeatmapSet.MaxStarDifficulty));
break;
}
}
}
}

View File

@ -17,7 +17,6 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Framework.Screens;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
@ -95,7 +94,7 @@ namespace osu.Game.Screens.Select
{
RelativeSizeAxes = Axes.X,
Height = filter_height,
FilterChanged = () => filterChanged(),
FilterChanged = criteria => filterChanged(criteria),
Exit = Exit,
});
Add(beatmapInfoWedge = new BeatmapInfoWedge
@ -181,61 +180,9 @@ namespace osu.Game.Screens.Select
protected abstract void OnSelected();
private ScheduledDelegate filterTask;
private void filterChanged(bool debounce = true, bool eagerSelection = true)
private void filterChanged(FilterCriteria criteria, bool debounce = true)
{
if (!carousel.IsLoaded) return;
if (Beatmap == null) return;
filterTask?.Cancel();
filterTask = Scheduler.AddDelayed(() =>
{
filterTask = null;
var search = FilterControl.Search;
BeatmapGroup newSelection = null;
carousel.Sort(FilterControl.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);
carousel.Filter(criteria, debounce);
}
private void onBeatmapSetAdded(BeatmapSetInfo s) => carousel.AddBeatmap(s);
@ -299,10 +246,7 @@ namespace osu.Game.Screens.Select
initialAddSetsTask.Cancel();
}
private void playMode_ValueChanged(object sender, EventArgs e)
{
filterChanged(false);
}
private void playMode_ValueChanged(object sender, EventArgs e) => carousel.Filter();
private void changeBackground(WorkingBeatmap beatmap)
{

View File

@ -197,6 +197,7 @@
<Compile Include="Screens\Play\SkipButton.cs" />
<Compile Include="Modes\UI\StandardComboCounter.cs" />
<Compile Include="Screens\Select\BeatmapCarousel.cs" />
<Compile Include="Screens\Select\FilterCriteria.cs" />
<Compile Include="Screens\Select\Filter\GroupMode.cs" />
<Compile Include="Screens\Select\Filter\SortMode.cs" />
<Compile Include="Screens\Select\MatchSongSelect.cs" />