diff --git a/BallanceTASEditor.csproj b/BallanceTASEditor.csproj index 0c888ac..f58ed89 100644 --- a/BallanceTASEditor.csproj +++ b/BallanceTASEditor.csproj @@ -64,6 +64,7 @@ AddItem.xaml + diff --git a/MainWindow.xaml b/MainWindow.xaml index 795d642..2087581 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -25,7 +25,10 @@ + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index cffac24..416b975 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -46,6 +46,7 @@ namespace BallanceTASEditor { mViewer = new TASViewer(mFile, uiTASSlider, uiTASData, uiStatusbar_Selected); RefreshUI(true); ChangeToolMode(ToolMode.Cursor); + mViewer.ChangeOverwrittenMode(uiMenu_Display_OverwrittenPaste.IsChecked); } private void funcMenu_File_Save(object sender, RoutedEventArgs e) { @@ -73,6 +74,20 @@ namespace BallanceTASEditor { } } + private void funcMenu_Display_OverwrittenPaste(object sender, RoutedEventArgs e) { + //uiMenu_Display_OverwrittenPaste.IsChecked = !uiMenu_Display_OverwrittenPaste.IsChecked; + if (mViewer != null) + mViewer.ChangeOverwrittenMode(uiMenu_Display_OverwrittenPaste.IsChecked); + } + + private void funcMenu_Display_Redo(object sender, RoutedEventArgs e) { + mViewer.ProcessOperation(OperationEnum.Redo); + } + + private void funcMenu_Display_Undo(object sender, RoutedEventArgs e) { + mViewer.ProcessOperation(OperationEnum.Undo); + } + // =========================== btn private void funcBtn_Cursor(object sender, RoutedEventArgs e) { ChangeToolMode(ToolMode.Cursor); @@ -173,6 +188,9 @@ namespace BallanceTASEditor { uiMenu_File_Close.IsEnabled = true; uiMenu_Display_ItemCount.IsEnabled = true; + uiMenu_Display_OverwrittenPaste.IsEnabled = true; + uiMenu_Display_Undo.IsEnabled = true; + uiMenu_Display_Redo.IsEnabled = true; uiStatusbar.Visibility = Visibility.Visible; } else { @@ -185,6 +203,9 @@ namespace BallanceTASEditor { uiMenu_File_Close.IsEnabled = false; uiMenu_Display_ItemCount.IsEnabled = false; + uiMenu_Display_OverwrittenPaste.IsEnabled = false; + uiMenu_Display_Undo.IsEnabled = false; + uiMenu_Display_Redo.IsEnabled = false; uiStatusbar.Visibility = Visibility.Collapsed; } diff --git a/UI/OperationEnum.cs b/UI/OperationEnum.cs new file mode 100644 index 0000000..c554ed5 --- /dev/null +++ b/UI/OperationEnum.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BallanceTASEditor.UI { + public enum OperationEnum { + Set, + Unset, + Copy, + PasteAfter, + PasteBefore, + Delete, + DeleteAfter, + DeleteBefore, + AddAfter, + AddBefore, + Undo, + Redo + } +} diff --git a/UI/SelectionHelp.cs b/UI/SelectionHelp.cs index af4ed8c..6dae148 100644 --- a/UI/SelectionHelp.cs +++ b/UI/SelectionHelp.cs @@ -72,6 +72,12 @@ namespace BallanceTASEditor.UI { SetMode(mMode); } + // onnly used for delete prev one / next one shift. + public void ShiftTo(bool toNext) { + if (!IsDataPartialReady()) throw new Exception("Shift operation with wrong condition."); + FirstClick(GetPoint() + (toNext ? 1 : -1), mStartField); + } + public SelectionRange GetRange() { if (mMode == ToolMode.Overwrite) throw new Exception("Read with wrong mode."); if (!(mIsStartConfirmed && mIsEndConfirmed)) throw new Exception("Data is not ready to read"); diff --git a/UI/TASFlow.xaml b/UI/TASFlow.xaml index b347808..4e25737 100644 --- a/UI/TASFlow.xaml +++ b/UI/TASFlow.xaml @@ -9,17 +9,19 @@ - - + + - - + + + - - + + + - - + + diff --git a/UI/TASFlow.xaml.cs b/UI/TASFlow.xaml.cs index 8248a05..0a82be7 100644 --- a/UI/TASFlow.xaml.cs +++ b/UI/TASFlow.xaml.cs @@ -28,6 +28,7 @@ namespace BallanceTASEditor.UI { } public event Action Click; + public event Action NewOperation; private int mItemCount; private List mItemList; @@ -81,7 +82,7 @@ namespace BallanceTASEditor.UI { if (SelectionHelp == null) return; ToolMode mode = SelectionHelp.GetToolMode(); - bool showCursorPasteAdd = mode == ToolMode.Cursor && SelectionHelp.IsDataPartialReady(); + bool showCursorPasteAddDeleteOne = mode == ToolMode.Cursor && SelectionHelp.IsDataPartialReady(); bool showFill = mode == ToolMode.Fill && SelectionHelp.IsDataReady(); bool showCursorCopyDelete = mode == ToolMode.Cursor && SelectionHelp.IsDataReady(); @@ -89,10 +90,12 @@ namespace BallanceTASEditor.UI { uiDataMenu_Unset.IsEnabled = showFill; uiDataMenu_Copy.IsEnabled = showCursorCopyDelete; uiDataMenu_Delete.IsEnabled = showCursorCopyDelete; - uiDataMenu_PasteAfter.IsEnabled = showCursorPasteAdd; - uiDataMenu_PasteBefore.IsEnabled = showCursorPasteAdd; - uiDataMenu_AddAfter.IsEnabled = showCursorPasteAdd; - uiDataMenu_AddBefore.IsEnabled = showCursorPasteAdd; + uiDataMenu_DeleteAfter.IsEnabled = showCursorPasteAddDeleteOne; + uiDataMenu_DeleteBefore.IsEnabled = showCursorPasteAddDeleteOne; + uiDataMenu_PasteAfter.IsEnabled = showCursorPasteAddDeleteOne; + uiDataMenu_PasteBefore.IsEnabled = showCursorPasteAddDeleteOne; + uiDataMenu_AddAfter.IsEnabled = showCursorPasteAddDeleteOne; + uiDataMenu_AddBefore.IsEnabled = showCursorPasteAddDeleteOne; } public void RefreshSelectionHighlight() { @@ -167,6 +170,50 @@ namespace BallanceTASEditor.UI { Click?.Invoke(); } + #region menu operation + + private void uiDataMenu_Set_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.Set); + } + + private void uiDataMenu_Unset_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.Unset); + } + + private void uiDataMenu_Copy_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.Copy); + } + + private void uiDataMenu_PasteAfter_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.PasteAfter); + } + + private void uiDataMenu_PasteBefore_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.PasteBefore); + } + + private void uiDataMenu_Delete_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.Delete); + } + + private void uiDataMenu_DeleteAfter_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.DeleteAfter); + } + + private void uiDataMenu_DeleteBefore_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.DeleteBefore); + } + + private void uiDataMenu_AddAfter_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.AddAfter); + } + + private void uiDataMenu_AddBefore_Click(object sender, RoutedEventArgs e) { + NewOperation?.Invoke(OperationEnum.AddBefore); + } + + #endregion + } public class TASFlowUIItem { diff --git a/UI/TASViewer.cs b/UI/TASViewer.cs index b1f303a..6210014 100644 --- a/UI/TASViewer.cs +++ b/UI/TASViewer.cs @@ -28,20 +28,14 @@ namespace BallanceTASEditor.UI { INVALID_FRAME_DATA = new FrameData(-1f, 0); mDataSource = new List(); mListLength = 0; + mOverwrittenPaste = false; // bind event and source mDataGrid.DataSources = mDataSource; mDataGrid.SelectionHelp = mSelectionHelp; - mDataGrid.uiDataMenu_Set.Click += funcDataMenu_Set; - mDataGrid.uiDataMenu_Unset.Click += funcDataMenu_Unset; - mDataGrid.uiDataMenu_Copy.Click += funcDataMenu_Copy; - mDataGrid.uiDataMenu_Delete.Click += funcDataMenu_Delete; - mDataGrid.uiDataMenu_PasteAfter.Click += funcDataMenu_PasteAfter; - mDataGrid.uiDataMenu_PasteBefore.Click += funcDataMenu_PasteBefore; - mDataGrid.uiDataMenu_AddAfter.Click += funcDataMenu_AddAfter; - mDataGrid.uiDataMenu_AddBefore.Click += funcDataMenu_AddBefore; mDataGrid.Click += funcDataMenu_Click; + mDataGrid.NewOperation += funcDataMenu_NewOperation; mSlider.ValueChanged += sliderValueChanged; @@ -52,15 +46,8 @@ namespace BallanceTASEditor.UI { public void Dispose() { mDataGrid.DataSources = null; - mDataGrid.uiDataMenu_Set.Click -= funcDataMenu_Set; - mDataGrid.uiDataMenu_Unset.Click -= funcDataMenu_Unset; - mDataGrid.uiDataMenu_Copy.Click -= funcDataMenu_Copy; - mDataGrid.uiDataMenu_Delete.Click -= funcDataMenu_Delete; - mDataGrid.uiDataMenu_PasteAfter.Click -= funcDataMenu_PasteAfter; - mDataGrid.uiDataMenu_PasteBefore.Click -= funcDataMenu_PasteBefore; - mDataGrid.uiDataMenu_AddAfter.Click -= funcDataMenu_AddAfter; - mDataGrid.uiDataMenu_AddBefore.Click -= funcDataMenu_AddBefore; mDataGrid.Click -= funcDataMenu_Click; + mDataGrid.NewOperation -= funcDataMenu_NewOperation; mSlider.ValueChanged -= sliderValueChanged; } @@ -74,6 +61,7 @@ namespace BallanceTASEditor.UI { SelectionHelp mSelectionHelp; int mListLength; List mDataSource; + bool mOverwrittenPaste; private void sliderValueChanged(object sender, RoutedPropertyChangedEventArgs e) { long pos = e.NewValue.ToInt64(); @@ -123,6 +111,10 @@ namespace BallanceTASEditor.UI { } } + public void ChangeOverwrittenMode(bool isOverwritten) { + mOverwrittenPaste = isOverwritten; + } + public void ChangeListLength(int newLen) { if (newLen < 5 || newLen > 30) return; int offset = newLen - mListLength; @@ -154,7 +146,7 @@ namespace BallanceTASEditor.UI { mDataGrid.RefreshDataSources(); mDataGrid.RefreshSelectionHighlight(); } - + public void ChangeToolMode(ToolMode mode) { mSelectionHelp.SetMode(mode); } @@ -163,72 +155,84 @@ namespace BallanceTASEditor.UI { return mListLength; } + public void ProcessOperation(OperationEnum oper) { + switch (oper) { + case OperationEnum.Set: + case OperationEnum.Unset: { + mFile.Set(mSelectionHelp.GetFieldRange(), mSelectionHelp.GetRange(), oper == OperationEnum.Set); + RefreshDisplay(); + } + break; + case OperationEnum.Copy: { + var data = new LinkedList(); + mFile.Copy(mSelectionHelp.GetRange(), data); + if (!ClipboardUtil.SetFrameData(data)) + MessageBox.Show("Fail to copy due to unknow reason!"); + } + break; + case OperationEnum.PasteAfter: + case OperationEnum.PasteBefore: { + var data = new LinkedList(); + if (ClipboardUtil.GetFrameData(data)) { + mFile.Insert(mSelectionHelp.GetPoint(), data, oper == OperationEnum.PasteBefore, mOverwrittenPaste); + mSelectionHelp.Reset(); + updateSliderRange(); + RefreshDisplay(); + } else MessageBox.Show("Fail to paste due to unknow reason or blank clipboard!"); + } + break; + case OperationEnum.Delete: { + mFile.Remove(mSelectionHelp.GetRange()); + mSelectionHelp.Reset(); + updateSliderRange(); + RefreshDisplay(); + } + break; + case OperationEnum.DeleteAfter: + case OperationEnum.DeleteBefore: { + var pos = mSelectionHelp.GetPoint(); + pos += oper == OperationEnum.DeleteBefore ? -1 : 1; + if (pos < 0 || pos > mFile.mFrameCount) return; + mFile.Remove(new SelectionRange(pos, pos)); + + // only delete before need shift selection + if (oper == OperationEnum.DeleteBefore) + mSelectionHelp.ShiftTo(false); + + updateSliderRange(); + RefreshDisplay(); + } + break; + case OperationEnum.AddAfter: + case OperationEnum.AddBefore: { + if (!DialogUtil.AddItemDialog(out int count, out float deltaTime)) return; + + var pos = mSelectionHelp.GetPoint(); + mFile.Add(pos, count, deltaTime, oper == OperationEnum.AddBefore); + mSelectionHelp.Reset(); + updateSliderRange(); + RefreshDisplay(); + } + break; + case OperationEnum.Undo: { + mFile.Undo(); + mSelectionHelp.Reset(); + updateSliderRange(); + RefreshDisplay(); + } + break; + case OperationEnum.Redo: { + mFile.Redo(); + mSelectionHelp.Reset(); + updateSliderRange(); + RefreshDisplay(); + } + break; + } + } + #region data menu - private void funcDataMenu_AddBefore(object sender, RoutedEventArgs e) { - if (!DialogUtil.AddItemDialog(out int count, out float deltaTime)) return; - - var pos = mSelectionHelp.GetPoint(); - mFile.Add(pos, count, deltaTime, true); - mSelectionHelp.Reset(); - updateSliderRange(); - RefreshDisplay(); - } - - private void funcDataMenu_AddAfter(object sender, RoutedEventArgs e) { - if (!DialogUtil.AddItemDialog(out int count, out float deltaTime)) return; - - var pos = mSelectionHelp.GetPoint(); - mFile.Add(pos, count, deltaTime, false); - mSelectionHelp.Reset(); - updateSliderRange(); - RefreshDisplay(); - } - - private void funcDataMenu_PasteBefore(object sender, RoutedEventArgs e) { - var data = new LinkedList(); - if (ClipboardUtil.GetFrameData(data)) { - mFile.Insert(mSelectionHelp.GetPoint(), data, true); - mSelectionHelp.Reset(); - updateSliderRange(); - RefreshDisplay(); - } else MessageBox.Show("Fail to paste due to unknow reason or blank clipboard!"); - } - - private void funcDataMenu_PasteAfter(object sender, RoutedEventArgs e) { - var data = new LinkedList(); - if (ClipboardUtil.GetFrameData(data)) { - mFile.Insert(mSelectionHelp.GetPoint(), data, false); - mSelectionHelp.Reset(); - updateSliderRange(); - RefreshDisplay(); - } else MessageBox.Show("Fail to paste due to unknow reason or blank clipboard!"); - } - - private void funcDataMenu_Delete(object sender, RoutedEventArgs e) { - mFile.Remove(mSelectionHelp.GetRange()); - mSelectionHelp.Reset(); - updateSliderRange(); - RefreshDisplay(); - } - - private void funcDataMenu_Copy(object sender, RoutedEventArgs e) { - var data = new LinkedList(); - mFile.Copy(mSelectionHelp.GetRange(), data); - if (!ClipboardUtil.SetFrameData(data)) - MessageBox.Show("Fail to copy due to unknow reason!"); - } - - private void funcDataMenu_Unset(object sender, RoutedEventArgs e) { - mFile.Set(mSelectionHelp.GetFieldRange(), mSelectionHelp.GetRange(), false); - RefreshDisplay(); - } - - private void funcDataMenu_Set(object sender, RoutedEventArgs e) { - mFile.Set(mSelectionHelp.GetFieldRange(), mSelectionHelp.GetRange(), true); - RefreshDisplay(); - } - private void funcDataMenu_Click() { var data = mSelectionHelp.GetPoint(); var field = (int)mSelectionHelp.GetPointField(); @@ -236,6 +240,10 @@ namespace BallanceTASEditor.UI { RefreshDisplay(); } + private void funcDataMenu_NewOperation(OperationEnum obj) { + ProcessOperation(obj); + } + #endregion } }