refactor: migrate project and start refactor
This commit is contained in:
49
Legacy/BallanceTASEditor/UI/AddItem.xaml
Normal file
49
Legacy/BallanceTASEditor/UI/AddItem.xaml
Normal file
@ -0,0 +1,49 @@
|
||||
<Window x:Class="BallanceTASEditor.UI.AddItem"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:BallanceTASEditor.UI"
|
||||
xmlns:converter="clr-namespace:BallanceTASEditor.UI"
|
||||
mc:Ignorable="d"
|
||||
Title="{DynamicResource ui_AddItem_Title}" Height="200" Width="400" WindowStyle="ToolWindow" WindowStartupLocation="CenterOwner" Icon="/BallanceTASEditor;component/icon.ico">
|
||||
<Window.Resources>
|
||||
<converter:AddItemConverter x:Key="conv_addItem"/>
|
||||
<converter:FPS2DeltaTimeConverter x:Key="conv_fps2DeltaTime"/>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="0" Text="{DynamicResource ui_AddItem_Count}" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="1" Text="{DynamicResource ui_AddItem_FPS}" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="2" Text="{DynamicResource ui_AddItem_DeltaTime}" VerticalAlignment="Center"/>
|
||||
|
||||
<TextBox x:Name="uiTextbox_Count" Margin="5" Padding="5" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center"/>
|
||||
<TextBox x:Name="uiTextbox_FPS" Margin="5" Padding="5" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"/>
|
||||
<TextBlock x:Name="uiText_DeltaTime" Margin="5" Padding="5" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center"
|
||||
Text="{Binding Converter={StaticResource conv_fps2DeltaTime}, Mode=OneWay, ElementName=uiTextbox_FPS, Path=Text}"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" Grid.ColumnSpan="2" Grid.Row="4">
|
||||
<Button x:Name="uiBtn_OK" Margin="5" Padding="5" Content="{DynamicResource ui_AddItem_OK}" MinWidth="50" Click="funcBtn_OK">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{StaticResource conv_addItem}" Mode="OneWay">
|
||||
<Binding ElementName="uiTextbox_Count" Path="Text"/>
|
||||
<Binding ElementName="uiTextbox_FPS" Path="Text"/>
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Cancel" Margin="5" Padding="5" Content="{DynamicResource ui_AddItem_Cancel}" MinWidth="50" Click="funcBtn_Cancel"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
42
Legacy/BallanceTASEditor/UI/AddItem.xaml.cs
Normal file
42
Legacy/BallanceTASEditor/UI/AddItem.xaml.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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.Shapes;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
/// <summary>
|
||||
/// AddItem.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class AddItem : Window {
|
||||
public AddItem() {
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public int Output_Count { get; private set; }
|
||||
public float Output_DeltaTime { get; private set; }
|
||||
|
||||
private void funcBtn_OK(object sender, RoutedEventArgs e) {
|
||||
int count;
|
||||
float fps;
|
||||
if (!int.TryParse(uiTextbox_Count.Text, out count)) return;
|
||||
if (!float.TryParse(uiTextbox_FPS.Text, out fps)) return;
|
||||
|
||||
Output_Count = count;
|
||||
Output_DeltaTime = 1000f / fps;
|
||||
|
||||
this.DialogResult = true;
|
||||
}
|
||||
|
||||
private void funcBtn_Cancel(object sender, RoutedEventArgs e) {
|
||||
this.DialogResult = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Legacy/BallanceTASEditor/UI/DialogUtil.cs
Normal file
62
Legacy/BallanceTASEditor/UI/DialogUtil.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using Microsoft.VisualBasic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using BallanceTASEditor.Core;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class DialogUtil {
|
||||
|
||||
public static string OpenFileDialog() {
|
||||
Microsoft.Win32.OpenFileDialog op = new Microsoft.Win32.OpenFileDialog();
|
||||
op.RestoreDirectory = true;
|
||||
op.Multiselect = false;
|
||||
op.Filter = I18NProcessor.GetI18N("code_DialogUtil_FileFilter");
|
||||
if (!(bool)op.ShowDialog()) return "";
|
||||
return op.FileName;
|
||||
}
|
||||
|
||||
public static string SaveFileDialog() {
|
||||
Microsoft.Win32.SaveFileDialog op = new Microsoft.Win32.SaveFileDialog();
|
||||
op.RestoreDirectory = true;
|
||||
op.Filter = I18NProcessor.GetI18N("code_DialogUtil_FileFilter");
|
||||
if (!(bool)op.ShowDialog()) return "";
|
||||
return op.FileName;
|
||||
}
|
||||
|
||||
public static bool ConfirmDialog(string str) {
|
||||
var result = MessageBox.Show(str, I18NProcessor.GetI18N("code_DialogUtil_Warning"), MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
return (result == MessageBoxResult.Yes);
|
||||
}
|
||||
|
||||
public static bool InputNumber(string title, int min, int max, ref int result) {
|
||||
while (true) {
|
||||
var dialog = Interaction.InputBox(title, I18NProcessor.GetI18N("code_DialogUtil_InputNumber_Title"), "");
|
||||
if (dialog == "") return false;
|
||||
if (int.TryParse(dialog, out result)) {
|
||||
if (result <= max && result >= min) break;
|
||||
}
|
||||
MessageBox.Show(I18NProcessor.GetI18N("code_DialogUtil_InputNumber_Wrong"),
|
||||
I18NProcessor.GetI18N("code_DialogUtil_Warning"),
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool AddItemDialog(out int count, out float deltaTime) {
|
||||
var win = new AddItem();
|
||||
if (!(bool)win.ShowDialog()) {
|
||||
count = 0;
|
||||
deltaTime = 0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
count = win.Output_Count;
|
||||
deltaTime = win.Output_DeltaTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
22
Legacy/BallanceTASEditor/UI/OperationEnum.cs
Normal file
22
Legacy/BallanceTASEditor/UI/OperationEnum.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public enum OperationEnum {
|
||||
Set,
|
||||
Unset,
|
||||
Cut,
|
||||
Copy,
|
||||
PasteAfter,
|
||||
PasteBefore,
|
||||
Delete,
|
||||
DeleteAfter,
|
||||
DeleteBefore,
|
||||
AddAfter,
|
||||
AddBefore,
|
||||
Undo,
|
||||
Redo
|
||||
}
|
||||
}
|
||||
137
Legacy/BallanceTASEditor/UI/SelectionHelp.cs
Normal file
137
Legacy/BallanceTASEditor/UI/SelectionHelp.cs
Normal file
@ -0,0 +1,137 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BallanceTASEditor.Core;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class SelectionHelp {
|
||||
public SelectionHelp() {
|
||||
SetMode(ToolMode.Cursor);
|
||||
}
|
||||
|
||||
public event Action SelectionChanged;
|
||||
|
||||
ToolMode mMode;
|
||||
FrameDataField mStartField;
|
||||
FrameDataField mEndField;
|
||||
long mStart;
|
||||
bool mIsStartConfirmed;
|
||||
long mEnd;
|
||||
bool mIsEndConfirmed;
|
||||
|
||||
public void SetMode(ToolMode mode) {
|
||||
switch (mode) {
|
||||
case ToolMode.Cursor:
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
mIsStartConfirmed = false;
|
||||
mIsEndConfirmed = false;
|
||||
break;
|
||||
case ToolMode.Fill:
|
||||
mStartField = FrameDataField.Key_Up;
|
||||
mEndField = FrameDataField.Key_Up;
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
mIsStartConfirmed = false;
|
||||
mIsEndConfirmed = false;
|
||||
break;
|
||||
case ToolMode.Overwrite:
|
||||
mStartField = FrameDataField.Key_Up;
|
||||
mStart = 0;
|
||||
mIsStartConfirmed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mMode = mode;
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
public void FirstClick(long index, FrameDataField field) {
|
||||
mStartField = field;
|
||||
mStart = index;
|
||||
mIsStartConfirmed = true;
|
||||
mIsEndConfirmed = false;
|
||||
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
public void LastClick(long index, FrameDataField field) {
|
||||
if (mMode == ToolMode.Overwrite) return;
|
||||
if (!mIsStartConfirmed) return;
|
||||
|
||||
mEndField = field;
|
||||
mEnd = index;
|
||||
mIsEndConfirmed = true;
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
// reuse set mode to reset
|
||||
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");
|
||||
return new SelectionRange(mStart, mEnd);
|
||||
}
|
||||
|
||||
public SelectionRange GetFieldRange() {
|
||||
if (mMode != ToolMode.Fill) throw new Exception("Read with wrong mode.");
|
||||
if (!(mIsStartConfirmed && mIsEndConfirmed)) throw new Exception("Data is not ready to read");
|
||||
return new SelectionRange((int)mStartField, (int)mEndField);
|
||||
}
|
||||
|
||||
public long GetPoint() {
|
||||
if (mMode == ToolMode.Fill) throw new Exception("Read with wrong mode.");
|
||||
if (!mIsStartConfirmed) throw new Exception("Data is not ready to read");
|
||||
|
||||
if (mMode == ToolMode.Overwrite) return mStart;
|
||||
else {
|
||||
// cursor mode
|
||||
if (mIsStartConfirmed) return mStart;
|
||||
else throw new Exception("Data is not ready to read");
|
||||
}
|
||||
}
|
||||
|
||||
public FrameDataField GetPointField() {
|
||||
if (mMode != ToolMode.Overwrite) throw new Exception("Read with wrong mode.");
|
||||
if (!mIsStartConfirmed) throw new Exception("Data is not ready to read");
|
||||
|
||||
return mStartField;
|
||||
}
|
||||
|
||||
public bool IsDataReady() {
|
||||
switch (mMode) {
|
||||
case ToolMode.Cursor:
|
||||
case ToolMode.Fill:
|
||||
return (mIsStartConfirmed && mIsEndConfirmed);
|
||||
case ToolMode.Overwrite:
|
||||
return mIsStartConfirmed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsDataPartialReady() {
|
||||
return (mMode == ToolMode.Cursor && mIsStartConfirmed && !mIsEndConfirmed);
|
||||
}
|
||||
|
||||
public ToolMode GetToolMode() {
|
||||
return mMode;
|
||||
}
|
||||
|
||||
private void OnSelectionChanged() {
|
||||
SelectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
47
Legacy/BallanceTASEditor/UI/StyleConverter.cs
Normal file
47
Legacy/BallanceTASEditor/UI/StyleConverter.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
|
||||
public class AddItemConverter : IMultiValueConverter {
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
|
||||
try {
|
||||
var textCount = values[0] as string;
|
||||
var textFps = values[1] as string;
|
||||
|
||||
var count = int.Parse(textCount);
|
||||
var fps = float.Parse(textFps);
|
||||
|
||||
if (count <= 0 || fps <= 0) return false;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class FPS2DeltaTimeConverter : IValueConverter {
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||
var text = value as string;
|
||||
if (text == null) return "0";
|
||||
|
||||
float data;
|
||||
if (!float.TryParse(text, out data)) return "0";
|
||||
return (1000f / data).ToString();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
401
Legacy/BallanceTASEditor/UI/TASFlow.cs
Normal file
401
Legacy/BallanceTASEditor/UI/TASFlow.cs
Normal file
@ -0,0 +1,401 @@
|
||||
using BallanceTASEditor.Core;
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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.UI {
|
||||
public partial class TASFlow {
|
||||
public TASFlow(Grid coreWindow, TextBlock[] headers) {
|
||||
uiCoreWindow = coreWindow;
|
||||
mHeaders = headers;
|
||||
mItemList = new List<TASFlowUIItem>();
|
||||
mRectMap = new Dictionary<Rectangle, CellPosition>();
|
||||
mItemCount = 0;
|
||||
mIsHorizontalLayout = true;
|
||||
SetItemCount(1);
|
||||
}
|
||||
|
||||
public event Action Click;
|
||||
|
||||
private readonly TextBlock[] mHeaders;
|
||||
private bool mIsHorizontalLayout;
|
||||
private Grid uiCoreWindow;
|
||||
private int mItemCount;
|
||||
private List<TASFlowUIItem> mItemList;
|
||||
private Dictionary<Rectangle, CellPosition> mRectMap;
|
||||
public SelectionHelp SelectionHelp { get; set; }
|
||||
public List<FrameDataDisplay> DataSources { get; set; }
|
||||
|
||||
public void ChangeLayout(bool isHorizontal) {
|
||||
if (isHorizontal == mIsHorizontalLayout) return;
|
||||
|
||||
// the layout changed, re-construct elements
|
||||
mIsHorizontalLayout = isHorizontal;
|
||||
|
||||
// delete original grid layout
|
||||
var lenHeader = mHeaders.Length;
|
||||
uiCoreWindow.ColumnDefinitions.Clear();
|
||||
uiCoreWindow.RowDefinitions.Clear();
|
||||
|
||||
// add header layout
|
||||
if (mIsHorizontalLayout) {
|
||||
// horizontal layout
|
||||
// row is header count
|
||||
// column is tas unit
|
||||
|
||||
// header
|
||||
layout_row_adder(GridLength.Auto);
|
||||
for (int r = 0; r < lenHeader; r++) {
|
||||
layout_row_adder(GridLength.Auto);
|
||||
}
|
||||
layout_row_adder(new GridLength(1, GridUnitType.Star));
|
||||
|
||||
// tas unit
|
||||
layout_column_adder(GridLength.Auto);
|
||||
for (int c = 0; c < mItemCount; c++) {
|
||||
layout_column_adder(new GridLength(1, GridUnitType.Star));
|
||||
}
|
||||
} else {
|
||||
// vertical layout
|
||||
// row is tas unit
|
||||
// column is header count (use start to split, not auto)
|
||||
|
||||
// header
|
||||
layout_column_adder(GridLength.Auto);
|
||||
for (int r = 0; r < lenHeader; r++) {
|
||||
if (r == 0 || r == 1)
|
||||
layout_column_adder(GridLength.Auto);
|
||||
else
|
||||
layout_column_adder(new GridLength(1, GridUnitType.Star));
|
||||
}
|
||||
//layout_column_adder(new GridLength(1, GridUnitType.Star));
|
||||
|
||||
// tas unit
|
||||
layout_row_adder(GridLength.Auto);
|
||||
for (int c = 0; c < mItemCount; c++) {
|
||||
layout_row_adder(new GridLength(1, GridUnitType.Star));
|
||||
}
|
||||
}
|
||||
|
||||
// now, change items attach prop
|
||||
// just swap Grid.Row and Grid.Column's number
|
||||
foreach (var item in mHeaders) {
|
||||
var swap = Grid.GetColumn(item);
|
||||
Grid.SetColumn(item, Grid.GetRow(item));
|
||||
Grid.SetRow(item, swap);
|
||||
}
|
||||
foreach (var item in mItemList) {
|
||||
item.FlipUnit();
|
||||
}
|
||||
|
||||
}
|
||||
private void layout_row_adder(GridLength size) {
|
||||
UI.Util.GridRowAdder(uiCoreWindow, size);
|
||||
}
|
||||
private void layout_column_adder(GridLength size) {
|
||||
UI.Util.GridColumnAdder(uiCoreWindow, size);
|
||||
}
|
||||
|
||||
public void RefreshDataSources() {
|
||||
if (DataSources == null) return;
|
||||
|
||||
for (int i = 0; i < mItemCount; i++) {
|
||||
mItemList[i].Reload(DataSources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetItemCount(int newCount) {
|
||||
var offset = newCount - mItemCount;
|
||||
var abs = Math.Abs(offset);
|
||||
if (offset == 0) return;
|
||||
|
||||
// change column defination first
|
||||
if (offset > 0) {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
if (mIsHorizontalLayout) {
|
||||
layout_column_adder(new GridLength(1, GridUnitType.Star));
|
||||
} else {
|
||||
layout_row_adder(new GridLength(1, GridUnitType.Star));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mIsHorizontalLayout) {
|
||||
uiCoreWindow.ColumnDefinitions.RemoveRange(newCount + 1, abs); // the first col is sheet header, so add 1 additionally
|
||||
} else {
|
||||
uiCoreWindow.RowDefinitions.RemoveRange(newCount + 1, abs); // the first col is sheet header, so add 1 additionally
|
||||
}
|
||||
}
|
||||
|
||||
// add / remove item
|
||||
if (offset > 0) {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
var newItem = new TASFlowUIItem(mItemCount + 1 + i, mIsHorizontalLayout); // the first col is sheet header, so add 1 additionally
|
||||
newItem.Add(uiCoreWindow, mRectMap, Rectangle_MouseDown);
|
||||
mItemList.Add(newItem);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
mItemList[newCount + i].Remove(uiCoreWindow, mRectMap, Rectangle_MouseDown);
|
||||
}
|
||||
mItemList.RemoveRange(newCount, abs);
|
||||
}
|
||||
|
||||
// apply new count
|
||||
mItemCount = newCount;
|
||||
}
|
||||
|
||||
public void RefreshSelectionHighlight() {
|
||||
ToolMode mode = SelectionHelp.GetToolMode();
|
||||
|
||||
if (mode == ToolMode.Cursor) {
|
||||
if (SelectionHelp.IsDataReady()) {
|
||||
var data = SelectionHelp.GetRange();
|
||||
foreach (var item in mItemList) {
|
||||
if (data.Within(item.rawFrame)) {
|
||||
item.SelectFull();
|
||||
} else {
|
||||
item.Unselect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (SelectionHelp.IsDataPartialReady()) {
|
||||
var data = SelectionHelp.GetPoint();
|
||||
foreach (var item in mItemList) {
|
||||
if (data == item.rawFrame) {
|
||||
item.SelectFull();
|
||||
} else {
|
||||
item.Unselect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (mode == ToolMode.Fill) {
|
||||
if (SelectionHelp.IsDataReady()) {
|
||||
var data = SelectionHelp.GetRange();
|
||||
var field = SelectionHelp.GetFieldRange();
|
||||
foreach (var item in mItemList) {
|
||||
if (data.Within(item.rawFrame)) {
|
||||
item.SelectField(field);
|
||||
} else {
|
||||
item.Unselect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// fail if prog run into this position, clear
|
||||
foreach (var item in mItemList) {
|
||||
item.Unselect();
|
||||
}
|
||||
}
|
||||
|
||||
private void Rectangle_MouseDown(object sender, MouseButtonEventArgs e) {
|
||||
if (SelectionHelp == null) return;
|
||||
|
||||
// because the first column is header
|
||||
// so all pos.column should -1
|
||||
var rect = sender as Rectangle;
|
||||
var pos = mRectMap[rect];
|
||||
if (!mItemList[pos.column - 1].rawIsEnable) return;
|
||||
if (e.MouseDevice.LeftButton == MouseButtonState.Pressed) {
|
||||
if (KeyboardState.IsKeyPressed(KeyboardState.VirtualKeyStates.VK_SHIFT)) {
|
||||
SelectionHelp.LastClick(mItemList[pos.column - 1].rawFrame, pos.field);
|
||||
} else {
|
||||
SelectionHelp.FirstClick(mItemList[pos.column - 1].rawFrame, pos.field);
|
||||
}
|
||||
} else if (e.MouseDevice.RightButton == MouseButtonState.Pressed) {
|
||||
// if we click right button and there are no full selection in cursor mode
|
||||
// try to add a first selection
|
||||
if (SelectionHelp.GetToolMode() == ToolMode.Cursor) {
|
||||
if (!SelectionHelp.IsDataReady()) {
|
||||
SelectionHelp.FirstClick(mItemList[pos.column - 1].rawFrame, pos.field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// note main window to process it.
|
||||
OnClick();
|
||||
}
|
||||
|
||||
// only raised in overwrite mode
|
||||
private void OnClick() {
|
||||
if (SelectionHelp.GetToolMode() == ToolMode.Overwrite)
|
||||
Click?.Invoke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TASFlowUIItem {
|
||||
private static readonly Thickness DEFAULT_MARGIN = new Thickness(2);
|
||||
private static readonly Thickness RECT_MARGIN = new Thickness(1);
|
||||
private static readonly SolidColorBrush SEL_RECT_NORMAL_BRUSH = new SolidColorBrush(Colors.White);
|
||||
private static readonly SolidColorBrush SEL_RECT_SELECTED_BRUSH = new SolidColorBrush(Colors.OrangeRed);
|
||||
private static readonly SolidColorBrush SEL_RECT_STROKE = new SolidColorBrush(Colors.LightGray);
|
||||
private static readonly Color COLOR_SET = Color.FromRgb(30, 144, 255);
|
||||
private static readonly Color COLOR_UNSET = Color.FromArgb(0, 255, 255, 255);
|
||||
private static readonly Color COLOR_SELECTED = Colors.OrangeRed;
|
||||
private static readonly Color COLOR_UNSELECTED = Colors.LightGray;
|
||||
private const double SELECTION_HEADER_HEIGHT = 10.0f;
|
||||
private const int KEY_COUNT = 9;
|
||||
|
||||
public TASFlowUIItem(int column, bool useHorizontalLayout) {
|
||||
// basic item
|
||||
sel_rect = new Rectangle();
|
||||
frame = new TextBlock();
|
||||
deltaTime = new TextBlock();
|
||||
|
||||
if (useHorizontalLayout) {
|
||||
Grid.SetRow(sel_rect, 0);
|
||||
Grid.SetRow(frame, 1);
|
||||
Grid.SetRow(deltaTime, 2);
|
||||
Grid.SetColumn(sel_rect, column);
|
||||
Grid.SetColumn(frame, column);
|
||||
Grid.SetColumn(deltaTime, column);
|
||||
} else {
|
||||
Grid.SetColumn(sel_rect, 0);
|
||||
Grid.SetColumn(frame, 1);
|
||||
Grid.SetColumn(deltaTime, 2);
|
||||
Grid.SetRow(sel_rect, column);
|
||||
Grid.SetRow(frame, column);
|
||||
Grid.SetRow(deltaTime, column);
|
||||
}
|
||||
|
||||
sel_rect.Margin = RECT_MARGIN;
|
||||
frame.Margin = DEFAULT_MARGIN;
|
||||
deltaTime.Margin = DEFAULT_MARGIN;
|
||||
|
||||
sel_rect.StrokeThickness = 2;
|
||||
sel_rect.Stroke = SEL_RECT_STROKE;
|
||||
if (useHorizontalLayout)
|
||||
sel_rect.Height = SELECTION_HEADER_HEIGHT;
|
||||
else
|
||||
sel_rect.Width = SELECTION_HEADER_HEIGHT;
|
||||
|
||||
// keystates item
|
||||
keystates = new Rectangle[KEY_COUNT];
|
||||
keystatesFill = new SolidColorBrush[KEY_COUNT];
|
||||
keystatesStroke = new SolidColorBrush[KEY_COUNT];
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
keystates[i] = new Rectangle();
|
||||
keystatesFill[i] = new SolidColorBrush(COLOR_UNSET);
|
||||
keystatesStroke[i] = new SolidColorBrush(COLOR_UNSELECTED);
|
||||
if (useHorizontalLayout) {
|
||||
Grid.SetRow(keystates[i], 3 + i);
|
||||
Grid.SetColumn(keystates[i], column);
|
||||
} else {
|
||||
Grid.SetColumn(keystates[i], 3 + i);
|
||||
Grid.SetRow(keystates[i], column);
|
||||
}
|
||||
keystates[i].Margin = RECT_MARGIN;
|
||||
keystates[i].StrokeThickness = 3;
|
||||
keystates[i].Stroke = keystatesStroke[i];
|
||||
keystates[i].Fill = keystatesFill[i];
|
||||
}
|
||||
|
||||
this.column = column;
|
||||
rawFrame = 0;
|
||||
rawIsEnable = false;
|
||||
}
|
||||
|
||||
public void FlipUnit() {
|
||||
UI.Util.SwapGridItemRC(sel_rect);
|
||||
UI.Util.SwapGridItemRC(frame);
|
||||
UI.Util.SwapGridItemRC(deltaTime);
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
UI.Util.SwapGridItemRC(keystates[i]);
|
||||
}
|
||||
|
||||
// swap sel_rect height and width
|
||||
var swap = sel_rect.Height;
|
||||
sel_rect.Height = sel_rect.Width;
|
||||
sel_rect.Width = swap;
|
||||
}
|
||||
|
||||
public void Add(Grid target, Dictionary<Rectangle, CellPosition> map, MouseButtonEventHandler func) {
|
||||
target.Children.Add(sel_rect);
|
||||
target.Children.Add(frame);
|
||||
target.Children.Add(deltaTime);
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
target.Children.Add(keystates[i]);
|
||||
keystates[i].MouseDown += func;
|
||||
map.Add(keystates[i], new CellPosition(column, (FrameDataField)i));
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(Grid target, Dictionary<Rectangle, CellPosition> map, MouseButtonEventHandler func) {
|
||||
target.Children.Remove(sel_rect);
|
||||
target.Children.Remove(frame);
|
||||
target.Children.Remove(deltaTime);
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
target.Children.Remove(keystates[i]);
|
||||
keystates[i].MouseDown -= func;
|
||||
map.Remove(keystates[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reload(FrameDataDisplay fdd) {
|
||||
var isEnable = fdd.isEnable;
|
||||
frame.Text = isEnable ? fdd.index.ToString() : "";
|
||||
deltaTime.Text = isEnable ? fdd.deltaTime.ToString() : "";
|
||||
keystatesFill[0].Color = isEnable && fdd.key_up ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[1].Color = isEnable && fdd.key_down ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[2].Color = isEnable && fdd.key_left ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[3].Color = isEnable && fdd.key_right ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[4].Color = isEnable && fdd.key_shift ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[5].Color = isEnable && fdd.key_space ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[6].Color = isEnable && fdd.key_q ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[7].Color = isEnable && fdd.key_esc ? COLOR_SET : COLOR_UNSET;
|
||||
keystatesFill[8].Color = isEnable && fdd.key_enter ? COLOR_SET : COLOR_UNSET;
|
||||
|
||||
sel_rect.Visibility = isEnable ? Visibility.Visible : Visibility.Collapsed;
|
||||
frame.Visibility = isEnable ? Visibility.Visible : Visibility.Collapsed;
|
||||
deltaTime.Visibility = isEnable ? Visibility.Visible : Visibility.Collapsed;
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
keystates[i].Visibility = isEnable ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
rawIsEnable = isEnable;
|
||||
rawFrame = fdd.index;
|
||||
}
|
||||
|
||||
public void SelectFull() {
|
||||
sel_rect.Fill = SEL_RECT_SELECTED_BRUSH;
|
||||
}
|
||||
|
||||
public void SelectField(SelectionRange range) {
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
keystatesStroke[i].Color = range.Within(i) ? COLOR_SELECTED : COLOR_UNSELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unselect() {
|
||||
sel_rect.Fill = SEL_RECT_NORMAL_BRUSH;
|
||||
for (int i = 0; i < KEY_COUNT; i++) {
|
||||
keystatesStroke[i].Color = COLOR_UNSELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
public long rawFrame;
|
||||
public bool rawIsEnable;
|
||||
|
||||
public Rectangle sel_rect;
|
||||
public TextBlock frame;
|
||||
public TextBlock deltaTime;
|
||||
public Rectangle[] keystates;
|
||||
private SolidColorBrush[] keystatesFill;
|
||||
private SolidColorBrush[] keystatesStroke;
|
||||
private int column;
|
||||
}
|
||||
}
|
||||
117
Legacy/BallanceTASEditor/UI/TASSlider.cs
Normal file
117
Legacy/BallanceTASEditor/UI/TASSlider.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using BallanceTASEditor.Core;
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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.UI {
|
||||
public class TASSlider {
|
||||
public TASSlider(TASSliderComponents _components) {
|
||||
components = _components;
|
||||
components.mSlider.Minimum = 0;
|
||||
mIsHorizontalLayout = true;
|
||||
|
||||
components.mSlider.ValueChanged += func_SliderValueChanged;
|
||||
}
|
||||
|
||||
public event Action<long> ValueChanged;
|
||||
TASSliderComponents components;
|
||||
bool mIsHorizontalLayout;
|
||||
|
||||
public void MoveSliderManually(bool isPrev, bool isFast, int fastCount) {
|
||||
var step = isFast ? fastCount : 1;
|
||||
components.mSlider.Value = Core.Util.Clamp(components.mSlider.Value.ToInt32() + (isPrev ? -1 : 1) * step, components.mSlider.Minimum.ToInt32(), components.mSlider.Maximum.ToInt32());
|
||||
}
|
||||
|
||||
public void UpdateRange(TASFile mFile) {
|
||||
components.mSlider.Maximum = mFile.mFrameCount == 0 ? 0 : mFile.mFrameCount - 1;
|
||||
var index = mFile.GetPointerIndex();
|
||||
if (index >= 0) {
|
||||
components.mSlider.Value = mFile.GetPointerIndex();
|
||||
components.mSlider.IsEnabled = true;
|
||||
} else {
|
||||
// invalid index, mean slider is useless, disable it
|
||||
components.mSlider.Value = components.mSlider.Maximum;
|
||||
components.mSlider.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void func_SliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
|
||||
ValueChanged?.Invoke(e.NewValue.ToInt64());
|
||||
}
|
||||
|
||||
public void ChangeLayout(bool isHorizontal) {
|
||||
if (isHorizontal == mIsHorizontalLayout) return;
|
||||
|
||||
// the layout changed, re-construct elements
|
||||
mIsHorizontalLayout = isHorizontal;
|
||||
|
||||
// change container
|
||||
components.container.RowDefinitions.Clear();
|
||||
components.container.ColumnDefinitions.Clear();
|
||||
if (mIsHorizontalLayout) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
UI.Util.GridColumnAdder(components.container, GridLength.Auto);
|
||||
}
|
||||
UI.Util.GridColumnAdder(components.container, new GridLength(1, GridUnitType.Star));
|
||||
} else {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
UI.Util.GridRowAdder(components.container, GridLength.Auto);
|
||||
}
|
||||
UI.Util.GridRowAdder(components.container, new GridLength(1, GridUnitType.Star));
|
||||
}
|
||||
|
||||
// flip elements
|
||||
UI.Util.SwapGridItemRC(components.btnFastPrev);
|
||||
UI.Util.SwapGridItemRC(components.btnPrev);
|
||||
UI.Util.SwapGridItemRC(components.btnNext);
|
||||
UI.Util.SwapGridItemRC(components.btnFastNext);
|
||||
UI.Util.SwapGridItemRC(components.mSlider);
|
||||
|
||||
// change transform
|
||||
if (mIsHorizontalLayout) {
|
||||
// clear all btn's transform and set slider as horizontal style
|
||||
components.btnFastPrev.RenderTransform = Transform.Identity;
|
||||
components.btnPrev.RenderTransform = Transform.Identity;
|
||||
components.btnNext.RenderTransform = Transform.Identity;
|
||||
components.btnFastNext.RenderTransform = Transform.Identity;
|
||||
|
||||
components.mSlider.RenderTransform = Transform.Identity;
|
||||
components.mSlider.Orientation = Orientation.Horizontal;
|
||||
components.mSlider.VerticalAlignment = VerticalAlignment.Center;
|
||||
components.mSlider.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
} else {
|
||||
components.btnFastPrev.RenderTransform = new RotateTransform(90);
|
||||
components.btnPrev.RenderTransform = new RotateTransform(90);
|
||||
components.btnNext.RenderTransform = new RotateTransform(90);
|
||||
components.btnFastNext.RenderTransform = new RotateTransform(90);
|
||||
|
||||
components.mSlider.RenderTransform = new RotateTransform(180);
|
||||
components.mSlider.Orientation = Orientation.Vertical;
|
||||
components.mSlider.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
components.mSlider.HorizontalAlignment = HorizontalAlignment.Center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TASSliderComponents {
|
||||
public Grid container;
|
||||
public Button btnFastPrev;
|
||||
public Button btnPrev;
|
||||
public Button btnNext;
|
||||
public Button btnFastNext;
|
||||
public Slider mSlider;
|
||||
}
|
||||
}
|
||||
253
Legacy/BallanceTASEditor/UI/TASViewer.cs
Normal file
253
Legacy/BallanceTASEditor/UI/TASViewer.cs
Normal file
@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BallanceTASEditor.Core;
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class TASViewer : IDisposable {
|
||||
public TASViewer(TASFile file, TASSlider slider, TASFlow datagrid) {
|
||||
mFile = file;
|
||||
mSlider = slider;
|
||||
mDataGrid = datagrid;
|
||||
|
||||
// restore slider
|
||||
mSlider.UpdateRange(mFile);
|
||||
|
||||
// init selection
|
||||
mSelectionHelp = new SelectionHelp();
|
||||
mSelectionHelp.SelectionChanged += funcSelectionHelp_SelectionChanged;
|
||||
|
||||
// init data
|
||||
INVALID_FRAME_DATA = new FrameData(-1f, 0);
|
||||
mDataSource = new List<FrameDataDisplay>();
|
||||
mListLength = 0;
|
||||
mOverwrittenPaste = false;
|
||||
|
||||
// bind event and source
|
||||
mDataGrid.DataSources = mDataSource;
|
||||
mDataGrid.SelectionHelp = mSelectionHelp;
|
||||
|
||||
mDataGrid.Click += funcDataMenu_Click;
|
||||
mSlider.ValueChanged += funcSlider_ValueChanged;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
mDataGrid.DataSources = null;
|
||||
|
||||
mDataGrid.Click -= funcDataMenu_Click;
|
||||
mSlider.ValueChanged -= funcSlider_ValueChanged;
|
||||
}
|
||||
|
||||
//const int DATA_LIST_LENGTH = 15;
|
||||
FrameData INVALID_FRAME_DATA;
|
||||
TASFile mFile;
|
||||
TASSlider mSlider;
|
||||
TASFlow mDataGrid;
|
||||
SelectionHelp mSelectionHelp;
|
||||
int mListLength;
|
||||
List<FrameDataDisplay> mDataSource;
|
||||
bool mOverwrittenPaste;
|
||||
|
||||
#region self event
|
||||
public event Action<bool, bool, bool> UpdateDataUI;
|
||||
public event Action<ToolMode> UpdateToolMode;
|
||||
public event Action<SelectionHelp> UpdateSelection;
|
||||
|
||||
private void OnUpdateDataUI() {
|
||||
ToolMode mode = mSelectionHelp.GetToolMode();
|
||||
bool showCursorPasteAddDeleteOne = mode == ToolMode.Cursor && mSelectionHelp.IsDataPartialReady();
|
||||
bool showFill = mode == ToolMode.Fill && mSelectionHelp.IsDataReady();
|
||||
bool showCursorCopyDelete = mode == ToolMode.Cursor && mSelectionHelp.IsDataReady();
|
||||
|
||||
UpdateDataUI?.Invoke(showCursorPasteAddDeleteOne, showFill, showCursorCopyDelete);
|
||||
}
|
||||
|
||||
private void OnUpdateToolMode() {
|
||||
UpdateToolMode?.Invoke(mSelectionHelp.GetToolMode());
|
||||
}
|
||||
|
||||
private void OnUpdateSelection() {
|
||||
UpdateSelection?.Invoke(mSelectionHelp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region process event
|
||||
|
||||
private void funcSlider_ValueChanged(long pos) {
|
||||
mFile.Shift(pos);
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
private void funcSelectionHelp_SelectionChanged() {
|
||||
mDataGrid.RefreshSelectionHighlight();
|
||||
OnUpdateDataUI();
|
||||
OnUpdateSelection();
|
||||
}
|
||||
|
||||
private void funcDataMenu_Click() {
|
||||
var data = mSelectionHelp.GetPoint();
|
||||
var field = (int)mSelectionHelp.GetPointField();
|
||||
mFile.Set(new SelectionRange(field, field), new SelectionRange(data, data), null);
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ChangeOverwrittenMode(bool isOverwritten) {
|
||||
mOverwrittenPaste = isOverwritten;
|
||||
}
|
||||
|
||||
public void ChangeListLength(int newLen) {
|
||||
if (newLen < 5 || newLen > 200) return;
|
||||
int offset = newLen - mListLength;
|
||||
int abs = Math.Abs(offset);
|
||||
if (offset == 0) return;
|
||||
|
||||
// change mDataSource first
|
||||
|
||||
if (offset > 0) {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
mDataSource.Add(new FrameDataDisplay(0, INVALID_FRAME_DATA));
|
||||
}
|
||||
} else {
|
||||
mDataSource.RemoveRange(newLen, abs);
|
||||
}
|
||||
|
||||
// then change viewer control
|
||||
mDataGrid.SetItemCount(newLen);
|
||||
|
||||
// apply new value
|
||||
mListLength = newLen;
|
||||
|
||||
// then refresh
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
public void RefreshDisplay() {
|
||||
mFile.Get(mDataSource, mListLength);
|
||||
mDataGrid.RefreshDataSources();
|
||||
mDataGrid.RefreshSelectionHighlight();
|
||||
}
|
||||
|
||||
public void ChangeToolMode(ToolMode mode) {
|
||||
mSelectionHelp.SetMode(mode);
|
||||
OnUpdateToolMode();
|
||||
}
|
||||
|
||||
public int GetItemCountInPage() {
|
||||
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.Cut: {
|
||||
// cut is a hybrid operation, first, do copy
|
||||
// then delete selected item
|
||||
// due to copy is not affect TASFile and only delete oper affect it
|
||||
// so this is a revocable oper
|
||||
var data = new LinkedList<FrameData>();
|
||||
mFile.Copy(mSelectionHelp.GetRange(), data);
|
||||
if (!ClipboardUtil.SetFrameData(data)) {
|
||||
MessageBox.Show("Fail to cut due to unknow reason!");
|
||||
break; // if fail to cut, do not delete selected items.
|
||||
}
|
||||
|
||||
// do delete
|
||||
mFile.Remove(mSelectionHelp.GetRange());
|
||||
mSelectionHelp.Reset();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Copy: {
|
||||
var data = new LinkedList<FrameData>();
|
||||
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<FrameData>();
|
||||
if (ClipboardUtil.GetFrameData(data)) {
|
||||
mFile.Insert(mSelectionHelp.GetPoint(), data, oper == OperationEnum.PasteBefore, mOverwrittenPaste);
|
||||
mSelectionHelp.Reset();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
} else MessageBox.Show("Fail to paste due to unknow reason or blank clipboard!");
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Delete: {
|
||||
mFile.Remove(mSelectionHelp.GetRange());
|
||||
mSelectionHelp.Reset();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.DeleteAfter:
|
||||
case OperationEnum.DeleteBefore: {
|
||||
var pos = mSelectionHelp.GetPoint();
|
||||
if (oper == OperationEnum.DeleteBefore) pos -= 1; // delete after mean delete current selected item
|
||||
if (pos < 0 || pos >= mFile.mFrameCount) return;
|
||||
|
||||
// delete before need shift selection
|
||||
// delete before couldn't cause empty list, so we just need to directly shift
|
||||
if (oper == OperationEnum.DeleteBefore)
|
||||
mSelectionHelp.ShiftTo(false);
|
||||
// also, if we use delete after and delete the tail of item list, we also need to shift pos(use `else if` to prevent double shift)
|
||||
else if (oper == OperationEnum.DeleteAfter && pos == mFile.mFrameCount - 1) {
|
||||
// but delete after may cause empty list error(delete the item within only 1 item list)
|
||||
// so we need prevent this situation
|
||||
if (mFile.mFrameCount == 1) mSelectionHelp.Reset(); //yes, reset selection to prevent error
|
||||
else mSelectionHelp.ShiftTo(false); //no, shift selection.
|
||||
}
|
||||
|
||||
// do real operation
|
||||
mFile.Remove(new SelectionRange(pos, pos));
|
||||
|
||||
mSlider.UpdateRange(mFile);
|
||||
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();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Undo: {
|
||||
mFile.Undo();
|
||||
mSelectionHelp.Reset();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Redo: {
|
||||
mFile.Redo();
|
||||
mSelectionHelp.Reset();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
52
Legacy/BallanceTASEditor/UI/Util.cs
Normal file
52
Legacy/BallanceTASEditor/UI/Util.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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.UI {
|
||||
|
||||
public static class Util {
|
||||
public static void GridRowAdder(Grid container, GridLength size) {
|
||||
var item = new RowDefinition();
|
||||
item.Height = size;
|
||||
container.RowDefinitions.Add(item);
|
||||
}
|
||||
|
||||
public static void GridColumnAdder(Grid container, GridLength size) {
|
||||
var item = new ColumnDefinition();
|
||||
item.Width = size;
|
||||
container.ColumnDefinitions.Add(item);
|
||||
}
|
||||
|
||||
public static void SwapGridItemRC(UIElement item) {
|
||||
var swap = Grid.GetColumn(item);
|
||||
Grid.SetColumn(item, Grid.GetRow(item));
|
||||
Grid.SetRow(item, swap);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ToolMode {
|
||||
Cursor,
|
||||
Fill,
|
||||
Overwrite
|
||||
}
|
||||
|
||||
public struct CellPosition {
|
||||
public CellPosition(int column, FrameDataField field) {
|
||||
this.column = column;
|
||||
this.field = field;
|
||||
}
|
||||
public int column;
|
||||
public FrameDataField field;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user