add song filtering

This commit is contained in:
Alex
2025-09-01 18:27:30 -07:00
parent 2457eb8bd8
commit 34c461d6c4
5 changed files with 83 additions and 39 deletions
+38 -14
View File
@@ -13,6 +13,17 @@ using UAssetAPI.UnrealTypes;
namespace MercuryConverter.Data;
public class FilterOptions
{
public List<int> categories = [];
public List<uint> sources = [];
public override string ToString()
{
return $"categories({categories.Count()})=[{string.Join(',', categories.Select(i => i.ToString()))}];sources({sources.Count()})=[{string.Join(',', sources.Select(i => i.ToString()))}]";
}
}
public static class Database
{
public static Dictionary<string, string> AudioPaths { get; } = new();
@@ -86,7 +97,7 @@ public static class Database
Rubi = data["Rubi"].ToString()!,
Name = data["MusicMessage"].ToString()!,
Artist = data["ArtistMessage"].ToString()!,
Genre = ((IntPropertyData)data["ScoreGenre"]).Value,
Category = ((IntPropertyData)data["ScoreGenre"]).Value,
Source = ((UInt32PropertyData)data["VersionNo"]).Value,
BpmMessage = data["Bpm"].ToString()!,
PreviewTime = previewBegin,
@@ -125,24 +136,37 @@ public static class Database
}
}
Console.WriteLine($"Data setup finished with {Songs.Count} songs.");
// SEARCH TEST
var camellia = Search("camellia").ToList();
camellia.ForEach(Console.WriteLine);
}
public static IEnumerable<Song> Search(string substr)
public static IEnumerable<Song> SearchAndFilter(string substr, FilterOptions filter)
{
var sanitized = substr.ToLower().Trim();
/// Filter
var filtered = new List<Song>();
// by source
var sourceSongs = new List<Song>();
if (filter.sources.Count() == 0)
sourceSongs.AddRange(Songs);
else
sourceSongs.AddRange(Songs.Where(s => filter.sources.Contains(s.Source)));
// by category
if (filter.categories.Count() == 0)
filtered.AddRange(sourceSongs);
else
filtered.AddRange(sourceSongs.Where(s => filter.categories.Contains(s.Category)));
/// Search
var sanitized = string.IsNullOrEmpty(substr) ? "" : substr.ToLower().Trim();
if (sanitized == "")
return Songs;
return filtered;
return Songs.Where(s =>
{
return
s.Artist.ToLower().Contains(sanitized) ||
s.Name.ToLower().Contains(sanitized);
});
return filtered.Where(s =>
{
return
s.Artist.ToLower().Contains(sanitized) ||
s.Name.ToLower().Contains(sanitized);
});
}
}
+2 -1
View File
@@ -7,7 +7,7 @@ namespace MercuryConverter.Data;
public static class Consts
{
public static readonly IReadOnlyDictionary<int, string> CATEGORY_INDEX = new Dictionary<int, string>
public static readonly IReadOnlyDictionary<int, string> CATEGORY_NAME = new Dictionary<int, string>
{
{ -1, "Unknown"},
{ 0, "Anime/Pop"},
@@ -19,6 +19,7 @@ public static class Consts
{ 6, "HARDCORE TANO*C" },
{ 7, "VTuber" },
};
public static readonly IReadOnlyDictionary<string, int> CATEGORY_INDEX = CATEGORY_NAME.ToDictionary(p => p.Value, p => p.Key);
public static readonly IReadOnlyDictionary<uint, string> NUM_SOURCE = new Dictionary<uint, string>
{
+1 -1
View File
@@ -21,7 +21,7 @@ public class Song
public required string Rubi { get; set; }
public required string BpmMessage { get; set; }
public string? Copyright { get; set; } // May have never been used?
public required int Genre { get; set; }
public required int Category { get; set; }
public required string? Jacket { get; set; }
public required float PreviewTime { get; set; }
public required float PreviewLen { get; set; }
+2 -2
View File
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MercuryConverter.UI.Views"
d:DesignWidth="800" d:DesignHeight="400"
d:DesignWidth="800" d:DesignHeight="600"
x:Class="MercuryConverter.UI.Views.Selection"
xmlns:data="clr-namespace:MercuryConverter.Data"
@@ -42,7 +42,7 @@
<!-- Song Listing Table -->
<DockPanel>
<DockPanel Margin="0 4 0 8" DockPanel.Dock="Top">
<TextBox Watermark="Search for song title or artist..." TextChanged="OnSearchTextChange"/>
<TextBox Name="SearchBox" Watermark="Search for song title or artist..." TextChanged="OnSearchTextChange"/>
</DockPanel>
<UserControl Background="{DynamicResource DataGridContentBackground}">
<DataGrid Name="ListingTable" IsReadOnly="True" SelectionMode="Extended" ItemsSource="{x:Static data:Database.Songs}"
+40 -21
View File
@@ -13,6 +13,9 @@ public partial class Selection : Panel
{
public static ObservableRangeCollection<Song> Selections { get; } = new();
private List<CheckBox> sourceCBs = new();
private List<CheckBox> categoryCBs = new();
public Selection()
{
InitializeComponent();
@@ -24,26 +27,21 @@ public partial class Selection : Panel
foreach (var (k, v) in Consts.NUM_SOURCE)
{
FilterSourceContainer.Children.Add(
new CheckBox
{
Name = $"FilterSourceCheckbox{k}",
Content = v,
}
);
var cb = new CheckBox { Content = v };
cb.IsCheckedChanged += OnFilterChange;
sourceCBs.Add(cb);
FilterSourceContainer.Children.Add(cb);
}
foreach (var (k, v) in Consts.CATEGORY_INDEX)
foreach (var (k, v) in Consts.CATEGORY_NAME)
{
if (k == -1)
continue;
FilterCategoryContainer.Children.Add(
new CheckBox
{
Name = $"FilterCategoryCheckbox{k}",
Content = v,
}
);
var cb = new CheckBox { Content = v };
cb.IsCheckedChanged += OnFilterChange;
categoryCBs.Add(cb);
FilterCategoryContainer.Children.Add(cb);
}
}
@@ -57,7 +55,7 @@ public partial class Selection : Panel
var cell = e.Cell;
var tb = (TextBlock)cell.Content!;
Console.WriteLine($"{e.PointerPressedEventArgs.Properties.IsRightButtonPressed} - {e.Cell.Content}");
// Console.WriteLine($"{e.PointerPressedEventArgs.Properties.IsRightButtonPressed} - {e.Cell.Content}");
}
private void OnSelectionChange(object? sender, SelectionChangedEventArgs e)
@@ -107,14 +105,35 @@ public partial class Selection : Panel
private void OnSearchTextChange(object? _, TextChangedEventArgs args)
{
var src = (TextBox)args.Source!;
if (string.IsNullOrEmpty(src.Text))
UpdateListing();
}
private void OnFilterChange(object? _, EventArgs __)
{
UpdateListing();
}
private void UpdateListing()
{
var filterOptions = new FilterOptions();
foreach (var cb in sourceCBs)
{
Dispatcher.UIThread.Post(() => ListingTable.ItemsSource = Database.Songs);
return;
if ((bool)cb.IsChecked!)
{
filterOptions.sources.Add(Consts.SOURCE_NUM[(string) cb.Content!]);
}
}
var searchResults = Database.Search(src.Text.ToLower());
foreach (var cb in categoryCBs)
{
if ((bool)cb.IsChecked!)
{
filterOptions.categories.Add(Consts.CATEGORY_INDEX[(string) cb.Content!]);
}
}
var searchResults = Database.SearchAndFilter(SearchBox.Text!, filterOptions);
Dispatcher.UIThread.Post(() => ListingTable.ItemsSource = searchResults);
}
}