diff --git a/src/Data/Database.cs b/src/Data/Database.cs index 6a69b90..fee4772 100644 --- a/src/Data/Database.cs +++ b/src/Data/Database.cs @@ -13,6 +13,17 @@ using UAssetAPI.UnrealTypes; namespace MercuryConverter.Data; +public class FilterOptions +{ + public List categories = []; + public List 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 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 Search(string substr) + public static IEnumerable SearchAndFilter(string substr, FilterOptions filter) { - var sanitized = substr.ToLower().Trim(); + /// Filter + var filtered = new List(); + // by source + var sourceSongs = new List(); + 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); + }); } } \ No newline at end of file diff --git a/src/Data/Song/Consts.cs b/src/Data/Song/Consts.cs index a0130e3..f37230b 100644 --- a/src/Data/Song/Consts.cs +++ b/src/Data/Song/Consts.cs @@ -7,7 +7,7 @@ namespace MercuryConverter.Data; public static class Consts { - public static readonly IReadOnlyDictionary CATEGORY_INDEX = new Dictionary + public static readonly IReadOnlyDictionary CATEGORY_NAME = new Dictionary { { -1, "Unknown"}, { 0, "Anime/Pop"}, @@ -19,6 +19,7 @@ public static class Consts { 6, "HARDCORE TANO*C" }, { 7, "VTuber" }, }; + public static readonly IReadOnlyDictionary CATEGORY_INDEX = CATEGORY_NAME.ToDictionary(p => p.Value, p => p.Key); public static readonly IReadOnlyDictionary NUM_SOURCE = new Dictionary { diff --git a/src/Data/Song/Song.cs b/src/Data/Song/Song.cs index 666d082..63a2438 100644 --- a/src/Data/Song/Song.cs +++ b/src/Data/Song/Song.cs @@ -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; } diff --git a/src/UI/Views/Selection/Selection.axaml b/src/UI/Views/Selection/Selection.axaml index a56679d..e7c49cd 100644 --- a/src/UI/Views/Selection/Selection.axaml +++ b/src/UI/Views/Selection/Selection.axaml @@ -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 @@ - + Selections { get; } = new(); + private List sourceCBs = new(); + private List 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); } } \ No newline at end of file