feat: use TasFile model to replace some view model code.
This commit is contained in:
@@ -15,13 +15,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.4.0" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||
<PackageReference Include="OneOf" Version="3.0.271" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Frontend\Models\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BallanceTasEditor.Frontend.Models {
|
||||
public partial class TasFile : ObservableObject {
|
||||
public TasFile() {
|
||||
FileBody = null;
|
||||
}
|
||||
|
||||
#region File Load and Save
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsFileLoaded))]
|
||||
[NotifyPropertyChangedFor(nameof(IsFileNotLoaded))]
|
||||
private Backend.ITasSequence? fileBody;
|
||||
|
||||
[MemberNotNullWhen(true, nameof(FileBody))]
|
||||
public bool IsFileLoaded {
|
||||
get => FileBody is not null;
|
||||
}
|
||||
|
||||
[MemberNotNullWhen(false, nameof(FileBody))]
|
||||
public bool IsFileNotLoaded {
|
||||
get => FileBody is null;
|
||||
}
|
||||
|
||||
public void NewFile(TasSequenceKind kind, int count, uint fps) {
|
||||
// Check status
|
||||
if (IsFileLoaded) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Initialize sequence
|
||||
var seq = TasSequenceKindHelper.CreateSequenceByKind(kind);
|
||||
// Initialize items
|
||||
Backend.TasStorage.Init(seq, count, fps);
|
||||
// Set members
|
||||
FileBody = seq;
|
||||
}
|
||||
|
||||
public void LoadFile(TasSequenceKind kind, string path) {
|
||||
// Check status
|
||||
if (IsFileLoaded) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Initialize sequence
|
||||
var seq = TasSequenceKindHelper.CreateSequenceByKind(kind);
|
||||
// Load into sequence
|
||||
Backend.TasStorage.Load(path, seq);
|
||||
// Set members
|
||||
FileBody = seq;
|
||||
}
|
||||
|
||||
public void SaveFile(string path) {
|
||||
// Check status
|
||||
if (IsFileNotLoaded) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Save sequence
|
||||
Backend.TasStorage.Save(path, FileBody);
|
||||
}
|
||||
|
||||
public void CloseFile() {
|
||||
// Check status
|
||||
if (IsFileNotLoaded) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Set member
|
||||
FileBody = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BallanceTasEditor.Frontend.Models {
|
||||
public enum TasSequenceKind {
|
||||
Array,
|
||||
DoubleLinkedList
|
||||
}
|
||||
|
||||
public static class TasSequenceKindHelper {
|
||||
public static Backend.ITasSequence CreateSequenceByKind(TasSequenceKind kind) {
|
||||
return kind switch {
|
||||
TasSequenceKind.Array => new Backend.ListTasSequence(),
|
||||
TasSequenceKind.DoubleLinkedList => new Backend.LegacyTasSequence(),
|
||||
_ => throw new UnreachableException(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,8 +15,9 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
public MainWindow(Shared.IDialogService dialogService) {
|
||||
m_DialogService = dialogService;
|
||||
|
||||
this.TasFile = null;
|
||||
this.TasFilePath = null;
|
||||
TasFile = new Models.TasFile();
|
||||
TasFile.PropertyChanged += TasFile_PropertyChanged;
|
||||
TasFilePath = null;
|
||||
|
||||
this.StatusMessage = "";
|
||||
m_StatusMessageDimmer = new DispatcherTimer();
|
||||
@@ -33,34 +34,38 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(WindowTitle))]
|
||||
[NotifyCanExecuteChangedFor(nameof(NewFileCommand))]
|
||||
[NotifyCanExecuteChangedFor(nameof(OpenFileCommand))]
|
||||
[NotifyCanExecuteChangedFor(nameof(SaveFileCommand))]
|
||||
[NotifyCanExecuteChangedFor(nameof(SaveFileAsCommand))]
|
||||
[NotifyCanExecuteChangedFor(nameof(CloseFileCommand))]
|
||||
private Backend.ITasSequence? tasFile;
|
||||
private Models.TasFile tasFile;
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(WindowTitle))]
|
||||
private string? tasFilePath;
|
||||
|
||||
private void TasFile_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) {
|
||||
// YYC MARK:
|
||||
// Due to the shitty limit of MVVM Toolkit,
|
||||
// I was forced trigger these command manually.
|
||||
NewFileCommand.NotifyCanExecuteChanged();
|
||||
OpenFileCommand.NotifyCanExecuteChanged();
|
||||
SaveFileCommand.NotifyCanExecuteChanged();
|
||||
SaveFileAsCommand.NotifyCanExecuteChanged();
|
||||
CloseFileCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanNewFile))]
|
||||
private void NewFile() {
|
||||
// Request new file properties
|
||||
var dialog = m_DialogService.ShowNewFileDialog();
|
||||
if (dialog is null) return;
|
||||
|
||||
// Initialize sequence
|
||||
var seq = new Backend.ListTasSequence();
|
||||
// Initialize items
|
||||
Backend.TasStorage.Init(seq, dialog.Count, dialog.Fps);
|
||||
// Create new file
|
||||
TasFile.NewFile(Models.TasSequenceKind.Array, dialog.Count, dialog.Fps);
|
||||
// Set members
|
||||
this.TasFile = seq;
|
||||
this.TasFilePath = null;
|
||||
TasFilePath = null;
|
||||
// Send notification
|
||||
UpdateStatusMessage($"New TAS file is created.");
|
||||
}
|
||||
|
||||
private bool CanNewFile() {
|
||||
return this.TasFile is null;
|
||||
return TasFile.IsFileNotLoaded;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanOpenFile))]
|
||||
@@ -69,23 +74,21 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
var dialog = m_DialogService.ShowOpenFileDialog();
|
||||
if (dialog is null) return;
|
||||
|
||||
// Initialize sequence
|
||||
var seq = new Backend.ListTasSequence();
|
||||
// Load into sequence
|
||||
// Load file
|
||||
try {
|
||||
Backend.TasStorage.Load(dialog.Path, seq);
|
||||
TasFile.LoadFile(Models.TasSequenceKind.Array, dialog.Path);
|
||||
} catch (Exception e) {
|
||||
m_DialogService.ShowOpenFileFailedDialog(e);
|
||||
return;
|
||||
}
|
||||
// Set members
|
||||
this.TasFile = seq;
|
||||
this.TasFilePath = dialog.Path;
|
||||
TasFilePath = dialog.Path;
|
||||
// Send notification
|
||||
UpdateStatusMessage($"TAS file {this.TasFilePath} is loaded.");
|
||||
}
|
||||
|
||||
private bool CanOpenFile() {
|
||||
return this.TasFile is null;
|
||||
return TasFile.IsFileNotLoaded;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanSaveFile))]
|
||||
@@ -102,18 +105,19 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
|
||||
// Save file
|
||||
try {
|
||||
Backend.TasStorage.Save(filePath, this.TasFile.Unwrap());
|
||||
TasFile.SaveFile(filePath);
|
||||
} catch (Exception e) {
|
||||
m_DialogService.ShowSaveFileFailedDialog(e);
|
||||
return;
|
||||
}
|
||||
// Update member
|
||||
this.TasFilePath = filePath;
|
||||
TasFilePath = filePath;
|
||||
// Send notification
|
||||
UpdateStatusMessage($"TAS file {this.TasFilePath} is saved.");
|
||||
}
|
||||
|
||||
private bool CanSaveFile() {
|
||||
return this.TasFile is not null;
|
||||
return TasFile.IsFileLoaded;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanSaveFileAs))]
|
||||
@@ -124,29 +128,33 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
|
||||
// Save file
|
||||
try {
|
||||
Backend.TasStorage.Save(dialog.Path, this.TasFile.Unwrap());
|
||||
TasFile.SaveFile(dialog.Path);
|
||||
} catch (Exception e) {
|
||||
m_DialogService.ShowSaveFileFailedDialog(e);
|
||||
return;
|
||||
}
|
||||
// Set file path
|
||||
TasFilePath = dialog.Path;
|
||||
// Send notification
|
||||
UpdateStatusMessage($"TAS file {this.TasFilePath} is saved.");
|
||||
}
|
||||
|
||||
private bool CanSaveFileAs() {
|
||||
return this.TasFile is not null;
|
||||
return TasFile.IsFileLoaded;
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCloseFile))]
|
||||
private void CloseFile() {
|
||||
this.TasFile = null;
|
||||
this.TasFilePath = null;
|
||||
// Close file
|
||||
TasFile.CloseFile();
|
||||
// Set members
|
||||
TasFilePath = null;
|
||||
// Send notification
|
||||
UpdateStatusMessage($"TAS file is closed.");
|
||||
}
|
||||
|
||||
private bool CanCloseFile() {
|
||||
return this.TasFile is not null;
|
||||
return TasFile.IsFileLoaded;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -228,7 +236,7 @@ namespace BallanceTasEditor.Frontend.ViewModels {
|
||||
|
||||
public string WindowTitle {
|
||||
get {
|
||||
if (TasFile is null) {
|
||||
if (TasFile.IsFileNotLoaded) {
|
||||
return "Ballance TAS Editor";
|
||||
} else {
|
||||
if (TasFilePath is null) {
|
||||
|
||||
Reference in New Issue
Block a user