diff --git a/MSUScripter/Configs/MsuTrackInfo.cs b/MSUScripter/Configs/MsuTrackInfo.cs index 9aa1693..6374060 100644 --- a/MSUScripter/Configs/MsuTrackInfo.cs +++ b/MSUScripter/Configs/MsuTrackInfo.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using MSUScripter.Models; -using MSUScripter.Tools; namespace MSUScripter.Configs; @@ -10,6 +9,7 @@ public class MsuTrackInfo public int TrackNumber { get; set; } public string TrackName { get; set; } = ""; public DateTime LastModifiedDate { get; set; } + public bool IsScratchPad { get; set; } [SkipConvert] public List Songs { get; set; } = new List(); diff --git a/MSUScripter/MSUScripter.csproj b/MSUScripter/MSUScripter.csproj index 7aef28a..5357760 100644 --- a/MSUScripter/MSUScripter.csproj +++ b/MSUScripter/MSUScripter.csproj @@ -8,7 +8,7 @@ true MSUScripterIcon.ico MSUScripterIcon.ico - 4.0.1 + 4.1.0 8.0.0 false 12 diff --git a/MSUScripter/Services/ControlServices/AddSongWindowService.cs b/MSUScripter/Services/ControlServices/AddSongWindowService.cs index 2932041..847488d 100644 --- a/MSUScripter/Services/ControlServices/AddSongWindowService.cs +++ b/MSUScripter/Services/ControlServices/AddSongWindowService.cs @@ -32,7 +32,7 @@ public AddSongWindowViewModel InitializeModel(MsuProjectViewModel project, int? _model.SingleMode = singleMode; _model.TrackSearchItems = [new ComboBoxAndSearchItem(null, "Track", addDescriptions ? "Default description" : null)]; _model.TrackSearchItems.AddRange(project.Tracks.OrderBy(x => x.TrackNumber).Select(x => - new ComboBoxAndSearchItem(x, $"Track #{x.TrackNumber} - {x.TrackName}", x.Description))); + new ComboBoxAndSearchItem(x, x.ToString(), x.Description))); _model.SelectedTrack = trackNumber == null ? null : project.Tracks.FirstOrDefault(x => x.TrackNumber == trackNumber); UpdateFilePath(filePath); diff --git a/MSUScripter/Services/ControlServices/AudioAnalysisWindowService.cs b/MSUScripter/Services/ControlServices/AudioAnalysisWindowService.cs index 3703d5c..51a5738 100644 --- a/MSUScripter/Services/ControlServices/AudioAnalysisWindowService.cs +++ b/MSUScripter/Services/ControlServices/AudioAnalysisWindowService.cs @@ -24,7 +24,9 @@ public AudioAnalysisViewModel InitializeModel(MsuProjectViewModel project) return _model; } - var songs = project.Tracks.SelectMany(x => x.Songs) + var songs = project.Tracks + .Where(x => !x.IsScratchPad) + .SelectMany(x => x.Songs) .OrderBy(x => x.TrackNumber) .Select(x => new AudioAnalysisSongViewModel() { diff --git a/MSUScripter/Services/ControlServices/CopyMoveTrackWindowService.cs b/MSUScripter/Services/ControlServices/CopyMoveTrackWindowService.cs index 9693b37..1b6a6bd 100644 --- a/MSUScripter/Services/ControlServices/CopyMoveTrackWindowService.cs +++ b/MSUScripter/Services/ControlServices/CopyMoveTrackWindowService.cs @@ -8,7 +8,7 @@ namespace MSUScripter.Services.ControlServices; -public class CopyMoveTrackWindowService (ConverterService converterService, ILogger logger) : ControlService +public class CopyMoveTrackWindowService (ConverterService converterService) : ControlService { private readonly CopyMoveTrackWindowViewModel _model = new(); @@ -76,34 +76,6 @@ public void RunCopyMove() } } - private void FixTrackSuffixes(MsuTrackInfoViewModel track) - { - if (_model.Project == null) - { - return; - } - - var msu = new FileInfo(_model.Project.MsuPath); - - for (var i = 0; i < track.Songs.Count; i++) - { - var songInfo = track.Songs[i]; - - if (i == 0) - { - songInfo.OutputPath = msu.FullName.Replace(msu.Extension, $"-{track.TrackNumber}.pcm"); - } - else - { - var altSuffix = i == 1 ? "alt" : $"alt{i}"; - songInfo.OutputPath = - msu.FullName.Replace(msu.Extension, $"-{track.TrackNumber}_{altSuffix}.pcm"); - } - - songInfo.ApplyCascadingSettings(_model.Project, track, i > 0, _model.PreviousSong?.CanPlaySongs == true, true, true); - } - } - public void UpdateTrackLocations() { List locationOptions = []; @@ -122,8 +94,6 @@ public void UpdateTrackLocations() } } - logger.LogInformation("{Location}", _model.TargetTrack.TrackName); - if (_model.Type != CopyMoveType.Swap) { locationOptions.Add("At the end of the list"); diff --git a/MSUScripter/Services/ControlServices/EditProjectPanelService.cs b/MSUScripter/Services/ControlServices/EditProjectPanelService.cs index 0375f1e..6f2179e 100644 --- a/MSUScripter/Services/ControlServices/EditProjectPanelService.cs +++ b/MSUScripter/Services/ControlServices/EditProjectPanelService.cs @@ -219,7 +219,7 @@ public bool OpenFolder() public void UpdateExportMenuOptions() { _model.DisplayAltSwapperExportButton = - _model.CreateAltSwapper && _model.MsuProjectViewModel?.Tracks.Any(x => x.Songs.Count > 1) == true; + _model.CreateAltSwapper && _model.MsuProjectViewModel?.Tracks.Any(x => x is { IsScratchPad: false, Songs.Count: > 1 }) == true; } public void Disable() diff --git a/MSUScripter/Services/ControlServices/MsuPcmGenerationWindowService.cs b/MSUScripter/Services/ControlServices/MsuPcmGenerationWindowService.cs index 4b0baf8..645c67a 100644 --- a/MSUScripter/Services/ControlServices/MsuPcmGenerationWindowService.cs +++ b/MSUScripter/Services/ControlServices/MsuPcmGenerationWindowService.cs @@ -30,7 +30,9 @@ public MsuPcmGenerationViewModel InitializeModel(MsuProjectViewModel project, bo var msuDirectory = new FileInfo(project.MsuPath).DirectoryName; if (string.IsNullOrEmpty(msuDirectory)) return _model; - var songs = project.Tracks.SelectMany(x => x.Songs) + var songs = project.Tracks + .Where(x => !x.IsScratchPad) + .SelectMany(x => x.Songs) .OrderBy(x => x.TrackNumber) .Select(x => new MsuPcmGenerationSongViewModel() { diff --git a/MSUScripter/Services/ControlServices/PackageMsuWindowService.cs b/MSUScripter/Services/ControlServices/PackageMsuWindowService.cs index 45dfccc..d9f24b5 100644 --- a/MSUScripter/Services/ControlServices/PackageMsuWindowService.cs +++ b/MSUScripter/Services/ControlServices/PackageMsuWindowService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -30,6 +31,8 @@ public class PackageMsuWindowService : ControlService public PackageMsuWindowViewModel InitializeModel(MsuProjectViewModel project) { _model.Project = project; + _model.ValidPcmPaths = project.Tracks.Where(x => !x.IsScratchPad).SelectMany(x => x.Songs) + .Select(x => x.OutputPath).Where(x => !string.IsNullOrEmpty(x)).Cast().ToList(); return _model; } @@ -66,6 +69,12 @@ public void PackageProjectTask(string zipPath) { continue; } + + if (string.Equals(Path.GetExtension(file), ".pcm", StringComparison.OrdinalIgnoreCase) && + !_model.ValidPcmPaths.Contains(file)) + { + continue; + } sb.AppendLine($"... adding {file}"); _model.Response = sb.ToString(); diff --git a/MSUScripter/Services/ControlServices/PyMusicLooperPanelService.cs b/MSUScripter/Services/ControlServices/PyMusicLooperPanelService.cs index 474b0f2..0daec01 100644 --- a/MSUScripter/Services/ControlServices/PyMusicLooperPanelService.cs +++ b/MSUScripter/Services/ControlServices/PyMusicLooperPanelService.cs @@ -306,7 +306,7 @@ async void GenerateTempPcm(PyMusicLooperResultViewModel result) private async Task CreateTempPcm(PyMusicLooperResultViewModel result, bool skipCleanup) { var normalization = _model.MsuSongMsuPcmInfoViewModel.Normalization ?? - _model.MsuProjectViewModel.BasicInfo.Normalization ?? -25; + _model.MsuProjectViewModel.BasicInfo.Normalization; return await msuPcmService.CreateTempPcm(false, _model.MsuProject, _model.MsuSongMsuPcmInfoViewModel.GetEffectiveFile()!, result.LoopStart, result.LoopEnd, normalization, skipCleanup: skipCleanup); } diff --git a/MSUScripter/Services/ControlServices/TrackOverviewPanelService.cs b/MSUScripter/Services/ControlServices/TrackOverviewPanelService.cs index b3eaeb6..fe45c8c 100644 --- a/MSUScripter/Services/ControlServices/TrackOverviewPanelService.cs +++ b/MSUScripter/Services/ControlServices/TrackOverviewPanelService.cs @@ -24,7 +24,7 @@ public void RefreshTracks() _model.Rows.Clear(); - foreach (var track in tracks.OrderBy(x => x.TrackNumber)) + foreach (var track in tracks.Where(x => !x.IsScratchPad).OrderBy(x => x.TrackNumber)) { if (!track.Songs.Any()) { diff --git a/MSUScripter/Services/ControlServices/VideoCreatorWindowService.cs b/MSUScripter/Services/ControlServices/VideoCreatorWindowService.cs index 0b817bc..7585a1d 100644 --- a/MSUScripter/Services/ControlServices/VideoCreatorWindowService.cs +++ b/MSUScripter/Services/ControlServices/VideoCreatorWindowService.cs @@ -26,7 +26,7 @@ public VideoCreatorWindowViewModel InitializeModel(MsuProjectViewModel project) { _model.PreviousPath = settings.PreviousPath; - _model.PcmPaths = project.Tracks.SelectMany(x => x.Songs) + _model.PcmPaths = project.Tracks.Where(x => !x.IsScratchPad).SelectMany(x => x.Songs) .Where(x => x.CheckCopyright && File.Exists(x.OutputPath)).Select(x => x.OutputPath).ToList(); if (_model.PcmPaths.Count == 0) diff --git a/MSUScripter/Services/ConverterService.cs b/MSUScripter/Services/ConverterService.cs index 1f7d846..a22931c 100644 --- a/MSUScripter/Services/ConverterService.cs +++ b/MSUScripter/Services/ConverterService.cs @@ -72,12 +72,14 @@ public MsuProjectViewModel ConvertProject(MsuProject project) foreach (var track in project.Tracks) { - var msuTypeTrack = project.MsuType.Tracks.First(x => x.Number == track.TrackNumber); + var msuTypeTrack = project.MsuType.Tracks.FirstOrDefault(x => x.Number == track.TrackNumber); var trackViewModel = new MsuTrackInfoViewModel() { Project = viewModel, - Description = msuTypeTrack.Description + Description = track.IsScratchPad + ? "Use this page to add songs for keeping and editing without including them in the MSU. All songs included in this will not be included when generating and packaging the MSU." + : msuTypeTrack?.Description }; ConvertViewModel(track, trackViewModel); diff --git a/MSUScripter/Services/MsuPcmService.cs b/MSUScripter/Services/MsuPcmService.cs index 8d00f0e..7cbd802 100644 --- a/MSUScripter/Services/MsuPcmService.cs +++ b/MSUScripter/Services/MsuPcmService.cs @@ -610,13 +610,13 @@ private bool RunMsuPcmInternal(string innerCommand, string expectedOutputPath, o Dither = project.BasicInfo.Dither, Verbosity = 2, Keep_temps = standAlone && _settings.RunMsuPcmWithKeepTemps, - First_track = project.Tracks.Min(x => x.TrackNumber), - Last_track = project.Tracks.Max(x => x.TrackNumber) + First_track = singleSong?.TrackNumber ?? project.Tracks.Min(x => x.TrackNumber), + Last_track = singleSong?.TrackNumber ?? project.Tracks.Where(x => !x.IsScratchPad).Max(x => x.TrackNumber) }; var tracks = new List(); var songs = singleSong == null - ? project.Tracks.SelectMany(x => x.Songs).ToList() + ? project.Tracks.Where(x => !x.IsScratchPad).SelectMany(x => x.Songs).ToList() : new List() { singleSong }; foreach (var song in songs) diff --git a/MSUScripter/Services/ProjectService.cs b/MSUScripter/Services/ProjectService.cs index 82c7f81..0392287 100644 --- a/MSUScripter/Services/ProjectService.cs +++ b/MSUScripter/Services/ProjectService.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Text; +using DynamicData; using Microsoft.Extensions.Logging; using MSURandomizerLibrary.Configs; using MSURandomizerLibrary.Services; @@ -122,6 +123,16 @@ public void SaveMsuProject(MsuProject project, bool isBackup) } } + if (!project.Tracks.Any(x => x.IsScratchPad)) + { + project.Tracks.Add(new MsuTrackInfo() + { + TrackNumber = 9999, + TrackName = "Scratch Pad", + IsScratchPad = true, + }); + } + if (project.MsuType == msuTypeService.GetSMZ3LegacyMSUType() || project.MsuType == msuTypeService.GetSMZ3MsuType()) { project.BasicInfo.IsSmz3Project = true; @@ -167,6 +178,13 @@ public MsuProject NewMsuProject(string projectPath, MsuType msuType, string msuP TrackName = track.Name }); } + + project.Tracks.Add(new MsuTrackInfo() + { + TrackNumber = 9999, + TrackName = "Scratch Pad", + IsScratchPad = true + }); if (!File.Exists(msuPath)) { @@ -283,6 +301,12 @@ public void ConvertProjectMsuType(MsuProject project, MsuType newMsuType, bool s var newTracks = new List(); foreach (var oldTrack in project.Tracks) { + if (oldTrack.IsScratchPad) + { + newTracks.Add(oldTrack); + continue; + } + var newTrackNumber = conversion(oldTrack.TrackNumber); if (oldTrack.TrackNumber == newTrackNumber) @@ -403,6 +427,7 @@ private MsuProject InternalGetSmz3MsuProject(MsuProject project, MsuType msuType var conversion = msuType.Conversions[project.MsuType]; var trackConversions = project.Tracks + .Where(x => !x.IsScratchPad) .Select(x => (x.TrackNumber, conversion(x.TrackNumber))) .Where(x => msuType.ValidTrackNumbers.Contains(x.Item2)); @@ -689,7 +714,7 @@ public void ExportMsuRandomizerYaml(MsuProject project, out string? error) var tracks = new List(); - foreach (var projectTrack in project.Tracks) + foreach (var projectTrack in project.Tracks.Where(x => !x.IsScratchPad)) { foreach (var projectSong in projectTrack.Songs) { @@ -799,14 +824,14 @@ public bool CreateAltSwapperFile(MsuProject project, ICollection? ot { var sb = new StringBuilder(); - var trackCombos = project.Tracks.Where(t => t.Songs.Count > 1) + var trackCombos = project.Tracks.Where(t => t is { IsScratchPad: false, Songs.Count: > 1 }) .Select(t => (t.Songs.First(s => !s.IsAlt), t.Songs.First(s => s.IsAlt))).ToList(); if (otherProjects != null) { foreach (var otherProject in otherProjects) { - trackCombos.AddRange(otherProject.Tracks.Where(t => t.Songs.Count > 1) + trackCombos.AddRange(otherProject.Tracks.Where(t => t is { IsScratchPad: false, Songs.Count: > 1 }) .Select(t => (t.Songs.First(s => !s.IsAlt), t.Songs.First(s => s.IsAlt)))); } } @@ -851,9 +876,9 @@ public bool ValidateProject(MsuProjectViewModel project, out string message) return false; } - var projectTracks = project.Tracks.SelectMany(x => x.Songs).ToList(); + var projectSongs = project.Tracks.Where(x => !x.IsScratchPad).SelectMany(x => x.Songs).ToList(); - var projectTrackNumbers = project.Tracks.SelectMany(x => x.Songs).Select(x => x.TrackNumber).Order().ToList(); + var projectTrackNumbers = projectSongs.Select(x => x.TrackNumber).Order().ToList(); var msuTrackNumbers = msu.Tracks.Where(x => !x.IsCopied).Select(x => x.Number).Order().ToList(); if (!projectTrackNumbers.SequenceEqual(msuTrackNumbers)) { @@ -885,21 +910,21 @@ public bool ValidateProject(MsuProjectViewModel project, out string message) return false; } - foreach (var projectTrack in projectTracks) + foreach (var projectSong in projectSongs) { - var filename = new FileInfo(projectTrack.OutputPath!).Name; + var filename = new FileInfo(projectSong.OutputPath!).Name; var msuTrack = msu.Tracks.FirstOrDefault(x => x.Path.EndsWith(filename)); if (msuTrack == null) { - message = $"Could not find track for song {projectTrack.SongName} in the YAML file."; + message = $"Could not find track for song {projectSong.SongName} in the YAML file."; statusBarService.UpdateStatusBar("YAML File Validation Failed"); return false; } - else if ((projectTrack.SongName ?? "") != msuTrack.SongName || (projectTrack.Album ?? "") != (msuTrack.Album ?? "") || - (projectTrack.Artist ?? "") != (msuTrack.Artist ?? "") || (projectTrack.Url ?? "") != (msuTrack.Url ?? "")) + else if ((projectSong.SongName ?? "") != msuTrack.SongName || (projectSong.Album ?? "") != (msuTrack.Album ?? "") || + (projectSong.Artist ?? "") != (msuTrack.Artist ?? "") || (projectSong.Url ?? "") != (msuTrack.Url ?? "")) { - message = $"Detail mismatch for song {projectTrack.SongName} under track #{projectTrack.TrackNumber}."; + message = $"Detail mismatch for song {projectSong.SongName} under track #{projectSong.TrackNumber}."; statusBarService.UpdateStatusBar("YAML File Validation Failed"); return false; } diff --git a/MSUScripter/Services/SharedPcmService.cs b/MSUScripter/Services/SharedPcmService.cs index 6f85ade..97b8a2c 100644 --- a/MSUScripter/Services/SharedPcmService.cs +++ b/MSUScripter/Services/SharedPcmService.cs @@ -15,6 +15,13 @@ public async Task GeneratePcmFile(MsuSongInfoViewModel { return new GeneratePcmFileResponse(false, false, "Currently generating another file", null); } + + if (songInfo.Track.IsScratchPad && songInfo.OutputPath?.StartsWith(Directories.TempFolder) != true) + { + var msuFile = new FileInfo(songInfo.Project.MsuPath); + var pcmFileName = msuFile.Name.Replace(msuFile.Extension, $"-{Guid.NewGuid()}.pcm"); + songInfo.OutputPath = Path.Combine(Directories.TempFolder, pcmFileName); + } await audioPlayerService.StopSongAsync(null, true); diff --git a/MSUScripter/Services/TrackListService.cs b/MSUScripter/Services/TrackListService.cs index 18750f4..0fb9f1a 100644 --- a/MSUScripter/Services/TrackListService.cs +++ b/MSUScripter/Services/TrackListService.cs @@ -47,17 +47,17 @@ public void WriteTrackListFile(MsuProject project) metroidTrackModifier = 0; } - var zeldaTracks = project.Tracks.Where(t => - t.TrackNumber >= zeldaTrackRange.Item1 && t.TrackNumber <= zeldaTrackRange.Item2 && t.Songs.Any()); + var zeldaTracks = project.Tracks.Where(t => !t.IsScratchPad && + t.TrackNumber >= zeldaTrackRange.Item1 && t.TrackNumber <= zeldaTrackRange.Item2 && t.Songs.Count != 0); - var metroidTracks = project.Tracks.Where(t => + var metroidTracks = project.Tracks.Where(t => !t.IsScratchPad && t.TrackNumber >= metroidTrackRange.Item1 && t.TrackNumber <= metroidTrackRange.Item2 && - t.Songs.Any()); + t.Songs.Count != 0); - var smz3Tracks = project.Tracks.Where(t => + var smz3Tracks = project.Tracks.Where(t => !t.IsScratchPad && !(t.TrackNumber >= zeldaTrackRange.Item1 && t.TrackNumber <= zeldaTrackRange.Item2) && !(t.TrackNumber >= metroidTrackRange.Item1 && t.TrackNumber <= metroidTrackRange.Item2) && - t.Songs.Any()); + t.Songs.Count != 0); if (project.BasicInfo.TrackList == TrackListType.List) { @@ -81,9 +81,9 @@ public void WriteTrackListFile(MsuProject project) } else { - var songs = project.Tracks.SelectMany(x => x.Songs).ToList(); + var songs = project.Tracks.Where(x => !x.IsScratchPad).SelectMany(x => x.Songs).ToList(); var numberLength = songs.Any(x => x.IsAlt) ? 12 : 6; - var trackLength = project.Tracks.Max(x => x.TrackName.Length) + 4; + var trackLength = project.Tracks.Where(x => !x.IsScratchPad).Max(x => x.TrackName.Length) + 4; var albumLength = songs.Max(x => string.IsNullOrEmpty(x.Album) ? 0 : x.Album.CleanString().Length + 4); var songLength = songs.Max(x => string.IsNullOrEmpty(x.SongName) ? 0 : x.SongName.CleanString().Length + 4); var artistLength = songs.Max(x => string.IsNullOrEmpty(x.Artist) ? 0 : x.Artist.CleanString().Length + 4); @@ -107,7 +107,7 @@ public void WriteTrackListFile(MsuProject project) } else { - var allTracks = project.Tracks.Where(t => t.Songs.Any()); + var allTracks = project.Tracks.Where(t => !t.IsScratchPad && t.Songs.Count != 0); if (project.BasicInfo.TrackList == TrackListType.List) { @@ -139,7 +139,7 @@ public void WriteTrackListFile(MsuProject project) private void AppendTrackList(IEnumerable tracks, StringBuilder sb, int trackModifier) { - foreach (var track in tracks.OrderBy(x => x.TrackNumber)) + foreach (var track in tracks.Where(x => !x.IsScratchPad).OrderBy(x => x.TrackNumber)) { sb.AppendLine($"Track {track.TrackNumber + trackModifier} ({track.TrackName})"); @@ -186,7 +186,7 @@ private void AppendTrackTable(IEnumerable tracks, StringBuilder sb var header = $"{headerNumber}{headerTrack}{headerAlbum}{headerSong}{headerArtist}"; sb.AppendLine(header); sb.AppendLine(new string('-', header.Length)); - foreach (var track in tracks.OrderBy(x => x.TrackNumber)) + foreach (var track in tracks.Where(x => !x.IsScratchPad).OrderBy(x => x.TrackNumber)) { foreach (var song in track.Songs.OrderBy(x => x.IsAlt)) { diff --git a/MSUScripter/ViewModels/MsuSongInfoViewModel.cs b/MSUScripter/ViewModels/MsuSongInfoViewModel.cs index 958307f..a5b4987 100644 --- a/MSUScripter/ViewModels/MsuSongInfoViewModel.cs +++ b/MSUScripter/ViewModels/MsuSongInfoViewModel.cs @@ -35,6 +35,8 @@ public MsuSongInfoViewModel() [Reactive] public string? OutputPath { get; set; } [Reactive] public bool IsAlt { get; set; } + + public bool DisplayPcmFile => !Track.IsScratchPad; [Reactive] public bool IsComplete { get; set; } @@ -61,6 +63,7 @@ public MsuSongInfoViewModel() [SkipConvert] public bool HasAudioAnalysis => !string.IsNullOrEmpty(PeakAudio); [Reactive] public bool ShowPanel { get; set; } = true; + public bool ShowCreatePcmSection => Project.BasicInfo.IsMsuPcmProject && !Track.IsScratchPad; public MsuSongMsuPcmInfoViewModel MsuPcmInfo { get; set; } = new(); public bool HasChangesSince(DateTime time) diff --git a/MSUScripter/ViewModels/MsuTrackInfoViewModel.cs b/MSUScripter/ViewModels/MsuTrackInfoViewModel.cs index 821aa8c..e45d630 100644 --- a/MSUScripter/ViewModels/MsuTrackInfoViewModel.cs +++ b/MSUScripter/ViewModels/MsuTrackInfoViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using MSUScripter.Models; using ReactiveUI; +using ReactiveUI.Fody.Helpers; namespace MSUScripter.ViewModels; @@ -24,7 +25,7 @@ public MsuTrackInfoViewModel() public DateTime LastModifiedDate { get; set; } - [SkipConvert] public string? Description { get; set; } + [SkipConvert, Reactive] public string? Description { get; set; } [SkipConvert] public bool HasDescription => !string.IsNullOrEmpty(Description); @@ -34,6 +35,8 @@ public MsuTrackInfoViewModel() [SkipConvert] public string Display => ToString(); + public bool IsScratchPad { get; set; } + public bool HasChangesSince(DateTime time) { return Songs.Any(x => x.HasChangesSince(time)) || LastModifiedDate > time; @@ -66,7 +69,7 @@ public void FixTrackSuffixes(bool? canPlaySongs = null) public override string ToString() { - return $"Track #{TrackNumber} - {TrackName}"; + return IsScratchPad ? "Scratch Pad" : $"Track #{TrackNumber} - {TrackName}"; } public override ViewModelBase DesignerExample() diff --git a/MSUScripter/ViewModels/PackageMsuWindowViewModel.cs b/MSUScripter/ViewModels/PackageMsuWindowViewModel.cs index 341d515..625ef2a 100644 --- a/MSUScripter/ViewModels/PackageMsuWindowViewModel.cs +++ b/MSUScripter/ViewModels/PackageMsuWindowViewModel.cs @@ -1,4 +1,5 @@ -using ReactiveUI.Fody.Helpers; +using System.Collections.Generic; +using ReactiveUI.Fody.Helpers; namespace MSUScripter.ViewModels; @@ -11,6 +12,8 @@ public class PackageMsuWindowViewModel : ViewModelBase [Reactive] public string Response { get; set; } = ""; [Reactive] public bool IsRunning { get; set; } + + public List ValidPcmPaths = []; public override ViewModelBase DesignerExample() { diff --git a/MSUScripter/ViewModels/TrackOverviewPanelViewModel.cs b/MSUScripter/ViewModels/TrackOverviewPanelViewModel.cs index f7d0bb9..c91d709 100644 --- a/MSUScripter/ViewModels/TrackOverviewPanelViewModel.cs +++ b/MSUScripter/ViewModels/TrackOverviewPanelViewModel.cs @@ -21,9 +21,9 @@ public class TrackOverviewPanelViewModel : ViewModelBase [Reactive] public int SelectedIndex { get; set; } = 0; - public int TotalTrackCount => MsuProjectViewModel.Tracks.Count; + public int TotalTrackCount => MsuProjectViewModel.Tracks.Count(x => !x.IsScratchPad); - public int CompletedTrackCount => MsuProjectViewModel.Tracks.Count(x => x.Songs.Any(y => y.HasFiles())); + public int CompletedTrackCount => MsuProjectViewModel.Tracks.Count(x => !x.IsScratchPad && x.Songs.Any(y => y.HasFiles())); public int TotalSongCount => Rows.Count(x => x.HasSong); diff --git a/MSUScripter/Views/EditProjectPanel.axaml b/MSUScripter/Views/EditProjectPanel.axaml index 245ae30..c1523d0 100644 --- a/MSUScripter/Views/EditProjectPanel.axaml +++ b/MSUScripter/Views/EditProjectPanel.axaml @@ -50,6 +50,13 @@ Padding="5" Click="TrackOverviewMenuItem_OnClick" > + diff --git a/MSUScripter/Views/EditProjectPanel.axaml.cs b/MSUScripter/Views/EditProjectPanel.axaml.cs index e3a7964..e114b82 100644 --- a/MSUScripter/Views/EditProjectPanel.axaml.cs +++ b/MSUScripter/Views/EditProjectPanel.axaml.cs @@ -278,4 +278,9 @@ private void EnableExport() { this.Find(nameof(ExportMenuButton))!.IsEnabled = true; } + + private void ScratchPadMenuItem_OnClick(object? sender, RoutedEventArgs e) + { + _service?.SetPage(9999); + } } \ No newline at end of file diff --git a/MSUScripter/Views/MsuSongInfoPanel.axaml b/MSUScripter/Views/MsuSongInfoPanel.axaml index ad11ce1..4043aed 100644 --- a/MSUScripter/Views/MsuSongInfoPanel.axaml +++ b/MSUScripter/Views/MsuSongInfoPanel.axaml @@ -119,7 +119,7 @@ > - + - +