write shit
This commit is contained in:
@ -34,6 +34,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
@ -56,11 +57,13 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="UI\SelectionHelp.cs" />
|
||||
<Compile Include="UI\StyleConverter.cs" />
|
||||
<Compile Include="UI\TASFlow.xaml.cs">
|
||||
<DependentUpon>TASFlow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\TASViewer.cs" />
|
||||
<Compile Include="UI\Util.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@ -131,16 +131,16 @@ namespace BallanceTASEditor.Core.TASStruct {
|
||||
public const int FRAMEDATA_OFFSET_KEY_STATES = 4;
|
||||
}
|
||||
|
||||
public enum FrameDataField {
|
||||
Key_Up,
|
||||
Key_Down,
|
||||
Key_Left,
|
||||
Key_Right,
|
||||
Key_Shift,
|
||||
Key_Space,
|
||||
Key_Q,
|
||||
Key_Esc,
|
||||
Key_Enter
|
||||
public enum FrameDataField : int {
|
||||
Key_Up = 0,
|
||||
Key_Down = 1,
|
||||
Key_Left = 2,
|
||||
Key_Right = 3,
|
||||
Key_Shift = 4,
|
||||
Key_Space = 5,
|
||||
Key_Q = 6,
|
||||
Key_Esc = 7,
|
||||
Key_Enter = 8
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
<MenuItem x:Name="uiMenu_File_Close" Header="Close" Click="funcMenu_File_Close"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Display">
|
||||
<MenuItem x:Name="uiMenu_Display_ItemCount" Header="Item Count"/>
|
||||
<MenuItem x:Name="uiMenu_Display_ItemCount" Header="Item Count" Click="funcMenu_Display_ItemCount"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem x:Name="uiMenu_Help_ReportBugs" Header="Report bugs" Click="funcMenu_Help_ReportBugs"/>
|
||||
@ -41,7 +41,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2">
|
||||
<Button x:Name="uiBtn_Select" Margin="5" Padding="5">
|
||||
<Button x:Name="uiBtn_Cursor" Margin="5" Padding="5" Click="funcBtn_Cursor">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Viewbox Width="24" Height="24">
|
||||
<Canvas Width="24" Height="24">
|
||||
@ -51,7 +51,7 @@
|
||||
<TextBlock Text="Select mode" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Fill" Margin="5" Padding="5">
|
||||
<Button x:Name="uiBtn_Fill" Margin="5" Padding="5" Click="funcBtn_Fill">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Viewbox Width="24" Height="24">
|
||||
<Canvas Width="24" Height="24">
|
||||
@ -61,7 +61,7 @@
|
||||
<TextBlock Text="Fill mode" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Draw" Margin="5" Padding="5">
|
||||
<Button x:Name="uiBtn_Overwrite" Margin="5" Padding="5" Click="funcBtn_Overwrite">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Viewbox Width="24" Height="24">
|
||||
<Canvas Width="24" Height="24">
|
||||
@ -127,13 +127,13 @@
|
||||
|
||||
</Grid>
|
||||
|
||||
<StatusBar Grid.Row="2">
|
||||
<TextBlock Text="Select mode"/>
|
||||
<TextBlock Text="Fill mode"/>
|
||||
<TextBlock Text="Draw mode"/>
|
||||
<StatusBar x:Name="uiStatusbar" Grid.Row="2">
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Cursor" Text="Select mode"/>
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Fill" Text="Fill mode"/>
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Overwrite" Text="Draw mode"/>
|
||||
<Separator/>
|
||||
<TextBlock Text="Selected: "/>
|
||||
<TextBlock Text="aaa"/>
|
||||
<TextBlock x:Name="uiStatusbar_Selected" Text="-"/>
|
||||
</StatusBar>
|
||||
|
||||
</Grid>
|
||||
|
||||
@ -22,15 +22,27 @@ namespace BallanceTASEditor {
|
||||
public partial class MainWindow : Window {
|
||||
public MainWindow() {
|
||||
InitializeComponent();
|
||||
|
||||
// bind event without xaml due to xaml shit design
|
||||
uiTASData.uiDataMenu_Set.Click += funcDataMenu_Set;
|
||||
uiTASData.uiDataMenu_Unset.Click += funcDataMenu_Unset;
|
||||
uiTASData.uiDataMenu_Copy.Click += funcDataMenu_Copy;
|
||||
uiTASData.uiDataMenu_Delete.Click += funcDataMenu_Delete;
|
||||
uiTASData.uiDataMenu_PasteAfter.Click += funcDataMenu_PasteAfter;
|
||||
uiTASData.uiDataMenu_PasteBefore.Click += funcDataMenu_PasteBefore;
|
||||
uiTASData.uiDataMenu_AddAfter.Click += funcDataMenu_AddAfter;
|
||||
uiTASData.uiDataMenu_AddBefore.Click += funcDataMenu_AddBefore;
|
||||
|
||||
RefreshUI(false);
|
||||
}
|
||||
|
||||
|
||||
TASFile mFile;
|
||||
TASViewer mViewer;
|
||||
|
||||
#region ui func
|
||||
|
||||
// menu
|
||||
// =========================== menu
|
||||
private void funcMenu_Help_ReportBugs(object sender, RoutedEventArgs e) {
|
||||
System.Diagnostics.Process.Start("https://github.com/yyc12345/BallanceTASEditor/issues");
|
||||
}
|
||||
@ -43,8 +55,9 @@ namespace BallanceTASEditor {
|
||||
var file = DialogUtil.OpenFileDialog();
|
||||
if (file == "") return;
|
||||
mFile = new TASFile(file);
|
||||
mViewer = new TASViewer(mFile, uiTASSlider, uiTASData);
|
||||
mViewer = new TASViewer(mFile, uiTASSlider, uiTASData, uiStatusbar_Selected);
|
||||
RefreshUI(true);
|
||||
ChangeToolMode(ToolMode.Cursor);
|
||||
}
|
||||
|
||||
private void funcMenu_File_Save(object sender, RoutedEventArgs e) {
|
||||
@ -65,9 +78,98 @@ namespace BallanceTASEditor {
|
||||
RefreshUI(false);
|
||||
}
|
||||
|
||||
private void funcMenu_Display_ItemCount(object sender, RoutedEventArgs e) {
|
||||
int newvalue = 0;
|
||||
if (DialogUtil.InputNumber("Input new count (>=5 && <=30)", 5, 30, ref newvalue)) {
|
||||
mViewer.ChangeListLength(newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================== btn
|
||||
private void funcBtn_Cursor(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Cursor);
|
||||
}
|
||||
|
||||
private void funcBtn_Fill(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Fill);
|
||||
}
|
||||
|
||||
private void funcBtn_Overwrite(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Overwrite);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region data menu
|
||||
|
||||
private void funcDataMenu_AddBefore(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_AddAfter(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_PasteBefore(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_PasteAfter(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_Delete(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_Copy(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_Unset(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void funcDataMenu_Set(object sender, RoutedEventArgs e) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ChangeToolMode(ToolMode mode) {
|
||||
switch (mode) {
|
||||
case ToolMode.Cursor:
|
||||
uiBtn_Cursor.IsEnabled = false;
|
||||
uiBtn_Fill.IsEnabled = true;
|
||||
uiBtn_Overwrite.IsEnabled = true;
|
||||
|
||||
uiStatusbar_Mode_Cursor.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Mode_Fill.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Mode_Overwrite.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
case ToolMode.Fill:
|
||||
uiBtn_Cursor.IsEnabled = true;
|
||||
uiBtn_Fill.IsEnabled = false;
|
||||
uiBtn_Overwrite.IsEnabled = true;
|
||||
|
||||
uiStatusbar_Mode_Cursor.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Mode_Fill.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Mode_Overwrite.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
case ToolMode.Overwrite:
|
||||
uiBtn_Cursor.IsEnabled = true;
|
||||
uiBtn_Fill.IsEnabled = true;
|
||||
uiBtn_Overwrite.IsEnabled = false;
|
||||
|
||||
uiStatusbar_Mode_Cursor.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Mode_Fill.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Mode_Overwrite.Visibility = Visibility.Visible;
|
||||
break;
|
||||
}
|
||||
|
||||
mViewer.ChangeToolMode(mode);
|
||||
}
|
||||
|
||||
private void RefreshUI(bool isFileOpened) {
|
||||
if (isFileOpened) {
|
||||
uiEditorPanel.Visibility = Visibility.Visible;
|
||||
@ -77,6 +179,10 @@ namespace BallanceTASEditor {
|
||||
uiMenu_File_Save.IsEnabled = true;
|
||||
uiMenu_File_SaveAs.IsEnabled = true;
|
||||
uiMenu_File_Close.IsEnabled = true;
|
||||
|
||||
uiMenu_Display_ItemCount.IsEnabled = true;
|
||||
|
||||
uiStatusbar.Visibility = Visibility.Visible;
|
||||
} else {
|
||||
uiEditorPanel.Visibility = Visibility.Collapsed;
|
||||
uiEditorNote.Visibility = Visibility.Visible;
|
||||
@ -85,6 +191,10 @@ namespace BallanceTASEditor {
|
||||
uiMenu_File_Save.IsEnabled = false;
|
||||
uiMenu_File_SaveAs.IsEnabled = false;
|
||||
uiMenu_File_Close.IsEnabled = false;
|
||||
|
||||
uiMenu_Display_ItemCount.IsEnabled = false;
|
||||
|
||||
uiStatusbar.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Microsoft.VisualBasic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -15,7 +16,7 @@ namespace BallanceTASEditor.UI {
|
||||
if (!(bool)op.ShowDialog()) return "";
|
||||
return op.FileName;
|
||||
}
|
||||
|
||||
|
||||
public static string SaveFileDialog() {
|
||||
Microsoft.Win32.SaveFileDialog op = new Microsoft.Win32.SaveFileDialog();
|
||||
op.RestoreDirectory = true;
|
||||
@ -29,5 +30,17 @@ namespace BallanceTASEditor.UI {
|
||||
return (result == MessageBoxResult.Yes);
|
||||
}
|
||||
|
||||
public static bool InputNumber(string title, int min, int max, ref int result) {
|
||||
while (true) {
|
||||
var dialog = Interaction.InputBox(title, "Input number", "");
|
||||
if (dialog == "") return false;
|
||||
if (int.TryParse(dialog, out result)) {
|
||||
if (result <= max && result >= min) break;
|
||||
}
|
||||
MessageBox.Show("Invalid number. Please input again", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
148
UI/SelectionHelp.cs
Normal file
148
UI/SelectionHelp.cs
Normal file
@ -0,0 +1,148 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.Cursor) return mStart;
|
||||
else {
|
||||
// cursor mode
|
||||
if (mIsStartConfirmed) return mStart;
|
||||
else throw new Exception("Data is not ready to read");
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct SelectionRange {
|
||||
public SelectionRange(long value1, long value2) {
|
||||
if (value1 > value2) {
|
||||
start = value2;
|
||||
end = value1;
|
||||
} else {
|
||||
start = value1;
|
||||
end = value2;
|
||||
}
|
||||
}
|
||||
public long start;
|
||||
public long end;
|
||||
public SelectionRange GetRelative(long refer) {
|
||||
var res = new SelectionRange();
|
||||
res.start = start - refer;
|
||||
res.end = end - refer;
|
||||
return res;
|
||||
}
|
||||
public bool Within(long num) {
|
||||
return (num >= start && num <= end);
|
||||
}
|
||||
public long GetCount() {
|
||||
return end - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,19 +38,20 @@
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="0" Text="Frame"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="1" Text="Delta Time"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="2" Text="^"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="3" Text="v"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="4" Text="<"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="5" Text=">"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="6" Text="shift"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="7" Text="space"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="8" Text="q"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="9" Text="esc"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="10" Text="enter"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="1" Text="Frame"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="2" Text="Delta Time"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="3" Text="^"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="4" Text="v"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="5" Text="<"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="6" Text=">"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="7" Text="shift"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="8" Text="space"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="9" Text="q"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="10" Text="esc"/>
|
||||
<TextBlock Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="11" Text="enter"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@ -21,12 +21,15 @@ namespace BallanceTASEditor.UI {
|
||||
public TASFlow() {
|
||||
InitializeComponent();
|
||||
mItemList = new List<TASFlowUIItem>();
|
||||
mRectMap = new Dictionary<Rectangle, CellPosition>();
|
||||
mItemCount = 0;
|
||||
SetItemCount(1);
|
||||
}
|
||||
|
||||
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 RefreshDataSources() {
|
||||
@ -57,12 +60,12 @@ namespace BallanceTASEditor.UI {
|
||||
if (offset > 0) {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
var newItem = new TASFlowUIItem(mItemCount + 1 + i); // the first col is sheet header, so add 1 additionally
|
||||
newItem.Add(uiCoreWindow);
|
||||
newItem.Add(uiCoreWindow, mRectMap, Rectangle_MouseDown);
|
||||
mItemList.Add(newItem);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < abs; i++) {
|
||||
mItemList[mItemCount].Remove(uiCoreWindow);
|
||||
mItemList[newCount + i].Remove(uiCoreWindow, mRectMap, Rectangle_MouseDown);
|
||||
}
|
||||
mItemList.RemoveRange(newCount, abs);
|
||||
}
|
||||
@ -71,57 +74,161 @@ namespace BallanceTASEditor.UI {
|
||||
mItemCount = newCount;
|
||||
}
|
||||
|
||||
public void RefreshDataMenu() {
|
||||
if (SelectionHelp == null) return;
|
||||
|
||||
ToolMode mode = SelectionHelp.GetToolMode();
|
||||
bool showCursorPasteAdd = mode == ToolMode.Cursor && SelectionHelp.IsDataPartialReady();
|
||||
bool showFill = mode == ToolMode.Fill && SelectionHelp.IsDataReady();
|
||||
bool showCursorCopyDelete = mode == ToolMode.Cursor && SelectionHelp.IsDataReady();
|
||||
|
||||
uiDataMenu_Set.IsEnabled = showFill;
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
SelectionHelp.FirstClick(mItemList[pos.column - 1].rawFrame, pos.field);
|
||||
} else if (e.MouseDevice.RightButton == MouseButtonState.Pressed) {
|
||||
SelectionHelp.LastClick(mItemList[pos.column - 1].rawFrame, pos.field);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 RECT_STROKE = new SolidColorBrush(Colors.Gray);
|
||||
private static readonly SolidColorBrush SEL_RECT_NORMAL_BRUSH = new SolidColorBrush(Colors.White);
|
||||
private static readonly SolidColorBrush SEL_RECT_SELECTED_BRUSH = new SolidColorBrush(Colors.Orange);
|
||||
private static readonly SolidColorBrush SEL_RECT_STROKE = new SolidColorBrush(Colors.Gray);
|
||||
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.Orange;
|
||||
private static readonly Color COLOR_UNSELECTED = Colors.Gray;
|
||||
private const int KEY_COUNT = 9;
|
||||
private const double SELECTION_HEADER_HEIGHT = 10.0f;
|
||||
|
||||
public TASFlowUIItem(int column) {
|
||||
// basic item
|
||||
sel_rect = new Rectangle();
|
||||
frame = new TextBlock();
|
||||
deltaTime = new TextBlock();
|
||||
|
||||
Grid.SetRow(frame, 0);
|
||||
Grid.SetRow(deltaTime, 1);
|
||||
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);
|
||||
|
||||
sel_rect.Margin = RECT_MARGIN;
|
||||
frame.Margin = DEFAULT_MARGIN;
|
||||
deltaTime.Margin = DEFAULT_MARGIN;
|
||||
|
||||
sel_rect.StrokeThickness = 3;
|
||||
sel_rect.Stroke = SEL_RECT_STROKE;
|
||||
sel_rect.Height = 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);
|
||||
Grid.SetRow(keystates[i], 2 + i);
|
||||
keystatesStroke[i] = new SolidColorBrush(COLOR_UNSELECTED);
|
||||
Grid.SetRow(keystates[i], 3 + i);
|
||||
Grid.SetColumn(keystates[i], column);
|
||||
keystates[i].Margin = RECT_MARGIN;
|
||||
keystates[i].StrokeThickness = 1;
|
||||
keystates[i].Stroke = RECT_STROKE;
|
||||
keystates[i].StrokeThickness = 3;
|
||||
keystates[i].Stroke = keystatesStroke[i];
|
||||
keystates[i].Fill = keystatesFill[i];
|
||||
}
|
||||
|
||||
this.column = column;
|
||||
rawFrame = 0;
|
||||
rawIsEnable = false;
|
||||
}
|
||||
|
||||
public void Add(Grid target) {
|
||||
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) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,11 +251,37 @@ namespace BallanceTASEditor.UI {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,30 +10,35 @@ using System.Windows;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class TASViewer : IDisposable {
|
||||
public TASViewer(TASFile file, Slider slider, TASFlow datagrid) {
|
||||
public TASViewer(TASFile file, Slider slider, TASFlow datagrid, TextBlock statusbar) {
|
||||
mFile = file;
|
||||
mSlider = slider;
|
||||
mDataGrid = datagrid;
|
||||
mStatusbar = statusbar;
|
||||
|
||||
// restore slider
|
||||
mSlider.Minimum = 0;
|
||||
updateSliderRange();
|
||||
|
||||
// init selection
|
||||
mSelectionHelp = new SelectionHelp();
|
||||
mSelectionHelp.SelectionChanged += funcSelectionHelp_SelectionChanged;
|
||||
|
||||
// init data
|
||||
mPosition = 0;
|
||||
mDataSource = new List<FrameDataDisplay>();
|
||||
INVALID_FRAME_DATA = new FrameData(-1f, 0);
|
||||
for (int i = 0; i < DATA_LIST_LENGTH; i++) {
|
||||
mDataSource.Add(new FrameDataDisplay(0, INVALID_FRAME_DATA));
|
||||
}
|
||||
mFile.Get(mDataSource, 0, DATA_LIST_LENGTH);
|
||||
mDataSource = new List<FrameDataDisplay>();
|
||||
mListLength = 0;
|
||||
|
||||
// bind event and source
|
||||
mDataGrid.SetItemCount(DATA_LIST_LENGTH);
|
||||
mDataGrid.DataSources = mDataSource;
|
||||
mDataGrid.RefreshDataSources();
|
||||
mDataGrid.SelectionHelp = mSelectionHelp;
|
||||
mSlider.ValueChanged += sliderValueChanged;
|
||||
|
||||
// display data
|
||||
ChangeListLength(DATA_LIST_LENGTH);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
mDataGrid.DataSources = null;
|
||||
mSlider.ValueChanged -= sliderValueChanged;
|
||||
@ -43,18 +48,20 @@ namespace BallanceTASEditor.UI {
|
||||
FrameData INVALID_FRAME_DATA;
|
||||
TASFile mFile;
|
||||
Slider mSlider;
|
||||
TextBlock mStatusbar;
|
||||
TASFlow mDataGrid;
|
||||
SelectionHelp mSelectionHelp;
|
||||
long mPosition;
|
||||
int mListLength;
|
||||
List<FrameDataDisplay> mDataSource;
|
||||
|
||||
private void sliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
|
||||
long pos = Convert.ToInt64(Math.Floor(e.NewValue));
|
||||
long offset = pos - mPosition;
|
||||
mFile.Shift(offset);
|
||||
mFile.Get(mDataSource, pos, DATA_LIST_LENGTH);
|
||||
|
||||
RefreshDisplay(pos);
|
||||
mPosition = pos;
|
||||
mDataGrid.RefreshDataSources();
|
||||
}
|
||||
|
||||
private void updateSliderRange() {
|
||||
@ -63,5 +70,76 @@ namespace BallanceTASEditor.UI {
|
||||
mSlider.Value = newSize;
|
||||
mSlider.Maximum = newSize;
|
||||
}
|
||||
|
||||
private void funcSelectionHelp_SelectionChanged() {
|
||||
mDataGrid.RefreshDataMenu();
|
||||
mDataGrid.RefreshSelectionHighlight();
|
||||
OnStatusbarSelectionChanged();
|
||||
}
|
||||
|
||||
private void OnStatusbarSelectionChanged() {
|
||||
var mode = mSelectionHelp.GetToolMode();
|
||||
|
||||
switch (mode) {
|
||||
case ToolMode.Cursor:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data = mSelectionHelp.GetRange();
|
||||
mStatusbar.Text = $"{data.start} - {data.end}";
|
||||
} else if (mSelectionHelp.IsDataPartialReady()) {
|
||||
var data2 = mSelectionHelp.GetPoint();
|
||||
mStatusbar.Text = data2.ToString();
|
||||
} else mStatusbar.Text = "-";
|
||||
break;
|
||||
case ToolMode.Fill:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data3 = mSelectionHelp.GetRange();
|
||||
mStatusbar.Text = $"{data3.start} - {data3.end}";
|
||||
} else mStatusbar.Text = "-";
|
||||
break;
|
||||
case ToolMode.Overwrite:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data4 = mSelectionHelp.GetPoint();
|
||||
mStatusbar.Text = data4.ToString();
|
||||
} else mStatusbar.Text = "-";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeListLength(int newLen) {
|
||||
if (newLen < 5 || newLen > 30) 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(mPosition);
|
||||
}
|
||||
|
||||
public void RefreshDisplay(long pos) {
|
||||
mFile.Get(mDataSource, pos, mListLength);
|
||||
mDataGrid.RefreshDataSources();
|
||||
mDataGrid.RefreshSelectionHighlight();
|
||||
}
|
||||
|
||||
public void ChangeToolMode(ToolMode mode) {
|
||||
mSelectionHelp.SetMode(mode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
24
UI/Util.cs
Normal file
24
UI/Util.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
|
||||
|
||||
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