diff --git a/GenshinLyreMidiPlayer.Data/Entities/History.cs b/GenshinLyreMidiPlayer.Data/Entities/History.cs
index 9b70b76..e154010 100644
--- a/GenshinLyreMidiPlayer.Data/Entities/History.cs
+++ b/GenshinLyreMidiPlayer.Data/Entities/History.cs
@@ -4,11 +4,19 @@ namespace GenshinLyreMidiPlayer.Data.Entities;
public class History
{
- public History() { }
+ protected History() { }
- public History(string path) { Path = path; }
+ public History(string path, int key)
+ {
+ Key = key;
+ Path = path;
+ }
public Guid Id { get; set; }
+ public int Key { get; set; }
+
public string Path { get; set; } = null!;
+
+ public Transpose? Transpose { get; set; }
}
\ No newline at end of file
diff --git a/GenshinLyreMidiPlayer.Data/Entities/Transpose.cs b/GenshinLyreMidiPlayer.Data/Entities/Transpose.cs
new file mode 100644
index 0000000..4aab082
--- /dev/null
+++ b/GenshinLyreMidiPlayer.Data/Entities/Transpose.cs
@@ -0,0 +1,10 @@
+using System.ComponentModel;
+
+namespace GenshinLyreMidiPlayer.Data.Entities;
+
+public enum Transpose
+{
+ [Description("Ignore missing notes")] Ignore,
+ [Description("Transpose up")] Up,
+ [Description("Transpose down")] Down
+}
\ No newline at end of file
diff --git a/GenshinLyreMidiPlayer.Data/Midi/MidiFile.cs b/GenshinLyreMidiPlayer.Data/Midi/MidiFile.cs
index a594e0c..907c9b8 100644
--- a/GenshinLyreMidiPlayer.Data/Midi/MidiFile.cs
+++ b/GenshinLyreMidiPlayer.Data/Midi/MidiFile.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using GenshinLyreMidiPlayer.Data.Entities;
using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;
using Melanchall.DryWetMidi.Tools;
@@ -13,14 +14,16 @@ public class MidiFile : Screen
private readonly ReadingSettings? _settings;
private int _position;
- public MidiFile(string path, ReadingSettings? settings = null)
+ public MidiFile(History history, ReadingSettings? settings = null)
{
_settings = settings;
- Path = path;
+ History = history;
InitializeMidi();
}
+ public History History { get; }
+
public int Position
{
get => _position + 1;
@@ -29,7 +32,7 @@ public int Position
public Melanchall.DryWetMidi.Core.MidiFile Midi { get; private set; } = null!;
- public string Path { get; }
+ public string Path => History.Path;
public string Title => GetFileNameWithoutExtension(Path);
diff --git a/GenshinLyreMidiPlayer.Data/Properties/Settings.Designer.cs b/GenshinLyreMidiPlayer.Data/Properties/Settings.Designer.cs
index ccd1866..c58545b 100644
--- a/GenshinLyreMidiPlayer.Data/Properties/Settings.Designer.cs
+++ b/GenshinLyreMidiPlayer.Data/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace GenshinLyreMidiPlayer.Data.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -46,8 +46,8 @@ public string LicenseUri {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
- [global::System.Configuration.DefaultSettingValueAttribute("https://github.com/sabihoshi/GenshinLyreMidiPlayer/blob/main/THIRD-PARTY-NOTICES." +
- "md")]
+ [global::System.Configuration.DefaultSettingValueAttribute("\r\n https://github.com/sabihoshi/GenshinLyreMidiPlayer/blob/main/TH" +
+ "IRD-PARTY-NOTICES.md\r\n ")]
public string ThirdPartyLicenseUri {
get {
return ((string)(this["ThirdPartyLicenseUri"]));
@@ -126,18 +126,6 @@ public bool UseSpeakers {
}
}
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("0")]
- public int KeyOffset {
- get {
- return ((int)(this["KeyOffset"]));
- }
- set {
- this["KeyOffset"] = value;
- }
- }
-
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("-1")]
diff --git a/GenshinLyreMidiPlayer.Data/Properties/Settings.settings b/GenshinLyreMidiPlayer.Data/Properties/Settings.settings
index 16f9919..69069c1 100644
--- a/GenshinLyreMidiPlayer.Data/Properties/Settings.settings
+++ b/GenshinLyreMidiPlayer.Data/Properties/Settings.settings
@@ -39,9 +39,6 @@
False
-
- 0
-
-1
diff --git a/GenshinLyreMidiPlayer.WPF/Core/LyrePlayer.cs b/GenshinLyreMidiPlayer.WPF/Core/LyrePlayer.cs
index f451773..ac0282e 100644
--- a/GenshinLyreMidiPlayer.WPF/Core/LyrePlayer.cs
+++ b/GenshinLyreMidiPlayer.WPF/Core/LyrePlayer.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using GenshinLyreMidiPlayer.Data.Entities;
using WindowsInput;
using WindowsInput.Native;
using static GenshinLyreMidiPlayer.WPF.Core.Keyboard;
@@ -9,13 +10,6 @@ namespace GenshinLyreMidiPlayer.WPF.Core;
public static class LyrePlayer
{
- public enum Transpose
- {
- Ignore,
- Up,
- Down
- }
-
private static readonly IInputSimulator Input = new InputSimulator();
private static readonly List LyreNotes = new()
diff --git a/GenshinLyreMidiPlayer.WPF/GenshinLyreMidiPlayer.WPF.csproj b/GenshinLyreMidiPlayer.WPF/GenshinLyreMidiPlayer.WPF.csproj
index 2f236ea..8b7510f 100644
--- a/GenshinLyreMidiPlayer.WPF/GenshinLyreMidiPlayer.WPF.csproj
+++ b/GenshinLyreMidiPlayer.WPF/GenshinLyreMidiPlayer.WPF.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
@@ -6,7 +6,7 @@
true
GenshinLyreMidiPlayer.WPF.App
app.manifest
- 3.0.0
+ 3.1.0
item_windsong_lyre.ico
enable
https://github.com/sabihoshi/GenshinLyreMidiPlayer
diff --git a/GenshinLyreMidiPlayer.WPF/ViewModels/LyrePlayerViewModel.cs b/GenshinLyreMidiPlayer.WPF/ViewModels/LyrePlayerViewModel.cs
index 1b653ce..b8727bc 100644
--- a/GenshinLyreMidiPlayer.WPF/ViewModels/LyrePlayerViewModel.cs
+++ b/GenshinLyreMidiPlayer.WPF/ViewModels/LyrePlayerViewModel.cs
@@ -4,6 +4,7 @@
using System.Windows;
using Windows.Media;
using Windows.Media.Playback;
+using GenshinLyreMidiPlayer.Data.Entities;
using GenshinLyreMidiPlayer.Data.Midi;
using GenshinLyreMidiPlayer.Data.Notification;
using GenshinLyreMidiPlayer.Data.Properties;
@@ -16,7 +17,7 @@
using ModernWpf.Controls;
using Stylet;
using StyletIoC;
-using static GenshinLyreMidiPlayer.WPF.Core.LyrePlayer.Transpose;
+using static GenshinLyreMidiPlayer.WPF.ViewModels.SettingsPageViewModel;
using MidiFile = GenshinLyreMidiPlayer.Data.Midi.MidiFile;
namespace GenshinLyreMidiPlayer.WPF.ViewModels;
@@ -29,25 +30,22 @@ public class LyrePlayerViewModel : Screen,
{
private static readonly Settings Settings = Settings.Default;
private readonly IEventAggregator _events;
+ private readonly MainWindowViewModel _main;
private readonly MediaPlayer? _player;
private readonly OutputDevice? _speakers;
private readonly PlaybackCurrentTimeWatcher _timeWatcher;
- private readonly SettingsPageViewModel _settings;
private bool _ignoreSliderChange;
private InputDevice? _inputDevice;
private TimeSpan _songPosition;
- public LyrePlayerViewModel(IContainer ioc,
- SettingsPageViewModel settings, PlaylistViewModel playlist)
+ public LyrePlayerViewModel(IContainer ioc, MainWindowViewModel main)
{
+ _main = main;
_timeWatcher = PlaybackCurrentTimeWatcher.Instance;
_events = ioc.Get();
_events.Subscribe(this);
- _settings = settings;
- Playlist = playlist;
-
SelectedMidiInput = MidiInputs[0];
_timeWatcher.CurrentTimeChanged += OnSongTick;
@@ -74,8 +72,8 @@ public LyrePlayerViewModel(IContainer ioc,
{
new ErrorContentDialog(e, closeText: "Ignore").ShowAsync();
- _settings.CanUseSpeakers = false;
- Settings.UseSpeakers = false;
+ SettingsView.CanUseSpeakers = false;
+ Settings.UseSpeakers = false;
}
}
@@ -124,7 +122,7 @@ public double SongPosition
public Playback? Playback { get; private set; }
- public PlaylistViewModel Playlist { get; }
+ public PlaylistViewModel Playlist => _main.PlaylistView;
public string PlayPauseIcon => Playback?.IsRunning ?? false ? PauseIcon : PlayIcon;
@@ -135,6 +133,8 @@ public double SongPosition
private MusicDisplayProperties? Display =>
_player?.SystemMediaTransportControls.DisplayUpdater.MusicProperties;
+ private SettingsPageViewModel SettingsView => _main.SettingsView;
+
private static string PauseIcon => "\xEDB4";
private static string PlayIcon => "\xF5B0";
@@ -355,10 +355,10 @@ public void UpdateButtons()
private int ApplyNoteSettings(int noteId)
{
- noteId -= Settings.KeyOffset;
+ noteId -= Playlist.OpenedFile?.History.Key ?? 0;
if (Settings.TransposeNotes)
- noteId = LyrePlayer.TransposeNote(noteId, _settings.Transpose ?? Ignore);
+ noteId = LyrePlayer.TransposeNote(noteId, SettingsView.Transpose.Key);
return noteId;
}
@@ -388,13 +388,13 @@ private async Task InitializePlayback()
// Check for notes that cannot be played even after transposing.
var outOfRange = midi.GetNotes().Where(note =>
- !_settings.SelectedLayout.Key.TryGetKey(ApplyNoteSettings(note.NoteNumber), out _));
+ !SettingsView.SelectedLayout.Key.TryGetKey(ApplyNoteSettings(note.NoteNumber), out _));
- if (_settings.Transpose is null && outOfRange.Any())
+ if (Playlist.OpenedFile.History.Transpose is null && outOfRange.Any())
{
await Application.Current.Dispatcher.Invoke(async () =>
{
- var options = new Enum[] { Up, Down };
+ var options = new Enum[] { Transpose.Up, Transpose.Down };
var exceptionDialog = new ErrorContentDialog(
new IndexOutOfRangeException(
"Some notes cannot be played by the Lyre because it is missing Sharps & Flats. " +
@@ -403,17 +403,17 @@ await Application.Current.Dispatcher.Invoke(async () =>
var result = await exceptionDialog.ShowAsync();
- _settings.Transpose = result switch
+ SettingsView.Transpose = result switch
{
- ContentDialogResult.None => Ignore,
- ContentDialogResult.Primary => Up,
- ContentDialogResult.Secondary => Down
+ ContentDialogResult.None => TransposeNames.ElementAt(0),
+ ContentDialogResult.Primary => TransposeNames.ElementAt(1),
+ ContentDialogResult.Secondary => TransposeNames.ElementAt(2)
};
});
}
Playback = midi.GetPlayback();
- Playback.Speed = _settings.SelectedSpeed.Speed;
+ Playback.Speed = SettingsView.SelectedSpeed.Speed;
Playback.InterruptNotesOnStop = true;
@@ -486,7 +486,7 @@ private void PlayNote(NoteEvent noteEvent)
return;
}
- var layout = _settings.SelectedLayout.Key;
+ var layout = SettingsView.SelectedLayout.Key;
var note = ApplyNoteSettings(noteEvent.NoteNumber);
switch (noteEvent.EventType)
diff --git a/GenshinLyreMidiPlayer.WPF/ViewModels/MainWindowViewModel.cs b/GenshinLyreMidiPlayer.WPF/ViewModels/MainWindowViewModel.cs
index f20390f..67fd62c 100644
--- a/GenshinLyreMidiPlayer.WPF/ViewModels/MainWindowViewModel.cs
+++ b/GenshinLyreMidiPlayer.WPF/ViewModels/MainWindowViewModel.cs
@@ -12,16 +12,16 @@ public class MainWindowViewModel : Conductor.StackNavigation
{
private readonly IContainer _ioc;
private readonly Stack _history = new();
- private NavigationView _navView;
+ private NavigationView _navView = null!;
public MainWindowViewModel(IContainer ioc, IEventAggregator events)
{
_ioc = ioc;
- SettingsView = ioc.Get();
- PlaylistView = ioc.Get();
- PlayerView = new(ioc, SettingsView, PlaylistView);
- PianoSheetView = new(SettingsView, PlaylistView);
+ PlaylistView = new(ioc, this);
+ SettingsView = new(ioc, this);
+ PlayerView = new(ioc, this);
+ PianoSheetView = new(this);
}
public bool ShowUpdate => SettingsView.NeedsUpdate && ActiveItem != SettingsView;
@@ -58,7 +58,7 @@ protected override async void OnViewLoaded()
}
await using var db = _ioc.Get();
- await PlaylistView.AddFiles(db.History.Select(midi => midi.Path));
+ await PlaylistView.AddFiles(db.History);
}
private void AutoSuggestBoxOnTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs e)
diff --git a/GenshinLyreMidiPlayer.WPF/ViewModels/PianoSheetViewModel.cs b/GenshinLyreMidiPlayer.WPF/ViewModels/PianoSheetViewModel.cs
index 05b6a12..7d18a07 100644
--- a/GenshinLyreMidiPlayer.WPF/ViewModels/PianoSheetViewModel.cs
+++ b/GenshinLyreMidiPlayer.WPF/ViewModels/PianoSheetViewModel.cs
@@ -6,22 +6,17 @@
using Melanchall.DryWetMidi.Interaction;
using PropertyChanged;
using Stylet;
-using static GenshinLyreMidiPlayer.WPF.Core.LyrePlayer.Transpose;
namespace GenshinLyreMidiPlayer.WPF.ViewModels;
public class PianoSheetViewModel : Screen
{
+ private readonly MainWindowViewModel _main;
private uint _bars = 1;
private uint _beats;
private uint _shorten = 1;
- public PianoSheetViewModel(SettingsPageViewModel settingsPage,
- PlaylistViewModel playlistView)
- {
- SettingsPage = settingsPage;
- PlaylistView = playlistView;
- }
+ public PianoSheetViewModel(MainWindowViewModel main) { _main = main; }
[OnChangedMethod(nameof(Update))] public char Delimiter { get; set; } = '.';
@@ -32,9 +27,9 @@ public PianoSheetViewModel(SettingsPageViewModel settingsPage,
set => SettingsPage.SelectedLayout = value;
}
- public PlaylistViewModel PlaylistView { get; }
+ public PlaylistViewModel PlaylistView => _main.PlaylistView;
- public SettingsPageViewModel SettingsPage { get; }
+ public SettingsPageViewModel SettingsPage => _main.SettingsView;
public string Result { get; private set; } = string.Empty;
@@ -84,7 +79,7 @@ public void Update()
foreach (var note in notes)
{
var offset = note.NoteNumber - SettingsPage.KeyOffset;
- var transpose = SettingsPage.Transpose ?? Ignore;
+ var transpose = SettingsPage.Transpose.Key;
var id = LyrePlayer.TransposeNote(offset, transpose);
if (!layout.TryGetKey(id, out var key)) continue;
diff --git a/GenshinLyreMidiPlayer.WPF/ViewModels/PlaylistViewModel.cs b/GenshinLyreMidiPlayer.WPF/ViewModels/PlaylistViewModel.cs
index 7187085..1113799 100644
--- a/GenshinLyreMidiPlayer.WPF/ViewModels/PlaylistViewModel.cs
+++ b/GenshinLyreMidiPlayer.WPF/ViewModels/PlaylistViewModel.cs
@@ -27,13 +27,14 @@ public enum LoopMode
}
private readonly IContainer _ioc;
-
private readonly IEventAggregator _events;
+ private readonly MainWindowViewModel _main;
- public PlaylistViewModel(IContainer ioc, IEventAggregator events)
+ public PlaylistViewModel(IContainer ioc, MainWindowViewModel main)
{
_ioc = ioc;
- _events = events;
+ _events = ioc.Get();
+ _main = main;
}
public BindableCollection FilteredTracks => string.IsNullOrWhiteSpace(FilterText)
@@ -44,7 +45,7 @@ public PlaylistViewModel(IContainer ioc, IEventAggregator events)
public bool Shuffle { get; set; }
- public LoopMode Loop { get; set; }
+ public LoopMode Loop { get; set; } = LoopMode.All;
public MidiFile? OpenedFile { get; set; }
@@ -56,8 +57,6 @@ public PlaylistViewModel(IContainer ioc, IEventAggregator events)
public Stack History { get; } = new();
- public string FilterText { get; set; }
-
public string LoopStateString =>
Loop switch
{
@@ -67,6 +66,8 @@ public PlaylistViewModel(IContainer ioc, IEventAggregator events)
LoopMode.All => "\xE8EE"
};
+ public string? FilterText { get; set; }
+
private BindableCollection ShuffledTracks { get; set; } = new();
public BindableCollection GetPlaylist() => Shuffle ? ShuffledTracks : Tracks;
@@ -100,17 +101,31 @@ public async Task AddFiles(IEnumerable files)
ShuffledTracks = new(Tracks.OrderBy(_ => Guid.NewGuid()));
RefreshPlaylist();
- await UpdateHistory();
var next = Next();
if (OpenedFile is null && Tracks.Count > 0 && next is not null)
_events.Publish(Next());
}
+ public async Task AddFiles(IEnumerable files)
+ {
+ foreach (var file in files)
+ {
+ await AddFile(file);
+ }
+
+ RefreshPlaylist();
+ }
+
public async Task ClearPlaylist()
{
+ await using var db = _ioc.Get();
+ db.History.RemoveRange(db.History);
+ await db.SaveChangesAsync();
+
Tracks.Clear();
- await UpdateHistory();
+ OpenedFile = null;
+ SelectedFile = null;
}
public async Task OpenFile()
@@ -127,11 +142,25 @@ public async Task OpenFile()
await AddFiles(openFileDialog.FileNames);
}
+ public async Task RemoveTrack()
+ {
+ if (SelectedFile is not null)
+ {
+ await using var db = _ioc.Get();
+ db.History.Remove(SelectedFile.History);
+ await db.SaveChangesAsync();
+
+ OpenedFile = OpenedFile == SelectedFile ? null : OpenedFile;
+ Tracks.Remove(SelectedFile);
+
+ RefreshPlaylist();
+ }
+ }
+
public async Task UpdateHistory()
{
await using var db = _ioc.Get();
- db.History.RemoveRange(db.History);
- db.History.AddRange(Tracks.Select(t => new History(t.Path)));
+ db.UpdateRange(Tracks.Select(t => t.History));
await db.SaveChangesAsync();
}
@@ -144,19 +173,21 @@ public void OnFileChanged(object sender, EventArgs e)
public void OnFilterTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs e)
=> FilterText = sender.Text;
- public void Previous()
+ public void OnOpenedFileChanged()
{
- History.Pop();
- _events.Publish(History.Pop());
+ if (OpenedFile is null) return;
+
+ var transpose = SettingsPageViewModel.TransposeNames
+ .FirstOrDefault(e => e.Key == OpenedFile.History.Transpose);
+
+ _main.SettingsView.Transpose = transpose;
+ _main.SettingsView.KeyOffset = OpenedFile.History.Key;
}
- public void RemoveTrack()
+ public void Previous()
{
- if (SelectedFile is not null)
- {
- Tracks.Remove(SelectedFile);
- RefreshPlaylist();
- }
+ History.Pop();
+ _events.Publish(History.Pop());
}
public void ToggleLoop()
@@ -178,21 +209,31 @@ public void ToggleShuffle()
RefreshPlaylist();
}
- private async Task AddFile(string fileName, ReadingSettings? settings = null)
+ private async Task AddFile(History history, ReadingSettings? settings = null)
{
try
{
- var file = new MidiFile(fileName, settings);
- Tracks.Add(file);
+ Tracks.Add(new(history, settings));
}
catch (Exception e)
{
settings ??= new();
if (await ExceptionHandler.TryHandleException(e, settings))
- await AddFile(fileName, settings);
+ await AddFile(history, settings);
}
}
+ private async Task AddFile(string fileName, ReadingSettings? settings = null)
+ {
+ var history = new History(fileName, _main.SettingsView.KeyOffset);
+
+ await AddFile(history);
+
+ await using var db = _ioc.Get();
+ db.History.Add(history);
+ await db.SaveChangesAsync();
+ }
+
private void RefreshPlaylist()
{
var playlist = GetPlaylist();
diff --git a/GenshinLyreMidiPlayer.WPF/ViewModels/SettingsPageViewModel.cs b/GenshinLyreMidiPlayer.WPF/ViewModels/SettingsPageViewModel.cs
index 70e19c1..4f4aa95 100644
--- a/GenshinLyreMidiPlayer.WPF/ViewModels/SettingsPageViewModel.cs
+++ b/GenshinLyreMidiPlayer.WPF/ViewModels/SettingsPageViewModel.cs
@@ -8,6 +8,8 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using GenshinLyreMidiPlayer.Data;
+using GenshinLyreMidiPlayer.Data.Entities;
using GenshinLyreMidiPlayer.Data.Git;
using GenshinLyreMidiPlayer.Data.Midi;
using GenshinLyreMidiPlayer.Data.Notification;
@@ -21,18 +23,33 @@
using ModernWpf.Controls;
using Stylet;
using StyletIoC;
+using static GenshinLyreMidiPlayer.Data.Entities.Transpose;
namespace GenshinLyreMidiPlayer.WPF.ViewModels;
public class SettingsPageViewModel : Screen
{
private static readonly Settings Settings = Settings.Default;
+
+ public static readonly Dictionary TransposeNames = new()
+ {
+ [Ignore] = "Ignore notes",
+ [Up] = "Shift one semitone up",
+ [Down] = "Shift one semitone down"
+ };
+
+ private readonly IContainer _ioc;
private readonly IEventAggregator _events;
- private int _keyOffset = Settings.KeyOffset;
+ private readonly MainWindowViewModel _main;
+ private int _keyOffset;
- public SettingsPageViewModel(IContainer ioc)
+ public SettingsPageViewModel(IContainer ioc, MainWindowViewModel main)
{
+ _ioc = ioc;
_events = ioc.Get();
+ _main = main;
+
+ _keyOffset = Playlist.OpenedFile?.History.Key ?? 0;
ThemeManager.Current.ApplicationTheme = Settings.AppTheme switch
{
@@ -135,6 +152,8 @@ public int KeyOffset
public KeyValuePair SelectedLayout { get; set; }
+ public KeyValuePair Transpose { get; set; } = TransposeNames.First();
+
public static List MidiSpeeds { get; } = new()
{
new("0.25x", 0.25),
@@ -161,12 +180,12 @@ public string GenshinLocation
public string UpdateString { get; set; } = string.Empty;
- public LyrePlayer.Transpose? Transpose { get; set; }
-
public uint MergeMilliseconds { get; set; } = Settings.MergeMilliseconds;
public static Version ProgramVersion => Assembly.GetExecutingAssembly().GetName().Version!;
+ private PlaylistViewModel Playlist => _main.PlaylistView;
+
public bool TryGetLocation()
{
var locations = new[]
@@ -327,11 +346,24 @@ private void OnAutoCheckUpdatesChanged()
{
if (AutoCheckUpdates)
_ = CheckForUpdate();
+
+ Settings.Modify(s => s.AutoCheckUpdates = AutoCheckUpdates);
}
private void OnIncludeBetaUpdatesChanged() => _ = CheckForUpdate();
- private void OnKeyOffsetChanged() => Settings.Modify(s => s.KeyOffset = KeyOffset);
+ private async void OnKeyOffsetChanged()
+ {
+ if (Playlist.OpenedFile is null)
+ return;
+
+ await using var db = _ioc.Get();
+
+ Playlist.OpenedFile.History.Key = KeyOffset;
+ db.Update(Playlist.OpenedFile.History);
+
+ await db.SaveChangesAsync();
+ }
private void OnMergeMillisecondsChanged()
{
@@ -352,4 +384,17 @@ private void OnSelectedLayoutIndexChanged()
}
private void OnSelectedSpeedChanged() => _events.Publish(this);
+
+ private async void OnTransposeChanged()
+ {
+ if (Playlist.OpenedFile is null)
+ return;
+
+ await using var db = _ioc.Get();
+
+ Playlist.OpenedFile.History.Transpose = Transpose.Key;
+ db.Update(Playlist.OpenedFile.History);
+
+ await db.SaveChangesAsync();
+ }
}
\ No newline at end of file
diff --git a/GenshinLyreMidiPlayer.WPF/Views/SettingsPageView.xaml b/GenshinLyreMidiPlayer.WPF/Views/SettingsPageView.xaml
index 2c9f450..0451199 100644
--- a/GenshinLyreMidiPlayer.WPF/Views/SettingsPageView.xaml
+++ b/GenshinLyreMidiPlayer.WPF/Views/SettingsPageView.xaml
@@ -69,6 +69,15 @@
+
+
+
+
+
+