mirror of
https://github.com/osukey/osukey.git
synced 2025-06-05 12:57:39 +09:00
Implement filtering with strings
This commit is contained in:
parent
75de03bd88
commit
678f0aaa16
@ -29,7 +29,9 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
private BeatmapGroupState state;
|
private BeatmapGroupState state;
|
||||||
|
|
||||||
public List<BeatmapPanel> BeatmapPanels;
|
public List<BeatmapPanel> BeatmapPanels;
|
||||||
|
|
||||||
|
public BeatmapSetInfo BeatmapSet;
|
||||||
|
|
||||||
public BeatmapGroupState State
|
public BeatmapGroupState State
|
||||||
{
|
{
|
||||||
@ -73,7 +75,9 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
GainedSelection = panelGainedSelection,
|
GainedSelection = panelGainedSelection,
|
||||||
StartRequested = p => { StartRequested?.Invoke(p.Beatmap); },
|
StartRequested = p => { StartRequested?.Invoke(p.Beatmap); },
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
|
BeatmapSet = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void headerGainedSelection(BeatmapSetHeader panel)
|
private void headerGainedSelection(BeatmapSetHeader panel)
|
||||||
|
@ -16,10 +16,11 @@ using osu.Game.Beatmaps.Drawables;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
class CarouselContainer : ScrollContainer
|
class CarouselContainer : ScrollContainer, IEnumerable<BeatmapGroup>
|
||||||
{
|
{
|
||||||
private Container<Panel> scrollableContent;
|
private Container<Panel> scrollableContent;
|
||||||
private List<BeatmapGroup> groups = new List<BeatmapGroup>();
|
private List<BeatmapGroup> groups = new List<BeatmapGroup>();
|
||||||
@ -27,29 +28,29 @@ namespace osu.Game.Screens.Select
|
|||||||
public BeatmapGroup SelectedGroup { get; private set; }
|
public BeatmapGroup SelectedGroup { get; private set; }
|
||||||
public BeatmapPanel SelectedPanel { get; private set; }
|
public BeatmapPanel SelectedPanel { get; private set; }
|
||||||
|
|
||||||
private List<float> yPositions = new List<float>();
|
private List<float> yPositions = new List<float>();
|
||||||
private CarouselLifetimeList<Panel> Lifetime;
|
private CarouselLifetimeList<Panel> Lifetime;
|
||||||
|
|
||||||
public CarouselContainer()
|
public CarouselContainer()
|
||||||
{
|
{
|
||||||
DistanceDecayJump = 0.01;
|
DistanceDecayJump = 0.01;
|
||||||
|
|
||||||
Add(scrollableContent = new Container<Panel>(Lifetime = new CarouselLifetimeList<Panel>(DepthComparer))
|
Add(scrollableContent = new Container<Panel>(Lifetime = new CarouselLifetimeList<Panel>(DepthComparer))
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class CarouselLifetimeList<T> : LifetimeList<Panel>
|
internal class CarouselLifetimeList<T> : LifetimeList<Panel>
|
||||||
{
|
{
|
||||||
public CarouselLifetimeList(IComparer<Panel> comparer)
|
public CarouselLifetimeList(IComparer<Panel> comparer)
|
||||||
: base(comparer)
|
: base(comparer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public int StartIndex;
|
public int StartIndex;
|
||||||
public int EndIndex;
|
public int EndIndex;
|
||||||
|
|
||||||
public override bool Update(FrameTimeInfo time)
|
public override bool Update(FrameTimeInfo time)
|
||||||
{
|
{
|
||||||
bool anyAliveChanged = false;
|
bool anyAliveChanged = false;
|
||||||
@ -75,9 +76,9 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
return anyAliveChanged;
|
return anyAliveChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddGroup(BeatmapGroup group)
|
public void AddGroup(BeatmapGroup group)
|
||||||
{
|
{
|
||||||
group.State = BeatmapGroupState.Collapsed;
|
group.State = BeatmapGroupState.Collapsed;
|
||||||
@ -100,7 +101,7 @@ namespace osu.Game.Screens.Select
|
|||||||
yPositions.Add(currentY);
|
yPositions.Add(currentY);
|
||||||
panel.MoveToY(currentY, 750, EasingTypes.OutExpo);
|
panel.MoveToY(currentY, 750, EasingTypes.OutExpo);
|
||||||
|
|
||||||
if (advance)
|
if (advance && panel.IsVisible)
|
||||||
currentY += panel.DrawHeight + 5;
|
currentY += panel.DrawHeight + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +201,9 @@ namespace osu.Game.Screens.Select
|
|||||||
/// <param name="halfHeight">Half the draw height of the carousel container.</param>
|
/// <param name="halfHeight">Half the draw height of the carousel container.</param>
|
||||||
private void updatePanel(Panel p, float halfHeight)
|
private void updatePanel(Panel p, float halfHeight)
|
||||||
{
|
{
|
||||||
float panelDrawY = p.Position.Y - Current + p.DrawHeight / 2;
|
var height = p.IsVisible ? p.DrawHeight : 0;
|
||||||
|
|
||||||
|
float panelDrawY = p.Position.Y - Current + height / 2;
|
||||||
float dist = Math.Abs(1f - panelDrawY / halfHeight);
|
float dist = Math.Abs(1f - panelDrawY / halfHeight);
|
||||||
|
|
||||||
// Setting the origin position serves as an additive position on top of potential
|
// Setting the origin position serves as an additive position on top of potential
|
||||||
@ -222,11 +225,11 @@ namespace osu.Game.Screens.Select
|
|||||||
float drawHeight = DrawHeight;
|
float drawHeight = DrawHeight;
|
||||||
float halfHeight = drawHeight / 2;
|
float halfHeight = drawHeight / 2;
|
||||||
|
|
||||||
foreach (Panel p in Lifetime.AliveItems)
|
foreach (Panel p in Lifetime.AliveItems)
|
||||||
{
|
{
|
||||||
float panelPosY = p.Position.Y;
|
float panelPosY = p.Position.Y;
|
||||||
p.IsOnScreen = panelPosY >= Current - p.DrawHeight && panelPosY <= Current + drawHeight;
|
p.IsOnScreen = panelPosY >= Current - p.DrawHeight && panelPosY <= Current + drawHeight;
|
||||||
updatePanel(p, halfHeight);
|
updatePanel(p, halfHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine range of indices for items that are now definitely on screen to be added
|
// Determine range of indices for items that are now definitely on screen to be added
|
||||||
@ -247,6 +250,13 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InvalidateVisible()
|
||||||
|
{
|
||||||
|
Lifetime.StartIndex = 0;
|
||||||
|
Lifetime.EndIndex = groups.Count - 1;
|
||||||
|
computeYPositions();
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||||
{
|
{
|
||||||
int direction = 0;
|
int direction = 0;
|
||||||
@ -288,5 +298,15 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
return base.OnKeyDown(state, args);
|
return base.OnKeyDown(state, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerator<BeatmapGroup> GetEnumerator()
|
||||||
|
{
|
||||||
|
return groups.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ namespace osu.Game.Screens.Select
|
|||||||
public string Search { get; private set; } = string.Empty;
|
public string Search { get; private set; } = string.Empty;
|
||||||
public SortMode Sort { get; private set; } = SortMode.Title;
|
public SortMode Sort { get; private set; } = SortMode.Title;
|
||||||
|
|
||||||
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
public FilterControl()
|
public FilterControl()
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -72,11 +74,17 @@ namespace osu.Game.Screens.Select
|
|||||||
Direction = FlowDirection.VerticalOnly,
|
Direction = FlowDirection.VerticalOnly,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SearchTextBox { RelativeSizeAxes = Axes.X },
|
searchTextBox = new SearchTextBox { RelativeSizeAxes = Axes.X },
|
||||||
new GroupSortTabs()
|
new GroupSortTabs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
searchTextBox.OnChange += (sender, text) =>
|
||||||
|
{
|
||||||
|
Search = searchTextBox.Text;
|
||||||
|
FilterChanged?.Invoke();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TabItem : ClickableContainer
|
private class TabItem : ClickableContainer
|
||||||
|
@ -31,6 +31,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
@ -52,6 +53,8 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private AudioSample sampleChangeDifficulty;
|
private AudioSample sampleChangeDifficulty;
|
||||||
private AudioSample sampleChangeBeatmap;
|
private AudioSample sampleChangeBeatmap;
|
||||||
|
|
||||||
|
private List<BeatmapGroup> beatmapGroups;
|
||||||
|
|
||||||
class WedgeBackground : Container
|
class WedgeBackground : Container
|
||||||
{
|
{
|
||||||
@ -82,6 +85,7 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
|
FilterControl filter;
|
||||||
|
|
||||||
private void start()
|
private void start()
|
||||||
{
|
{
|
||||||
@ -112,6 +116,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
const float carouselWidth = 640;
|
const float carouselWidth = 640;
|
||||||
const float bottomToolHeight = 50;
|
const float bottomToolHeight = 50;
|
||||||
|
beatmapGroups = new List<BeatmapGroup>();
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new ParallaxContainer
|
new ParallaxContainer
|
||||||
@ -134,10 +139,11 @@ namespace osu.Game.Screens.Select
|
|||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
},
|
},
|
||||||
new FilterControl
|
filter = new FilterControl
|
||||||
{
|
{
|
||||||
Position = wedged_container_start_position,
|
Position = wedged_container_start_position,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
|
FilterChanged = filterChanged,
|
||||||
},
|
},
|
||||||
beatmapInfoWedge = new BeatmapInfoWedge
|
beatmapInfoWedge = new BeatmapInfoWedge
|
||||||
{
|
{
|
||||||
@ -203,6 +209,41 @@ namespace osu.Game.Screens.Select
|
|||||||
Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
|
Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void filterChanged()
|
||||||
|
{
|
||||||
|
var search = filter.Search;
|
||||||
|
BeatmapGroup newSelection = null;
|
||||||
|
bool changed = false;
|
||||||
|
foreach (var beatmapGroup in carousel)
|
||||||
|
{
|
||||||
|
var set = beatmapGroup.BeatmapSet;
|
||||||
|
if (set == null)
|
||||||
|
continue;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
changed = changed && beatmapGroup.Header.Alpha == 1;
|
||||||
|
beatmapGroup.Header.Alpha = 1;
|
||||||
|
if (newSelection == null || beatmapGroup.BeatmapSet.OnlineBeatmapSetID == Beatmap.BeatmapSetInfo.OnlineBeatmapSetID)
|
||||||
|
newSelection = beatmapGroup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
changed = changed && beatmapGroup.Header.Alpha == 0;
|
||||||
|
beatmapGroup.Header.Alpha = 0;
|
||||||
|
beatmapGroup.State = BeatmapGroupState.Collapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newSelection != null)
|
||||||
|
selectBeatmap(newSelection.BeatmapSet.Beatmaps[0]);
|
||||||
|
if (changed)
|
||||||
|
carousel.InvalidateVisible();
|
||||||
|
}
|
||||||
|
|
||||||
private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s)
|
private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s)
|
||||||
{
|
{
|
||||||
Schedule(() => addBeatmapSet(s, Game, true));
|
Schedule(() => addBeatmapSet(s, Game, true));
|
||||||
@ -347,7 +388,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database);
|
var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database);
|
||||||
|
|
||||||
var group = new BeatmapGroup(beatmap)
|
var group = new BeatmapGroup(beatmap, beatmapSet)
|
||||||
{
|
{
|
||||||
SelectionChanged = selectionChanged,
|
SelectionChanged = selectionChanged,
|
||||||
StartRequested = b => start()
|
StartRequested = b => start()
|
||||||
@ -357,6 +398,8 @@ namespace osu.Game.Screens.Select
|
|||||||
//this likely won't scale so well, but allows us to completely async the loading flow.
|
//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
|
Task.WhenAll(group.BeatmapPanels.Select(panel => panel.Preload(game))).ContinueWith(task => Schedule(delegate
|
||||||
{
|
{
|
||||||
|
beatmapGroups.Add(group);
|
||||||
|
|
||||||
carousel.AddGroup(group);
|
carousel.AddGroup(group);
|
||||||
|
|
||||||
if (Beatmap == null || select)
|
if (Beatmap == null || select)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user