commit cead8a5f54e4b9fc9a9b002b1d66cecc2ec57385 Author: Alex <15199219+muskit@users.noreply.github.com> Date: Wed Aug 6 17:03:37 2025 -0700 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c027db3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,134 @@ + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.svclog +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.azurePubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +packages/ +## TODO: If the tool you use requires repositories.config, also uncomment the next line +!packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +![Ss]tyle[Cc]op.targets +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml + +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store + +_NCrunch* \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/App.axaml b/App.axaml new file mode 100644 index 0000000..cd700b7 --- /dev/null +++ b/App.axaml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/App.axaml.cs b/App.axaml.cs new file mode 100644 index 0000000..d138ab6 --- /dev/null +++ b/App.axaml.cs @@ -0,0 +1,23 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace MercuryConverter; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow(); + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/Data/Song/Chart.cs b/Data/Song/Chart.cs new file mode 100644 index 0000000..a1ef026 --- /dev/null +++ b/Data/Song/Chart.cs @@ -0,0 +1,25 @@ +using System; + +namespace MercuryConverter.Data; + + +public class Chart +{ + public required string audioId; + public required string audioOffset; + public required string audioPreviewTime; + public required string audioPreviewDuration; + public required string video; + public required string designer; + public required string clearRequirement; + public required string diffLevel; + public string diffString + { + get + { + var d = Convert.ToDouble(diffLevel); + var i = (int)d; + return $"{(int)d}{(d > i ? "+" : "")}"; + } + } +} \ No newline at end of file diff --git a/Data/Song/Consts.cs b/Data/Song/Consts.cs new file mode 100644 index 0000000..2b425b5 --- /dev/null +++ b/Data/Song/Consts.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MercuryConverter.Data; + +public static class Consts +{ + private static Dictionary _CATEGORY_INDEX = new() + { + { -1, "Unknown"}, + { 0, "Anime/Pop"}, + { 1, "Vocaloid"}, + { 2, "Touhou Project"}, + { 3, "2.5D" }, + { 4, "Variety" }, + { 5, "Original" }, + { 6, "HARDCORE TANO*C" }, + { 7, "VTuber" }, + }; + public static readonly IReadOnlyDictionary CATEGORY_INDEX = _CATEGORY_INDEX; + + private static Dictionary _NUM_SOURCE = new() + { + { 1, string.Concat(new int[] {87, 65, 67, 67, 65}.Select(i => Convert.ToChar(i))) }, + { 2, string.Concat(new int[] {87, 65, 67, 67, 65, 32, 83}.Select(i => Convert.ToChar(i))) }, + { 3, string.Concat(new int[] {87, 65, 67, 67, 65, 32, 76, 73, 76, 89}.Select(i => Convert.ToChar(i))) }, + { 4, string.Concat(new int[] {87, 65, 67, 67, 65, 32, 76, 73, 76, 89, 32, 82}.Select(i => Convert.ToChar(i))) }, + { 5, string.Concat(new int[] {87, 65, 67, 67, 65, 32, 82, 101, 118, 101, 114, 115, 101}.Select(i => Convert.ToChar(i))) } + }; + public static readonly IReadOnlyDictionary NUM_SOURCE = _NUM_SOURCE; + public static readonly IReadOnlyDictionary SOURCE_NUM = _NUM_SOURCE.ToDictionary(p => p.Value, p=>p.Key); + + private static string[] _DIFFICULTIES = { + "Normal", "Hard", "Expert", "Inferno" + }; + public static readonly IReadOnlyList DIFFICULTIES = _DIFFICULTIES; +} \ No newline at end of file diff --git a/Data/Song/Song.cs b/Data/Song/Song.cs new file mode 100644 index 0000000..a1f0734 --- /dev/null +++ b/Data/Song/Song.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using Avalonia.Media; + +namespace MercuryConverter.Data; + +public class Song +{ + /// + /// Format: `Snn-nnn` where `n` is a digit. + /// + public required string id; + public required string name; + public required string rubi; + public required string artist; + public required string copyright; + public required string tempo; + public required string version; + public required int genreId; + public required string game; + public required string jacket; + public Chart?[] charts = { null, null, null, null }; +} \ No newline at end of file diff --git a/Database.cs b/Database.cs new file mode 100644 index 0000000..1f3303c --- /dev/null +++ b/Database.cs @@ -0,0 +1,10 @@ +namespace MercuryConverter; + +using System; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +public static class Database +{ + public static readonly ObservableCollection Songs = new(); +} \ No newline at end of file diff --git a/MainWindow.axaml b/MainWindow.axaml new file mode 100644 index 0000000..1d5c926 --- /dev/null +++ b/MainWindow.axaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + diff --git a/MainWindow.axaml.cs b/MainWindow.axaml.cs new file mode 100644 index 0000000..8374a92 --- /dev/null +++ b/MainWindow.axaml.cs @@ -0,0 +1,36 @@ +using Avalonia.Controls; +using Avalonia.Styling; + +namespace MercuryConverter; + +using MercuryConverter.Views; + +public partial class MainWindow : Window +{ + public string RunType + { + get + { + if (Design.IsDesignMode) + { + return "In Design!"; + } + return "In Runtime."; + } + } + + public MainWindow() + { + InitializeComponent(); + + // Force dark mode in designer + if (Design.IsDesignMode) + { + RequestedThemeVariant = ThemeVariant.Dark; + } + // LblPlatform.Content = RunType; + + // Setup tab views + SelectionControl.Content = new Selection(); + } +} \ No newline at end of file diff --git a/MercuryConverter.csproj b/MercuryConverter.csproj new file mode 100644 index 0000000..29a7fbc --- /dev/null +++ b/MercuryConverter.csproj @@ -0,0 +1,23 @@ + + + WinExe + net9.0 + enable + true + app.manifest + true + + + + + + + + + + + None + All + + + diff --git a/MercuryConverter.sln b/MercuryConverter.sln new file mode 100644 index 0000000..6db20d3 --- /dev/null +++ b/MercuryConverter.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MercuryConverter", "MercuryConverter.csproj", "{8D7AB684-46C8-6289-FBE5-52DC512A35BE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8D7AB684-46C8-6289-FBE5-52DC512A35BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D7AB684-46C8-6289-FBE5-52DC512A35BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D7AB684-46C8-6289-FBE5-52DC512A35BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D7AB684-46C8-6289-FBE5-52DC512A35BE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8A55B6C1-9740-4A8D-859C-4CC399386136} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..d05d2ad --- /dev/null +++ b/Program.cs @@ -0,0 +1,21 @@ +using Avalonia; +using System; + +namespace MercuryConverter; + +class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} diff --git a/Views/Selection/Selection.axaml b/Views/Selection/Selection.axaml new file mode 100644 index 0000000..ce44557 --- /dev/null +++ b/Views/Selection/Selection.axaml @@ -0,0 +1,31 @@ + + + + + + + + Search/Filter + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Views/Selection/Selection.axaml.cs b/Views/Selection/Selection.axaml.cs new file mode 100644 index 0000000..74e5e38 --- /dev/null +++ b/Views/Selection/Selection.axaml.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Specialized; +using Avalonia.Controls; + +namespace MercuryConverter.Views; + +public partial class Selection : Panel +{ + public Selection() + { + InitializeComponent(); + Database.Songs.CollectionChanged += OnSongsChg; + } + + private void OnSongsChg(object? sender, NotifyCollectionChangedEventArgs e) + { + Console.WriteLine("Songs collection changed!"); + + if (e.NewItems != null) + { + Console.WriteLine("Added..."); + foreach (Data.Song added in e.NewItems) + { + Console.WriteLine($"[{added.id}] {added.artist} - {added.name}"); + } + } + if (e.OldItems != null) + { + Console.WriteLine("Removed..."); + foreach (Data.Song rem in e.OldItems) + { + Console.WriteLine($"[{rem.id}] {rem.artist} - {rem.name}"); + } + } + } +} \ No newline at end of file diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..21207b1 --- /dev/null +++ b/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + +