diff --git a/BallanceTasEditor/BallanceTasEditor/Backend/AppSettings.cs b/BallanceTasEditor/BallanceTasEditor/Backend/AppSettings.cs
new file mode 100644
index 0000000..0e2a4d2
--- /dev/null
+++ b/BallanceTasEditor/BallanceTasEditor/Backend/AppSettings.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BallanceTasEditor.Backend {
+
+ public enum EditorLayoutKind {
+ Horizontal, Vertical
+ }
+
+ public class AppSettings {
+
+
+
+ public EditorLayoutKind EditorLayout { get; set; }
+
+ }
+}
diff --git a/BallanceTasEditor/BallanceTasEditor/Backend/TasFrame.cs b/BallanceTasEditor/BallanceTasEditor/Backend/TasFrame.cs
index 3a907b0..d3c38c1 100644
--- a/BallanceTasEditor/BallanceTasEditor/Backend/TasFrame.cs
+++ b/BallanceTasEditor/BallanceTasEditor/Backend/TasFrame.cs
@@ -156,6 +156,14 @@ namespace BallanceTasEditor.Backend {
raw.KeyFlags = m_KeyFlags;
}
+ ///
+ /// 返回自身的克隆(深拷贝)。
+ ///
+ /// 自身的克隆。
+ public TasFrame Clone() {
+ return new TasFrame(m_TimeDelta, m_KeyFlags);
+ }
+
///
/// 该帧的持续时间(以秒为单位)。
///
diff --git a/BallanceTasEditor/BallanceTasEditor/Backend/TasStorage.cs b/BallanceTasEditor/BallanceTasEditor/Backend/TasStorage.cs
index 7cc1d3c..675c34c 100644
--- a/BallanceTasEditor/BallanceTasEditor/Backend/TasStorage.cs
+++ b/BallanceTasEditor/BallanceTasEditor/Backend/TasStorage.cs
@@ -10,11 +10,31 @@ using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
public static class TasStorage {
+
+ ///
+ /// Initialize given TAS sequence with given count frame which has given FPS.
+ ///
+ /// The TAS sequence to initialize.
+ /// The count of frame.
+ /// The FPS of frame.
+ public static void Init(ITasSequence seq, int count, uint fps) {
+ var frame = TasFrame.FromFps(fps);
+ var iter = Enumerable.Range(0, count).Select((_) => frame.Clone());
+ var exactSizeIter = new ExactSizeEnumerableAdapter(iter, count);
+ seq.Insert(seq.GetCount(), exactSizeIter);
+ }
+
internal const int SIZEOF_I32 = sizeof(int);
internal const int SIZEOF_F32 = sizeof(float);
internal const int SIZEOF_U32 = sizeof(uint);
internal const int SIZEOF_RAW_TAS_FRAME = SIZEOF_F32 + SIZEOF_U32;
+ ///
+ /// Save given TAS sequence into given file path.
+ ///
+ /// The path to file for saving.
+ /// The TAS sequence to save.
+ /// Any exception occurs when saving.
public static void Save(string filepath, ITasSequence seq) {
using (var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) {
Save(fs, seq);
@@ -22,6 +42,12 @@ namespace BallanceTasEditor.Backend {
}
}
+ ///
+ /// Save given TAS sequence into given file stream.
+ ///
+ /// The file stream for saving.
+ /// The TAS sequence to save.
+ /// Any exception occurs when saving.
public static void Save(Stream fs, ITasSequence seq) {
var totalByte = seq.GetCount() * SIZEOF_RAW_TAS_FRAME;
fs.Write(BitConverter.GetBytes(totalByte), 0, SIZEOF_I32);
@@ -46,6 +72,12 @@ namespace BallanceTasEditor.Backend {
//zo.Close();
}
+ ///
+ /// Load TAS sequence from given file path into given sequence.
+ ///
+ /// The path to file for loading.
+ /// The TAS sequence to load.
+ /// Any exception occurs when loading.
public static void Load(string filepath, ITasSequence seq) {
using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
Load(fs, seq);
@@ -53,6 +85,12 @@ namespace BallanceTasEditor.Backend {
}
}
+ ///
+ /// Load TAS sequence from given file stream into given sequence.
+ ///
+ /// The file stream for loading.
+ /// The TAS sequence to load.
+ /// Any exception occurs when loading.
public static void Load(Stream fs, ITasSequence seq) {
// Read total bytes
var lenCache = new byte[SIZEOF_I32];
diff --git a/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj b/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
index 54e2f8f..f14dc7d 100644
--- a/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
+++ b/BallanceTasEditor/BallanceTasEditor/BallanceTasEditor.csproj
@@ -17,9 +17,12 @@
+
+
+
diff --git a/BallanceTasEditor/BallanceTasEditor/Frontend/Behaviors/ConfirmCloseBehavior.cs b/BallanceTasEditor/BallanceTasEditor/Frontend/Behaviors/ConfirmCloseBehavior.cs
new file mode 100644
index 0000000..674b2c5
--- /dev/null
+++ b/BallanceTasEditor/BallanceTasEditor/Frontend/Behaviors/ConfirmCloseBehavior.cs
@@ -0,0 +1,49 @@
+using Microsoft.Xaml.Behaviors;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace BallanceTasEditor.Frontend.Behaviors {
+ public class ConfirmCloseBehavior : Behavior {
+
+ public ICommand ConfirmCommand {
+ get { return (ICommand)GetValue(ConfirmCommandProperty); }
+ set { SetValue(ConfirmCommandProperty, value); }
+ }
+
+ // Using a DependencyProperty as the backing store for ConfirmCommand. This enables animation, styling, binding, etc...
+ public static readonly DependencyProperty ConfirmCommandProperty =
+ DependencyProperty.Register("ConfirmCommand", typeof(ICommand), typeof(ConfirmCloseBehavior));
+
+
+ protected override void OnAttached() {
+ base.OnAttached();
+ AssociatedObject.Closing += OnClosing;
+ }
+
+ protected override void OnDetaching() {
+ AssociatedObject.Closing -= OnClosing;
+ base.OnDetaching();
+ }
+
+ private void OnClosing(object? sender, CancelEventArgs e) {
+ if (ConfirmCommand?.CanExecute(null) == true) {
+ // 假设Command返回 bool 或通过回调/事件通知结果
+ bool allowClose = (Func