Compare commits
10 Commits
2626608a2d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| df68c79f28 | |||
| 96f61362d3 | |||
| e8fc96e3ac | |||
| 5971069e02 | |||
| b506dafcbd | |||
| 0534b22501 | |||
| 352c133620 | |||
| 9d8f4b1727 | |||
| 1c57481f84 | |||
| 1def4c47f6 |
@ -4,6 +4,11 @@
|
||||
xmlns:local="clr-namespace:BallanceTASEditor"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Language/DefaultLanguage.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -25,6 +26,24 @@ namespace BallanceTASEditor {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// init configure manager
|
||||
GlobalVariable.configManager = new Core.ConfigManager("ballance-tas-editor.cfg", new Dictionary<string, string>() {
|
||||
{Core.ConfigManager.CfgNode_Language, CultureInfo.CurrentCulture.ThreeLetterWindowsLanguageName},
|
||||
{Core.ConfigManager.CfgNode_ItemCount, "15"},
|
||||
{Core.ConfigManager.CfgNode_IsHorizonLayout, "True"},
|
||||
{Core.ConfigManager.CfgNode_IsOverwrittenPaste, "False"}
|
||||
});
|
||||
|
||||
// init i18n
|
||||
Core.I18NProcessor.ChangeLanguage(GlobalVariable.configManager.Configuration[Core.ConfigManager.CfgNode_Language]);
|
||||
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e) {
|
||||
base.OnExit(e);
|
||||
|
||||
GlobalVariable.configManager.Save();
|
||||
}
|
||||
|
||||
private void UncatchedErrorHandle(string message, string stackTrace) {
|
||||
@ -50,7 +69,10 @@ namespace BallanceTASEditor {
|
||||
;//skip
|
||||
}
|
||||
|
||||
MessageBox.Show("A fatal error occurs. The application should exit. Please send the error log, reproduce step and corresponding TAS file(is possible) to use to help fixing this problem.", "Ballance TAS Editor", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show("A fatal error occurs. The application should exit. Please send the error log, reproduce step and corresponding TAS file(if possible) to developer to help fixing this problem.",
|
||||
"Ballance TAS Editor",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error
|
||||
);
|
||||
App.Current.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
@ -36,8 +36,17 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
@ -51,9 +60,6 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="zlib.net, Version=1.0.3.0, Culture=neutral, PublicKeyToken=47d7877cb3620160">
|
||||
<HintPath>..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
@ -61,20 +67,30 @@
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Core\ClipboardUtil.cs" />
|
||||
<Compile Include="Core\ConfigManager.cs" />
|
||||
<Compile Include="Core\FileOperation.cs" />
|
||||
<Compile Include="Core\I18NProcessor.cs" />
|
||||
<Compile Include="Core\KeyboardState.cs" />
|
||||
<Compile Include="Core\LimitedStack.cs" />
|
||||
<Compile Include="GlobalVariable.cs" />
|
||||
<Compile Include="UI\AddItem.xaml.cs">
|
||||
<DependentUpon>AddItem.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\OperationEnum.cs" />
|
||||
<Compile Include="UI\SelectionHelp.cs" />
|
||||
<Compile Include="UI\StyleConverter.cs" />
|
||||
<Compile Include="UI\TASFlow.xaml.cs">
|
||||
<DependentUpon>TASFlow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\TASFlow.cs" />
|
||||
<Compile Include="UI\TASSlider.cs" />
|
||||
<Compile Include="UI\TASViewer.cs" />
|
||||
<Compile Include="UI\Util.cs" />
|
||||
<Page Include="Language\CHS.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Language\DefaultLanguage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@ -96,10 +112,6 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\TASFlow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
@ -126,5 +138,8 @@
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
65
BallanceTASEditor/Core/ConfigManager.cs
Normal file
65
BallanceTASEditor/Core/ConfigManager.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BallanceTASEditor.Core {
|
||||
public class ConfigManager {
|
||||
|
||||
public ConfigManager(string fileName, Dictionary<string, string> defaultValue) {
|
||||
_fileName = fileName;
|
||||
_defaultValue = defaultValue;
|
||||
|
||||
Configuration = Read();
|
||||
}
|
||||
|
||||
string _fileName;
|
||||
Dictionary<string, string> _defaultValue;
|
||||
public Dictionary<string, string> Configuration;
|
||||
|
||||
public static readonly string CfgNode_Language = "Language";
|
||||
public static readonly string CfgNode_ItemCount = "ItemCount";
|
||||
public static readonly string CfgNode_IsHorizonLayout = "IsHorizonLayout";
|
||||
public static readonly string CfgNode_IsOverwrittenPaste = "IsOverwrittenPaste";
|
||||
|
||||
Dictionary<string, string> Read() {
|
||||
if (!File.Exists(Path.Combine(Environment.CurrentDirectory, _fileName)))
|
||||
Init();
|
||||
|
||||
Dictionary<string, string> data;
|
||||
using (StreamReader fs = new StreamReader(Path.Combine(Environment.CurrentDirectory, _fileName), Encoding.UTF8)) {
|
||||
data = JsonConvert.DeserializeObject<Dictionary<string, string>>(fs.ReadToEnd());
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
// check field to make sure each field is existed
|
||||
// because version update it might be changed
|
||||
foreach(var pair in _defaultValue) {
|
||||
if (!data.ContainsKey(pair.Key)) {
|
||||
data.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void Init() {
|
||||
using (StreamWriter fs = new StreamWriter(Path.Combine(Environment.CurrentDirectory, _fileName), false, Encoding.UTF8)) {
|
||||
fs.Write(JsonConvert.SerializeObject(_defaultValue));
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save() {
|
||||
using (StreamWriter fs = new StreamWriter(Path.Combine(Environment.CurrentDirectory, _fileName), false, Encoding.UTF8)) {
|
||||
fs.Write(JsonConvert.SerializeObject(this.Configuration));
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
40
BallanceTASEditor/Core/I18NProcessor.cs
Normal file
40
BallanceTASEditor/Core/I18NProcessor.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace BallanceTASEditor.Core {
|
||||
public static class I18NProcessor {
|
||||
|
||||
public static string GetI18N(string key, params string[] parameters) {
|
||||
try {
|
||||
var cache = (string)(App.Current.Resources[key]);
|
||||
return string.Format(cache, parameters);
|
||||
} catch (Exception) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static void ChangeLanguage(string target) {
|
||||
ResourceDictionary langRd = null;
|
||||
try {
|
||||
langRd =
|
||||
Application.LoadComponent(
|
||||
new Uri(@"Language/" + target + ".xaml", UriKind.Relative))
|
||||
as ResourceDictionary;
|
||||
} catch {
|
||||
;
|
||||
}
|
||||
|
||||
if (langRd != null) {
|
||||
if (App.Current.Resources.MergedDictionaries.Count > 0) {
|
||||
App.Current.Resources.MergedDictionaries.Clear();
|
||||
}
|
||||
App.Current.Resources.MergedDictionaries.Add(langRd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,8 @@ namespace BallanceTASEditor.Core {
|
||||
}
|
||||
|
||||
public long GetPointerIndex() {
|
||||
if (mPointer == null) throw new Exception("Data is not ready");
|
||||
// return invalid data to prevent error
|
||||
if (mPointer == null) return -1;//throw new Exception("Data is not ready");
|
||||
return mPointerIndex;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -12,34 +12,63 @@ namespace BallanceTASEditor.Core {
|
||||
public static void CompressTAS(LinkedList<FrameData> mem, FileStream file) {
|
||||
file.Write(BitConverter.GetBytes(mem.Count * ConstValue.FRAMEDATA_SIZE), 0, 4);
|
||||
|
||||
var zo = new zlib.ZOutputStream(file, 9);
|
||||
var node = mem.First;
|
||||
while (node != null) {
|
||||
zo.Write(BitConverter.GetBytes(node.Value.deltaTime), 0, 4);
|
||||
zo.Write(BitConverter.GetBytes(node.Value.keystates), 0, 4);
|
||||
node = node.Next;
|
||||
using (var zo = new Ionic.Zlib.ZlibStream(file, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.Level9, true)) {
|
||||
var node = mem.First;
|
||||
while (node != null) {
|
||||
zo.Write(BitConverter.GetBytes(node.Value.deltaTime), 0, 4);
|
||||
zo.Write(BitConverter.GetBytes(node.Value.keystates), 0, 4);
|
||||
node = node.Next;
|
||||
}
|
||||
zo.Close();
|
||||
}
|
||||
zo.finish();
|
||||
zo.Close();
|
||||
|
||||
//var zo = new zlib.ZOutputStream(file, 9);
|
||||
//var node = mem.First;
|
||||
//while (node != null) {
|
||||
// zo.Write(BitConverter.GetBytes(node.Value.deltaTime), 0, 4);
|
||||
// zo.Write(BitConverter.GetBytes(node.Value.keystates), 0, 4);
|
||||
// node = node.Next;
|
||||
//}
|
||||
//zo.finish();
|
||||
//zo.Close();
|
||||
}
|
||||
|
||||
public static void DecompressTAS(LinkedList<FrameData> ls, FileStream file) {
|
||||
var lengthTemp = new byte[4];
|
||||
var mem = new MemoryStream();
|
||||
file.Read(lengthTemp, 0, 4);
|
||||
Int32 expectedLength = BitConverter.ToInt32(lengthTemp, 0);
|
||||
long expectedCount = expectedLength / ConstValue.FRAMEDATA_SIZE;
|
||||
|
||||
var zo = new zlib.ZOutputStream(mem);
|
||||
CopyStream(file, zo);
|
||||
zo.finish();
|
||||
using (var mem = new MemoryStream()) {
|
||||
using (var zo = new Ionic.Zlib.ZlibStream(mem, Ionic.Zlib.CompressionMode.Decompress, true)) {
|
||||
CopyStream(file, zo);
|
||||
zo.Close();
|
||||
}
|
||||
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
for(long i = 0; i < expectedCount; i++) {
|
||||
ls.AddLast(new FrameData(mem));
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
for (long i = 0; i < expectedCount; i++) {
|
||||
ls.AddLast(new FrameData(mem));
|
||||
}
|
||||
mem.Close();
|
||||
}
|
||||
mem.Close();
|
||||
zo.Close();
|
||||
|
||||
//mem.Seek(0, SeekOrigin.Begin);
|
||||
//for (long i = 0; i < expectedCount; i++) {
|
||||
// ls.AddLast(new FrameData(mem));
|
||||
//}
|
||||
//mem.Close();
|
||||
//zo.Close();
|
||||
|
||||
//var zo = new zlib.ZOutputStream(mem);
|
||||
//CopyStream(file, zo);
|
||||
//zo.finish();
|
||||
|
||||
//mem.Seek(0, SeekOrigin.Begin);
|
||||
//for (long i = 0; i < expectedCount; i++) {
|
||||
// ls.AddLast(new FrameData(mem));
|
||||
//}
|
||||
//mem.Close();
|
||||
//zo.Close();
|
||||
}
|
||||
|
||||
public static void CopyStream(Stream origin, Stream target) {
|
||||
|
||||
13
BallanceTASEditor/GlobalVariable.cs
Normal file
13
BallanceTASEditor/GlobalVariable.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BallanceTASEditor {
|
||||
public class GlobalVariable {
|
||||
|
||||
public static Core.ConfigManager configManager;
|
||||
|
||||
}
|
||||
}
|
||||
77
BallanceTASEditor/Language/CHS.xaml
Normal file
77
BallanceTASEditor/Language/CHS.xaml
Normal file
@ -0,0 +1,77 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:BallanceTASEditor.Language"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<!-- ui data-->
|
||||
<sys:String x:Key="ui_MainWindow_Title">Ballance TAS 编辑器</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File">文件</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Open">打开</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Save">保存</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_SaveAs">另存为...</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Close">关闭</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display">编辑</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_Undo">撤销</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_Redo">重做</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_ItemCount">项个数</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_OverwrittenPaste">覆盖式粘贴</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_HorizontalLayout">横向布局</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help">帮助</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help_ReportBugs">汇报漏洞</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help_About">关于</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_EditorNote">打开或拖入一个 TAS 文件以编辑</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Cursor">选择模式</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Fill">填充模式</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Overwritten">画笔模式</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Cursor">选择模式</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Fill">填充模式</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Overwritten">画笔模式</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_OverwrittenPaste">覆盖式粘贴</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Selected">已选择:</sys:String>
|
||||
|
||||
|
||||
<sys:String x:Key="ui_TASFlow_Sheet_Frame">帧</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Sheet_DeltaTime">间隔时间</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Set">设置</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Unset">不设置</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Cut">剪切</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Copy">复制</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_PasteAfter">粘贴于后方</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_PasteBefore">粘贴于前方</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Delete">删除</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_DeleteAfter">向后删除</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_DeleteBefore">向前删除</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_AddAfter">在后方添加新项</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_AddBefore">在前方添加新项</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_AddItem_Title">添加项</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_Count">个数</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_FPS">帧率</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_DeltaTime">间隔时间</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_OK">好</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_Cancel">取消</sys:String>
|
||||
|
||||
<!-- code data-->
|
||||
|
||||
<sys:String x:Key="code_Shared_ProgramName">Ballance TAS 编辑器</sys:String>
|
||||
|
||||
<sys:String x:Key="code_MainWindow_Menu_Help_About" xml:space="preserve">基于 MIT 开源许可证发布
|
||||
版本:1.2 stable
|
||||
程序:yyc12345.
|
||||
图标设计:plAer_2</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Closing">文件未关闭。您想直接退出吗?所有修改不会被保存。</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_File_Close">您想要关闭这个TAS文件吗?</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_File_Open_Fail">无法打开文件,文件可能不是合法的TAS文件。</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_Display_ItemCount">输入新的数量(<=5 && >=30)</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_Warning">警告</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_FileFilter">TAS 文件(*.tas)|*.tas|所有文件(*.*)|*.*</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_InputNumber_Title">输入数字</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_InputNumber_Wrong">无效的数字,请再试一次。</sys:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
77
BallanceTASEditor/Language/DefaultLanguage.xaml
Normal file
77
BallanceTASEditor/Language/DefaultLanguage.xaml
Normal file
@ -0,0 +1,77 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:BallanceTASEditor.Language"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<!-- ui data-->
|
||||
<sys:String x:Key="ui_MainWindow_Title">Ballance TAS Editor</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File">File</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Open">Open</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Save">Save</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_SaveAs">Save As ...</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_File_Close">Close</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display">Edit</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_Undo">Undo</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_Redo">Redo</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_ItemCount">Item Count</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_OverwrittenPaste">Overwritten Paste</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Display_HorizontalLayout">Horizontal Layout</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help">Help</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help_ReportBugs">Report Bugs</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Menu_Help_About">About</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_EditorNote">Open or drop a TAS file for editing</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Cursor">Select mode</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Fill">Fill mode</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_Tools_Overwritten">Draw mode</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Cursor">Select mode</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Fill">Fill mode</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_Mode_Overwritten">Draw mode</sys:String>
|
||||
<sys:String x:Key="ui_MainWindow_StatusBar_OverwrittenPaste">Overwritten paste</sys:String>
|
||||
<sys:String xml:space="preserve" x:Key="ui_MainWindow_StatusBar_Selected">Selected: </sys:String>
|
||||
|
||||
|
||||
<sys:String x:Key="ui_TASFlow_Sheet_Frame">Frame</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Sheet_DeltaTime">Delta Time</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Set">Set</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Unset">Unset</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Cut">Cut</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Copy">Copy</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_PasteAfter">Paste after this</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_PasteBefore">Paste before this</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_Delete">Delete</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_DeleteAfter">Delete this frame</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_DeleteBefore">Delete last frame</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_AddAfter">Add blank item after this</sys:String>
|
||||
<sys:String x:Key="ui_TASFlow_Menu_AddBefore">Add blank item before this</sys:String>
|
||||
|
||||
<sys:String x:Key="ui_AddItem_Title">Add Item</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_Count">Count</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_FPS">FPS</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_DeltaTime">Delta Time</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_OK">OK</sys:String>
|
||||
<sys:String x:Key="ui_AddItem_Cancel">Cancel</sys:String>
|
||||
|
||||
<!-- code data-->
|
||||
|
||||
<sys:String x:Key="code_Shared_ProgramName">Ballance TAS Editor</sys:String>
|
||||
|
||||
<sys:String x:Key="code_MainWindow_Menu_Help_About" xml:space="preserve">Under MIT License
|
||||
Version: 1.2 stable
|
||||
Program: yyc12345.
|
||||
Icon design: plAer_2</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Closing">File is not closed. Do you want to just quit? All changes will not be saved.</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_File_Close">Do you want to close this TAS file?</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_File_Open_Fail">Fail to open file. This file might not a legal TAS file.</sys:String>
|
||||
<sys:String x:Key="code_MainWindow_Menu_Display_ItemCount">Input new count (<=5 && >=30)</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_Warning">Warning</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_FileFilter">TAS file(*.tas)|*.tas|All file(*.*)|*.*</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_InputNumber_Title">Input number</sys:String>
|
||||
<sys:String x:Key="code_DialogUtil_InputNumber_Wrong">Invalid number. Please input again.</sys:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
@ -1,4 +1,4 @@
|
||||
<Window x:Class="BallanceTASEditor.MainWindow"
|
||||
<Window x:Class="BallanceTASEditor.MainWindow"
|
||||
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"
|
||||
@ -7,9 +7,47 @@
|
||||
xmlns:controls="clr-namespace:BallanceTASEditor.UI"
|
||||
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
|
||||
mc:Ignorable="d"
|
||||
Title="Ballance TAS Editor" Height="500" Width="800" KeyUp="funcWindow_KeyUp"
|
||||
input:InputMethod.IsInputMethodEnabled="False">
|
||||
Title="{DynamicResource ui_MainWindow_Title}" Height="500" Width="800" KeyUp="funcWindow_KeyUp"
|
||||
input:InputMethod.IsInputMethodEnabled="False" MouseWheel="funcWindow_MouseWheel" Icon="icon.ico" Closing="funcWindow_Closing">
|
||||
|
||||
<!-- shortcut defination-->
|
||||
<Window.Resources>
|
||||
<RoutedUICommand x:Key="commandMenu_File_Open"/>
|
||||
<RoutedUICommand x:Key="commandMenu_File_Save"/>
|
||||
<RoutedUICommand x:Key="commandMenu_Display_Undo"/>
|
||||
<RoutedUICommand x:Key="commandMenu_Display_Redo"/>
|
||||
<RoutedUICommand x:Key="commandDataMenu_Cut"/>
|
||||
<RoutedUICommand x:Key="commandDataMenu_Copy"/>
|
||||
<RoutedUICommand x:Key="commandDataMenu_PasteAfter"/>
|
||||
<RoutedUICommand x:Key="commandDataMenu_DeleteAfter"/>
|
||||
<RoutedUICommand x:Key="commandDataMenu_DeleteBefore"/>
|
||||
</Window.Resources>
|
||||
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Gesture="Ctrl+O" Command="{StaticResource commandMenu_File_Open}"/>
|
||||
<KeyBinding Gesture="Ctrl+S" Command="{StaticResource commandMenu_File_Save}"/>
|
||||
<KeyBinding Gesture="Ctrl+Z" Command="{StaticResource commandMenu_Display_Undo}"/>
|
||||
<KeyBinding Gesture="Ctrl+Y" Command="{StaticResource commandMenu_Display_Redo}"/>
|
||||
<KeyBinding Gesture="Ctrl+X" Command="{StaticResource commandDataMenu_Cut}"/>
|
||||
<KeyBinding Gesture="Ctrl+C" Command="{StaticResource commandDataMenu_Copy}"/>
|
||||
<KeyBinding Gesture="Ctrl+V" Command="{StaticResource commandDataMenu_PasteAfter}"/>
|
||||
<KeyBinding Gesture="Delete" Command="{StaticResource commandDataMenu_DeleteAfter}"/>
|
||||
<KeyBinding Gesture="Back" Command="{StaticResource commandDataMenu_DeleteBefore}"/>
|
||||
</Window.InputBindings>
|
||||
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="{StaticResource commandMenu_File_Open}" Executed="funcCommand_Menu_File_Open" CanExecute="funcCanExeCmd_Menu_File_Open"/>
|
||||
<CommandBinding Command="{StaticResource commandMenu_File_Save}" Executed="funcCommand_Menu_File_Save" CanExecute="funcCanExeCmd_Menu_File_Save"/>
|
||||
<CommandBinding Command="{StaticResource commandMenu_Display_Undo}" Executed="funcCommand_Menu_Display_Undo" CanExecute="funcCanExeCmd_Menu_Display_Undo"/>
|
||||
<CommandBinding Command="{StaticResource commandMenu_Display_Redo}" Executed="funcCommand_Menu_Display_Redo" CanExecute="funcCanExeCmd_Menu_Display_Redo"/>
|
||||
<CommandBinding Command="{StaticResource commandDataMenu_Cut}" Executed="funcCommand_DataMenu_Cut" CanExecute="funcCanExeCmd_DataMenu_Cut"/>
|
||||
<CommandBinding Command="{StaticResource commandDataMenu_Copy}" Executed="funcCommand_DataMenu_Copy" CanExecute="funcCanExeCmd_DataMenu_Copy"/>
|
||||
<CommandBinding Command="{StaticResource commandDataMenu_PasteAfter}" Executed="funcCommand_DataMenu_PasteAfter" CanExecute="funcCanExeCmd_DataMenu_PasteAfter"/>
|
||||
<CommandBinding Command="{StaticResource commandDataMenu_DeleteAfter}" Executed="funcCommand_DataMenu_DeleteAfter" CanExecute="funcCanExeCmd_DataMenu_DeleteAfter"/>
|
||||
<CommandBinding Command="{StaticResource commandDataMenu_DeleteBefore}" Executed="funcCommand_DataMenu_DeleteBefore" CanExecute="funcCanExeCmd_DataMenu_DeleteBefore"/>
|
||||
</Window.CommandBindings>
|
||||
|
||||
<!-- real ui elements-->
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
@ -18,31 +56,44 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Menu Grid.Row="0">
|
||||
<MenuItem Header="File">
|
||||
<MenuItem x:Name="uiMenu_File_Open" Header="Open" Click="funcMenu_File_Open"/>
|
||||
<MenuItem x:Name="uiMenu_File_Save" Header="Save" Click="funcMenu_File_Save"/>
|
||||
<MenuItem x:Name="uiMenu_File_SaveAs" Header="Save As..." Click="funcMenu_File_SaveAs"/>
|
||||
<MenuItem x:Name="uiMenu_File_Close" Header="Close" Click="funcMenu_File_Close"/>
|
||||
<MenuItem Header="{DynamicResource ui_MainWindow_Menu_File}">
|
||||
<MenuItem x:Name="uiMenu_File_Open" Header="{DynamicResource ui_MainWindow_Menu_File_Open}" Click="funcMenu_File_Open" InputGestureText="Ctrl + O"/>
|
||||
<MenuItem x:Name="uiMenu_File_Save" Header="{DynamicResource ui_MainWindow_Menu_File_Save}" Click="funcMenu_File_Save" InputGestureText="Ctrl + S"/>
|
||||
<MenuItem x:Name="uiMenu_File_SaveAs" Header="{DynamicResource ui_MainWindow_Menu_File_SaveAs}" Click="funcMenu_File_SaveAs"/>
|
||||
<MenuItem x:Name="uiMenu_File_Close" Header="{DynamicResource ui_MainWindow_Menu_File_Close}" Click="funcMenu_File_Close"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Display">
|
||||
<MenuItem x:Name="uiMenu_Display_Undo" Header="Undo" Click="funcMenu_Display_Undo"/>
|
||||
<MenuItem x:Name="uiMenu_Display_Redo" Header="Redo" Click="funcMenu_Display_Redo"/>
|
||||
<MenuItem x:Name="uiMenu_Display_ItemCount" Header="Item Count" Click="funcMenu_Display_ItemCount"/>
|
||||
<MenuItem x:Name="uiMenu_Display_OverwrittenPaste" Header="Overwritten Paste" IsCheckable="True" Checked="funcMenu_Display_OverwrittenPaste" Unchecked="funcMenu_Display_OverwrittenPaste"/>
|
||||
<MenuItem Header="{DynamicResource ui_MainWindow_Menu_Display}">
|
||||
<MenuItem x:Name="uiMenu_Display_Undo" Header="{DynamicResource ui_MainWindow_Menu_Display_Undo}" Click="funcMenu_Display_Undo" InputGestureText="Ctrl + Z"/>
|
||||
<MenuItem x:Name="uiMenu_Display_Redo" Header="{DynamicResource ui_MainWindow_Menu_Display_Redo}" Click="funcMenu_Display_Redo" InputGestureText="Ctrl + Y"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiMenu_Display_ItemCount" Header="{DynamicResource ui_MainWindow_Menu_Display_ItemCount}" Click="funcMenu_Display_ItemCount"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiMenu_Display_OverwrittenPaste" Header="{DynamicResource ui_MainWindow_Menu_Display_OverwrittenPaste}" Click="funcMenu_Display_OverwrittenPaste"/>
|
||||
<MenuItem x:Name="uiMenu_Display_HorizontalLayout" Header="{DynamicResource ui_MainWindow_Menu_Display_HorizontalLayout}" Click="funcMenu_Display_HorizontalLayout"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem x:Name="uiMenu_Help_ReportBugs" Header="Report bugs" Click="funcMenu_Help_ReportBugs"/>
|
||||
<MenuItem x:Name="uiMenu_Help_About" Header="About" Click="funcMenu_Help_About"/>
|
||||
<MenuItem Header="{DynamicResource ui_MainWindow_Menu_Help}">
|
||||
<MenuItem x:Name="uiMenu_Help_ReportBugs" Header="{DynamicResource ui_MainWindow_Menu_Help_ReportBugs}" Click="funcMenu_Help_ReportBugs"/>
|
||||
<MenuItem x:Name="uiMenu_Help_About" Header="{DynamicResource ui_MainWindow_Menu_Help_About}" Click="funcMenu_Help_About"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<TextBlock x:Name="uiEditorNote" Grid.Row="1" Text="Open a TAS file for editing" Opacity="0.5" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16"/>
|
||||
<Grid x:Name="uiEditorNote" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" AllowDrop="True" Drop="funcDrop_Drop" DragEnter="funcDrop_DragEnter" Visibility="Collapsed">
|
||||
<Rectangle StrokeThickness="4" Stroke="Gray" StrokeDashArray="4 4" Fill="#ffffff"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Viewbox Width="24" Height="24" Margin="20, 20, 0, 20" VerticalAlignment="Center">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Gray" Data="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
<TextBlock Margin="20" Text="{DynamicResource ui_MainWindow_EditorNote}" Foreground="Gray" FontSize="16" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="uiEditorPanel" Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.ColumnSpan="2">
|
||||
@ -53,7 +104,7 @@
|
||||
<Path Fill="Black" Data="M10.07,14.27C10.57,14.03 11.16,14.25 11.4,14.75L13.7,19.74L15.5,18.89L13.19,13.91C12.95,13.41 13.17,12.81 13.67,12.58L13.95,12.5L16.25,12.05L8,5.12V15.9L9.82,14.43L10.07,14.27M13.64,21.97C13.14,22.21 12.54,22 12.31,21.5L10.13,16.76L7.62,18.78C7.45,18.92 7.24,19 7,19A1,1 0 0,1 6,18V3A1,1 0 0,1 7,2C7.24,2 7.47,2.09 7.64,2.23L7.65,2.22L19.14,11.86C19.57,12.22 19.62,12.85 19.27,13.27C19.12,13.45 18.91,13.57 18.7,13.61L15.54,14.23L17.74,18.96C18,19.46 17.76,20.05 17.26,20.28L13.64,21.97Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
<TextBlock Text="Select mode" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource ui_MainWindow_Tools_Cursor}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Fill" Margin="5" Padding="5" Click="funcBtn_Fill">
|
||||
@ -63,7 +114,7 @@
|
||||
<Path Fill="Black" Data="M19,11.5C19,11.5 17,13.67 17,15A2,2 0 0,0 19,17A2,2 0 0,0 21,15C21,13.67 19,11.5 19,11.5M5.21,10L10,5.21L14.79,10M16.56,8.94L7.62,0L6.21,1.41L8.59,3.79L3.44,8.94C2.85,9.5 2.85,10.47 3.44,11.06L8.94,16.56C9.23,16.85 9.62,17 10,17C10.38,17 10.77,16.85 11.06,16.56L16.56,11.06C17.15,10.47 17.15,9.5 16.56,8.94Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
<TextBlock Text="Fill mode" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource ui_MainWindow_Tools_Fill}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Overwrite" Margin="5" Padding="5" Click="funcBtn_Overwrite">
|
||||
@ -73,72 +124,146 @@
|
||||
<Path Fill="Black" Data="M18.62,1.5C18.11,1.5 17.6,1.69 17.21,2.09L10.75,8.55L14.95,12.74L21.41,6.29C22.2,5.5 22.2,4.24 21.41,3.46L20.04,2.09C19.65,1.69 19.14,1.5 18.62,1.5M9.8,9.5L3.23,16.07L3.93,16.77C3.4,17.24 2.89,17.78 2.38,18.29C1.6,19.08 1.6,20.34 2.38,21.12C3.16,21.9 4.42,21.9 5.21,21.12C5.72,20.63 6.25,20.08 6.73,19.58L7.43,20.27L14,13.7" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
<TextBlock Text="Draw mode" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{DynamicResource ui_MainWindow_Tools_Overwritten}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<controls:TASFlow x:Name="uiTASData" Grid.Row="1" Margin="5" BorderThickness="1" BorderBrush="Gray">
|
||||
</controls:TASFlow>
|
||||
<Grid x:Name="uiLayoutContainer" Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="2" Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="uiTASFlowContainer" BorderThickness="1" BorderBrush="Gray" Grid.Row="0" Margin="5" Background="#ffffff">
|
||||
<Grid x:Name="uiTASData">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="uiDataMenu_Set" Header="{DynamicResource ui_TASFlow_Menu_Set}" Click="funcDataMenu_Set"/>
|
||||
<MenuItem x:Name="uiDataMenu_Unset" Header="{DynamicResource ui_TASFlow_Menu_Unset}" Click="funcDataMenu_Unset"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_Cut" Header="{DynamicResource ui_TASFlow_Menu_Cut}" Click="funcDataMenu_Cut" InputGestureText="Ctrl + X"/>
|
||||
<MenuItem x:Name="uiDataMenu_Copy" Header="{DynamicResource ui_TASFlow_Menu_Copy}" Click="funcDataMenu_Copy" InputGestureText="Ctrl + C"/>
|
||||
<MenuItem x:Name="uiDataMenu_PasteAfter" Header="{DynamicResource ui_TASFlow_Menu_PasteAfter}" Click="funcDataMenu_PasteAfter" InputGestureText="Ctrl + V"/>
|
||||
<MenuItem x:Name="uiDataMenu_PasteBefore" Header="{DynamicResource ui_TASFlow_Menu_PasteBefore}" Click="funcDataMenu_PasteBefore"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_Delete" Header="{DynamicResource ui_TASFlow_Menu_Delete}" Click="funcDataMenu_Delete"/>
|
||||
<MenuItem x:Name="uiDataMenu_DeleteAfter" Header="{DynamicResource ui_TASFlow_Menu_DeleteAfter}" Click="funcDataMenu_DeleteAfter" InputGestureText="Del"/>
|
||||
<MenuItem x:Name="uiDataMenu_DeleteBefore" Header="{DynamicResource ui_TASFlow_Menu_DeleteBefore}" Click="funcDataMenu_DeleteBefore" InputGestureText="Backspace"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_AddAfter" Header="{DynamicResource ui_TASFlow_Menu_AddAfter}" Click="funcDataMenu_AddAfter"/>
|
||||
<MenuItem x:Name="uiDataMenu_AddBefore" Header="{DynamicResource ui_TASFlow_Menu_AddBefore}" Click="funcDataMenu_AddBefore"/>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<Button x:Name="uiBtn_FastMovePrev" Grid.Column="0" Margin="2" HorizontalAlignment="Center" Click="funcBtn_FastMovePrev">
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M11.5,12L20,18V6M11,18V6L2.5,12L11,18Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_MovePrev" Grid.Column="1" Margin="2" HorizontalAlignment="Center" Click="funcBtn_MovePrev">
|
||||
<Viewbox Width="16" Height="16" RenderTransformOrigin="0.5,0.5">
|
||||
<Viewbox.RenderTransform>
|
||||
<RotateTransform Angle="-90"/>
|
||||
</Viewbox.RenderTransform>
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M7,15L12,10L17,15H7Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_MoveNext" Grid.Column="2" Margin="2" HorizontalAlignment="Center" Click="funcBtn_MoveNext">
|
||||
<Viewbox Width="16" Height="16" RenderTransformOrigin="0.5,0.5">
|
||||
<Viewbox.RenderTransform>
|
||||
<RotateTransform Angle="-90"/>
|
||||
</Viewbox.RenderTransform>
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M7,10L12,15L17,10H7Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_FastMoveNext" Grid.Column="3" Margin="2" HorizontalAlignment="Center" Click="funcBtn_FastMoveNext">
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M13,6V18L21.5,12M4,18L12.5,12L4,6V18Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Slider x:Name="uiTASSlider" Margin="5,0,0,0" Grid.Column="4" SmallChange="1" LargeChange="10" Maximum="1" VerticalAlignment="Center">
|
||||
</Slider>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock x:Name="uiFlowHeader_Frame" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="1" Text="{DynamicResource ui_TASFlow_Sheet_Frame}"/>
|
||||
<TextBlock x:Name="uiFlowHeader_DeltaTime" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="2" Text="{DynamicResource ui_TASFlow_Sheet_DeltaTime}"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Up" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="3" Text="^"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Down" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="4" Text="v"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Left" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="5" Text="<"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Right" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="6" Text=">"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Shift" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="7" Text="shift"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Space" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="8" Text="space"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Q" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="9" Text="q"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Esc" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="10" Text="esc"/>
|
||||
<TextBlock x:Name="uiFlowHeader_Enter" Padding="2" Background="#afafaf" Grid.Column="0" Grid.Row="11" Text="enter"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid x:Name="uiTASSliderContainer" Grid.Row="1" Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="uiBtn_FastMovePrev" Grid.Column="0" Margin="2" HorizontalAlignment="Center" Click="funcBtn_FastMovePrev" RenderTransformOrigin="0.5, 0.5">
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M11.5,12L20,18V6M11,18V6L2.5,12L11,18Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_MovePrev" Grid.Column="1" Margin="2" HorizontalAlignment="Center" Click="funcBtn_MovePrev" RenderTransformOrigin="0.5, 0.5">
|
||||
<Viewbox Width="16" Height="16" RenderTransformOrigin="0.5,0.5">
|
||||
<Viewbox.RenderTransform>
|
||||
<RotateTransform Angle="-90"/>
|
||||
</Viewbox.RenderTransform>
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M7,15L12,10L17,15H7Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_MoveNext" Grid.Column="2" Margin="2" HorizontalAlignment="Center" Click="funcBtn_MoveNext" RenderTransformOrigin="0.5, 0.5">
|
||||
<Viewbox Width="16" Height="16" RenderTransformOrigin="0.5,0.5">
|
||||
<Viewbox.RenderTransform>
|
||||
<RotateTransform Angle="-90"/>
|
||||
</Viewbox.RenderTransform>
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M7,10L12,15L17,10H7Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_FastMoveNext" Grid.Column="3" Margin="2" HorizontalAlignment="Center" Click="funcBtn_FastMoveNext" RenderTransformOrigin="0.5, 0.5">
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="Black" Data="M13,6V18L21.5,12M4,18L12.5,12L4,6V18Z" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Button>
|
||||
<Slider x:Name="uiTASSlider" Margin="2" Grid.Column="4" SmallChange="1" LargeChange="10" Maximum="1" VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.5">
|
||||
</Slider>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
<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 x:Name="uiStatusbar_Selected" Text="-"/>
|
||||
<StatusBarItem x:Name="uiStatusbar_Runtime_Mode">
|
||||
<Grid>
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Cursor" Text="{DynamicResource ui_MainWindow_StatusBar_Mode_Cursor}"/>
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Fill" Text="{DynamicResource ui_MainWindow_StatusBar_Mode_Fill}"/>
|
||||
<TextBlock x:Name="uiStatusbar_Mode_Overwrite" Text="{DynamicResource ui_MainWindow_StatusBar_Mode_Overwritten}"/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
<Separator x:Name="uiStatusbar_Runtime_Separator1"/>
|
||||
<StatusBarItem x:Name="uiStatusbar_Runtime_PasteMode">
|
||||
<TextBlock x:Name="uiStatusbar_OverwrittenPaste" Text="{DynamicResource ui_MainWindow_StatusBar_OverwrittenPaste}"/>
|
||||
</StatusBarItem>
|
||||
<Separator x:Name="uiStatusbar_Runtime_Separator2"/>
|
||||
<StatusBarItem x:Name="uiStatusbar_Runtime_Selected">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{DynamicResource ui_MainWindow_StatusBar_Selected}"/>
|
||||
<TextBlock x:Name="uiStatusbar_Selected" Text="-"/>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
|
||||
<StatusBarItem DockPanel.Dock="Right" HorizontalAlignment="Right">
|
||||
<TextBlock Text="v1.2 stable" Foreground="Gray" FontStyle="Italic"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
</Grid>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using BallanceTASEditor.Core;
|
||||
using BallanceTASEditor.Core;
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using BallanceTASEditor.UI;
|
||||
using System;
|
||||
@ -22,31 +22,83 @@ namespace BallanceTASEditor {
|
||||
public partial class MainWindow : Window {
|
||||
public MainWindow() {
|
||||
InitializeComponent();
|
||||
mIsHorizontalLayout = true;
|
||||
|
||||
// init layout controller
|
||||
var headers = new List<TextBlock>();
|
||||
headers.Add(uiFlowHeader_Frame);
|
||||
headers.Add(uiFlowHeader_DeltaTime);
|
||||
headers.Add(uiFlowHeader_Up);
|
||||
headers.Add(uiFlowHeader_Down);
|
||||
headers.Add(uiFlowHeader_Left);
|
||||
headers.Add(uiFlowHeader_Right);
|
||||
headers.Add(uiFlowHeader_Shift);
|
||||
headers.Add(uiFlowHeader_Space);
|
||||
headers.Add(uiFlowHeader_Q);
|
||||
headers.Add(uiFlowHeader_Esc);
|
||||
headers.Add(uiFlowHeader_Enter);
|
||||
mFlow = new TASFlow(uiTASData, headers.ToArray());
|
||||
|
||||
var components = new TASSliderComponents();
|
||||
components.container = uiTASSliderContainer;
|
||||
components.btnFastPrev = uiBtn_FastMovePrev;
|
||||
components.btnPrev = uiBtn_MovePrev;
|
||||
components.btnNext = uiBtn_MoveNext;
|
||||
components.btnFastNext = uiBtn_FastMoveNext;
|
||||
components.mSlider = uiTASSlider;
|
||||
mSlider = new TASSlider(components); ;
|
||||
|
||||
// refresh ui and load cfg
|
||||
RefreshUI(false);
|
||||
ApplyConfigureManager();
|
||||
}
|
||||
|
||||
TASFile mFile;
|
||||
TASViewer mViewer;
|
||||
TASFlow mFlow;
|
||||
TASSlider mSlider;
|
||||
bool mIsHorizontalLayout;
|
||||
|
||||
#region ui func
|
||||
|
||||
// shortcut
|
||||
|
||||
private void funcCommand_Menu_File_Open(object sender, ExecutedRoutedEventArgs e) => funcMenu_File_Open(sender, e);
|
||||
private void funcCommand_Menu_File_Save(object sender, ExecutedRoutedEventArgs e) => funcMenu_File_Save(sender, e);
|
||||
private void funcCommand_Menu_Display_Undo(object sender, ExecutedRoutedEventArgs e) => funcMenu_Display_Undo(sender, e);
|
||||
private void funcCommand_Menu_Display_Redo(object sender, ExecutedRoutedEventArgs e) => funcMenu_Display_Redo(sender, e);
|
||||
private void funcCommand_DataMenu_Cut(object sender, ExecutedRoutedEventArgs e) => funcDataMenu_Cut(sender, e);
|
||||
private void funcCommand_DataMenu_Copy(object sender, ExecutedRoutedEventArgs e) => funcDataMenu_Copy(sender, e);
|
||||
private void funcCommand_DataMenu_PasteAfter(object sender, ExecutedRoutedEventArgs e) => funcDataMenu_PasteAfter(sender, e);
|
||||
private void funcCommand_DataMenu_DeleteAfter(object sender, ExecutedRoutedEventArgs e) => funcDataMenu_DeleteAfter(sender, e);
|
||||
private void funcCommand_DataMenu_DeleteBefore(object sender, ExecutedRoutedEventArgs e) => funcDataMenu_DeleteBefore(sender, e);
|
||||
private void funcCanExeCmd_Menu_File_Open(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = uiMenu_File_Open.IsEnabled;
|
||||
private void funcCanExeCmd_Menu_File_Save(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = uiMenu_File_Save.IsEnabled;
|
||||
private void funcCanExeCmd_Menu_Display_Undo(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = uiMenu_Display_Undo.IsEnabled;
|
||||
private void funcCanExeCmd_Menu_Display_Redo(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = uiMenu_Display_Redo.IsEnabled;
|
||||
private void funcCanExeCmd_DataMenu_Cut(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = mViewer != null && uiDataMenu_Cut.IsEnabled;
|
||||
private void funcCanExeCmd_DataMenu_Copy(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = mViewer != null && uiDataMenu_Copy.IsEnabled;
|
||||
private void funcCanExeCmd_DataMenu_PasteAfter(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = mViewer != null && uiDataMenu_PasteAfter.IsEnabled;
|
||||
private void funcCanExeCmd_DataMenu_DeleteAfter(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = mViewer != null && uiDataMenu_DeleteAfter.IsEnabled;
|
||||
private void funcCanExeCmd_DataMenu_DeleteBefore(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = mViewer != null && uiDataMenu_DeleteBefore.IsEnabled;
|
||||
|
||||
// =========================== menu
|
||||
#region window menu
|
||||
|
||||
private void funcMenu_Help_ReportBugs(object sender, RoutedEventArgs e) {
|
||||
System.Diagnostics.Process.Start("https://github.com/yyc12345/BallanceTASEditor/issues");
|
||||
}
|
||||
|
||||
private void funcMenu_Help_About(object sender, RoutedEventArgs e) {
|
||||
MessageBox.Show("Under MIT License\nVersion: 1.0 alpha\nyyc12345.", "Ballance TAS Editor");
|
||||
MessageBox.Show(I18NProcessor.GetI18N("code_MainWindow_Menu_Help_About"),
|
||||
I18NProcessor.GetI18N("code_Shared_ProgramName"),
|
||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
private void funcMenu_File_Open(object sender, RoutedEventArgs e) {
|
||||
var file = DialogUtil.OpenFileDialog();
|
||||
if (file == "") return;
|
||||
mFile = new TASFile(file);
|
||||
mViewer = new TASViewer(mFile, uiTASSlider, uiTASData, uiStatusbar_Selected);
|
||||
RefreshUI(true);
|
||||
ChangeToolMode(ToolMode.Cursor);
|
||||
mViewer.ChangeOverwrittenMode(uiMenu_Display_OverwrittenPaste.IsChecked);
|
||||
OpenFile(file);
|
||||
}
|
||||
|
||||
private void funcMenu_File_Save(object sender, RoutedEventArgs e) {
|
||||
@ -60,26 +112,48 @@ namespace BallanceTASEditor {
|
||||
}
|
||||
|
||||
private void funcMenu_File_Close(object sender, RoutedEventArgs e) {
|
||||
if (!DialogUtil.ConfirmDialog("Do you want to close this TAS file?")) return;
|
||||
if (!DialogUtil.ConfirmDialog(I18NProcessor.GetI18N("code_MainWindow_Menu_File_Close"))) return;
|
||||
|
||||
mViewer.UpdateDataUI -= RefreshDataUI;
|
||||
mViewer.UpdateSelection -= RefreshSelection;
|
||||
mViewer.UpdateToolMode -= RefreshToolMode;
|
||||
|
||||
mViewer.Dispose();
|
||||
mFile = null;
|
||||
mViewer = null;
|
||||
RefreshUI(false);
|
||||
}
|
||||
|
||||
private void funcWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
if (!(mFile is null)) {
|
||||
if (!DialogUtil.ConfirmDialog(I18NProcessor.GetI18N("code_MainWindow_Closing"))) {
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (DialogUtil.InputNumber(I18NProcessor.GetI18N("code_MainWindow_Menu_Display_ItemCount"), 5, 30, ref newvalue)) {
|
||||
ChangeItemCount(newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
private void funcMenu_Display_OverwrittenPaste(object sender, RoutedEventArgs e) {
|
||||
//uiMenu_Display_OverwrittenPaste.IsChecked = !uiMenu_Display_OverwrittenPaste.IsChecked;
|
||||
uiMenu_Display_OverwrittenPaste.IsChecked = !uiMenu_Display_OverwrittenPaste.IsChecked;
|
||||
uiStatusbar_OverwrittenPaste.Visibility = uiMenu_Display_OverwrittenPaste.IsChecked ? Visibility.Visible : Visibility.Hidden;
|
||||
|
||||
GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_IsOverwrittenPaste] = uiMenu_Display_OverwrittenPaste.IsChecked.ToString();
|
||||
if (mViewer != null)
|
||||
mViewer.ChangeOverwrittenMode(uiMenu_Display_OverwrittenPaste.IsChecked);
|
||||
}
|
||||
|
||||
private void funcMenu_Display_HorizontalLayout(object sender, RoutedEventArgs e) {
|
||||
uiMenu_Display_HorizontalLayout.IsChecked = !uiMenu_Display_HorizontalLayout.IsChecked;
|
||||
GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_IsHorizonLayout] = uiMenu_Display_HorizontalLayout.IsChecked.ToString();
|
||||
ChangeLayout(uiMenu_Display_HorizontalLayout.IsChecked);
|
||||
}
|
||||
|
||||
private void funcMenu_Display_Redo(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Redo);
|
||||
}
|
||||
@ -88,35 +162,85 @@ namespace BallanceTASEditor {
|
||||
mViewer.ProcessOperation(OperationEnum.Undo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region datamenu operation
|
||||
|
||||
private void funcDataMenu_Set(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Set);
|
||||
}
|
||||
|
||||
private void funcDataMenu_Unset(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Unset);
|
||||
}
|
||||
|
||||
private void funcDataMenu_Cut(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Cut);
|
||||
}
|
||||
|
||||
private void funcDataMenu_Copy(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Copy);
|
||||
}
|
||||
|
||||
private void funcDataMenu_PasteAfter(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.PasteAfter);
|
||||
}
|
||||
|
||||
private void funcDataMenu_PasteBefore(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.PasteBefore);
|
||||
}
|
||||
|
||||
private void funcDataMenu_Delete(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.Delete);
|
||||
}
|
||||
|
||||
private void funcDataMenu_DeleteAfter(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.DeleteAfter);
|
||||
}
|
||||
|
||||
private void funcDataMenu_DeleteBefore(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.DeleteBefore);
|
||||
}
|
||||
|
||||
private void funcDataMenu_AddAfter(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.AddAfter);
|
||||
}
|
||||
|
||||
private void funcDataMenu_AddBefore(object sender, RoutedEventArgs e) {
|
||||
mViewer.ProcessOperation(OperationEnum.AddBefore);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// =========================== btn
|
||||
private void funcBtn_Cursor(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Cursor);
|
||||
mViewer.ChangeToolMode(ToolMode.Cursor);
|
||||
}
|
||||
|
||||
private void funcBtn_Fill(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Fill);
|
||||
mViewer.ChangeToolMode(ToolMode.Fill);
|
||||
}
|
||||
|
||||
private void funcBtn_Overwrite(object sender, RoutedEventArgs e) {
|
||||
ChangeToolMode(ToolMode.Overwrite);
|
||||
mViewer.ChangeToolMode(ToolMode.Overwrite);
|
||||
}
|
||||
|
||||
// move btn
|
||||
|
||||
private void funcBtn_FastMovePrev(object sender, RoutedEventArgs e) {
|
||||
MoveSliderManually(true, true);
|
||||
mSlider.MoveSliderManually(true, true, mViewer.GetItemCountInPage());
|
||||
}
|
||||
|
||||
private void funcBtn_MovePrev(object sender, RoutedEventArgs e) {
|
||||
MoveSliderManually(true, false);
|
||||
mSlider.MoveSliderManually(true, false, mViewer.GetItemCountInPage());
|
||||
}
|
||||
|
||||
private void funcBtn_MoveNext(object sender, RoutedEventArgs e) {
|
||||
MoveSliderManually(false, false);
|
||||
mSlider.MoveSliderManually(false, false, mViewer.GetItemCountInPage());
|
||||
}
|
||||
|
||||
private void funcBtn_FastMoveNext(object sender, RoutedEventArgs e) {
|
||||
MoveSliderManually(false, true);
|
||||
mSlider.MoveSliderManually(false, true, mViewer.GetItemCountInPage());
|
||||
}
|
||||
|
||||
// move keyboard
|
||||
@ -124,26 +248,117 @@ namespace BallanceTASEditor {
|
||||
private void funcWindow_KeyUp(object sender, KeyEventArgs e) {
|
||||
if (mFile == null || mViewer == null) return;
|
||||
|
||||
switch(e.Key) {
|
||||
switch (e.Key) {
|
||||
case Key.A:
|
||||
MoveSliderManually(true, true);
|
||||
mSlider.MoveSliderManually(true, true, mViewer.GetItemCountInPage());
|
||||
break;
|
||||
case Key.S:
|
||||
MoveSliderManually(true, false);
|
||||
mSlider.MoveSliderManually(true, false, mViewer.GetItemCountInPage());
|
||||
break;
|
||||
case Key.D:
|
||||
MoveSliderManually(false, false);
|
||||
mSlider.MoveSliderManually(false, false, mViewer.GetItemCountInPage());
|
||||
break;
|
||||
case Key.F:
|
||||
MoveSliderManually(false, true);
|
||||
mSlider.MoveSliderManually(false, true, mViewer.GetItemCountInPage());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// move mouse
|
||||
|
||||
private void funcWindow_MouseWheel(object sender, MouseWheelEventArgs e) {
|
||||
if (e.Delta > 0) {
|
||||
// wheel up
|
||||
if (KeyboardState.IsKeyPressed(KeyboardState.VirtualKeyStates.VK_SHIFT)) {
|
||||
// move quickly
|
||||
mSlider.MoveSliderManually(true, true, mViewer.GetItemCountInPage());
|
||||
} else if (KeyboardState.IsKeyPressed(KeyboardState.VirtualKeyStates.VK_CONTROL)) {
|
||||
// decrease item count
|
||||
var newvalue = mViewer.GetItemCountInPage();
|
||||
ChangeItemCount(newvalue - 1);
|
||||
} else {
|
||||
// normally move
|
||||
mSlider.MoveSliderManually(true, false, mViewer.GetItemCountInPage());
|
||||
}
|
||||
|
||||
} else if (e.Delta < 0) {
|
||||
// wheel down
|
||||
if (KeyboardState.IsKeyPressed(KeyboardState.VirtualKeyStates.VK_SHIFT)) {
|
||||
// move quickly
|
||||
mSlider.MoveSliderManually(false, true, mViewer.GetItemCountInPage());
|
||||
} else if (KeyboardState.IsKeyPressed(KeyboardState.VirtualKeyStates.VK_CONTROL)) {
|
||||
// increase item count
|
||||
var newvalue = mViewer.GetItemCountInPage();
|
||||
ChangeItemCount(newvalue + 1);
|
||||
} else {
|
||||
// normally move
|
||||
mSlider.MoveSliderManually(false, false, mViewer.GetItemCountInPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drop file to open
|
||||
private void funcDrop_Drop(object sender, DragEventArgs e) {
|
||||
string fileName = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
|
||||
OpenFile(fileName);
|
||||
}
|
||||
|
||||
private void funcDrop_DragEnter(object sender, DragEventArgs e) {
|
||||
// only accept one file
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
||||
var arr = (System.Array)e.Data.GetData(DataFormats.FileDrop);
|
||||
if (arr.Length != 1) e.Effects = DragDropEffects.None;
|
||||
else e.Effects = DragDropEffects.Link;
|
||||
} else e.Effects = DragDropEffects.None;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ApplyConfigureManager() {
|
||||
var isOverwrittenPaste = bool.Parse(GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_IsOverwrittenPaste]);
|
||||
var isHorizontalLayout = bool.Parse(GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_IsHorizonLayout]);
|
||||
var itemCount = int.Parse(GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_ItemCount]);
|
||||
|
||||
private void ChangeToolMode(ToolMode mode) {
|
||||
uiMenu_Display_OverwrittenPaste.IsChecked = isOverwrittenPaste;
|
||||
uiMenu_Display_HorizontalLayout.IsChecked = isHorizontalLayout;
|
||||
uiStatusbar_OverwrittenPaste.Visibility = isOverwrittenPaste ? Visibility.Visible : Visibility.Hidden;
|
||||
if (mViewer != null) {
|
||||
mViewer.ChangeOverwrittenMode(isOverwrittenPaste);
|
||||
mViewer.ChangeListLength(itemCount);
|
||||
ChangeLayout(isHorizontalLayout);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenFile(string file) {
|
||||
#if DEBUG
|
||||
#else
|
||||
try {
|
||||
#endif
|
||||
mFile = new TASFile(file);
|
||||
|
||||
#if DEBUG
|
||||
#else
|
||||
} catch {
|
||||
MessageBox.Show(I18NProcessor.GetI18N("code_MainWindow_Menu_File_Open_Fail"),
|
||||
I18NProcessor.GetI18N("code_Shared_ProgramName"),
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
mFile = null;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
mViewer = new TASViewer(mFile, mSlider, mFlow);
|
||||
|
||||
mViewer.UpdateDataUI += RefreshDataUI;
|
||||
mViewer.UpdateSelection += RefreshSelection;
|
||||
mViewer.UpdateToolMode += RefreshToolMode;
|
||||
|
||||
RefreshUI(true);
|
||||
ApplyConfigureManager(); // apply item count and overwritten item
|
||||
mViewer.ChangeToolMode(ToolMode.Cursor);
|
||||
}
|
||||
|
||||
private void RefreshToolMode(ToolMode mode) {
|
||||
switch (mode) {
|
||||
case ToolMode.Cursor:
|
||||
uiBtn_Cursor.IsEnabled = false;
|
||||
@ -173,8 +388,6 @@ namespace BallanceTASEditor {
|
||||
uiStatusbar_Mode_Overwrite.Visibility = Visibility.Visible;
|
||||
break;
|
||||
}
|
||||
|
||||
mViewer.ChangeToolMode(mode);
|
||||
}
|
||||
|
||||
private void RefreshUI(bool isFileOpened) {
|
||||
@ -189,10 +402,15 @@ namespace BallanceTASEditor {
|
||||
|
||||
uiMenu_Display_ItemCount.IsEnabled = true;
|
||||
uiMenu_Display_OverwrittenPaste.IsEnabled = true;
|
||||
uiMenu_Display_HorizontalLayout.IsEnabled = true;
|
||||
uiMenu_Display_Undo.IsEnabled = true;
|
||||
uiMenu_Display_Redo.IsEnabled = true;
|
||||
|
||||
uiStatusbar.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Runtime_Mode.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Runtime_PasteMode.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Runtime_Selected.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Runtime_Separator1.Visibility = Visibility.Visible;
|
||||
uiStatusbar_Runtime_Separator2.Visibility = Visibility.Visible;
|
||||
} else {
|
||||
uiEditorPanel.Visibility = Visibility.Collapsed;
|
||||
uiEditorNote.Visibility = Visibility.Visible;
|
||||
@ -204,16 +422,89 @@ namespace BallanceTASEditor {
|
||||
|
||||
uiMenu_Display_ItemCount.IsEnabled = false;
|
||||
uiMenu_Display_OverwrittenPaste.IsEnabled = false;
|
||||
uiMenu_Display_HorizontalLayout.IsEnabled = false;
|
||||
uiMenu_Display_Undo.IsEnabled = false;
|
||||
uiMenu_Display_Redo.IsEnabled = false;
|
||||
|
||||
uiStatusbar.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Runtime_Mode.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Runtime_PasteMode.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Runtime_Selected.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Runtime_Separator1.Visibility = Visibility.Collapsed;
|
||||
uiStatusbar_Runtime_Separator2.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveSliderManually(bool isPrev, bool isFast) {
|
||||
var step = isFast ? mViewer.GetItemCountInPage() : 1;
|
||||
uiTASSlider.Value = Util.Clamp(uiTASSlider.Value.ToInt32() + (isPrev ? -1 : 1) * step, uiTASSlider.Minimum.ToInt32(), uiTASSlider.Maximum.ToInt32());
|
||||
private void RefreshDataUI(bool showCursorPasteAddDeleteOne, bool showFill, bool showCursorCopyDelete) {
|
||||
uiDataMenu_Set.IsEnabled = showFill;
|
||||
uiDataMenu_Unset.IsEnabled = showFill;
|
||||
uiDataMenu_Cut.IsEnabled = showCursorCopyDelete;
|
||||
uiDataMenu_Copy.IsEnabled = showCursorCopyDelete;
|
||||
uiDataMenu_Delete.IsEnabled = showCursorCopyDelete;
|
||||
uiDataMenu_DeleteAfter.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
uiDataMenu_DeleteBefore.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
uiDataMenu_PasteAfter.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
uiDataMenu_PasteBefore.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
uiDataMenu_AddAfter.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
uiDataMenu_AddBefore.IsEnabled = showCursorPasteAddDeleteOne;
|
||||
}
|
||||
|
||||
private void RefreshSelection(SelectionHelp mSelectionHelp) {
|
||||
var mode = mSelectionHelp.GetToolMode();
|
||||
|
||||
switch (mode) {
|
||||
case ToolMode.Cursor:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data = mSelectionHelp.GetRange();
|
||||
uiStatusbar_Selected.Text = $"{data.start} - {data.end}";
|
||||
} else if (mSelectionHelp.IsDataPartialReady()) {
|
||||
var data2 = mSelectionHelp.GetPoint();
|
||||
uiStatusbar_Selected.Text = data2.ToString();
|
||||
} else uiStatusbar_Selected.Text = "-";
|
||||
break;
|
||||
case ToolMode.Fill:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data3 = mSelectionHelp.GetRange();
|
||||
uiStatusbar_Selected.Text = $"{data3.start} - {data3.end}";
|
||||
} else uiStatusbar_Selected.Text = "-";
|
||||
break;
|
||||
case ToolMode.Overwrite:
|
||||
if (mSelectionHelp.IsDataReady()) {
|
||||
var data4 = mSelectionHelp.GetPoint();
|
||||
uiStatusbar_Selected.Text = data4.ToString();
|
||||
} else uiStatusbar_Selected.Text = "-";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeItemCount(int count) {
|
||||
GlobalVariable.configManager.Configuration[ConfigManager.CfgNode_ItemCount] = count.ToString();
|
||||
mViewer.ChangeListLength(count);
|
||||
}
|
||||
|
||||
private void ChangeLayout(bool isHorizontal) {
|
||||
if (isHorizontal == mIsHorizontalLayout) return;
|
||||
mIsHorizontalLayout = isHorizontal;
|
||||
|
||||
// swap window size
|
||||
var swap = this.Width;
|
||||
this.Width = this.Height;
|
||||
this.Height = swap;
|
||||
// change self layout first
|
||||
uiLayoutContainer.RowDefinitions.Clear();
|
||||
uiLayoutContainer.ColumnDefinitions.Clear();
|
||||
if (isHorizontal) {
|
||||
UI.Util.GridRowAdder(uiLayoutContainer, new GridLength(1, GridUnitType.Star));
|
||||
UI.Util.GridRowAdder(uiLayoutContainer, GridLength.Auto);
|
||||
} else {
|
||||
UI.Util.GridColumnAdder(uiLayoutContainer, new GridLength(1, GridUnitType.Star));
|
||||
UI.Util.GridColumnAdder(uiLayoutContainer, GridLength.Auto);
|
||||
}
|
||||
UI.Util.SwapGridItemRC(uiTASFlowContainer);
|
||||
UI.Util.SwapGridItemRC(uiTASSliderContainer);
|
||||
|
||||
// change sub layout
|
||||
mFlow.ChangeLayout(isHorizontal);
|
||||
mSlider.ChangeLayout(isHorizontal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,12 +7,12 @@ using System.Windows;
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("BallanceTASEditor")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyTitle("Ballance TAS Editor")]
|
||||
[assembly: AssemblyDescription("Ballance TAS Editor")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("BallanceTASEditor")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyCompany("Ballance Community")]
|
||||
[assembly: AssemblyProduct("Ballance TAS Editor")]
|
||||
[assembly: AssemblyCopyright("Copyright © Ballance Community 2022")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@ -51,5 +51,5 @@ using System.Windows;
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("1.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
xmlns:local="clr-namespace:BallanceTASEditor.UI"
|
||||
xmlns:converter="clr-namespace:BallanceTASEditor.UI"
|
||||
mc:Ignorable="d"
|
||||
Title="Add Item" Height="200" Width="400" WindowStyle="ToolWindow" WindowStartupLocation="CenterOwner">
|
||||
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"/>
|
||||
@ -25,9 +25,9 @@
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="0" Text="Count" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="1" Text="FPS" VerticalAlignment="Center"/>
|
||||
<TextBlock Margin="5" Grid.Column="0" Grid.Row="2" Text="Delta Time" VerticalAlignment="Center"/>
|
||||
<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"/>
|
||||
@ -35,7 +35,7 @@
|
||||
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="OK" MinWidth="50" Click="funcBtn_OK">
|
||||
<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"/>
|
||||
@ -43,7 +43,7 @@
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
<Button x:Name="uiBtn_Cancel" Margin="5" Padding="5" Content="Cancel" MinWidth="50" Click="funcBtn_Cancel"/>
|
||||
<Button x:Name="uiBtn_Cancel" Margin="5" Padding="5" Content="{DynamicResource ui_AddItem_Cancel}" MinWidth="50" Click="funcBtn_Cancel"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using BallanceTASEditor.Core;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class DialogUtil {
|
||||
@ -12,7 +13,7 @@ namespace BallanceTASEditor.UI {
|
||||
Microsoft.Win32.OpenFileDialog op = new Microsoft.Win32.OpenFileDialog();
|
||||
op.RestoreDirectory = true;
|
||||
op.Multiselect = false;
|
||||
op.Filter = "TAS file(*.tas)|*.tas|All file(*.*)|*.*";
|
||||
op.Filter = I18NProcessor.GetI18N("code_DialogUtil_FileFilter");
|
||||
if (!(bool)op.ShowDialog()) return "";
|
||||
return op.FileName;
|
||||
}
|
||||
@ -20,24 +21,26 @@ namespace BallanceTASEditor.UI {
|
||||
public static string SaveFileDialog() {
|
||||
Microsoft.Win32.SaveFileDialog op = new Microsoft.Win32.SaveFileDialog();
|
||||
op.RestoreDirectory = true;
|
||||
op.Filter = "TAS file(*.tas)|*.tas|All file(*.*)|*.*";
|
||||
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, "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
|
||||
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, "Input number", "");
|
||||
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("Invalid number. Please input again", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
MessageBox.Show(I18NProcessor.GetI18N("code_DialogUtil_InputNumber_Wrong"),
|
||||
I18NProcessor.GetI18N("code_DialogUtil_Warning"),
|
||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ namespace BallanceTASEditor.UI {
|
||||
public enum OperationEnum {
|
||||
Set,
|
||||
Unset,
|
||||
Cut,
|
||||
Copy,
|
||||
PasteAfter,
|
||||
PasteBefore,
|
||||
|
||||
@ -15,27 +15,98 @@ using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
/// <summary>
|
||||
/// TASFlow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class TASFlow : UserControl {
|
||||
public TASFlow() {
|
||||
InitializeComponent();
|
||||
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;
|
||||
public event Action<OperationEnum> NewOperation;
|
||||
|
||||
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;
|
||||
|
||||
@ -51,24 +122,30 @@ namespace BallanceTASEditor.UI {
|
||||
|
||||
// change column defination first
|
||||
if (offset > 0) {
|
||||
for(int i = 0; i < abs; i++) {
|
||||
var item = new ColumnDefinition();
|
||||
item.Width = GridLength.Auto;
|
||||
uiCoreWindow.ColumnDefinitions.Add(item);
|
||||
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 {
|
||||
uiCoreWindow.ColumnDefinitions.RemoveRange(newCount + 1, abs); // the first col is sheet header, so add 1 additionally
|
||||
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); // the first col is sheet header, so add 1 additionally
|
||||
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++) {
|
||||
for (int i = 0; i < abs; i++) {
|
||||
mItemList[newCount + i].Remove(uiCoreWindow, mRectMap, Rectangle_MouseDown);
|
||||
}
|
||||
mItemList.RemoveRange(newCount, abs);
|
||||
@ -78,26 +155,6 @@ namespace BallanceTASEditor.UI {
|
||||
mItemCount = newCount;
|
||||
}
|
||||
|
||||
public void RefreshDataMenu() {
|
||||
if (SelectionHelp == null) return;
|
||||
|
||||
ToolMode mode = SelectionHelp.GetToolMode();
|
||||
bool showCursorPasteAddDeleteOne = 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_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() {
|
||||
ToolMode mode = SelectionHelp.GetToolMode();
|
||||
|
||||
@ -158,6 +215,14 @@ namespace BallanceTASEditor.UI {
|
||||
} 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.
|
||||
@ -170,50 +235,6 @@ 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 {
|
||||
@ -226,21 +247,30 @@ namespace BallanceTASEditor.UI {
|
||||
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 int KEY_COUNT = 9;
|
||||
private const double SELECTION_HEADER_HEIGHT = 10.0f;
|
||||
private const int KEY_COUNT = 9;
|
||||
|
||||
public TASFlowUIItem(int column) {
|
||||
public TASFlowUIItem(int column, bool useHorizontalLayout) {
|
||||
// basic item
|
||||
sel_rect = new Rectangle();
|
||||
frame = new TextBlock();
|
||||
deltaTime = new TextBlock();
|
||||
|
||||
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);
|
||||
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;
|
||||
@ -248,7 +278,10 @@ namespace BallanceTASEditor.UI {
|
||||
|
||||
sel_rect.StrokeThickness = 2;
|
||||
sel_rect.Stroke = SEL_RECT_STROKE;
|
||||
sel_rect.Height = SELECTION_HEADER_HEIGHT;
|
||||
if (useHorizontalLayout)
|
||||
sel_rect.Height = SELECTION_HEADER_HEIGHT;
|
||||
else
|
||||
sel_rect.Width = SELECTION_HEADER_HEIGHT;
|
||||
|
||||
// keystates item
|
||||
keystates = new Rectangle[KEY_COUNT];
|
||||
@ -258,8 +291,13 @@ namespace BallanceTASEditor.UI {
|
||||
keystates[i] = new Rectangle();
|
||||
keystatesFill[i] = new SolidColorBrush(COLOR_UNSET);
|
||||
keystatesStroke[i] = new SolidColorBrush(COLOR_UNSELECTED);
|
||||
Grid.SetRow(keystates[i], 3 + i);
|
||||
Grid.SetColumn(keystates[i], column);
|
||||
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];
|
||||
@ -271,6 +309,20 @@ namespace BallanceTASEditor.UI {
|
||||
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);
|
||||
@ -1,59 +0,0 @@
|
||||
<UserControl x:Class="BallanceTASEditor.UI.TASFlow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:BallanceTASEditor.UI"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="400" d:DesignWidth="800">
|
||||
<Grid x:Name="uiCoreWindow" Background="#ffffff">
|
||||
<Grid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="uiDataMenu_Set" Header="Set" Click="uiDataMenu_Set_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_Unset" Header="Unset" Click="uiDataMenu_Unset_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_Copy" Header="Copy" Click="uiDataMenu_Copy_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_PasteAfter" Header="Paste after this" Click="uiDataMenu_PasteAfter_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_PasteBefore" Header="Paste before this" Click="uiDataMenu_PasteBefore_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_Delete" Header="Delete" Click="uiDataMenu_Delete_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_DeleteAfter" Header="Delete next frame" Click="uiDataMenu_DeleteAfter_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_DeleteBefore" Header="Delete last frame" Click="uiDataMenu_DeleteBefore_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="uiDataMenu_AddAfter" Header="Add blank item after this" Click="uiDataMenu_AddAfter_Click"/>
|
||||
<MenuItem x:Name="uiDataMenu_AddBefore" Header="Add blank item before this" Click="uiDataMenu_AddBefore_Click"/>
|
||||
</ContextMenu>
|
||||
</Grid.ContextMenu>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<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="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>
|
||||
117
BallanceTASEditor/UI/TASSlider.cs
Normal file
117
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;
|
||||
}
|
||||
}
|
||||
@ -10,15 +10,13 @@ using System.Windows;
|
||||
|
||||
namespace BallanceTASEditor.UI {
|
||||
public class TASViewer : IDisposable {
|
||||
public TASViewer(TASFile file, Slider slider, TASFlow datagrid, TextBlock statusbar) {
|
||||
public TASViewer(TASFile file, TASSlider slider, TASFlow datagrid) {
|
||||
mFile = file;
|
||||
mSlider = slider;
|
||||
mDataGrid = datagrid;
|
||||
mStatusbar = statusbar;
|
||||
|
||||
// restore slider
|
||||
mSlider.Minimum = 0;
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
|
||||
// init selection
|
||||
mSelectionHelp = new SelectionHelp();
|
||||
@ -35,86 +33,78 @@ namespace BallanceTASEditor.UI {
|
||||
mDataGrid.SelectionHelp = mSelectionHelp;
|
||||
|
||||
mDataGrid.Click += funcDataMenu_Click;
|
||||
mDataGrid.NewOperation += funcDataMenu_NewOperation;
|
||||
|
||||
mSlider.ValueChanged += sliderValueChanged;
|
||||
|
||||
// display data
|
||||
ChangeListLength(DATA_LIST_LENGTH);
|
||||
mSlider.ValueChanged += funcSlider_ValueChanged;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
mDataGrid.DataSources = null;
|
||||
|
||||
mDataGrid.Click -= funcDataMenu_Click;
|
||||
mDataGrid.NewOperation -= funcDataMenu_NewOperation;
|
||||
|
||||
mSlider.ValueChanged -= sliderValueChanged;
|
||||
mSlider.ValueChanged -= funcSlider_ValueChanged;
|
||||
}
|
||||
|
||||
const int DATA_LIST_LENGTH = 15;
|
||||
//const int DATA_LIST_LENGTH = 15;
|
||||
FrameData INVALID_FRAME_DATA;
|
||||
TASFile mFile;
|
||||
Slider mSlider;
|
||||
TextBlock mStatusbar;
|
||||
TASSlider mSlider;
|
||||
TASFlow mDataGrid;
|
||||
SelectionHelp mSelectionHelp;
|
||||
int mListLength;
|
||||
List<FrameDataDisplay> mDataSource;
|
||||
bool mOverwrittenPaste;
|
||||
|
||||
private void sliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
|
||||
long pos = e.NewValue.ToInt64();
|
||||
mFile.Shift(pos);
|
||||
#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 updateSliderRange() {
|
||||
mSlider.Maximum = mFile.mFrameCount - 1;
|
||||
mSlider.Value = mFile.GetPointerIndex();
|
||||
}
|
||||
|
||||
private void funcSelectionHelp_SelectionChanged() {
|
||||
mDataGrid.RefreshDataMenu();
|
||||
mDataGrid.RefreshSelectionHighlight();
|
||||
OnStatusbarSelectionChanged();
|
||||
OnUpdateDataUI();
|
||||
OnUpdateSelection();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 > 30) return;
|
||||
if (newLen < 5 || newLen > 200) return;
|
||||
int offset = newLen - mListLength;
|
||||
int abs = Math.Abs(offset);
|
||||
if (offset == 0) return;
|
||||
@ -147,6 +137,7 @@ namespace BallanceTASEditor.UI {
|
||||
|
||||
public void ChangeToolMode(ToolMode mode) {
|
||||
mSelectionHelp.SetMode(mode);
|
||||
OnUpdateToolMode();
|
||||
}
|
||||
|
||||
public int GetItemCountInPage() {
|
||||
@ -161,6 +152,25 @@ namespace BallanceTASEditor.UI {
|
||||
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);
|
||||
@ -174,7 +184,7 @@ namespace BallanceTASEditor.UI {
|
||||
if (ClipboardUtil.GetFrameData(data)) {
|
||||
mFile.Insert(mSelectionHelp.GetPoint(), data, oper == OperationEnum.PasteBefore, mOverwrittenPaste);
|
||||
mSelectionHelp.Reset();
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
} else MessageBox.Show("Fail to paste due to unknow reason or blank clipboard!");
|
||||
}
|
||||
@ -182,7 +192,7 @@ namespace BallanceTASEditor.UI {
|
||||
case OperationEnum.Delete: {
|
||||
mFile.Remove(mSelectionHelp.GetRange());
|
||||
mSelectionHelp.Reset();
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
@ -192,12 +202,12 @@ namespace BallanceTASEditor.UI {
|
||||
if (oper == OperationEnum.DeleteBefore) pos -= 1; // delete after mean delete current selected item
|
||||
if (pos < 0 || pos >= mFile.mFrameCount) return;
|
||||
|
||||
// only delete before need shift selection
|
||||
// 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) {
|
||||
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
|
||||
@ -207,7 +217,7 @@ namespace BallanceTASEditor.UI {
|
||||
// do real operation
|
||||
mFile.Remove(new SelectionRange(pos, pos));
|
||||
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
@ -218,40 +228,26 @@ namespace BallanceTASEditor.UI {
|
||||
var pos = mSelectionHelp.GetPoint();
|
||||
mFile.Add(pos, count, deltaTime, oper == OperationEnum.AddBefore);
|
||||
mSelectionHelp.Reset();
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Undo: {
|
||||
mFile.Undo();
|
||||
mSelectionHelp.Reset();
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
case OperationEnum.Redo: {
|
||||
mFile.Redo();
|
||||
mSelectionHelp.Reset();
|
||||
updateSliderRange();
|
||||
mSlider.UpdateRange(mFile);
|
||||
RefreshDisplay();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region data menu
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private void funcDataMenu_NewOperation(OperationEnum obj) {
|
||||
ProcessOperation(obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,9 +3,37 @@ 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,
|
||||
|
||||
BIN
BallanceTASEditor/icon.ico
Normal file
BIN
BallanceTASEditor/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 264 KiB |
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="zlib.net" version="1.0.4.0" targetFramework="net40" />
|
||||
<package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
119
README.md
119
README.md
@ -1 +1,120 @@
|
||||
# Ballance TAS Editor
|
||||
|
||||
A editor written for TAS file editing.
|
||||
|
||||
## Deprecation Note
|
||||
|
||||
I have lost all my interests on this game, Ballance, since 1 year ago. However, recently, I noticed that there were some improvements and modifications in Ballance TAS. What I want to clarified is that I have no intention on updating this project to adapt the new format or feature of Ballance TAS. So I archive this repository to explicitly indicate this standpoint.
|
||||
|
||||
However, this status is not prepetual. I will reopen this repository until I have learned enough text editor skills, such as Gap Buffer, to improve this application, or, restored the interests on this game (barely but still possible). You can freely fork this repository, or create new Ballance TAS editor on your own. That's your right granted by open source license.
|
||||
|
||||
## Basic Interface
|
||||
|
||||
### Program Menu
|
||||
|
||||
* File
|
||||
* Open: Open a TAS file.
|
||||
* Save: Save modifications to opended TAS file.
|
||||
* Save as...: Save the modifications as a new TAS file and switch to the new file.
|
||||
* Close: Close current file.
|
||||
* Edit
|
||||
* Undo: Undo a operation.
|
||||
* Redo: Redo previous undo operation.
|
||||
* Item Count: Set the count of items showed in editor panel.
|
||||
* Overwritten Paste: Switch paste mode between Overwritten Mode and Insert Mode.
|
||||
* Horizontal Layout: Switch editor layout between horzontal layout and vertical layout.
|
||||
* Help
|
||||
* Report Bugs: Open a web page to report bugs about this program.
|
||||
* About: Open a dialog to show some infomations about this prrogram.
|
||||
|
||||
### TAS Unit Menu
|
||||
|
||||
Right click TAS unit will open a menu. The enable statue of each is decided by your current tools and selected items.
|
||||
|
||||
|Operation|Needed mode|Needed selection|What the operation do|
|
||||
|:---|:---|:---|:---|
|
||||
|Set|Fill mode|Multiple selection|Set selected units as *set* status|
|
||||
|Unset|Fill mode|Multiple selection|Set selected units as *unset* status|
|
||||
|Cut|Cursor mode|Multiple selection|Cut selected units|
|
||||
|Copy|Cursor mode|Multiple selection|Copy selected units|
|
||||
|Paste after this|Cursor mode|Single selection|Pasted copied units after selected unit|
|
||||
|Paste before this|Cursor mode|Single selection|Pasted copied units before selected unit|
|
||||
|Delete|Cursor mode|Single selection|Delete selected units|
|
||||
|Delete this frame|Cursor mode|Single selection|Delete selected unit, and move selection to the next unit|
|
||||
|Delete last frame|Cursor mode|Single selection|Delete one unit aheading of selected unit|
|
||||
|Add blank item after this|Cursor mode|Single selection|Add blank unit after selected unit|
|
||||
|Add blank item before this|Cursor mode|Single selection|Add blank unit before selected unit|
|
||||
|
||||
### Status Bar
|
||||
|
||||
A status bar will be shown at the bottom of window if you opended a TAS file. The item located in status bar from left to right is: Current tools mode, Overwritten paste status, Current selected region.
|
||||
|
||||
## View
|
||||
|
||||
### Basic Operation
|
||||
|
||||
Once a file opened, a slider will be placed at the bottom of window. You can drag it and go to any position of this file which you want to browse.
|
||||
4 buttons were located at the left of slider, from left to right is: fast rewind, rewind, forward, fast forward. Fase backward and fast forward will rewind or forward the number of units by one page at a time.
|
||||
|
||||
If you want to change the count of shown units in display panel, please use Edit - Item Count to change it.
|
||||
|
||||
### Quick Operation
|
||||
|
||||
The key ASDF of keyboard are corresponding with the functions of 4 buttons.
|
||||
|
||||
A mouse wheel will scroll 1 TAS unit.
|
||||
Or, if you press Shift at the same time, it will scroll 1 page TAS units.
|
||||
Or, if you press Crtl at the same time, it will increase or decrease the count of shown item in display panel.
|
||||
|
||||
### Horzontal Layout and Vertical Layout
|
||||
|
||||
After opening a file, you can use Edit - Horizontal Layout to switch layout between horzontal layout and vertical layout. Different layouts suit for different people. Please choose your favorite layout freely.
|
||||
|
||||
## Mode Introduction
|
||||
|
||||
### Basic Mode
|
||||
|
||||
Once ths file opened, 3 tools buttons were placed at the top of window. They are:
|
||||
|
||||
* Cursor mode: Allow you pick TAS unit by column. In this mode, you can copy, paste, insert, delete and etc...
|
||||
* Fill mode: Allow you select TAS unit by cell. And you can set or unset the status of cells.
|
||||
* Draw mode: See cursor as brush. Flip the set status of clicked cell.
|
||||
|
||||
### Multiple and Single Selection
|
||||
|
||||
Cursor mode allow single selection. Click a TAS unit directly, you can select it.
|
||||
|
||||
Cursor mode and Fill mode allow multiple selection. For a multiple selection, you should click a cell as the start point, then hold on shift to click another cell, as the end of selection.
|
||||
Click a cell again will start a new selection, hold shift click a cell to finish the new multiple selection.
|
||||
If you want to multiple select a single cell(if operation require), you can hold on shift to click the start of selection to finish a single cell's multiple selection.
|
||||
|
||||
### Highlight of Selection
|
||||
|
||||
In cursor mode, selected TAS unit will show a orange rectangle at the top of them.
|
||||
|
||||
In fill mode, selected cell will show with orange border.
|
||||
|
||||
## Special Operation
|
||||
|
||||
### Overwritten Paste and Insert Paste
|
||||
|
||||
Paste have 2 mode, overwritten paste and insert paste.
|
||||
Insert will insert copied content before or after selected unit.
|
||||
However, overwrite pasting will use the currently selected cell as the beginning or end of the paste, and write the contents of the clipboard forward or backward directly. The original data of affected unit will be wipe out. If the length of data is not enough, additional items will be added.
|
||||
|
||||
### Shortcut
|
||||
|
||||
* `Ctrl + O`:Open file
|
||||
* `Ctrl + S`:Save file
|
||||
* `Ctrl + Z`:Undo
|
||||
* `Ctrl + Y`:Redo
|
||||
* `Ctrl + X`:Cut
|
||||
* `Ctrl + C`:Copy
|
||||
* `Ctrl + V`:Paste After
|
||||
* `Delete`:Delete this frame
|
||||
* `Backspace`:Delete last frame
|
||||
|
||||
## Something Went Wrong
|
||||
|
||||
If program crashed, program will output a error log in the folder called `logs`. Please send error log to developer to help us to locate and reproduce error.
|
||||
|
||||
|
||||
105
README_ZH.md
105
README_ZH.md
@ -2,40 +2,83 @@
|
||||
|
||||
一款专门用于编辑Ballance TAS文件的编辑器
|
||||
|
||||
## 基本操作
|
||||
## 弃用说明
|
||||
|
||||
### 菜单
|
||||
一年前,我对 Ballance 这款游戏失去了兴趣。然而,最近,我注意到 Ballance TAS 有一些改进和修改。我想澄清的是,我无意更新这个项目以适应 Ballance TAS 的新格式或功能。所以我存档了这个存储库以明确表明这一立场。
|
||||
|
||||
* File
|
||||
* Open:打开一个TAS文件
|
||||
* Save:保存当前改动到TAS文件
|
||||
* Save As...:将当前改动保存到另一个新地方,保存完毕后文件自动切换成新目标,之后的保存操作将针对新文件来保存
|
||||
* Close:关闭当前文件
|
||||
* Display
|
||||
* Item Count:设置一行显示多少个TAS操作单元:最少5个,最多30个
|
||||
* Help
|
||||
* Report bugs:打开一个网页来汇报这个程序的Bug
|
||||
* About:关于此程序
|
||||
但是,这种状态不是永久的。我将重新打开这个存储库,直到我学会了足够的文本编辑器技能(例如 Gap Buffer)来改进这个应用程序,或者恢复对这个游戏的兴趣(勉强但仍然可能)。您可以自由地分叉这个存储库,或者自己创建新的 Ballance TAS 编辑器。这是开源许可证授予您的权利。
|
||||
|
||||
## 基本界面
|
||||
|
||||
### 程序菜单
|
||||
|
||||
* 文件
|
||||
* 打开:打开一个TAS文件
|
||||
* 保存:保存当前改动到TAS文件
|
||||
* 另存为...:将当前改动保存到另一个新地方,保存完毕后文件自动切换成新目标,之后的保存操作将针对新文件来保存
|
||||
* 关闭:关闭当前文件
|
||||
* 编辑
|
||||
* 撤销:撤销上一步操作
|
||||
* 重做:重做上个撤销的操作
|
||||
* 项个数:设置一个页面显示多少个TAS操作单元。
|
||||
* 覆盖式粘贴:决定粘贴时的操作是插入式还是覆盖式,详情请查看“覆盖式粘贴”章节
|
||||
* 横向布局:决定TAS单元的显示方向,选中为横向布局,不选中则为纵向布局
|
||||
* 帮助
|
||||
* 汇报漏洞:打开一个网页来汇报这个程序的Bug
|
||||
* 关于:关于此程序
|
||||
|
||||
### TAS单元菜单
|
||||
|
||||
在TAS单元页面右键将打开一个操作菜单,其会根据您当前选择的工具,和选中的项目决定可以做的操作:
|
||||
|
||||
|操作|需要的模式|需要的选中|作用|
|
||||
|:---|:---|:---|:---|
|
||||
|设置|填充模式|多选|设置选中单元为设置状态|
|
||||
|不设置|填充模式|多选|设置选中单元为不设置状态|
|
||||
|剪切|选择模式|多选|剪切选中单元|
|
||||
|复制|选择模式|多选|复制选中单元|
|
||||
|粘贴于后方|选择模式|单选|在其后方粘贴剪贴板中已复制的单元|
|
||||
|粘贴于前方|选择模式|单选|在其前方粘贴剪贴板中已复制的单元|
|
||||
|删除|选择模式|单选|删除选中单元|
|
||||
|向后删除|选择模式|单选|删除当前选中单元,将光标移至后一项|
|
||||
|向前删除|选择模式|单选|删除当前选中单元之前的一项|
|
||||
|在后方添加新项|选择模式|单选|在其后方添加空白单元|
|
||||
|在前方添加新项|选择模式|单选|在其前方添加空白单元|
|
||||
|
||||
### 状态栏
|
||||
|
||||
在打开文件后,底部状态栏将显示当前的状态:当前工具模式 和 当前选定的区域
|
||||
在打开文件后,底部状态栏将显示当前的状态,从左至右分别是:当前工具模式,覆盖式粘贴状态 和 当前选定的区域
|
||||
|
||||
## 移动视图
|
||||
## 视图
|
||||
|
||||
### 基本操作
|
||||
|
||||
打开文件后,靠近底部有一个滑条,可以快速滑动到希望浏览的位置。
|
||||
滑条左侧有4个按钮,分别是:快退,退一个单元,进一个单元,快进。快进和快退将一次性前进或后退一个页面的单元数量。
|
||||
|
||||
如果要控制界面中显示的TAS单元数量,可以选择编辑 - 项个数进行设置
|
||||
|
||||
### 快速操作
|
||||
|
||||
键盘上的ASDF四个键从左至右也分别对应滑条左侧的四个按钮的功能。
|
||||
|
||||
鼠标滚轮一次可以一次向前或向后滚动一个TAS单元。
|
||||
如果按住Shift滚动鼠标滚轮,可以一次向前或向后滚动一整页。
|
||||
如果按住Ctrl滚动鼠标滚轮,可以增加或减少当前页面显示的TAS单元的个数。
|
||||
|
||||
### 横向布局与纵向布局
|
||||
|
||||
打开文档后,通过编辑 - 横向布局的勾选来确定启用的布局,不同的布局适用于不同的人,请根据自身喜好选择。
|
||||
|
||||
## 模式介绍
|
||||
|
||||
### 基本模式
|
||||
|
||||
打开文件后,上部3个带有图标的按钮,是TAS编辑器的三种模式,它们分别是:
|
||||
|
||||
* Select mode:选择模式:允许成列的选择TAS操作单元。在此模式下可以进行复制,粘贴,插入和删除操作。
|
||||
* Fill mode:填充模式:像编辑表格那样,允许多列选择和跨行选择(但必须连续),并且支持在选择区域内批量设置或不设置项目
|
||||
* Draw mode:绘画模式:将鼠标视为画笔,反转点击的单元格的设置状态。
|
||||
* 选择模式:允许成列的选择TAS操作单元。在此模式下可以进行复制,粘贴,插入和删除操作。
|
||||
* 填充模式:像编辑表格那样,允许多列选择和跨行选择(但必须连续),并且支持在选择区域内批量设置或不设置项目
|
||||
* 画笔模式:将鼠标视为画笔,反转点击的单元格的设置状态。
|
||||
|
||||
### 如何单选与多选
|
||||
|
||||
@ -43,6 +86,7 @@
|
||||
|
||||
选择模式和填充模式允许多选,具体操作是点击某个单元格作为起始位置,然后按住Shift点击第二个单元格作为终止位置。完成多选。
|
||||
再次左键单击重新开始一次选择。再次按住Shift左键单击重新选定终止位置。
|
||||
如果您仅仅只需要选中一个单元格,但是要求的操作需要多选,可以再按Shift点击当前单元完成多选。
|
||||
|
||||
### 选择的标识
|
||||
|
||||
@ -50,18 +94,25 @@
|
||||
|
||||
填充模式下,选中的单元格的外边框将从灰色变为橘色。
|
||||
|
||||
### 模式中的菜单
|
||||
## 特殊操作
|
||||
|
||||
在表格页面右键将打开一个操作菜单,如下:
|
||||
### 覆盖式粘贴与插入式粘贴
|
||||
|
||||
* Set:位于填充模式且已多选时,设置选中单元为设置状态
|
||||
* Unset:位于填充模式且已多选时,设置选中单元为不设置状态
|
||||
* Copy:位于选择模式且已多选时,复制选中单元
|
||||
* Delete:位于选择模式且已多选时,删除选中单元
|
||||
* Paste after this:位于选择模式且已单选时,在其前方粘贴剪贴板中已复制的单元
|
||||
* Paste before this:位于选择模式且已单选时,在其后方粘贴剪贴板中已复制的单元
|
||||
* Add blank item after this:位于选择模式且已单选时,在其前方添加空白单元
|
||||
* Add blank item before this:位于选择模式且已单选时,在其后方添加空白单元
|
||||
覆盖式粘贴与插入式粘贴为粘贴的两种模式。
|
||||
插入式粘贴为在选中项前或后方插入剪贴板内的内容。
|
||||
覆盖式粘贴则将会以当前选中单元为粘贴的头或尾,向前或向后覆盖式写入剪贴板内的内容,如果后方或前方数据长度不够,则会添加额外的项目补充。
|
||||
|
||||
### 快捷键
|
||||
|
||||
* `Ctrl + O`:打开文件
|
||||
* `Ctrl + S`:保存文件
|
||||
* `Ctrl + Z`:撤销
|
||||
* `Ctrl + Y`:重做
|
||||
* `Ctrl + X`:剪切
|
||||
* `Ctrl + C`:复制
|
||||
* `Ctrl + V`:向后粘贴
|
||||
* `Delete`:向后删除
|
||||
* `Backspace`:向前删除
|
||||
|
||||
## 出错啦
|
||||
|
||||
|
||||
Reference in New Issue
Block a user