1
0

47 Commits

Author SHA1 Message Date
a9fab50ada feat: support view model closing view window 2026-04-05 18:07:15 +08:00
a55a8c7456 feat: write shit 2026-04-02 20:35:30 +08:00
08734c6ef7 feat: introduce batchly visit in tas sequence 2026-04-01 13:33:30 +08:00
5f10338d33 test: finish tas op test 2026-04-01 13:16:05 +08:00
c74e22bff0 test: add test for tas oper and fix uniform fps op issue 2026-03-31 16:52:22 +08:00
b8184c6ab4 test: add test for tas oper and fix issue 2026-03-31 14:26:17 +08:00
d0174bbf86 fix: fix build issue and tas seq refactor issue 2026-03-30 10:58:26 +08:00
530dc2a76e feat: add before and after support for tas operation 2026-03-30 10:40:50 +08:00
eeb6f1802c feat: update tas oper oocupation calc 2026-03-29 10:44:04 +08:00
d8f8536b8b feat: fix nullable warning 2026-03-29 10:39:59 +08:00
b73a035311 feat: finish tas operation 2026-03-29 10:33:13 +08:00
97458d893e feat: write shit operator 2026-03-29 10:06:10 +08:00
43c24c63c7 feat: write some tas oper 2026-03-29 09:21:21 +08:00
7f4d511715 feat: update some interface 2026-03-27 16:11:11 +08:00
ba53ad1da4 refactor: refactor project 2026-03-25 10:33:05 +08:00
6c07355601 refactor: refactor editor 2026-03-11 13:56:49 +08:00
802c258a99 fix: fix shit 2026-01-20 09:24:03 +08:00
8f1b7cc196 fix: fix what a shit 2026-01-19 22:43:58 +08:00
b16c7508f0 doc: update doc style for sonnet 2026-01-19 19:21:08 +08:00
590645b13c feat: add pyi generation for pyi in sonnet 2026-01-19 16:14:52 +08:00
84897a409b feat: add fps module in sonnet 2026-01-19 11:14:13 +08:00
5323617ca6 chore: change project layout 2026-01-19 10:44:10 +08:00
0e9837a75a doc: add docstring for sonnet 2026-01-19 10:27:53 +08:00
87e6c63aae feat: add build notes and fix build issue for sonnet 2026-01-19 10:14:53 +08:00
85fc2ad3ce feat: remove fps support from rust to python 2026-01-19 09:34:16 +08:00
06482e2218 feat: finish sonnet expose interface 2026-01-18 22:50:47 +08:00
c42305c8d2 feat: finish sonnet tas file rw functions 2026-01-18 20:39:47 +08:00
49940b43d5 write some sonnet code 2026-01-18 14:56:37 +08:00
941e59e471 chore: adjust directory layout for new added planned peoject 2026-01-18 11:07:52 +08:00
ab5a68bed7 feat: commit content which I don't know when I create them 2026-01-18 10:43:30 +08:00
4aaf64eae5 feat: add tas operation interface 2025-11-19 13:19:07 +08:00
eb40906975 fix: update some words and styles 2025-11-18 22:34:01 +08:00
ee6a565ce0 feat: add clear keys icon 2025-11-18 22:05:05 +08:00
334accd070 feat: use new IEnumeratable type 2025-11-18 21:56:50 +08:00
9d41119710 feat: add icon for editor layout 2025-11-18 21:12:33 +08:00
86ea296a1b refactor: migrate project to .net core 8 to resolve the issue that we can not use CommunityToolkit.Mvvm 2025-11-18 20:53:42 +08:00
a1b1fcbf7b feat: got stuck with bug of Community.Mvvm generating codes 2025-11-18 14:50:17 +08:00
02118f4c0a feat: add all essential dialogs 2025-11-17 13:22:00 +08:00
9d51866443 fix: fix accessory icon and update project nuget system 2025-11-17 12:35:47 +08:00
7bc8a99d49 feat: make style but not finished 2025-11-17 10:42:50 +08:00
d9d0bb2ed5 chore: add build build script for assets 2025-11-16 21:30:56 +08:00
1d8cb1a783 feat: add icon resources for editor 2025-11-16 15:44:14 +08:00
df4a7252c1 refactor(utils): improve TasStorage implementation and tests
- Change exception type from ArgumentOutOfRangeException to ArgumentException
- Fix node seeking logic by correcting candidate order
- Update Visit, Insert, and Remove methods with proper range checks
- Enhance cursor management after removal operations
- Add comprehensive test cases for edge scenarios
- Introduce AssertExtension for better exception testing
- Handle empty collection states more robustly
2025-11-15 12:20:46 +08:00
630365a6a6 refactor(storage): rename TasMemory to TasStorage and update references
- Renamed TasMemory.cs file to TasStorage.cs
- Updated project file reference from TasMemory to TasStorage
- Removed unused test project files and configurations
- Fixed solution file project name and GUID references
- Cleaned up obsolete MSTest configuration files
2025-11-13 14:08:31 +08:00
2ec880c5a6 refactor(utils): rename TasFrame to RawTasFrame and add new TasFrame class
- Renamed original TasFrame struct to RawTasFrame to reflect its role as raw binary data
- Added new TasFrame class with encapsulated fields and helper methods
- Added FpsConverter usage for time delta calculation
- Added conversion methods between RawTasFrame and TasFrame
- Added getter and setter methods for frame properties
- Updated key flag operations to use private field instead of public one
- Added new utility files FpsConverter.cs and TasMemory.cs to project
2025-11-12 15:58:49 +08:00
c57108536a refactor: re-add once for fixing windows case-insensitive issue. 2025-11-12 09:19:59 +08:00
abb4d1354b refactor: delete once for fixing windows case-insensitive issue. 2025-11-12 09:19:23 +08:00
218 changed files with 9217 additions and 954 deletions

View File

@@ -1,31 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36414.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BallanceTasEditor", "BallanceTasEditor\BallanceTasEditor.csproj", "{DD898514-03ED-4257-AFD1-290EEDF68113}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BallanceTasEditorTest", "BallanceTasEditorTest\BallanceTasEditorTest.csproj", "{1DC1A8CD-E963-4FF8-91D9-059522419961}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD898514-03ED-4257-AFD1-290EEDF68113}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD898514-03ED-4257-AFD1-290EEDF68113}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD898514-03ED-4257-AFD1-290EEDF68113}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD898514-03ED-4257-AFD1-290EEDF68113}.Release|Any CPU.Build.0 = Release|Any CPU
{1DC1A8CD-E963-4FF8-91D9-059522419961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1DC1A8CD-E963-4FF8-91D9-059522419961}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DC1A8CD-E963-4FF8-91D9-059522419961}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DC1A8CD-E963-4FF8-91D9-059522419961}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5A4468A2-79ED-47F3-80FE-299A89DE9D0E}
EndGlobalSection
EndGlobal

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -1,9 +0,0 @@
<Application x:Class="BallanceTasEditor.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BallanceTasEditor"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View File

@@ -1,151 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DD898514-03ED-4257-AFD1-290EEDF68113}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>BallanceTasEditor</RootNamespace>
<AssemblyName>BallanceTasEditor</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>App.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommunityToolkit.Mvvm, Version=8.2.0.0, Culture=neutral, PublicKeyToken=4aff67a105548ee2, processorArchitecture=MSIL">
<HintPath>..\packages\CommunityToolkit.Mvvm.8.2.1\lib\netstandard2.0\CommunityToolkit.Mvvm.dll</HintPath>
</Reference>
<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.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.ComponentModel.Annotations.5.0.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Views\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Utils\TasFrame.cs" />
<Compile Include="Views\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
<Folder Include="ViewModels\" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\App.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="App.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\CommunityToolkit.Mvvm.8.2.1\build\netstandard2.0\CommunityToolkit.Mvvm.targets" Condition="Exists('..\packages\CommunityToolkit.Mvvm.8.2.1\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\CommunityToolkit.Mvvm.8.2.1\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CommunityToolkit.Mvvm.8.2.1\build\netstandard2.0\CommunityToolkit.Mvvm.targets'))" />
</Target>
</Project>

View File

@@ -1,52 +0,0 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BallanceTasEditor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BallanceTasEditor")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,62 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BallanceTasEditor.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BallanceTasEditor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BallanceTasEditor.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -1,105 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Utils {
/// <summary>
/// 描述TAS文件中一帧的结构。
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct TasFrame {
/// <summary>
/// 该帧的持续时间(以秒为单位)。
/// </summary>
public float TimeDelta;
/// <summary>
/// 该帧的按键组合。
/// </summary>
public uint KeyFlags;
/// <summary>
/// 判断按键是否被按下。
/// </summary>
/// <param name="key">要检查的按键。</param>
/// <returns>true表示被按下否则为false。</returns>
public bool IsKeyPressed(TasKey key) {
return (KeyFlags & (1u << (int)key)) != 0;
}
/// <summary>
/// 设置按键状态。
/// </summary>
/// <param name="key">要设置的按键。</param>
/// <param name="pressed">true表示设置为按下否则为松开。</param>
public void SetKeyPressed(TasKey key, bool pressed = true) {
if (pressed) KeyFlags |= (1u << (int)key);
else KeyFlags &= ~(1u << (int)key);
}
/// <summary>
/// 反转按键状态。
/// </summary>
/// <param name="key">要反转的按键。</param>
public void FlipKeyPressed(TasKey key) {
KeyFlags ^= (1u << (int)key);
}
/// <summary>
/// 获取或设置Up键的按下状态。
/// </summary>
public bool KeyUpPressed { get { return IsKeyPressed(TasKey.KeyUp); } set { SetKeyPressed(TasKey.KeyUp, value); } }
/// <summary>
/// 获取或设置Down键的按下状态。
/// </summary>
public bool KeyDownPressed { get { return IsKeyPressed(TasKey.KeyDown); } set { SetKeyPressed(TasKey.KeyDown, value); } }
/// <summary>
/// 获取或设置Left键的按下状态。
/// </summary>
public bool KeyLeftPressed { get { return IsKeyPressed(TasKey.KeyLeft); } set { SetKeyPressed(TasKey.KeyLeft, value); } }
/// <summary>
/// 获取或设置Right键的按下状态。
/// </summary>
public bool KeyRightPressed { get { return IsKeyPressed(TasKey.KeyRight); } set { SetKeyPressed(TasKey.KeyRight, value); } }
/// <summary>
/// 获取或设置Shift键的按下状态。
/// </summary>
public bool KeyShiftPressed { get { return IsKeyPressed(TasKey.KeyShift); } set { SetKeyPressed(TasKey.KeyShift, value); } }
/// <summary>
/// 获取或设置Space键的按下状态。
/// </summary>
public bool KeySpacePressed { get { return IsKeyPressed(TasKey.KeySpace); } set { SetKeyPressed(TasKey.KeySpace, value); } }
/// <summary>
/// 获取或设置Q键的按下状态。
/// </summary>
public bool KeyQPressed { get { return IsKeyPressed(TasKey.KeyQ); } set { SetKeyPressed(TasKey.KeyQ, value); } }
/// <summary>
/// 获取或设置Esc键的按下状态。
/// </summary>
public bool KeyEscPressed { get { return IsKeyPressed(TasKey.KeyEsc); } set { SetKeyPressed(TasKey.KeyEsc, value); } }
/// <summary>
/// 获取或设置回车键的按下状态。
/// </summary>
public bool KeyEnterPressed { get { return IsKeyPressed(TasKey.KeyEnter); } set { SetKeyPressed(TasKey.KeyEnter, value); } }
}
/// <summary>
/// 描述TAS文件中的可能的按键。
/// </summary>
public enum TasKey : int {
KeyUp = 0,
KeyDown = 1,
KeyLeft = 2,
KeyRight = 3,
KeyShift = 4,
KeySpace = 5,
KeyQ = 6,
KeyEsc = 7,
KeyEnter = 8,
}
}

View File

@@ -1,12 +0,0 @@
<Window x:Class="BallanceTasEditor.Views.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"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Icon="/Assets/App.ico">
<Grid>
</Grid>
</Window>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommunityToolkit.Mvvm" version="8.2.1" targetFramework="net48" />
<package id="DotNetZip" version="1.9.1.8" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.ComponentModel.Annotations" version="5.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
</packages>

View File

@@ -0,0 +1,5 @@
# Ignore generated files
*.bat
*.sh
*.ico
*.png

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuAbout.svg"
inkscape:export-filename="MenuAbout.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="8.2291667"
inkscape:cx="18.106329"
inkscape:cy="5.7113924"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 13,9 H 11 V 7 h 2 m 0,10 h -2 v -6 h 2 M 12,2 A 10,10 0 0 0 2,12 10,10 0 0 0 12,22 10,10 0 0 0 22,12 10,10 0 0 0 12,2 Z"
id="path1"
style="display:none" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="M 11.331646,21.963844 C 10.350843,21.895612 9.2782955,21.655947 8.3848101,21.305362 7.073815,20.790955 5.9477316,20.049837 4.9354663,19.035217 3.2965843,17.392523 2.3386597,15.380387 2.0634649,13.002532 c -0.047583,-0.41115 -0.047583,-1.593914 0,-2.005064 C 2.2936647,9.0083985 3.0074126,7.2671058 4.2115248,5.756962 4.5556094,5.3254265 5.3306962,4.5509678 5.756962,4.2127774 7.2569939,3.0226832 8.9585632,2.3129438 10.877027,2.0771533 c 0.55463,-0.068167 1.691316,-0.068167 2.245946,0 1.913756,0.2352119 3.64152,0.9554548 5.120065,2.1343715 0.42793,0.3412098 1.204026,1.1170463 1.540553,1.5400384 1.212522,1.5240584 1.924504,3.259118 2.152658,5.2459048 0.04781,0.416369 0.0489,1.531707 0.0019,1.971736 -0.210539,1.971877 -0.927503,3.72952 -2.151259,5.273834 -0.337806,0.426291 -1.112351,1.201462 -1.543867,1.545114 -1.509369,1.202033 -3.301249,1.937356 -5.225316,2.144284 -0.419189,0.04508 -1.263447,0.06081 -1.686076,0.03141 z m 1.670886,-7.958781 V 10.997468 H 12 10.997468 v 3.007595 3.007595 H 12 13.002532 Z m 0,-5.9999997 V 6.9873418 H 12 10.997468 V 8.0050633 9.0227848 H 12 13.002532 Z"
id="path2" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 10.997468,8.0050633 V 6.9873418 H 12 13.002532 V 8.0050633 9.0227848 H 12 10.997468 Z"
id="path3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 10.997468,14.005063 V 10.997468 H 12 13.002532 v 3.007595 3.007595 H 12 10.997468 Z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuAdd.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
inkscape:export-filename="CtxMenuAdd.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="23.275598"
inkscape:cx="13.469042"
inkscape:cy="11.814949"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 11,2 a 2,2 0 0 1 2,2 v 16 a 2,2 0 0 1 -2,2 H 2 V 2 h 9 m -7,8 v 4 h 7 V 10 H 4 m 0,6 v 4 h 7 V 16 H 4 M 4,4 v 4 h 7 V 4 H 4 m 11,7 h 3 V 8 h 2 v 3 h 3 v 2 h -3 v 3 h -2 v -3 h -3 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.0012889"
d="M 2.0192821,12.009734 V 2.0192821 h 4.5734928 c 3.2470388,0 4.6395251,0.014132 4.8011651,0.048725 0.70855,0.1516385 1.310681,0.7145009 1.501846,1.4039032 0.07566,0.2728392 0.07918,0.6513922 0.07918,8.5156767 0,7.156645 -0.0084,8.262238 -0.06409,8.476192 -0.176436,0.677383 -0.615301,1.157706 -1.29273,1.414847 l -0.254312,0.09653 -4.6722757,0.01251 -4.6722752,0.01251 z m 9.0223249,5.991952 V 15.982403 H 7.5186037 3.9956008 v 2.019283 2.019282 h 3.5230029 3.5230033 z m 0,-6.014883 V 9.9675204 H 7.5186037 3.9956008 v 2.0192826 2.019282 h 3.5230029 3.5230033 z m 0,-5.97192 V 3.9956008 H 7.5186037 3.9956008 V 6.014883 8.0341651 h 3.5230029 3.5230033 z"
id="path2" />
<path
style="fill:#4caf50;fill-opacity:1;stroke-width:0.0012889"
d="m 18.001686,14.478683 v -1.503721 h -1.482239 -1.48224 v -0.988159 -0.98816 h 1.48224 1.482239 V 9.5164042 8.0341651 h 0.988159 0.988159 v 1.4822391 1.4822388 h 1.503721 1.503721 v 0.98816 0.988159 h -1.503721 -1.503721 v 1.503721 1.50372 h -0.988159 -0.988159 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,32 @@
import pathlib
def fetch_svg_files() -> tuple[pathlib.Path, ...]:
return tuple(file for file in pathlib.Path("./").glob("*.svg"))
def generate_windows_script(svg_files: tuple[pathlib.Path, ...]) -> None:
with open("./BuildIcons.bat", "w", encoding="utf-8") as f:
for svg_file in svg_files:
png_file = f'{svg_file.stem}.png'
ico_file = f'{svg_file.stem}.ico'
f.write(f"inkscape --without-gui {svg_file} -o {png_file} -w 250 -h 256\n")
f.write(f"magick {png_file} -define icon:auto-resize=256,128,64,48,32,16 {ico_file}\n")
def generate_linux_script(svg_files: tuple[pathlib.Path, ...]) -> None:
with open("./BuildIcons.sh", "w", encoding="utf-8") as f:
for svg_file in svg_files:
png_file = f'{svg_file.stem}.png'
ico_file = f'{svg_file.stem}.ico'
f.write(f"inkscape --without-gui {svg_file} -o {png_file} -w 250 -h 256\n")
f.write(f"magick {png_file} -define icon:auto-resize=256,128,64,48,32,16 {ico_file}\n")
def main():
print("Fetching SVG files...")
svg_files = fetch_svg_files()
print("Building Windows script...")
generate_windows_script(svg_files)
print("Building Linux script...")
generate_linux_script(svg_files)
print("Done!")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="Cancel.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 12,2 C 17.5,2 22,6.5 22,12 22,17.5 17.5,22 12,22 6.5,22 2,17.5 2,12 2,6.5 6.5,2 12,2 m 0,2 C 10.1,4 8.4,4.6 7.1,5.7 L 18.3,16.9 C 19.3,15.5 20,13.8 20,12 20,7.6 16.4,4 12,4 M 16.9,18.3 5.7,7.1 C 4.6,8.4 4,10.1 4,12 c 0,4.4 3.6,8 8,8 1.9,0 3.6,-0.6 4.9,-1.7 z"
id="path1"
style="display:none" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 11.529114,21.976736 C 10.22238,21.889141 9.0970988,21.622033 8.0114321,21.141743 5.0411839,19.827731 2.8549818,17.127924 2.2192797,13.988839 2.0648176,13.226108 2.0373265,12.925617 2.0373265,12 c 0,-0.925617 0.027491,-1.226108 0.1819532,-1.988839 C 2.9672398,6.3177478 5.8643146,3.2688861 9.5104706,2.3379617 10.411349,2.1079524 11.074436,2.0255288 12.01519,2.026618 c 1.996985,0.00231 3.807406,0.5499071 5.467923,1.6538737 2.455605,1.6325675 4.010624,4.1204917 4.426934,7.0827903 0.07357,0.523513 0.07357,1.949923 0,2.473436 -0.326722,2.324832 -1.359557,4.372036 -2.997659,5.94173 -1.596575,1.5299 -3.611736,2.485613 -5.773541,2.738166 -0.389906,0.04555 -1.312862,0.08002 -1.609733,0.06012 z m 1.563357,-2.032544 c 0.925767,-0.122293 1.765668,-0.379382 2.5417,-0.778003 0.341195,-0.175259 0.942023,-0.568381 1.150639,-0.752863 l 0.136709,-0.120893 -5.605032,-5.606976 C 8.2337189,9.6016202 5.704605,7.0785217 5.6962335,7.0785715 5.6878621,7.0786214 5.5669726,7.2324188 5.4275903,7.4203437 4.7111807,8.3862562 4.2640759,9.494702 4.0680851,10.790778 c -0.065181,0.431036 -0.090079,1.53472 -0.044835,1.987446 0.2406062,2.407596 1.546148,4.562332 3.5868762,5.919974 0.4303689,0.286313 1.2614491,0.698786 1.7409864,0.864068 0.6315864,0.217689 1.3326383,0.369549 1.9653433,0.425729 0.425722,0.0378 1.326427,0.01559 1.776015,-0.0438 z m 5.537897,-3.505461 c 0.686116,-1.101759 1.081879,-2.107709 1.286142,-3.269111 0.0819,-0.465656 0.111841,-1.431584 0.06035,-1.946773 C 19.735881,8.811741 18.433266,6.6619006 16.388891,5.3012482 15.724197,4.8588544 14.767203,4.4347242 13.990518,4.2383123 12.090514,3.75783 10.037364,3.9752015 8.3658289,4.8338107 8.0246342,5.0090703 7.4238064,5.4021922 7.2151899,5.5866738 L 7.078481,5.707567 l 5.605063,5.608114 5.605064,5.608114 0.07595,-0.09009 c 0.04177,-0.04955 0.161387,-0.227288 0.265811,-0.394971 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="ClearKeys.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 19.36,2.72 1.42,1.42 -5.72,5.71 c 1.07,1.54 1.22,3.39 0.32,4.59 L 9.06,8.12 c 1.2,-0.9 3.05,-0.75 4.59,0.32 L 19.36,2.72 M 5.93,17.57 C 3.92,15.56 2.69,13.16 2.35,10.92 l 4.88,-2.09 7.44,7.44 -2.09,4.88 C 10.34,20.81 7.94,19.58 5.93,17.57 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392;fill-opacity:1"
d="M 12.136709,21.054947 C 9.849802,20.570498 7.6401138,19.296543 5.8025316,17.403096 4.4028758,15.960889 3.3992023,14.37058 2.7993906,12.644655 2.6463627,12.204326 2.4273042,11.35402 2.3985171,11.088608 L 2.3803943,10.921519 4.7251585,9.9189873 C 6.0147788,9.3675949 7.1043011,8.9044989 7.1463187,8.8898851 c 0.071606,-0.024904 0.3085786,0.2056059 3.7789633,3.6759029 2.036411,2.03636 3.702566,3.714727 3.702566,3.729703 0,0.01498 -0.461067,1.105251 -1.024592,2.422831 l -1.024593,2.395602 -0.09186,-0.0021 c -0.05053,-0.0012 -0.208066,-0.02675 -0.350091,-0.05684 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 12.228787,11.256636 9.0890771,8.1168152 9.262956,8.0055861 c 0.537045,-0.3435433 1.29721,-0.5112188 2.003468,-0.4419202 0.416509,0.040868 0.869029,0.1466631 1.241447,0.2902384 0.298885,0.1152267 0.773018,0.3576119 0.98551,0.5038104 0.07023,0.04832 0.138874,0.087855 0.152539,0.087855 0.01366,0 1.306513,-1.281613 2.872996,-2.8480292 l 2.84815,-2.8480293 0.691078,0.6910787 0.691079,0.6910786 -2.855424,2.8555452 C 15.12356,9.75757 15.039674,9.8448024 15.081906,9.911253 c 0.598284,0.941377 0.857172,1.729415 0.860857,2.620393 0.002,0.475353 -0.04848,0.782692 -0.194207,1.183063 -0.08105,0.222676 -0.299494,0.631956 -0.355907,0.666821 -0.01328,0.0082 -1.437021,-1.397993 -3.163862,-3.124894 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuCloseFile.svg"
inkscape:export-filename="MenuCloseFile.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,6.41 17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12 Z"
id="path1"
style="display:none" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 5.7112968,18.273322 5.0281633,17.589682 7.8228805,14.794841 10.617598,12 7.8227956,9.2050739 5.0279935,6.4101481 5.7190708,5.7190708 6.4101481,5.0279935 9.2050739,7.8227956 12,10.617598 14.794926,7.8227956 17.589852,5.0279935 18.280929,5.7190708 18.972006,6.4101481 16.177205,9.2050739 13.382402,12 l 2.794803,2.794926 2.794801,2.794926 -0.691077,0.691077 -0.691077,0.691077 L 14.794926,16.177205 12,13.382402 9.2125966,16.169682 c -1.5330718,1.533004 -2.794325,2.78728 -2.8027848,2.78728 -0.00846,0 -0.3227916,-0.307638 -0.698515,-0.68364 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuCopy.svg"
inkscape:export-filename="CtxMenuCopy.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,21 H 8 V 7 H 19 M 19,5 H 8 A 2,2 0 0 0 6,7 v 14 a 2,2 0 0 0 2,2 h 11 a 2,2 0 0 0 2,-2 V 7 A 2,2 0 0 0 19,5 M 16,1 H 4 A 2,2 0 0 0 2,3 V 17 H 4 V 3 h 12 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 7.732731,22.963972 C 7.0594098,22.864737 6.5049441,22.453575 6.2116792,21.836042 6.0001842,21.390694 6.0136007,21.952801 6.0224163,13.906505 L 6.0303797,6.6379747 6.1149051,6.38842 C 6.3177954,5.7894024 6.7782372,5.3289195 7.3867677,5.1164439 l 0.2537386,-0.088596 5.7642917,-0.00806 c 6.41828,-0.00897 5.985444,-0.022482 6.448367,0.2013129 0.13367,0.064622 0.314101,0.1746294 0.400956,0.2444612 0.289636,0.2328687 0.557401,0.6491472 0.667759,1.0381285 0.05283,0.1862194 0.05533,0.5254323 0.05533,7.5013675 v 7.306329 l -0.07112,0.227849 c -0.114404,0.36654 -0.237515,0.567898 -0.520744,0.851714 -0.196424,0.196831 -0.313672,0.286167 -0.486622,0.370778 -0.491078,0.240246 0.08936,0.219525 -6.288607,0.2245 -3.144126,0.0025 -5.7773831,-0.0075 -5.877396,-0.02226 z M 19.017722,14.005063 V 6.9873418 H 13.503797 7.9898734 v 7.0177212 7.017722 h 5.5139236 5.513925 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 2.0122757,9.835443 C 2.0213249,1.8350443 1.9993464,2.5817311 2.2400775,2.0962025 2.3985362,1.7766082 2.7824829,1.3929839 3.0987342,1.2382668 3.590707,0.99758293 2.9557283,1.0191219 9.835443,1.0097525 l 6.144304,-0.00837 V 1.9892977 2.977213 h -6.0000002 -6 V 9.9797468 16.982278 H 2.9919694 2.0041921 Z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="Count.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,10.73 V 19 H 17 V 11.36 L 15,12 v 7 h -2 v -6.38 l -2,0.64 V 19 H 9 V 13.89 L 7,14.5 V 19 H 5 V 15.15 L 2.57,15.92 2,14 5,13.05 V 5 h 2 v 7.42 L 9,11.79 V 5 h 2 v 6.16 l 2,-0.63 V 5 h 2 V 9.9 L 17,9.26 V 5 h 2 V 8.63 L 21,8 21.57,9.92 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="m 5.0278481,17.056181 c 0,-1.825137 -0.00292,-1.93027 -0.053165,-1.914915 -0.029241,0.0089 -0.5769929,0.182104 -1.2172276,0.384819 C 3.1172213,15.728801 2.588954,15.88988 2.5835286,15.884038 2.566855,15.866086 2.0228601,14.02271 2.0316438,14.013926 c 0.00712,-0.0071 0.9150886,-0.296574 2.548103,-0.812316 L 5.0278481,13.06009 V 9.0363743 5.0126582 H 6 6.9721519 v 3.7063291 c 0,2.7432597 0.00895,3.7063287 0.034461,3.7063287 0.018954,0 0.4769283,-0.139377 1.0177215,-0.309728 L 9.0075949,11.80586 V 8.4092591 5.0126582 h 0.9873418 0.9873413 v 3.0835443 c 0,1.6959494 0.0034,3.0834795 0.0076,3.0833995 0.0042,-8e-5 0.458735,-0.14235 1.010127,-0.316156 l 1.002532,-0.31601 0.0078,-2.7673889 0.0078,-2.7673889 h 0.987182 0.987182 v 2.4455696 c 0,1.3450633 0.01173,2.4455697 0.02606,2.4455697 0.01433,0 0.46889,-0.141497 1.010127,-0.3144374 l 0.984068,-0.3144377 0.0078,-2.131132 0.0078,-2.1311322 h 0.971946 0.971947 v 1.807595 c 0,1.6324705 0.0047,1.8075949 0.04834,1.8075949 0.02658,0 0.480295,-0.1364151 1.008247,-0.3031449 0.527952,-0.1667298 0.961605,-0.300021 0.963674,-0.2962025 0.0075,0.013889 0.538938,1.8304651 0.542827,1.8556019 0.0022,0.014231 -0.570173,0.2070414 -1.271945,0.4284664 l -1.275949,0.402593 -0.0077,4.13609 -0.0077,4.13609 H 18 17.027956 v -3.812658 c 0,-3.029225 -0.0078,-3.812909 -0.03797,-3.813876 -0.02089,-6.7e-4 -0.47886,0.139123 -1.017721,0.310649 l -0.979747,0.311868 v 3.502008 3.502009 h -0.987342 -0.987341 v -3.189874 c 0,-1.75443 -0.0089,-3.189873 -0.01975,-3.189873 -0.01833,0 -1.089876,0.340464 -1.734681,0.551161 l -0.281013,0.09182 v 2.868381 2.868381 H 9.9949367 9.0075949 v -2.551899 c 0,-1.403544 -0.010723,-2.551899 -0.023829,-2.551899 -0.021828,0 -0.8292687,0.243646 -1.6698419,0.503877 L 6.9721519,14.49323 v 2.247056 2.247056 H 6 5.0278481 Z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuCut.svg"
inkscape:export-filename="CtxMenuCut.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 19,3 -6,6 2,2 7,-7 V 3 M 12,12.5 A 0.5,0.5 0 0 1 11.5,12 0.5,0.5 0 0 1 12,11.5 0.5,0.5 0 0 1 12.5,12 0.5,0.5 0 0 1 12,12.5 M 6,20 A 2,2 0 0 1 4,18 c 0,-1.11 0.9,-2 2,-2 a 2,2 0 0 1 2,2 c 0,1.11 -0.9,2 -2,2 M 6,8 A 2,2 0 0 1 4,6 C 4,4.89 4.9,4 6,4 A 2,2 0 0 1 8,6 C 8,7.11 7.1,8 6,8 M 9.64,7.64 C 9.87,7.14 10,6.59 10,6 A 4,4 0 0 0 6,2 4,4 0 0 0 2,6 4,4 0 0 0 6,10 C 6.59,10 7.14,9.87 7.64,9.64 L 10,12 7.64,14.36 C 7.14,14.13 6.59,14 6,14 a 4,4 0 0 0 -4,4 4,4 0 0 0 4,4 4,4 0 0 0 4,-4 C 10,17.41 9.87,16.86 9.64,16.36 L 12,14 l 7,7 h 3 v -1 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 5.5842781,21.964047 C 4.339761,21.822016 3.2064639,21.093606 2.5774271,20.031438 1.2229574,17.744332 2.4536028,14.794021 5.0352495,14.139133 5.8475049,13.933087 6.6312814,13.98564 7.4526058,14.301218 L 7.6596419,14.380767 8.8500258,13.190384 10.04041,12 8.8522575,10.811848 7.6641056,9.6236962 7.3066001,9.7492381 C 6.819573,9.920263 6.4891941,9.9757522 5.9696203,9.9737921 4.3736523,9.9677714 2.934284,8.999163 2.3234014,7.5201059 1.3969459,5.2769897 2.6776086,2.7371976 5.0369113,2.1387113 6.9639442,1.6498794 8.9551282,2.6764902 9.7010725,4.5434505 10.059319,5.4400751 10.075549,6.377366 9.7489334,7.3074677 l -0.1252481,0.3566683 6.1856257,6.185681 6.185626,6.185682 v 0.478453 0.478453 h -1.480964 -1.480964 l -3.516505,-3.516407 -3.516505,-3.516407 -1.188151,1.188152 -1.1881518,1.188151 0.1255419,0.357506 c 0.1710249,0.487027 0.2265141,0.817406 0.224554,1.33698 -0.00499,1.321703 -0.6586593,2.532518 -1.776572,3.290787 -0.1954478,0.132571 -0.6334849,0.348183 -0.898982,0.442501 -0.4878228,0.1733 -1.2107122,0.257813 -1.71396,0.200379 z M 6.609957,19.91537 C 6.9322712,19.812494 7.1291711,19.693945 7.3913244,19.444925 7.6467263,19.202318 7.8077672,18.947058 7.9195859,18.607595 7.9881254,18.399522 7.9996426,18.31211 7.9996426,18 c 0,-0.31211 -0.011517,-0.399522 -0.080057,-0.607595 C 7.8064545,17.048958 7.6468256,16.798232 7.377432,16.540855 7.204995,16.376109 7.0783467,16.286716 6.8911243,16.1976 6.5588291,16.039431 6.3679009,15.996302 6,15.996302 c -0.3658931,0 -0.5596074,0.04332 -0.8810127,0.197033 -0.4121962,0.197131 -0.7285218,0.513456 -0.9256523,0.925652 -0.158978,0.33242 -0.1986895,0.51809 -0.194931,0.911393 0.00533,0.557793 0.1839253,0.986581 0.5764834,1.384079 0.2992605,0.303025 0.6713157,0.499759 1.0867709,0.574657 0.2535658,0.04571 0.6772618,0.01276 0.9482987,-0.07375 z m 5.634296,-7.468871 c 0.155071,-0.082 0.272203,-0.274136 0.272203,-0.446499 0,-0.264115 -0.252341,-0.516456 -0.516456,-0.516456 -0.264115,0 -0.516456,0.252341 -0.516456,0.516456 0,0.172363 0.117132,0.364495 0.272203,0.446499 0.167842,0.08876 0.320664,0.08876 0.488506,0 z M 6.609957,7.9153701 C 6.9322712,7.8124943 7.1291711,7.6939449 7.3913244,7.4449249 7.6467263,7.2023183 7.8077672,6.9470576 7.9195859,6.6075949 7.9881254,6.3995216 7.9996426,6.31211 7.9996426,6 c 0,-0.31211 -0.011517,-0.3995216 -0.080057,-0.6075949 C 7.8064545,5.0489578 7.6468256,4.7982317 7.377432,4.5408546 7.204995,4.3761094 7.0783467,4.2867161 6.8911243,4.1976002 6.5588291,4.0394309 6.3679009,3.9963016 6,3.9963016 c -0.3658931,0 -0.5596074,0.043323 -0.8810127,0.1970334 C 4.5895301,4.446545 4.174649,4.9586 4.0367025,5.5291139 c -0.05196,0.2148954 -0.05196,0.7268768 0,0.9417722 0.077445,0.320293 0.2635966,0.6547956 0.5043669,0.9063141 0.3192966,0.3335505 0.6853802,0.5334562 1.1205889,0.6119155 0.2535658,0.045713 0.6772618,0.012763 0.9482987,-0.073746 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="m 14.012604,9.9872898 -0.979578,-0.9799251 3,-2.9998848 3,-2.999885 h 1.480955 1.480956 v 0.4785304 0.4785303 l -3.501378,3.5012796 -3.501378,3.5012798 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuDelete.svg"
inkscape:export-filename="CtxMenuDelete.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 19,4 h -3.5 l -1,-1 h -5 l -1,1 H 5 V 6 H 19 M 6,19 a 2,2 0 0 0 2,2 h 8 a 2,2 0 0 0 2,-2 V 7 H 6 Z"
id="path1"
style="display:none" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 7.7620253,20.971055 C 7.3386196,20.91084 6.9168794,20.705385 6.6252386,20.417257 6.3839009,20.178826 6.2322126,19.938241 6.116161,19.609835 L 6.03038,19.367089 6.02235,13.192405 6.01432,7.0177215 H 12 17.985673 l -0.008,6.1746835 -0.008,6.174684 -0.08578,0.242746 c -0.177069,0.501075 -0.519519,0.907554 -0.955057,1.133625 -0.484128,0.251292 -0.07556,0.231342 -4.837643,0.236217 -2.3308858,0.0024 -4.2789871,-0.0015 -4.3291137,-0.0086 z"
id="path2" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 5.0126582,4.9974684 V 4.0101266 H 6.7674339 8.5222095 L 9.0227848,3.5088608 9.5233601,3.0075949 H 12 14.47664 l 0.500575,0.5012659 0.500575,0.5012658 h 1.754776 1.754776 V 4.9974684 5.9848101 H 12 5.0126582 Z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="ModeDraw.svg"
inkscape:export-filename="ModeDraw.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 20.71,4.63 19.37,3.29 C 19,2.9 18.35,2.9 17.96,3.29 L 9,12.25 11.75,15 20.71,6.04 C 21.1,5.65 21.1,5 20.71,4.63 M 7,14 a 3,3 0 0 0 -3,3 c 0,1.31 -1.16,2 -2,2 0.92,1.22 2.5,2 4,2 a 4,4 0 0 0 4,-4 3,3 0 0 0 -3,-3 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 10.38224,13.617684 9.0228718,12.258064 13.541816,7.743439 c 2.485419,-2.483044 4.560258,-4.5426056 4.610754,-4.5768037 0.256759,-0.1738888 0.63648,-0.1955397 0.936756,-0.053412 0.216451,0.1024519 1.708771,1.6016747 1.80634,1.8146961 0.135527,0.295894 0.108591,0.656175 -0.06963,0.9313875 -0.03929,0.060672 -2.09936,2.1370418 -4.577931,4.6141551 l -4.506493,4.503842 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 5.6506329,20.97425 C 4.8256535,20.875845 4.1800619,20.669077 3.5220067,20.292501 3.0937142,20.047408 2.7806729,19.802016 2.3862001,19.402146 L 2.023033,19.03401 2.3102507,18.981251 c 0.4462914,-0.08198 0.7942386,-0.266895 1.1259583,-0.598386 0.2042891,-0.204149 0.285994,-0.312445 0.3733282,-0.494827 0.1292382,-0.269893 0.1990561,-0.563898 0.2006637,-0.845 0.00578,-1.010574 0.5105492,-1.966611 1.3248123,-2.509201 0.530838,-0.353727 1.0151954,-0.503421 1.6371387,-0.505968 0.8410411,-0.0034 1.5300377,0.275962 2.11356,0.857102 0.6038998,0.601436 0.8879487,1.286847 0.8880526,2.142877 1.272e-4,1.048729 -0.4086055,2.026331 -1.1626819,2.780887 -0.5795684,0.579938 -1.285145,0.951877 -2.0983795,1.106145 -0.2572454,0.0488 -0.8655971,0.08281 -1.0620702,0.05937 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="EditorLayout.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 17,16.88 c 0.56,0 1,0.44 1,1 0,0.56 -0.44,1 -1,1 -0.56,0 -1,-0.45 -1,-1 0,-0.55 0.44,-1 1,-1 m 0,-3 c 2.73,0 5.06,1.66 6,4 -0.94,2.34 -3.27,4 -6,4 -2.73,0 -5.06,-1.66 -6,-4 0.94,-2.34 3.27,-4 6,-4 m 0,1.5 c -1.38,0 -2.5,1.12 -2.5,2.5 0,1.38 1.12,2.5 2.5,2.5 1.38,0 2.5,-1.12 2.5,-2.5 0,-1.38 -1.12,-2.5 -2.5,-2.5 M 18,3 H 4 C 2.9,3 2,3.9 2,5 v 12 c 0,1.1 0.9,2 2,2 H 9.42 C 9.26,18.68 9.12,18.34 9,18 9.12,17.66 9.26,17.32 9.42,17 H 4 v -4 h 6 v 2.97 c 0.55,-0.86 1.23,-1.6 2,-2.21 V 13 h 1.15 c 1.16,-0.64 2.47,-1 3.85,-1 1.06,0 2.07,0.21 3,0.59 V 5 C 20,3.9 19.1,3 18,3 m -8,8 H 4 V 7 h 6 v 4 m 8,0 H 12 V 7 h 6 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 3.6628462,18.954277 C 2.9389876,18.812286 2.3759743,18.324642 2.1168369,17.615228 l -0.081394,-0.222823 -0.00795,-6.31273 C 2.0187833,4.1608898 2.0079771,4.5989137 2.1975777,4.1854184 2.4627257,3.6071637 3.0327014,3.1622473 3.6490655,3.0524039 4.0078744,2.98846 18.006733,2.9865703 18.3391,3.050421 c 0.772499,0.1484042 1.363905,0.6920224 1.57275,1.4456672 0.06203,0.2238257 0.06283,0.2770438 0.06283,4.1387442 0,2.1516016 -0.01025,3.9119406 -0.02278,3.9118636 -0.01253,-7.7e-5 -0.130705,-0.04212 -0.262607,-0.09342 -0.298338,-0.116046 -1.048666,-0.308327 -1.491824,-0.3823 -0.478751,-0.07991 -1.886507,-0.08033 -2.36962,-7.01e-4 -0.888588,0.146464 -1.949529,0.494282 -2.526929,0.828427 -0.122446,0.07086 -0.147925,0.07345 -0.721519,0.07345 h -0.59459 v 0.389632 0.389632 l -0.205063,0.164798 c -0.480657,0.386278 -1.187873,1.161369 -1.598081,1.751459 l -0.15635,0.22491 -0.0079,-1.460216 -0.0079,-1.460215 H 7.00224 3.9949367 v 2.020253 2.020253 h 2.6886076 c 1.4807347,0 2.6886076,0.01174 2.6886076,0.02613 0,0.01437 -0.052575,0.140828 -0.1168326,0.281013 -0.064258,0.140185 -0.1534676,0.351781 -0.1982437,0.470213 l -0.081411,0.215332 0.134109,0.333693 c 0.07376,0.183531 0.1629697,0.390265 0.1982436,0.459407 0.035274,0.06914 0.064135,0.13993 0.064135,0.157305 0,0.03934 -5.5084997,0.03791 -5.7093057,-0.0015 z M 10.010127,9.0075949 V 6.9873418 H 7.0025316 3.9949367 v 2.0202531 2.0202531 h 3.0075949 3.0075954 z m 7.989873,0 V 6.9873418 H 14.992405 11.98481 V 9.0075949 11.027848 H 14.992405 18 Z"
id="path2" />
<path
style="fill:#2196f3;stroke-width:0.000911392;fill-opacity:1"
d="m 16.426066,21.8414 c -1.029487,-0.09183 -2.15905,-0.487628 -3.013408,-1.055912 -0.958091,-0.637283 -1.676676,-1.447469 -2.190361,-2.46958 -0.23281,-0.463235 -0.231597,-0.392375 -0.01432,-0.836503 0.780517,-1.595445 2.19126,-2.786582 3.914876,-3.305459 1.824557,-0.549264 3.823645,-0.266322 5.413859,0.766254 1.009506,0.655504 1.846896,1.618122 2.329721,2.67812 l 0.123713,0.2716 -0.186695,0.378922 c -0.715355,1.451907 -1.925808,2.556638 -3.464893,3.162265 -0.353851,0.13924 -0.974949,0.300502 -1.400537,0.363635 -0.41,0.06082 -1.110727,0.08244 -1.511952,0.04666 z m 1.285326,-1.547018 c 0.362606,-0.115278 0.723028,-0.320767 0.974453,-0.55557 0.376823,-0.351912 0.585002,-0.684396 0.730974,-1.167446 0.07096,-0.234832 0.08086,-0.319606 0.08086,-0.692885 0,-0.373279 -0.0099,-0.458053 -0.08086,-0.692885 -0.213191,-0.705491 -0.660219,-1.237582 -1.315696,-1.566056 -0.446454,-0.223727 -1.086544,-0.305521 -1.591507,-0.20337 -1.296023,0.262177 -2.165591,1.462516 -2.003867,2.766108 0.133179,1.073496 0.897442,1.909623 1.975264,2.161001 0.268477,0.06262 0.966925,0.03486 1.230379,-0.0489 z"
id="path3" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="m 16.70278,18.811229 c -0.316978,-0.113491 -0.534483,-0.329272 -0.63793,-0.632872 -0.06423,-0.188514 -0.04057,-0.52591 0.0503,-0.717166 0.224074,-0.471628 0.817052,-0.692295 1.278645,-0.475827 0.222808,0.104487 0.362138,0.230984 0.471128,0.427734 0.08235,0.148668 0.08951,0.185873 0.08951,0.465383 0,0.280009 -0.0071,0.316545 -0.09017,0.466597 -0.228247,0.412084 -0.739454,0.617254 -1.161479,0.466151 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuExit.svg"
inkscape:export-filename="MenuExit.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 16.56,5.44 15.11,6.89 C 16.84,7.94 18,9.83 18,12 A 6,6 0 0 1 12,18 6,6 0 0 1 6,12 C 6,9.83 7.16,7.94 8.88,6.88 L 7.44,5.44 C 5.36,6.88 4,9.28 4,12 a 8,8 0 0 0 8,8 8,8 0 0 0 8,-8 C 20,9.28 18.64,6.88 16.56,5.44 M 13,3 h -2 v 10 h 2"
id="path1"
style="display:none" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 11.027848,7.9898734 V 3.0075949 H 12 12.972152 V 7.9898734 12.972152 H 12 11.027848 Z"
id="path2" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 11.483544,19.971955 C 9.8107382,19.827359 8.4589975,19.316458 7.1544304,18.335732 6.7622016,18.040868 6.1094976,17.412088 5.8125524,17.043038 4.2172283,15.060333 3.6483077,12.521526 4.2535688,10.086076 4.5271077,8.9854095 5.0846047,7.8669471 5.796735,6.9901428 6.2034945,6.4893236 6.8584218,5.867662 7.2976448,5.5654686 L 7.4325955,5.47262 8.1375035,6.1780069 8.8424114,6.8833938 8.6515853,7.0100589 C 8.1575572,7.3379815 7.5531172,7.9103006 7.1897423,8.3942176 5.3936935,10.786068 5.6335239,14.13677 7.7526498,16.258673 c 0.8070945,0.808152 1.8532809,1.377097 2.9728442,1.616715 2.724802,0.583185 5.467865,-0.749608 6.683865,-3.24754 0.75664,-1.554305 0.801236,-3.397039 0.1206,-4.9832852 C 17.08339,8.6038174 16.316175,7.6748717 15.383287,7.0453651 L 15.151816,6.8891702 15.85961,6.1808951 16.567404,5.47262 16.702355,5.565469 c 0.445671,0.3066296 1.092038,0.9198545 1.500152,1.4232325 0.714301,0.8810363 1.27035,1.9965647 1.543924,3.0973745 0.51739,2.081873 0.171435,4.288308 -0.957433,6.106329 -0.431187,0.694418 -1.149237,1.514907 -1.74596,1.995043 -1.162736,0.935561 -2.51337,1.521243 -3.979747,1.725758 -0.337799,0.04711 -1.300276,0.08291 -1.579747,0.05875 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="ModeFill.svg"
inkscape:export-filename="ModeFill.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 19,11.5 c 0,0 -2,2.17 -2,3.5 a 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 c 0,-1.33 -2,-3.5 -2,-3.5 M 5.21,10 10,5.21 14.79,10 M 16.56,8.94 7.62,0 6.21,1.41 8.59,3.79 3.44,8.94 c -0.59,0.56 -0.59,1.53 0,2.12 l 5.5,5.5 C 9.23,16.85 9.62,17 10,17 c 0.38,0 0.77,-0.15 1.06,-0.44 l 5.5,-5.5 c 0.59,-0.59 0.59,-1.56 0,-2.12 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 9.6384167,16.935445 C 9.2507593,16.831044 9.3311247,16.904748 6.2494794,13.827439 4.6489715,12.229183 3.2990313,10.858896 3.2496123,10.782358 2.9759808,10.358565 2.9439713,9.8222203 3.1645435,9.356962 3.2507838,9.1750533 3.4690921,8.9482338 5.935137,6.4783528 L 8.6121138,3.7972123 7.4199281,2.6047401 6.2277427,1.4122681 6.9191742,0.72132696 7.6106054,0.03038582 12.18635,4.6101296 c 4.946784,4.9511086 4.666272,4.6522369 4.765743,5.0776651 0.05094,0.217859 0.02322,0.5789313 -0.06207,0.8084083 -0.03726,0.100253 -0.126339,0.264303 -0.197959,0.364556 -0.07162,0.100254 -1.406127,1.454641 -2.965573,3.009751 -3.053796,3.045304 -2.951675,2.952787 -3.383453,3.065251 -0.218479,0.05691 -0.492605,0.05678 -0.7046253,-3.16e-4 z M 14.794937,10.00246 c 0,-0.012572 -1.08,-1.1027925 -2.4,-2.4227132 l -2.4000003,-2.3998557 -2.4,2.3998557 c -1.32,1.3199207 -2.4,2.4101414 -2.4,2.4227132 0,0.01257 2.16,0.02286 4.8,0.02286 2.6400003,0 4.8000003,-0.01028 4.8000003,-0.02286 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="m 18.577215,16.939382 c -0.680512,-0.155967 -1.245308,-0.671972 -1.46342,-1.337 -0.1115,-0.339968 -0.117348,-0.781583 -0.01472,-1.111243 0.152218,-0.488929 0.388174,-0.944145 0.818843,-1.579747 0.257857,-0.380557 0.873709,-1.168293 1.01728,-1.301205 l 0.07651,-0.07083 0.203708,0.237915 c 0.82073,0.958542 1.502365,2.05586 1.68722,2.716139 0.341917,1.221288 -0.55616,2.430611 -1.839346,2.476806 -0.188483,0.0068 -0.372986,-0.0049 -0.486076,-0.03084 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuFlip.svg"
inkscape:export-filename="CtxMenuFlip.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,3 H 5 C 3.9,3 3,3.9 3,5 v 14 c 0,1.1 0.9,2 2,2 h 14 c 1.1,0 2,-0.9 2,-2 V 5 C 21,3.9 20.1,3 19,3 m 0,16 H 5 V 5 H 19 V 19 M 7,17 V 7 h 10"
id="path1"
style="display:none" />
<path
style="fill:#3f51b5;fill-opacity:1;stroke-width:0.000911392"
d="M 7.0177215,11.98481 V 7.0177215 H 11.99237 16.967019 L 12,11.98481 c -2.7318604,2.731899 -4.9704523,4.967089 -4.9746487,4.967089 -0.0042,0 -0.00763,-2.23519 -0.00763,-4.967089 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 4.7016725,20.961245 C 4.267274,20.887447 3.9471267,20.717838 3.6146444,20.385356 3.3313434,20.102055 3.2084459,19.901174 3.0939001,19.534177 L 3.0227848,19.306329 V 12 4.6936709 L 3.0939001,4.4658228 C 3.2084459,4.0988264 3.3313434,3.8979454 3.6146444,3.6146444 3.8979454,3.3313434 4.0988264,3.2084459 4.4658228,3.0939001 L 4.6936709,3.0227848 H 12 19.306329 l 0.227848,0.071115 c 0.336369,0.1049864 0.558748,0.2352187 0.817223,0.4785919 0.264385,0.2489368 0.423948,0.498034 0.543048,0.8477612 l 0.08277,0.2430379 v 7.3215192 7.321519 l -0.07112,0.227848 c -0.114546,0.366997 -0.237443,0.567878 -0.520744,0.851179 -0.27637,0.276369 -0.472973,0.398786 -0.835989,0.520537 l -0.212658,0.07132 -7.24557,0.0042 c -3.9850631,0.0023 -7.3103231,-0.0068 -7.3894665,-0.02021 z M 19.017722,12 V 4.9822785 H 12 4.9822785 V 12 19.017722 H 12 19.017722 Z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="Fps.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 12,20 a 7,7 0 0 1 -7,-7 7,7 0 0 1 7,-7 7,7 0 0 1 7,7 7,7 0 0 1 -7,7 M 19.03,7.39 20.45,5.97 C 20,5.46 19.55,5 19.04,4.56 L 17.62,6 C 16.07,4.74 14.12,4 12,4 a 9,9 0 0 0 -9,9 9,9 0 0 0 9,9 c 5,0 9,-4.03 9,-9 0,-2.12 -0.74,-4.07 -1.97,-5.61 M 11,14 h 2 V 8 H 11 M 15,1 H 9 v 2 h 6 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 11.559494,21.976745 C 9.2366601,21.824258 7.2312377,20.92933 5.6498876,19.339561 4.4903706,18.173871 3.6978661,16.781663 3.2945064,15.201818 3.0855265,14.383303 3.0405649,13.993908 3.0405649,13.002532 c 0,-0.974376 0.041245,-1.344609 0.2386026,-2.141773 C 4.0254815,7.846251 6.2538416,5.4370242 9.1898734,4.470306 11.628033,3.6675175 14.27658,3.9433558 16.47064,5.2285762 c 0.324285,0.1899575 0.791894,0.5076908 0.992585,0.6744479 l 0.14677,0.1219525 0.725448,-0.7249759 0.725448,-0.724976 0.68945,0.6923565 0.68945,0.6923565 -0.715183,0.7188653 -0.715184,0.7188654 0.194935,0.2582278 c 0.443839,0.5879499 0.864919,1.34137 1.146082,2.0506329 1.168831,2.9484999 0.685221,6.3188369 -1.265748,8.8211579 -0.312008,0.400184 -0.918673,1.030616 -1.297351,1.348177 -1.34102,1.124585 -2.960831,1.828669 -4.693671,2.040198 -0.376242,0.04593 -1.239898,0.0802 -1.534177,0.06088 z m 1.412658,-2.030248 c 1.523217,-0.221548 2.896644,-0.903423 3.968948,-1.970491 1.155296,-1.149656 1.855449,-2.610092 2.03248,-4.239514 0.05132,-0.472385 0.02063,-1.492758 -0.05772,-1.919086 C 18.610442,10.155588 17.818615,8.7523209 16.59014,7.6957862 15.576922,6.8243817 14.35627,6.2643363 13.016637,6.0562335 c -0.485325,-0.075392 -1.547951,-0.075392 -2.033276,0 -3.0598698,0.4753299 -5.3926186,2.7729217 -5.9113383,5.8222475 -0.067548,0.397086 -0.092665,1.424795 -0.045445,1.859449 0.2298566,2.115779 1.3493986,3.945802 3.1455732,5.141809 0.8214893,0.547 1.9689581,0.964431 2.9620251,1.07754 0.158734,0.01808 0.336456,0.03846 0.394937,0.04529 0.205651,0.02403 1.142637,-0.01238 1.443038,-0.05608 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 11.012658,10.997468 V 8.0202532 H 12 12.987342 v 2.9772148 2.977216 H 12 11.012658 Z"
id="path3" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 9.0075949,1.9898734 V 1.0025316 H 12 14.992405 V 1.9898734 2.9772152 H 12 9.0075949 Z"
id="path4" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 11.118987,19.941663 C 10.100265,19.804016 9.0041927,19.402853 8.2025316,18.874238 6.6932647,17.879029 5.6315772,16.386393 5.2101726,14.667253 c -0.1642962,-0.670254 -0.1909042,-0.954299 -0.173019,-1.847 0.014291,-0.713273 0.025165,-0.84783 0.095376,-1.180159 0.5883018,-2.7846026 2.6497191,-4.8686284 5.4244324,-5.4839252 0.860794,-0.1908823 2.00559,-0.1924705 2.870886,-0.00398 1.605781,0.3497874 3.043812,1.2318922 4.035893,2.4756623 0.783336,0.9820682 1.360798,2.3582019 1.476949,3.5196749 0.04768,0.476751 0.0394,1.445854 -0.01557,1.823262 -0.227282,1.560489 -0.907233,2.907085 -2.022542,4.005505 -0.173382,0.170756 -0.410936,0.387143 -0.527898,0.48086 -1.046457,0.838478 -2.446606,1.40267 -3.728361,1.502346 -0.506703,0.0394 -1.160196,0.03177 -1.527336,-0.01783 z m 1.868355,-8.944195 V 8.0202532 H 12 11.012658 v 2.9772148 2.977216 H 12 12.987342 Z"
id="path5" />
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="PanelGoto.svg"
inkscape:export-filename="PanelGoto.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 21.5,14.5 16,20 10.5,14.5 11.91,13.09 15,16.17 V 10.5 C 15,8 13,6 10.5,6 H 4 V 4 h 6.5 c 3.59,0 6.5,2.91 6.5,6.5 v 5.67 l 3.09,-3.09 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="m 13.253009,17.232756 -2.726611,-2.726738 0.691231,-0.688453 0.691232,-0.688453 1.549367,1.530278 1.549367,1.530277 0.0084,-2.892302 c 0.0084,-2.903059 -0.0011,-3.258546 -0.10094,-3.7480135 C 14.59614,7.9853538 13.422815,6.6882122 11.885867,6.200489 11.238599,5.99509 11.451241,6.0052622 7.556962,5.9934063 L 4.0253165,5.9826543 V 4.9963905 4.0101266 l 3.349367,2.54e-5 c 2.0210801,1.53e-5 3.4818945,0.01223 3.6835445,0.030799 2.776522,0.255683 5.083884,2.234982 5.736727,4.9210744 0.185474,0.7631204 0.181307,0.675357 0.194601,4.0990106 l 0.0122,3.142048 1.547237,-1.547014 1.547237,-1.547014 0.691052,0.691052 0.691051,0.691051 -2.73404,2.734167 c -1.503723,1.503792 -2.740933,2.734168 -2.749357,2.734168 -0.0084,0 -1.242292,-1.227032 -2.741928,-2.726738 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuNewFile.svg"
inkscape:export-filename="MenuNewFile.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 14,2 H 6 C 4.89,2 4,2.89 4,4 v 16 c 0,1.11 0.89,2 2,2 h 7.81 C 13.28,21.09 13,20.05 13,19 c 0,-3.31 2.69,-6 6,-6 0.34,0 0.67,0.03 1,0.08 V 8 L 14,2 M 13,9 V 3.5 L 18.5,9 H 13 m 10,11 h -3 v 3 h -2 v -3 h -3 v -2 h 3 v -3 h 2 v 3 h 3 z"
id="path1"
style="display:none" />
<path
style="fill:#4caf50;fill-opacity:1;stroke-width:0.000911392"
d="M 18.01519,21.493671 V 19.989873 H 16.511392 15.007595 V 19.002532 18.01519 h 1.503797 1.503798 v -1.503798 -1.503797 h 0.987342 0.987341 v 1.503797 1.503798 h 1.503798 1.503797 v 0.987342 0.987341 h -1.503797 -1.503798 v 1.503798 1.503797 H 19.002532 18.01519 Z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 5.7231554,21.964593 C 5.0649017,21.868122 4.4967329,21.444414 4.206714,20.833717 3.9965657,20.391204 4.0101266,21.000565 4.0101266,12 4.0101266,2.9994351 3.9965657,3.6087955 4.206714,3.166283 4.4095389,2.7391915 4.7390089,2.4076824 5.1564049,2.2107145 5.5843531,2.0087671 5.2444359,2.0231706 9.8269571,2.0128067 l 4.1611339,-0.00941 3.000891,3.0007762 3.000891,3.0007762 V 10.53412 c 0,1.391044 -0.01025,2.5289 -0.02278,2.528569 -0.01253,-3.31e-4 -0.118481,-0.01476 -0.235443,-0.03206 -0.329369,-0.04873 -1.196627,-0.03938 -1.579747,0.01702 -0.899658,0.132444 -1.723073,0.443021 -2.44705,0.922983 -1.838362,1.218744 -2.854125,3.269382 -2.69952,5.449834 0.05464,0.770674 0.252975,1.511861 0.587966,2.197302 l 0.184334,0.377173 -3.949574,-0.0038 c -2.1722658,-0.0021 -4.0194705,-0.01403 -4.1048996,-0.02655 z M 18.501266,9.0000626 c 0,-0.029792 -5.476475,-5.5063917 -5.506266,-5.5063917 -0.01257,0 -0.02285,1.2440506 -0.02285,2.7645569 v 2.764557 h 2.764557 c 1.520506,0 2.764557,-0.010225 2.764557,-0.022722 z"
id="path3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 13.002532,6.2658864 V 3.5393678 l 2.718987,2.71886 c 1.495443,1.4953732 2.718987,2.7223064 2.718987,2.7265188 0,0.00421 -1.223544,0.00766 -2.718987,0.00766 h -2.718987 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="PanelNextItem.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
inkscape:export-filename="PanelNextItem.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="true"
inkscape:zoom="23.275598"
inkscape:cx="9.537886"
inkscape:cy="10.354192"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 8,5 V 19 L 19,12 Z"
id="path1"
inkscape:transform-center-y="-0.002224505"
inkscape:transform-center-x="-1.5019817"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.0012889"
d="m 8.0126835,12.013226 c 0,-3.8189466 0.010012,-6.9435389 0.022248,-6.9435389 0.032125,0 10.7723235,6.8300949 10.8382665,6.8924599 0.05287,0.05 -0.784932,0.589638 -10.7638468,6.933166 l -0.096668,0.06145 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="PanelNextPage.svg"
inkscape:export-filename="PanelNextPage.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 13,6 v 12 l 8.5,-6 M 4,18 12.5,12 4,6 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="m 13.017722,12 c 0,-4.7586168 0.0076,-5.9533143 0.03797,-5.9346594 C 13.256963,6.189132 21.432911,11.981208 21.432911,12 c 0,0.01879 -8.175948,5.810868 -8.377215,5.93466 -0.03033,0.01865 -0.03797,-1.176043 -0.03797,-5.93466 z"
id="path2" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 4.0253165,12 V 6.042519 L 4.2771548,6.2187279 C 6.0250855,7.4417381 12.440506,11.985129 12.440506,12 c 0,0.01487 -6.4154205,4.558262 -8.1633512,5.781272 l -0.2518383,0.176209 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="Ok.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 21,7 9,19 3.5,13.5 4.91,12.09 9,16.17 19.59,5.59 Z"
id="path1"
style="display:none" />
<path
style="fill:#4caf50;fill-opacity:1;stroke-width:0.000911392"
d="m 6.2582379,16.222795 -2.7340405,-2.734167 0.6910654,-0.691066 0.6910654,-0.691065 2.0445697,2.044402 2.0445697,2.044401 5.2997344,-5.285057 5.299735,-5.2850569 0.691248,0.6885345 0.691249,0.6885344 -5.977296,5.977354 c -3.287512,3.287544 -5.9841722,5.977353 -5.9925774,5.977353 -0.00841,0 -1.2456003,-1.230375 -2.7493227,-2.734167 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuOpenFile.svg"
inkscape:export-filename="MenuOpenFile.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 14,17 h 4 v -3 l 5,4.5 -5,4.5 V 20 H 14 V 17 M 13,9 h 5.5 L 13,3.5 V 9 M 6,2 h 8 l 6,6 v 4.34 C 19.37,12.12 18.7,12 18,12 a 6,6 0 0 0 -6,6 c 0,1.54 0.58,2.94 1.53,4 H 6 C 4.89,22 4,21.1 4,20 V 4 A 2,2 0 0 1 6,2 Z"
id="path1"
style="display:none" />
<path
style="fill:#ffc107;fill-opacity:1;stroke-width:0.000911392"
d="m 18.01519,21.466997 v -1.477124 h -2.005063 -2.005064 v -1.488607 -1.488608 h 2.005064 2.005063 v -1.473417 c 0,-0.81038 0.007,-1.473418 0.01559,-1.473418 0.01983,0 4.919289,4.408316 4.926435,4.432586 0.0052,0.01757 -4.766711,4.321005 -4.883428,4.404031 -0.05764,0.041 -0.05859,0.01764 -0.05859,-1.435443 z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 5.7229753,21.964571 C 5.074628,21.869571 4.5128542,21.454279 4.2229787,20.855696 3.9933439,20.381508 4.0101266,21.079751 4.0101266,12 c 0,-7.2585787 0.00515,-8.1698005 0.047396,-8.3784959 C 4.2014983,2.9101856 4.7097321,2.3446116 5.4221443,2.1029223 l 0.2436785,-0.082669 4.1611343,-0.00843 4.1611339,-0.00843 3.000891,3.0007762 3.000891,3.0007762 v 2.1494253 c 0,1.182183 -0.0066,2.149424 -0.01473,2.149424 -0.0081,0 -0.131448,-0.03382 -0.274102,-0.07516 C 19.076806,12.047738 18.817622,12.015264 18,12.015505 c -0.606372,1.79e-4 -0.814618,0.01117 -1.032911,0.05451 -0.637588,0.126594 -1.158106,0.29979 -1.654403,0.550481 -1.785893,0.902096 -2.98371,2.56686 -3.269503,4.544059 -0.07684,0.531584 -0.04662,1.519558 0.06226,2.035443 0.201397,0.954269 0.62043,1.83632 1.240878,2.612007 l 0.14632,0.18293 -3.807079,-0.0038 c -2.0938934,-0.0021 -3.8770565,-0.01404 -3.9625847,-0.02658 z M 18.501266,9.0000626 c 0,-0.029792 -5.476475,-5.5063917 -5.506266,-5.5063917 -0.01257,0 -0.02285,1.2440506 -0.02285,2.7645569 v 2.764557 h 2.764557 c 1.520506,0 2.764557,-0.010225 2.764557,-0.022722 z"
id="path3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="m 12.986049,6.3007054 c 0.01233,-1.5020968 0.02848,-2.7373462 0.0359,-2.7449986 0.0074,-0.00765 1.232463,1.205074 2.722337,2.6949474 1.489873,1.4898735 2.702599,2.7150553 2.694947,2.7226262 -0.0077,0.00757 -1.242794,0.023833 -2.744758,0.036138 l -2.730845,0.022372 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuPaste.svg"
inkscape:export-filename="CtxMenuPaste.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,20 H 5 V 4 H 7 V 7 H 17 V 4 h 2 M 12,2 a 1,1 0 0 1 1,1 1,1 0 0 1 -1,1 1,1 0 0 1 -1,-1 1,1 0 0 1 1,-1 m 7,0 H 14.82 C 14.4,0.84 13.3,0 12,0 10.7,0 9.6,0.84 9.18,2 H 5 A 2,2 0 0 0 3,4 v 16 a 2,2 0 0 0 2,2 h 14 a 2,2 0 0 0 2,-2 V 4 A 2,2 0 0 0 19,2 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 4.6632911,21.950184 C 4.2268111,21.868691 3.8877991,21.686743 3.5789666,21.368228 3.36184,21.144293 3.2110821,20.894168 3.1052522,20.582278 L 3.0227848,20.339241 V 12.01519 3.6911392 L 3.0939001,3.4632911 C 3.2001914,3.1227418 3.3327427,2.8963128 3.5742111,2.6428064 3.8242417,2.3803111 4.0748069,2.220536 4.4202532,2.1033201 l 0.2430379,-0.082467 2.2669352,-0.00932 2.2669355,-0.00932 0.082135,-0.193257 C 9.5887112,1.0809277 10.307018,0.42349258 11.071849,0.16830592 c 0.56997,-0.19017118 1.286332,-0.19017118 1.856302,0 0.769125,0.25661946 1.481401,0.90853418 1.792552,1.64064498 l 0.08213,0.193257 2.266936,0.00932 2.266935,0.00932 0.243038,0.082467 c 0.345446,0.1172159 0.596011,0.276991 0.846042,0.5394863 0.241468,0.2535064 0.37402,0.4799354 0.480311,0.8204847 l 0.07112,0.2278481 v 8.324051 8.324051 l -0.08277,0.243037 c -0.22551,0.662191 -0.73113,1.145497 -1.40584,1.343799 -0.171654,0.05045 -0.602836,0.05387 -7.397469,0.05869 -5.8281042,0.0041 -7.2560721,-0.0025 -7.4278479,-0.03459 z M 19.017722,12 V 3.9797468 H 18 16.982278 V 5.4835443 6.9873418 H 12 7.0177215 V 5.4835443 3.9797468 H 6 4.9822785 V 12 20.020253 H 12 19.017722 Z M 12.449139,3.9079458 c 0.202764,-0.1037909 0.370168,-0.2703269 0.464595,-0.4621865 0.06309,-0.1281919 0.07357,-0.1929555 0.07334,-0.4533542 -3.02e-4,-0.3450317 -0.04456,-0.4637025 -0.260198,-0.69764 -0.37006,-0.4014675 -1.083698,-0.4014675 -1.453758,0 -0.215636,0.2339375 -0.259896,0.3526083 -0.260198,0.69764 -2.23e-4,0.2564138 0.01069,0.3260336 0.06996,0.4463638 0.121718,0.247111 0.365371,0.4532926 0.6437,0.544707 0.04177,0.01372 0.185317,0.020827 0.318988,0.015794 0.192389,-0.00724 0.276492,-0.026276 0.403569,-0.091324 z"
id="path2" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 4.9822784,12 V 3.9797468 H 5.9999999 7.0177214 V 5.4835442 6.9873417 H 12 16.982278 V 5.4835442 3.9797468 H 18 19.017721 V 12 20.020253 H 12 4.9822784 Z"
id="path3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 11.612187,3.9213539 C 11.419513,3.8312842 11.16675,3.5774443 11.088415,3.3953504 11.030824,3.2614767 11.02291,3.1976237 11.032946,2.9477766 11.046408,2.6126055 11.110835,2.4663946 11.333841,2.264922 11.536689,2.0816609 11.69942,2.0224222 12,2.0224222 c 0.300579,0 0.463311,0.059239 0.666159,0.2424998 0.223643,0.2020476 0.287421,0.3473823 0.301019,0.6859481 0.0106,0.2638115 0.004,0.3114177 -0.06338,0.4566332 -0.08589,0.1851411 -0.250012,0.3597039 -0.447166,0.4756166 -0.116185,0.068309 -0.177543,0.081194 -0.425316,0.089318 -0.239154,0.00784 -0.312097,-0.00105 -0.419129,-0.051084 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuPreference.svg"
inkscape:export-filename="MenuPreference.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 21.71,20.29 -1.42,1.42 a 1,1 0 0 1 -1.41,0 L 7,9.85 A 3.81,3.81 0 0 1 6,10 4,4 0 0 1 2.22,4.7 L 4.76,7.24 5.29,6.71 6.71,5.29 7.24,4.76 4.7,2.22 A 4,4 0 0 1 10,6 3.81,3.81 0 0 1 9.85,7 l 11.86,11.88 a 1,1 0 0 1 0,1.41 M 2.29,18.88 a 1,1 0 0 0 0,1.41 l 1.42,1.42 a 1,1 0 0 0 1.41,0 L 10.59,16.25 7.76,13.42 M 20,2 16,4 v 2 l -2.17,2.17 2,2 L 18,8 h 2 l 2,-4 z"
id="path1"
style="display:none" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="M 4.1902587,21.955067 C 4.1138883,21.933557 3.9908503,21.880036 3.916841,21.836133 3.8428316,21.79223 3.4241445,21.396456 2.9864251,20.956636 2.074956,20.040791 2.0228885,19.966387 2.0228885,19.579747 c 0,-0.438399 -0.1721945,-0.242777 2.9497228,-3.351029 l 2.7860088,-2.773813 1.3991711,1.399302 1.3991708,1.399302 -2.7797468,2.778202 c -2.4161228,2.414779 -2.8016394,2.788168 -2.9471058,2.854397 -0.2068738,0.09419 -0.4552461,0.120955 -0.6398507,0.06896 z"
id="path2" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="M 14.840498,9.144295 13.868693,8.1721343 14.93941,7.1010987 16.010127,6.0300632 V 5.0200643 4.0100654 l 1.989906,-0.9948148 1.989907,-0.9948147 0.994812,0.9948119 0.994812,0.994812 -0.994815,1.9899068 -0.994814,1.9899068 h -1.01032 -1.01032 l -1.062966,1.0632912 c -0.584631,0.5848101 -1.069954,1.0632914 -1.078496,1.0632914 -0.0085,0 -0.452843,-0.4374726 -0.987335,-0.972161 z"
id="path3" />
<path
style="fill:#4caf50;fill-opacity:1;stroke-width:0.000911392"
d="m 19.374212,21.963529 c -0.06292,-0.01573 -0.172285,-0.05741 -0.243038,-0.09262 -0.08953,-0.04455 -1.949592,-1.884038 -6.117275,-6.049589 L 7.025266,9.8357541 6.6797216,9.9050795 C 5.2431916,10.193285 3.6910988,9.5729016 2.7978637,8.3534707 2.0581241,7.3435896 1.8403523,6.0883935 2.1897537,4.8484378 L 2.2231877,4.7297869 3.4888991,5.9952292 4.7546104,7.2606714 6.0076411,6.0076411 7.2606714,4.7546104 5.9958465,3.4895164 4.7310213,2.2244223 4.8946246,2.1773954 c 0.7640425,-0.2196198 1.635711,-0.1989949 2.3836361,0.0564 1.8540188,0.633095 3.0019763,2.575993 2.6268312,4.4458635 l -0.069313,0.3454825 5.9990491,6.0038846 c 6.674895,6.680277 6.140027,6.109775 6.141549,6.550721 0.0013,0.387242 -0.04898,0.458823 -0.977983,1.391294 -0.671366,0.673871 -0.842446,0.829454 -0.993331,0.903354 -0.20203,0.09895 -0.450924,0.134115 -0.630851,0.08913 z"
id="path4" />
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="PanelPrevItem.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
inkscape:export-filename="PanelPrevItem.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="true"
inkscape:zoom="16.458333"
inkscape:cx="8.9316458"
inkscape:cy="13.367089"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="24"
spacingy="24"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<path
d="m 15.996037,19.004449 v -14 l -11.0000004,7 z"
id="path1"
inkscape:transform-center-y="0.002224495"
inkscape:transform-center-x="1.5019815"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.00182278"
d="M 10.557478,15.503251 C 7.642065,13.643299 5.2144231,12.094177 5.162718,12.06076 5.0888479,12.013017 6.2035397,11.2776 10.366082,8.6278483 13.279637,6.7731647 15.727785,5.2206459 15.806411,5.1778064 l 0.142956,-0.07789 V 11.99806 c 0,3.793979 -0.02051,6.895618 -0.04557,6.892532 -0.02506,-0.0031 -2.430907,-1.527389 -5.346319,-3.387341 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="PanelPreviousPage.svg"
inkscape:export-filename="PanelPreviousPage.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 11.5,12 20,18 V 6 M 11,18 V 6 l -8.5,6 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 15.767089,14.98795 C 13.461266,13.360227 11.574684,12.01565 11.574684,12 c 0,-0.01565 1.886582,-1.360227 4.192405,-2.9879504 l 4.192405,-2.9594967 0.0077,2.9737235 c 0.0043,1.6355476 0.0043,4.3118996 0,5.9474476 l -0.0077,2.973723 z"
id="path2" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 6.7746835,14.993342 C 4.4688608,13.365705 2.5822785,12.018701 2.5822785,12 c 0,-0.0187 1.8865823,-1.365705 4.192405,-2.993342 l 4.1924055,-2.9593398 0.0077,2.9763409 c 0.0043,1.6369879 0.0043,4.3156939 0,5.9526819 l -0.0077,2.976341 z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuRedo.svg"
inkscape:export-filename="MenuRedo.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 18.4,10.6 C 16.55,9 14.15,8 11.5,8 6.85,8 2.92,11.03 1.54,15.22 L 3.9,16 c 1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88 L 13,16 h 9 V 7 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 2.7149443,15.589087 C 1.6314354,15.229913 1.5581357,15.201132 1.582197,15.144304 c 0.014149,-0.03342 0.075457,-0.197469 0.1362403,-0.364557 0.1437606,-0.39519 0.5582255,-1.25107 0.8017802,-1.655696 0.7359854,-1.222719 1.7580153,-2.330396 2.910895,-3.1548305 1.4690576,-1.0505361 3.0435223,-1.6554478 4.9283815,-1.8934917 0.495557,-0.062585 1.889393,-0.05369 2.4,0.015316 2.013831,0.2721609 3.865093,1.0694667 5.383751,2.3186862 0.128912,0.10604 0.245071,0.192801 0.258133,0.192801 0.01306,0 0.826955,-0.8031216 1.808653,-1.784714 l 1.784906,-1.7847136 v 4.4733216 4.473321 h -4.473321 -4.473322 l 1.784714,-1.784906 c 0.981592,-0.981698 1.784714,-1.799405 1.784714,-1.817127 0,-0.08677 -0.96885,-0.742141 -1.492691,-1.00972 -2.478931,-1.266245 -5.4186815,-1.160131 -7.7858647,0.28104 -1.0292476,0.626619 -1.9969756,1.582614 -2.6463403,2.614257 -0.2108992,0.335054 -0.5513616,1.028996 -0.6856274,1.397468 -0.054796,0.15038 -0.1073135,0.282179 -0.1167051,0.292885 -0.00939,0.01071 -0.5383888,-0.153343 -1.1755492,-0.364557 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuReportBug.svg"
inkscape:export-filename="MenuReportBug.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 14,12 h -4 v -2 h 4 m 0,6 h -4 v -2 h 4 M 20,8 H 17.19 C 16.74,7.22 16.12,6.55 15.37,6.04 L 17,4.41 15.59,3 13.42,5.17 C 12.96,5.06 12.5,5 12,5 11.5,5 11.04,5.06 10.59,5.17 L 8.41,3 7,4.41 8.62,6.04 C 7.88,6.55 7.26,7.22 6.81,8 H 4 v 2 H 6.09 C 6.04,10.33 6,10.66 6,11 v 1 H 4 v 2 h 2 v 1 c 0,0.34 0.04,0.67 0.09,1 H 4 v 2 h 2.81 c 1.04,1.79 2.97,3 5.19,3 2.22,0 4.15,-1.21 5.19,-3 H 20 V 16 H 17.91 C 17.96,15.67 18,15.34 18,15 v -1 h 2 v -2 h -2 v -1 c 0,-0.34 -0.04,-0.67 -0.09,-1 H 20 Z"
id="path1"
style="display:none" />
<path
style="fill:#f44336;fill-opacity:1;stroke-width:0.000911392"
d="M 11.44457,20.960684 C 10.268963,20.837699 9.160419,20.381815 8.2481013,19.646148 7.784009,19.271918 7.2132188,18.625426 6.9087535,18.129168 l -0.0885,-0.144249 -1.4050633,-5.4e-5 -1.4050633,-5.5e-5 v -0.987342 -0.987341 h 1.0514822 1.0514823 l -0.018275,-0.09874 c -0.050465,-0.272649 -0.078625,-0.737704 -0.0791,-1.306329 L 6.0151899,13.974684 H 5.0126582 4.0101266 V 12.987342 12 h 1.0025316 1.0025317 l 2.492e-4,-0.63038 c 2.227e-4,-0.56308 0.026451,-0.982946 0.079706,-1.275949 L 6.1130911,9.994937 H 5.0616088 4.0101266 V 9.0075949 8.0202532 H 5.4156872 6.8212477 L 6.9239757,7.8485034 C 7.2396784,7.3206838 7.8820183,6.612072 8.3792926,6.243038 8.514384,6.1427848 8.6221558,6.0522939 8.6187858,6.041947 8.6154155,6.0316002 8.2640506,5.6647865 7.8379747,5.2268056 7.4118987,4.7888247 7.0598449,4.4212554 7.055633,4.4099851 7.0514209,4.3987147 7.3556193,4.0820767 7.7316298,3.7063449 L 8.415285,3.0231963 9.5013132,4.1061441 10.587342,5.1890918 10.860759,5.1319439 c 0.740234,-0.1547187 1.548142,-0.1549796 2.286406,-7.385e-4 l 0.265493,0.055468 1.086114,-1.0818234 1.086113,-1.0818234 0.690953,0.6909526 0.690952,0.6909526 -0.801063,0.8014914 c -0.440585,0.4408203 -0.795961,0.8154163 -0.789724,0.8324356 0.0062,0.017019 0.141212,0.1309264 0.299946,0.2531271 0.511384,0.3936857 1.087946,1.0346713 1.400075,1.5565176 l 0.102728,0.1717498 h 1.405561 1.40556 V 9.007595 9.9949368 h -1.051482 -1.051482 l 0.01795,0.098734 c 0.05326,0.293003 0.07948,0.712869 0.07971,1.275949 L 17.98481,12 h 1.002532 1.002531 v 0.987342 0.987342 H 18.987342 17.98481 l -5.26e-4,0.630379 c -4.75e-4,0.568625 -0.02863,1.03368 -0.0791,1.306329 l -0.01827,0.09874 h 1.051482 1.051482 v 0.987341 0.987342 l -1.405063,5.5e-5 -1.405063,5.4e-5 -0.0895,0.144249 c -0.927305,1.494579 -2.467675,2.515394 -4.203906,2.785961 -0.388738,0.06058 -1.087199,0.08265 -1.441772,0.04556 z m 2.560493,-5.968279 V 13.974684 H 12 9.9949367 v 1.017721 1.017722 H 12 14.005063 Z m 0,-3.994937 V 9.9949367 H 12 9.9949367 V 10.997468 12 H 12 14.005063 Z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuSaveFile.svg"
inkscape:export-filename="MenuSaveFile.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 17,3 H 5 C 3.89,3 3,3.9 3,5 v 14 c 0,1.1 0.89,2 2,2 h 14 c 1.1,0 2,-0.9 2,-2 V 7 L 17,3 m 2,16 H 5 V 5 H 16.17 L 19,7.83 V 19 m -7,-7 c -1.66,0 -3,1.34 -3,3 0,1.66 1.34,3 3,3 1.66,0 3,-1.34 3,-3 0,-1.66 -1.34,-3 -3,-3 M 6,6 h 9 v 4 H 6 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 4.6481013,20.947504 C 3.8865883,20.806355 3.27429,20.234416 3.0826937,19.485282 3.02389,19.255361 3.0227848,19.117279 3.0227848,12 c 0,-7.1172787 0.00111,-7.2553613 0.059909,-7.4852816 C 3.2491494,3.8638828 3.7253235,3.3531532 4.3862962,3.116515 l 0.2618051,-0.09373 6.1670887,-0.00796 6.167088,-0.00796 1.99783,1.9982769 1.997829,1.9982767 -0.008,6.1970214 -0.008,6.197021 -0.06755,0.197469 c -0.173999,0.508649 -0.543132,0.933861 -1.012981,1.166875 -0.194894,0.09666 -0.3643,0.155927 -0.529595,0.185294 -0.345134,0.06132 -14.3730779,0.0617 -14.7037977,3.98e-4 z M 19.002532,13.405185 V 7.7926475 L 17.597591,6.387463 16.19265,4.9822785 H 10.595059 4.9974684 V 12 19.017722 H 12 19.002532 Z"
id="path2" />
<path
style="fill:#2196f3;stroke-width:0.000911392;fill-opacity:1"
d="M 6,8.0050633 V 6.0151899 h 4.496203 4.496202 V 8.0050633 9.9949367 H 10.496203 6 Z"
id="path3" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="M 11.490833,17.936734 C 10.558851,17.768231 9.7576781,17.174304 9.3427367,16.344304 9.1105368,15.879838 9.0247064,15.502363 9.0284344,14.962025 c 0.00414,-0.600204 0.1488872,-1.085652 0.4731877,-1.586969 0.4386874,-0.678142 1.1902739,-1.174683 1.9891259,-1.314132 0.243434,-0.04249 0.77507,-0.04249 1.018504,0 0.798852,0.139449 1.550438,0.63599 1.989126,1.314132 0.324301,0.501317 0.469047,0.986765 0.473188,1.586969 0.0037,0.540338 -0.0821,0.917813 -0.314303,1.382279 -0.579581,1.159326 -1.897109,1.821925 -3.16643,1.59243 z"
id="path4" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 5.0278481,12 V 5.0126582 h 5.5672109 5.567211 l 1.404941,1.4051845 1.404941,1.4051845 v 5.5821578 5.582157 H 12 5.0278481 Z M 12.42946,17.982311 C 14.034247,17.759106 15.184307,16.266379 14.992167,14.65603 14.866121,13.599616 14.233134,12.718538 13.279008,12.271419 12.816401,12.054634 12.619509,12.01519 12,12.01519 c -0.481116,0 -0.575978,0.0084 -0.789322,0.07019 -1.2141457,0.351465 -2.0552376,1.333709 -2.203115,2.572844 -0.1466226,1.228622 0.4848225,2.424631 1.587579,3.007006 0.55892,0.29517 1.197809,0.405608 1.834318,0.317077 z M 15.022785,8.0050633 V 5.9848101 H 10.511392 6 v 2.0202532 2.0202527 h 4.511392 4.511393 z"
id="path5" />
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuSaveFileAs.svg"
inkscape:export-filename="MenuSaveFileAs.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 1,7 h 2 v 14 h 14 v 2 H 3 C 1.9,23 1,22.11 1,21 V 7 M 19,1 H 7 C 5.89,1 5,1.9 5,3 v 14 c 0,1.1 0.89,2 2,2 h 14 c 1.1,0 2,-0.9 2,-2 V 5 L 19,1 m 2,16 H 7 V 3 H 18.17 L 21,5.83 V 17 m -7,-7 c -1.66,0 -3,1.34 -3,3 0,1.66 1.34,3 3,3 1.66,0 3,-1.34 3,-3 0,-1.66 -1.34,-3 -3,-3 M 8,4 h 9 V 8 H 8 Z"
id="path1"
style="display:none" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 7.0025316,9.9949367 V 3.0075949 h 5.5672094 5.56721 l 1.420132,1.4203731 1.420132,1.4203731 V 11.41531 16.982278 H 13.989873 7.0025316 Z m 7.7468354,5.9261113 c 0.286349,-0.07445 0.737718,-0.276533 0.961429,-0.430451 0.250881,-0.17261 0.615684,-0.545602 0.79031,-0.808048 0.390391,-0.586722 0.56107,-1.268707 0.494256,-1.974915 -0.08581,-0.906972 -0.564475,-1.70851 -1.321945,-2.213628 -0.286251,-0.190886 -0.495771,-0.288228 -0.859081,-0.399127 -0.238938,-0.07294 -0.310042,-0.08032 -0.794083,-0.08243 -0.631191,-0.0028 -0.860528,0.04561 -1.351899,0.28513 -0.776631,0.378566 -1.36166,1.093044 -1.585604,1.936451 -0.109627,0.412874 -0.116209,1.072271 -0.0148,1.482426 0.09037,0.36551 0.346886,0.879986 0.592328,1.188009 0.421818,0.529371 1.095641,0.931046 1.778174,1.059995 0.33991,0.06422 0.978233,0.04308 1.310911,-0.04341 z M 17.027848,6 V 3.9797468 H 12.501266 7.9746835 V 6 8.0202532 h 4.5265825 4.526582 z"
id="path2" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="M 8.0050633,6 V 4.0101266 h 4.4962027 4.496202 V 6 7.9898734 H 12.501266 8.0050633 Z"
id="path3" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="m 13.46204,15.93254 c -1.151985,-0.228895 -2.047547,-1.062521 -2.348099,-2.185705 -0.07132,-0.266512 -0.08119,-0.359724 -0.08045,-0.759493 6.75e-4,-0.364973 0.01344,-0.502119 0.06413,-0.688874 0.243972,-0.898869 0.78919,-1.572083 1.594797,-1.969191 0.47737,-0.23531 0.697894,-0.284025 1.297453,-0.286609 0.599805,-0.0026 0.841557,0.04981 1.321519,0.286439 1.828574,0.901505 2.235899,3.332506 0.799117,4.769288 -0.569361,0.569362 -1.329675,0.884187 -2.120636,0.878098 -0.175443,-0.0014 -0.412968,-0.02113 -0.527833,-0.04395 z"
id="path4" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 6.5924051,18.937654 C 6.475443,18.912845 6.2635443,18.836958 6.121519,18.769016 5.7717106,18.601676 5.399597,18.233068 5.2324088,17.888281 5.0126187,17.435016 5.0287949,18.060674 5.0282971,9.9937246 5.0277967,1.8835908 5.0086084,2.5810792 5.2455337,2.0972309 5.4753857,1.6278274 5.9505878,1.2407482 6.5012658,1.0743655 6.6742586,1.0220972 6.9969372,1.0188438 12.835443,1.0105028 l 6.151899,-0.00879 1.9979,1.9983946 1.9979,1.9983944 -0.008,6.1969512 -0.008,6.196951 -0.0814,0.222833 c -0.223615,0.612151 -0.657885,1.045139 -1.266922,1.263184 l -0.261805,0.09373 -7.275949,0.0053 c -6.3326448,0.0046 -7.3035202,-5.43e-4 -7.4886079,-0.0398 z M 21.007595,11.41531 V 5.8179615 L 19.587463,4.3975884 18.167331,2.9772152 h -5.59759 -5.5975891 v 7.0177215 7.0177213 h 7.0177211 7.017722 z"
id="path5" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 2.7261414,22.962677 C 2.3101478,22.903023 1.9164237,22.704352 1.6085974,22.398772 1.3780219,22.16988 1.2325673,21.937144 1.1186926,21.614898 l -0.085781,-0.242746 -0.00791,-7.177215 -0.00791,-7.1772155 h 0.9876536 0.9876537 v 7.0025315 7.002532 h 7.0025316 7.0025315 v 0.987342 0.987341 l -7.0405062,-0.0037 C 5.9787399,22.9916 2.8336781,22.978098 2.7261414,22.962677 Z"
id="path6" />
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuSaveFileThenRunGame.svg"
inkscape:export-filename="MenuSaveFileThenRunGame.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 6,9 h 2 v 2 h 2 v 2 H 8 v 2 H 6 V 13 H 4 V 11 H 6 V 9 M 18.5,9 A 1.5,1.5 0 0 1 20,10.5 1.5,1.5 0 0 1 18.5,12 1.5,1.5 0 0 1 17,10.5 1.5,1.5 0 0 1 18.5,9 m -3,3 A 1.5,1.5 0 0 1 17,13.5 1.5,1.5 0 0 1 15.5,15 1.5,1.5 0 0 1 14,13.5 1.5,1.5 0 0 1 15.5,12 M 17,5 a 7,7 0 0 1 7,7 7,7 0 0 1 -7,7 C 15.04,19 13.27,18.2 12,16.9 10.73,18.2 8.96,19 7,19 A 7,7 0 0 1 0,12 7,7 0 0 1 7,5 H 17 M 7,7 a 5,5 0 0 0 -5,5 5,5 0 0 0 5,5 c 1.64,0 3.09,-0.79 4,-2 h 2 c 0.91,1.21 2.36,2 4,2 a 5,5 0 0 0 5,-5 5,5 0 0 0 -5,-5 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;stroke-width:0.000911392"
d="M 6.4860759,18.968569 C 4.7670441,18.811622 3.259831,18.116758 2.0689469,16.932158 1.0130699,15.881853 0.32053616,14.508606 0.08667443,13.001449 c -0.07509073,-0.483934 -0.07509073,-1.518964 0,-2.002898 C 0.27816547,9.764458 0.78433085,8.6018886 1.5487173,7.6405063 1.7876039,7.3400544 2.2846678,6.8428704 2.6096638,6.5793036 3.5871327,5.7865911 4.730335,5.2863971 6.0303797,5.0826122 6.3577069,5.0313029 6.7343013,5.0278481 12,5.0278481 c 5.263021,0 5.64246,0.00348 5.96962,0.054698 1.283141,0.2008916 2.400277,0.6850108 3.395522,1.4714742 0.288263,0.2277908 0.853077,0.792665 1.086372,1.0864863 0.763774,0.9619282 1.270708,2.1264468 1.461812,3.3580444 0.07509,0.483934 0.07509,1.518964 0,2.002898 -0.238282,1.53564 -0.930885,2.891988 -2.02837,3.972221 -0.56197,0.553135 -1.106852,0.941147 -1.803943,1.284591 -1.00239,0.493859 -1.941477,0.710611 -3.083545,0.711718 -0.87109,8.44e-4 -1.480475,-0.100041 -2.305167,-0.381624 -0.879762,-0.300385 -1.91867,-0.939338 -2.508881,-1.543018 -0.08292,-0.08481 -0.163095,-0.154198 -0.178177,-0.154198 -0.01508,0 -0.14154,0.108024 -0.28102,0.240054 -0.981087,0.92868 -2.3110943,1.56515 -3.7191597,1.77979 -0.310337,0.04731 -1.2439206,0.0827 -1.5189874,0.05759 z m 1.4694638,-2.046432 c 1.1570179,-0.227658 2.2122153,-0.861363 2.9476683,-1.770238 l 0.116769,-0.144304 h 0.978011 0.978011 l 0.216282,0.255326 c 1.303724,1.539076 3.472966,2.134274 5.415314,1.485856 0.400406,-0.133668 0.948915,-0.411486 1.296409,-0.656625 0.333998,-0.235619 0.886059,-0.777432 1.128374,-1.107428 0.457118,-0.622526 0.762865,-1.334396 0.910063,-2.118901 0.07136,-0.38032 0.07136,-1.351326 0,-1.731646 C 21.795243,10.349672 21.489496,9.6378021 21.032378,9.0152765 20.788998,8.6838301 20.237969,8.1435679 19.89816,7.9032202 19.543664,7.652485 18.857658,7.3175238 18.461356,7.2016621 17.730523,6.9879973 18.202131,7.0025316 12,7.0025316 c -6.201171,0 -5.7289522,-0.014528 -6.4613563,0.1987823 C 5.1291518,7.3205769 4.3900442,7.6884706 4.0479223,7.9433263 3.015435,8.7124533 2.3510895,9.7519422 2.0765803,11.027848 2.0173465,11.303165 2.0079507,11.436257 2.0079507,12 c 0,0.563743 0.0094,0.696835 0.06863,0.972152 0.338412,1.572923 1.2887228,2.813122 2.6957076,3.518019 0.4965251,0.248759 1.0666217,0.419639 1.6431548,0.492517 0.3526545,0.04458 1.1689045,0.01249 1.540097,-0.06055 z"
id="path2" />
<path
style="fill:#f44336;stroke-width:0.000911392;fill-opacity:1"
d="m 15.117103,14.929139 c -0.09015,-0.02424 -0.233695,-0.08132 -0.318988,-0.126838 -0.198612,-0.105993 -0.496727,-0.403905 -0.602455,-0.602044 -0.522191,-0.978606 0.189202,-2.173183 1.293967,-2.172838 0.834986,2.6e-4 1.485214,0.645123 1.482814,1.470579 -0.0013,0.433123 -0.150266,0.773303 -0.472018,1.077602 -0.368609,0.348615 -0.898259,0.483979 -1.38332,0.353539 z"
id="path3" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="m 18.318987,11.965123 c -0.570298,-0.06501 -1.079976,-0.498315 -1.242973,-1.056713 -0.05897,-0.202006 -0.06266,-0.613473 -0.0071,-0.794721 0.157203,-0.5131363 0.539281,-0.8922616 1.050556,-1.042437 0.900415,-0.2644763 1.857798,0.4700769 1.854503,1.42287 -0.0014,0.398586 -0.120535,0.704978 -0.385444,0.991112 -0.34977,0.377793 -0.770381,0.536789 -1.26951,0.479889 z"
id="path4" />
<path
style="fill:#4caf50;fill-opacity:1;stroke-width:0.000911392"
d="M 6,13.974684 V 12.972152 H 5.0126582 4.0253165 V 12 11.027848 H 5.0126582 6 V 10.025316 9.0227848 h 0.9873418 0.9873417 v 1.0025312 1.002532 H 8.9772152 9.9797468 V 12 12.972152 H 8.9772152 7.9746835 v 1.002532 1.002531 H 6.9873418 6 Z"
id="path5" />
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="ModeSelect.svg"
inkscape:export-filename="ModeSelect.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 13.64,21.97 C 13.14,22.21 12.54,22 12.31,21.5 L 10.13,16.76 7.62,18.78 C 7.45,18.92 7.24,19 7,19 A 1,1 0 0 1 6,18 V 3 A 1,1 0 0 1 7,2 c 0.24,0 0.47,0.09 0.64,0.23 l 0.01,-0.01 11.49,9.64 c 0.43,0.36 0.48,0.99 0.13,1.41 -0.15,0.18 -0.36,0.3 -0.57,0.34 l -3.16,0.62 2.2,4.73 c 0.26,0.5 0.02,1.09 -0.48,1.32 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 12.987342,22.027431 C 12.81734,21.986309 12.653607,21.890809 12.516456,21.752777 12.39357,21.629102 12.274088,21.384801 11.334807,19.336709 10.76009,18.083544 10.25387,16.986079 10.209875,16.897898 l -0.07999,-0.160331 -1.3041394,1.048547 c -0.7172766,0.576701 -1.366247,1.078699 -1.4421566,1.115551 -0.1921246,0.09327 -0.5643433,0.095 -0.766139,0.0036 C 6.4173979,18.814573 6.2131769,18.615268 6.1145459,18.414426 L 6.0303797,18.243038 V 10.496203 2.7493671 L 6.098879,2.6103625 C 6.2099264,2.3850152 6.3645723,2.2289993 6.5839385,2.1210056 c 0.1744286,-0.085871 0.2318348,-0.099003 0.425368,-0.097303 0.1932096,0.0017 0.2515171,0.016251 0.4274633,0.1066965 0.1535465,0.078931 1.6032412,1.2784622 5.8847492,4.8692597 3.124557,2.6204905 5.747516,4.8278392 5.828799,4.9052202 0.307963,0.293178 0.403619,0.697889 0.25735,1.088827 -0.07936,0.212117 -0.321185,0.463777 -0.517065,0.538099 -0.07211,0.02736 -0.853506,0.191863 -1.736435,0.365562 -0.882929,0.173699 -1.610859,0.32135 -1.617623,0.328113 -0.0068,0.0068 0.502845,1.118545 1.132462,2.470624 l 1.14476,2.458326 0.002,0.227848 c 0.0017,0.190532 -0.01196,0.256223 -0.0831,0.401092 -0.162033,0.329962 -0.197447,0.350607 -2.226878,1.298174 -1.01754,0.475103 -1.918427,0.888201 -2.001972,0.917996 -0.156381,0.05577 -0.356513,0.06658 -0.516455,0.02789 z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuSet.svg"
inkscape:export-filename="CtxMenuSet.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,3 H 5 A 2,2 0 0 0 3,5 v 14 a 2,2 0 0 0 2,2 h 14 a 2,2 0 0 0 2,-2 V 5 A 2,2 0 0 0 19,3 m 0,16 H 5 V 5 H 19 V 19 M 17,17 H 7 V 7 h 10 z"
id="path1"
style="display:none" />
<path
style="fill:#3f51b5;fill-opacity:1;stroke-width:0.000911392"
d="M 7.0177215,12 V 7.0177215 H 12 16.982278 V 12 16.982278 H 12 7.0177215 Z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 4.7848101,20.97361 C 4.7513924,20.966909 4.6488608,20.946726 4.556962,20.928757 4.330066,20.884394 3.9368364,20.690826 3.751114,20.532077 3.4166536,20.246194 3.1622064,19.842986 3.0638682,19.443038 3.0027937,19.194644 3.0027937,4.8053556 3.0638682,4.556962 3.2048886,3.983423 3.6177058,3.4742364 4.1468354,3.2211831 4.5940589,3.007301 3.9811648,3.0227848 12,3.0227848 c 8.020183,0 7.406477,-0.015533 7.853165,0.1987625 0.422942,0.2029037 0.721769,0.50177 0.925164,0.9252881 C 20.992765,4.593342 20.977215,3.9793602 20.977215,12 c 0,8.018835 0.01548,7.405941 -0.198398,7.853165 -0.245337,0.512995 -0.69601,0.891601 -1.27502,1.071133 -0.155303,0.04816 -0.678123,0.05215 -7.412658,0.05665 -3.9850631,0.0027 -7.2729112,-6.39e-4 -7.3063289,-0.0073 z M 19.017722,12 V 4.9822785 H 12 4.9822785 V 12 19.017722 H 12 19.017722 Z"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="SetFps.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 15,3 H 9 V 1 h 6 v 2 m 4.39,7.74 -8.39,8.39 v 2.81 C 6.5,21.44 3,17.63 3,13 3,8.03 7.03,4 12,4 c 2.12,0 4.07,0.74 5.62,2 L 19.04,4.56 C 19.55,5 20,5.46 20.45,5.97 l -1.42,1.42 c 0.64,0.8 1.14,1.72 1.47,2.71 -0.4,0.11 -0.79,0.32 -1.11,0.64 M 13,7 h -2 v 7 h 2 V 7 m 0,12.96 V 22 h 2.04 L 21.17,15.88 19.13,13.83 13,19.96 m 9.85,-6.49 -1.32,-1.32 c -0.2,-0.2 -0.53,-0.2 -0.72,0 l -0.98,0.98 2.04,2.04 0.98,-0.98 c 0.2,-0.19 0.2,-0.52 0,-0.72 z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 10.617722,21.869283 C 7.1016228,21.340408 4.1834446,18.683535 3.2945064,15.201818 3.0855265,14.383303 3.0405649,13.993908 3.0405649,13.002532 c 0,-0.974376 0.041245,-1.344609 0.2386026,-2.141773 C 4.0254815,7.846251 6.2538416,5.4370242 9.1898734,4.470306 11.628033,3.6675175 14.27658,3.9433558 16.47064,5.2285762 c 0.324285,0.1899575 0.791894,0.5076908 0.992585,0.6744479 l 0.14677,0.1219525 0.725448,-0.7249759 0.725448,-0.724976 0.68945,0.6923565 0.68945,0.6923565 -0.716246,0.7188653 -0.716246,0.7188654 0.119733,0.1518987 c 0.2491,0.3160211 0.595056,0.8667573 0.820595,1.3063291 0.231781,0.4517365 0.525111,1.1488748 0.506675,1.2041828 -0.0053,0.01581 -0.118759,0.07288 -0.252196,0.126825 -0.133437,0.05394 -0.324638,0.151242 -0.424891,0.216223 -0.123556,0.08009 -1.569498,1.503728 -4.488312,4.419089 l -4.306033,4.300941 -0.0079,1.399438 -0.0079,1.399438 z m 2.4,-11.37308 V 6.9873418 H 12 10.982278 v 3.5088612 3.50886 H 12 13.017722 Z"
id="path2" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 9.0075949,1.9898734 V 1.0025316 H 12 14.992405 V 1.9898734 2.9772152 H 12 9.0075949 Z"
id="path3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.000911392"
d="M 11.012658,10.496203 V 7.0177215 H 12 12.987342 v 3.4784815 3.478481 H 12 11.012658 Z"
id="path4" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="m 13.017722,20.984754 v -1.010183 l 3.060759,-3.059653 3.06076,-3.059653 1.002286,1.021505 1.002287,1.021504 -3.068109,3.047574 -3.06811,3.047574 -0.994937,7.57e-4 -0.994936,7.58e-4 z"
id="path5" />
<path
style="fill:#2196f3;fill-opacity:1;stroke-width:0.000911392"
d="m 20.847851,14.133929 -0.994842,-0.995184 0.524128,-0.520556 c 0.288271,-0.286306 0.556118,-0.536828 0.595216,-0.556715 0.09182,-0.0467 0.313582,-0.04645 0.404661,4.53e-4 0.118316,0.06093 1.484102,1.43356 1.546837,1.554584 0.06532,0.126016 0.07411,0.251348 0.02658,0.37898 -0.02738,0.07352 -1.048604,1.133623 -1.092045,1.133623 -0.0086,0 -0.463367,-0.447833 -1.01053,-0.995185 z"
id="path6" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="MenuUndo.svg"
inkscape:export-filename="MenuUndo.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 12.5,8 C 9.85,8 7.45,9 5.6,10.6 L 2,7 v 9 h 9 L 7.38,12.38 c 1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5 l 2.37,-0.78 C 21.08,11.03 17.15,8 12.5,8 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 2.0050633,11.506426 V 7.0331045 l 1.7849058,1.7847136 c 0.9816983,0.9815924 1.7955017,1.7847139 1.8084523,1.7847139 0.01295,0 0.1386777,-0.09314 0.279394,-0.206968 1.4353397,-1.161117 3.1676552,-1.9502868 4.9069946,-2.2354199 0.64975,-0.1065148 0.886663,-0.123818 1.701266,-0.1242539 1.051297,-5.627e-4 1.655593,0.070495 2.582278,0.303646 1.440571,0.362442 2.69963,0.9907175 3.98497,1.9885158 0.354657,0.275317 1.358779,1.289994 1.656017,1.673425 0.529597,0.683168 1.022942,1.489533 1.330679,2.174976 0.138766,0.309085 0.416119,1.018878 0.402672,1.030508 -0.0141,0.0122 -2.225795,0.737259 -2.279683,0.74735 -0.0442,0.0083 -0.07762,-0.05022 -0.173973,-0.304565 -0.974459,-2.572278 -3.259104,-4.496687 -5.953593,-5.014848 -2.266175,-0.435795 -4.5078586,0.09426 -6.3873417,1.510317 -0.1462026,0.110153 -0.2658228,0.214777 -0.2658228,0.232499 0,0.01772 0.8031211,0.835429 1.7847135,1.817127 l 1.784714,1.784906 H 6.4783844 2.0050633 Z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
version="1.1"
id="svg1"
sodipodi:docname="CtxMenuUnset.svg"
inkscape:export-filename="CtxMenuUnset.png"
inkscape:export-xdpi="1024"
inkscape:export-ydpi="1024"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="M 19,3 H 5 C 3.89,3 3,3.89 3,5 v 14 a 2,2 0 0 0 2,2 h 14 a 2,2 0 0 0 2,-2 V 5 C 21,3.89 20.1,3 19,3 m 0,2 V 19 H 5 V 5 Z"
id="path1"
style="display:none" />
<path
style="fill:#607d8b;fill-opacity:1;stroke-width:0.000911392"
d="M 4.7848101,20.97361 C 4.7513924,20.966909 4.6488608,20.946726 4.556962,20.928757 4.4650633,20.910789 4.2805063,20.843549 4.1468354,20.779336 3.7339925,20.581014 3.4181278,20.264972 3.2211831,19.853165 3.0072916,19.405922 3.0227848,20.020374 3.0227848,11.98481 c 0,-6.9612422 0.0025,-7.2999639 0.055335,-7.4861782 0.1958206,-0.6902103 0.7303018,-1.2246914 1.4205121,-1.4205121 0.1862143,-0.052831 0.524936,-0.055335 7.4861781,-0.055335 8.036914,0 7.421647,-0.015542 7.868355,0.1987625 0.422942,0.2029037 0.721769,0.50177 0.925164,0.9252881 C 20.992765,4.593342 20.977215,3.9793602 20.977215,12 c 0,8.018835 0.01548,7.405941 -0.198398,7.853165 -0.245337,0.512995 -0.69601,0.891601 -1.27502,1.071133 -0.155303,0.04816 -0.678123,0.05215 -7.412658,0.05665 -3.9850631,0.0027 -7.2729112,-6.39e-4 -7.3063289,-0.0073 z M 19.017722,12 V 4.9822785 H 12 4.9822785 V 12 19.017722 H 12 19.017722 Z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,4 @@
<Solution>
<Project Path="BallanceTasEditor/BallanceTasEditor.csproj" />
<Project Path="BallanceTasEditorTests/BallanceTasEditorTests.csproj" />
</Solution>

View File

@@ -0,0 +1,18 @@
<Application x:Class="BallanceTasEditor.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BallanceTasEditor"
StartupUri="Frontend/Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Frontend/Styles/AccessoryIconControl.xaml"/>
<ResourceDictionary Source="/Frontend/Styles/NoteBanner.xaml"/>
<ResourceDictionary Source="/Frontend/Styles/GenericButton.xaml"/>
<ResourceDictionary>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace BallanceTasEditor {

View File

@@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
public enum EditorLayoutKind {
Horizontal, Vertical
}
public class AppSettings {
public EditorLayoutKind EditorLayout { get; set; }
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
/// <summary>
/// 一种提前给定元素个数的的IEnumerable。
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IExactSizeEnumerable<out T> : IEnumerable<T> {
/// <summary>
/// 该迭代器会返回的元素的个数。
/// </summary>
/// <remarks>
/// 如果迭代器返回的元素个数与该方法给定的个数不同,
/// 则是未定义行为。
/// </remarks>
/// <returns>迭代器会返回的元素的准确个数。大于等于0。</returns>
public int GetCount();
}
/// <summary>
/// 将普通IEnumerable转变为IExactSizeEnumerable的适配器。
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class ExactSizeEnumerableAdapter<T> : IExactSizeEnumerable<T> {
/// <summary>
/// 以迭代器和指定长度构建适配器。
/// </summary>
/// <remarks>
/// 如果迭代器返回的元素个数与该方法给定的个数不同,
/// 则是未定义行为。
/// </remarks>
/// <param name="enumerable">一个迭代器,其最多只能迭代给定次数。</param>
/// <param name="count">迭代器会迭代的次数。</param>
public ExactSizeEnumerableAdapter(IEnumerable<T> enumerable, int count) {
m_Inner = enumerable;
m_Count = count;
}
private readonly IEnumerable<T> m_Inner;
private readonly int m_Count;
public IEnumerator<T> GetEnumerator() {
return m_Inner.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return m_Inner.GetEnumerator();
}
public int GetCount() {
return m_Count;
}
}
}

View File

@@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
public class FileWatcher : IDisposable {
/// <summary>
/// Create a file watcher.
/// </summary>
/// <remarks>
/// This new created file watcher is not watching specified file
/// unless you explicitly call <see cref="Start"/> method.
/// </remarks>
/// <param name="filepath">The path to watching file.</param>
public FileWatcher(string filepath) {
m_FilePath = filepath;
m_IsWatching = false;
m_EventMutex = new Mutex();
m_IsEventProcessing = false;
// Get directory and file info
string directory = Path.GetDirectoryName(filepath) ?? throw new ArgumentException("Invalid file path", nameof(filepath));
string filename = Path.GetFileName(filepath);
// Create FileSystemWatcher
m_FileSystemWatcher = new FileSystemWatcher(directory, filename) {
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName,
EnableRaisingEvents = false
};
m_FileSystemWatcher.Changed += OnFileSystemChanged;
m_FileSystemWatcher.Deleted += OnFileSystemDeleted;
m_FileSystemWatcher.Renamed += OnFileSystemRenamed;
}
/// <summary>
/// The path to watching file.
/// </summary>
private string m_FilePath;
/// <summary>
/// Whether the file watcher is watching file.
/// </summary>
private bool m_IsWatching;
/// <summary>
/// The FileSystemWatcher instance.
/// </summary>
private readonly FileSystemWatcher m_FileSystemWatcher;
/// <summary>
/// Flag to indicate if disposed.
/// </summary>
private bool m_Disposed = false;
/// <summary>
/// Start watching file.
/// </summary>
public void Start() {
if (m_Disposed) throw new ObjectDisposedException(nameof(FileWatcher));
if (m_IsWatching) {
throw new InvalidOperationException("File watcher is already watching file.");
} else {
m_FileSystemWatcher.EnableRaisingEvents = true;
m_IsWatching = true;
}
}
/// <summary>
/// Stop watching file.
/// </summary>
public void Stop() {
if (m_Disposed) throw new ObjectDisposedException(nameof(FileWatcher));
if (m_IsWatching) {
m_FileSystemWatcher.EnableRaisingEvents = false;
m_IsWatching = false;
} else {
throw new InvalidOperationException("File watcher is not watching file.");
}
}
/// <summary>
/// Dispose the file watcher and release resources.
/// </summary>
public void Dispose() {
if (!m_Disposed) {
// Stop watching.
if (m_IsWatching) {
Stop();
}
// Dispose members
m_FileSystemWatcher.Dispose();
m_EventMutex.Dispose();
m_Disposed = true;
}
}
/// <summary>
/// The event handler when file is modified.
/// </summary>
public delegate void FileModifiedHandler();
/// <summary>
/// The event handler when file is deleted.
/// </summary>
public delegate void FileDeletedHandler();
/// <summary>
/// The event when file is modified.
/// </summary>
/// <remarks>
/// Before user process this event completely,
/// there is no any other event will be triggered.
/// </remarks>
public event FileModifiedHandler? FileModified;
/// <summary>
/// The event when file is deleted.
/// </summary>
/// <remarks>
/// Before user process this event completely,
/// there is no any other event will be triggered.
/// </remarks>
public event FileDeletedHandler? FileDeleted;
private Mutex m_EventMutex;
private bool m_IsEventProcessing;
private void OnFileModified() {
if (FileModified is not null) {
lock (m_EventMutex) {
if (m_IsEventProcessing) return;
else m_IsEventProcessing = true;
}
try {
FileModified.Invoke();
}
finally {
lock (m_EventMutex) {
m_IsEventProcessing = false;
}
}
}
}
private void OnFileDeleted() {
if (FileDeleted is not null) {
lock (m_EventMutex) {
if (m_IsEventProcessing) return;
else m_IsEventProcessing = true;
}
try {
FileDeleted.Invoke();
}
finally {
lock (m_EventMutex) {
m_IsEventProcessing = false;
}
}
}
}
/// <summary>
/// Handler for FileSystemWatcher Changed event.
/// </summary>
private void OnFileSystemChanged(object sender, FileSystemEventArgs e) {
// Filter out our own change notifications to avoid infinite loops
if (e.ChangeType == WatcherChangeTypes.Changed) {
OnFileModified();
}
}
/// <summary>
/// Handler for FileSystemWatcher Deleted event.
/// </summary>
private void OnFileSystemDeleted(object sender, FileSystemEventArgs e) {
OnFileDeleted();
}
/// <summary>
/// Handler for FileSystemWatcher Renamed event.
/// </summary>
private void OnFileSystemRenamed(object sender, RenamedEventArgs e) {
// Treat rename as a delete since the original file is gone
OnFileDeleted();
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
/// <summary>
/// FPS converter
/// </summary>
public static class FpsConverter {
/// <summary>
/// Check if the FPS is valid
/// </summary>
/// <param name="fps">FPS in integer</param>
/// <returns>Is valid</returns>
public static bool IsValidFps(uint fps) {
return fps > 0;
}
/// <summary>
/// Check if the FPS is valid
/// </summary>
/// <param name="fps">FPS in float point</param>
/// <returns>Is valid</returns>
public static bool IsValidFps(float fps) {
return fps > 0;
}
/// <summary>
/// Check if the delta time is valid
/// </summary>
/// <param name="delta">Delta time in float point</param>
/// <returns>Is valid</returns>
public static bool IsValidDelta(float delta) {
return delta > 0;
}
/// <summary>
/// Convert float point delta time to float point FPS
/// </summary>
/// <param name="delta">Delta time in float point</param>
/// <returns>FPS in float point</returns>
public static float ToFps(float delta) {
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(delta, nameof(delta));
return 1f / delta;
}
/// <summary>
/// Convert float point delta time to integer FPS
/// </summary>
/// <param name="delta">Delta time in float point</param>
/// <returns>FPS in round integer</returns>
public static uint ToRoundFps(float delta) {
return Convert.ToUInt32(ToFps(delta));
}
/// <summary>
/// Convert integer FPS to float point delta time
/// </summary>
/// <param name="fps">FPS in integer</param>
/// <returns>Delta time in float point</returns>
public static float ToDelta(uint fps) {
return ToDelta((float)fps);
}
/// <summary>
/// Convert float point FPS to float point delta time
/// </summary>
/// <param name="fps">FPS in float point</param>
/// <returns>Delta time in float point</returns>
public static float ToDelta(float fps) {
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(fps, nameof(fps));
return 1f / fps;
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace BallanceTasEditor.Backend {
public class TasClipboard {
// Reference: https://stackoverflow.com/questions/22272822/copy-binary-data-to-clipboard
private static readonly string CLIPBOARD_DATA_FORMAT = "BallanceTasEditor.TasFrames";
public static void SetClipboard(IExactSizeEnumerable<TasFrame> frames) {
DataObject data = new DataObject();
var rawFrames = frames.Select((f) => f.ToRaw()).ToArray();
data.SetData(CLIPBOARD_DATA_FORMAT, rawFrames, false);
Clipboard.SetDataObject(data, true);
}
private static RawTasFrame[]? GetClipboardObject() {
DataObject? retrievedData = Clipboard.GetDataObject() as DataObject;
if (retrievedData is null) return null;
if (!retrievedData.GetDataPresent(CLIPBOARD_DATA_FORMAT)) return null;
RawTasFrame[]? rawFrames = retrievedData.GetData(CLIPBOARD_DATA_FORMAT) as RawTasFrame[];
if (rawFrames is null) return null;
return rawFrames;
}
public static bool HasClipboard() {
return GetClipboardObject() is not null;
}
public static IExactSizeEnumerable<TasFrame>? GetClipboard() {
var rawFrames = GetClipboardObject();
if (rawFrames is null) return null;
return new EnumerableArray(rawFrames);
}
private sealed class EnumerableArray : IExactSizeEnumerable<TasFrame> {
public EnumerableArray(RawTasFrame[] rawFrames) {
m_RawFrames = rawFrames;
}
private RawTasFrame[] m_RawFrames;
public IEnumerator<TasFrame> GetEnumerator() {
return m_RawFrames.Select((f) => TasFrame.FromRaw(f)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public int GetCount() {
return m_RawFrames.Length;
}
}
}
}

View File

@@ -0,0 +1,297 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
/// <summary>
/// 原始的TAS帧结构与二进制结构保持一致。
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[Serializable]
public struct RawTasFrame {
/// <summary>
/// 该帧的持续时间(以秒为单位)。
/// </summary>
public float TimeDelta;
/// <summary>
/// 该帧的按键组合。
/// </summary>
public uint KeyFlags;
}
/// <summary>
/// 描述TAS文件中的可能的按键。
/// </summary>
public struct TasKey : IEquatable<TasKey> {
private TasKey(int bitPos) {
m_BitPos = bitPos;
}
private int m_BitPos;
public static readonly TasKey KEY_UP = new TasKey(0);
public static readonly TasKey KEY_DOWN = new TasKey(1);
public static readonly TasKey KEY_LEFT = new TasKey(2);
public static readonly TasKey KEY_RIGHT = new TasKey(3);
public static readonly TasKey KEY_SHIFT = new TasKey(4);
public static readonly TasKey KEY_SPACE = new TasKey(5);
public static readonly TasKey KEY_Q = new TasKey(6);
public static readonly TasKey KEY_ESC = new TasKey(7);
public static readonly TasKey KEY_ENTER = new TasKey(8);
public const int MIN_KEY_INDEX = 0;
public const int MAX_KEY_INDEX = 8;
public static bool IsValidIndex(int index) {
return index >= MIN_KEY_INDEX && index <= MAX_KEY_INDEX;
}
public static TasKey FromIndex(int index) {
if (index < MIN_KEY_INDEX || index > MAX_KEY_INDEX) {
throw new ArgumentOutOfRangeException(nameof(index));
} else {
return new TasKey(index);
}
}
public int ToIndex() {
return m_BitPos;
}
public uint ToBitMaskKey() {
return 1u << m_BitPos;
}
public bool Equals(TasKey other) {
return m_BitPos == other.m_BitPos;
}
public override bool Equals(object? obj) {
if (obj is TasKey other) {
return Equals(other);
} else {
return false;
}
}
public override int GetHashCode() {
return m_BitPos.GetHashCode();
}
public static bool operator ==(TasKey left, TasKey right) {
return left.Equals(right);
}
public static bool operator !=(TasKey left, TasKey right) {
return !left.Equals(right);
}
public override string ToString() {
return m_BitPos switch {
0 => "KeyUp",
1 => "KeyDown",
2 => "KeyLeft",
3 => "KeyRight",
4 => "KeyShift",
5 => "KeySpace",
6 => "KeyQ",
7 => "KeyEsc",
8 => "KeyEnter",
_ => $"KeyUnknown<Pos={m_BitPos}>"
};
}
}
/// <summary>
/// 描述TAS文件中一帧的结构。
/// </summary>
public class TasFrame : IEquatable<TasFrame> {
private TasFrame(float timeDelta, uint keyFlags) {
m_TimeDelta = timeDelta;
m_KeyFlags = keyFlags;
}
/// <summary>
/// 以指定的FPS无任何按键初始化当前帧。
/// </summary>
public static TasFrame FromFps(uint fps = 60) {
return new TasFrame(FpsConverter.ToDelta(fps), 0);
}
/// <summary>
/// 从原始TAS数据初始化。
/// </summary>
/// <param name="raw">要用来初始化的原始数据。</param>
public static TasFrame FromRaw(RawTasFrame raw) {
return new TasFrame(raw.TimeDelta, raw.KeyFlags);
}
/// <summary>
/// 将原始TAS数据覆写到自身
/// </summary>
/// <param name="raw">要写入的原始TAS数据</param>
public void FromRawImplace(RawTasFrame raw) {
m_TimeDelta = raw.TimeDelta;
m_KeyFlags = raw.KeyFlags;
}
/// <summary>
/// 转换为原始TAS数据。
/// </summary>
/// <returns>转换后的原始TAS数据。</returns>
public RawTasFrame ToRaw() {
return new RawTasFrame() { TimeDelta = m_TimeDelta, KeyFlags = m_KeyFlags };
}
/// <summary>
/// 原位转换为原始TAS数据。
/// </summary>
/// <param name="raw">以引用传递的原始TAS数据。</param>
public void ToRawImplace(ref RawTasFrame raw) {
raw.TimeDelta = m_TimeDelta;
raw.KeyFlags = m_KeyFlags;
}
/// <summary>
/// 返回自身的克隆(深拷贝)。
/// </summary>
/// <returns>自身的克隆。</returns>
public TasFrame Clone() {
return new TasFrame(m_TimeDelta, m_KeyFlags);
}
/// <summary>
/// 该帧的持续时间(以秒为单位)。
/// </summary>
private float m_TimeDelta;
/// <summary>
/// 该帧的按键组合。
/// </summary>
private uint m_KeyFlags;
/// <summary>
/// 获取帧时间Delta。
/// </summary>
/// <returns>获取到的帧时间Delta。</returns>
public float GetTimeDelta() {
return m_TimeDelta;
}
/// <summary>
/// 设置帧时间Delta。
/// </summary>
/// <param name="delta">要设置的帧时间Delta。</param>
public void SetTimeDelta(float delta) {
m_TimeDelta = delta;
}
/// <summary>
/// 判断按键是否被按下。
/// </summary>
/// <param name="key">要检查的按键。</param>
/// <returns>true表示被按下否则为false。</returns>
public bool IsKeyPressed(TasKey key) {
return (m_KeyFlags & key.ToBitMaskKey()) != 0;
}
/// <summary>
/// 设置按键状态。
/// </summary>
/// <param name="key">要设置的按键。</param>
/// <param name="pressed">true表示设置为按下否则为松开。</param>
public void SetKeyPressed(TasKey key, bool pressed = true) {
if (pressed) m_KeyFlags |= key.ToBitMaskKey();
else m_KeyFlags &= ~key.ToBitMaskKey();
}
/// <summary>
/// 反转按键状态。
/// </summary>
/// <param name="key">要反转的按键。</param>
public void FlipKeyPressed(TasKey key) {
m_KeyFlags ^= key.ToBitMaskKey();
}
/// <summary>
/// 获取或设置Up键的按下状态。
/// </summary>
public bool KeyUpPressed { get { return IsKeyPressed(TasKey.KEY_UP); } set { SetKeyPressed(TasKey.KEY_UP, value); } }
/// <summary>
/// 获取或设置Down键的按下状态。
/// </summary>
public bool KeyDownPressed { get { return IsKeyPressed(TasKey.KEY_DOWN); } set { SetKeyPressed(TasKey.KEY_DOWN, value); } }
/// <summary>
/// 获取或设置Left键的按下状态。
/// </summary>
public bool KeyLeftPressed { get { return IsKeyPressed(TasKey.KEY_LEFT); } set { SetKeyPressed(TasKey.KEY_LEFT, value); } }
/// <summary>
/// 获取或设置Right键的按下状态。
/// </summary>
public bool KeyRightPressed { get { return IsKeyPressed(TasKey.KEY_RIGHT); } set { SetKeyPressed(TasKey.KEY_RIGHT, value); } }
/// <summary>
/// 获取或设置Shift键的按下状态。
/// </summary>
public bool KeyShiftPressed { get { return IsKeyPressed(TasKey.KEY_SHIFT); } set { SetKeyPressed(TasKey.KEY_SHIFT, value); } }
/// <summary>
/// 获取或设置Space键的按下状态。
/// </summary>
public bool KeySpacePressed { get { return IsKeyPressed(TasKey.KEY_SPACE); } set { SetKeyPressed(TasKey.KEY_SPACE, value); } }
/// <summary>
/// 获取或设置Q键的按下状态。
/// </summary>
public bool KeyQPressed { get { return IsKeyPressed(TasKey.KEY_Q); } set { SetKeyPressed(TasKey.KEY_Q, value); } }
/// <summary>
/// 获取或设置Esc键的按下状态。
/// </summary>
public bool KeyEscPressed { get { return IsKeyPressed(TasKey.KEY_ESC); } set { SetKeyPressed(TasKey.KEY_ESC, value); } }
/// <summary>
/// 获取或设置回车键的按下状态。
/// </summary>
public bool KeyEnterPressed { get { return IsKeyPressed(TasKey.KEY_ENTER); } set { SetKeyPressed(TasKey.KEY_ENTER, value); } }
/// <summary>
/// 清除所有按键,将所有按键设置为不按下。
/// </summary>
public void ClearKeyPressed() {
m_KeyFlags = 0;
}
/// <summary>
/// 指示当前对象是否等于另一个 TasFrame 对象。
/// </summary>
/// <param name="other">要比较的 TasFrame 对象。</param>
/// <returns>如果两个对象相等则为 true否则为 false。</returns>
public bool Equals(TasFrame? other) {
return other is not null &&
m_TimeDelta == other.m_TimeDelta &&
m_KeyFlags == other.m_KeyFlags;
}
/// <summary>
/// 指示当前对象是否等于另一个对象。
/// </summary>
/// <param name="obj">要比较的对象。</param>
/// <returns>如果两个对象相等则为 true否则为 false。</returns>
public override bool Equals(object? obj) {
if (obj is TasFrame other) {
return Equals(other);
} else {
return false;
}
}
/// <summary>
/// 返回此实例的哈希代码。
/// </summary>
/// <returns>32 位有符号整数哈希代码。</returns>
public override int GetHashCode() {
return HashCode.Combine(m_TimeDelta, m_KeyFlags);
}
}
}

View File

@@ -0,0 +1,532 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
/// <summary>
/// TAS操作接口。所有TAS操作均需要支持此接口。
/// </summary>
public interface ITasOperation {
/// <summary>
/// 执行对应的TAS操作。
/// </summary>
/// <param name="seq">所要操作的TAS存储容器。</param>
void Execute(ITasSequence seq);
/// <summary>
/// 检查该操作是否已经被执行过。
/// </summary>
/// <remarks>
/// 所有Tas操作类创建后只能执行一次或者不执行
/// 因此有此函数用于获取是否已经执行过。
/// </remarks>
/// <returns>如果已经执行过返回true否则返回false。</returns>
bool IsExecuted();
}
/// <summary>
/// 可撤销的TAS操作接口所有可撤销的TAS操作均需支持此接口。
/// </summary>
public interface ITasRevocableOperation : ITasOperation {
/// <summary>
/// 撤销对应TAS操作。
/// </summary>
/// <param name="seq">所要撤销操作的TAS存储容器。</param>
void Revoke(ITasSequence seq);
/// <summary>
/// 返回该TAS操作占用的内存大小。
/// </summary>
/// <remarks>
/// 可撤销的TAS操作会在内存中存储一定数据用于撤销对应操作。
/// 该函数返回的占用用于衡量该操作的开销。
/// 我们应当基于大小,而非写死的个数决定撤销栈中的最大操作次数,
/// 例如对于小型操作我们可以存储100个对于大型操作则只能存储5个等。
/// 用于解决编辑者目前认为撤销栈大小不足的情况。
/// <para/>
/// 该函数返回的大小可以不是特别精确,但要准确反映空间复杂度。
/// </remarks>
/// <returns>占用的内存大小以byte为单位。</returns>
int Occupation();
}
internal static class OperationUtils {
internal const int SIZEOF_DELTA_TIME = sizeof(float);
internal const int SIZEOF_KEYS = sizeof(uint);
internal const int SIZEOF_FRAME = SIZEOF_DELTA_TIME + SIZEOF_KEYS;
internal static readonly InvalidOperationException ExecutionEnvironment = new InvalidOperationException("Can not execute one TAS operation multiple times.");
internal static readonly InvalidOperationException RevokeEnvironment = new InvalidOperationException("Can not revoke an not executed TAS operation.");
}
public enum CellKeysOperationKind {
Set, Unset, Flip
}
public class CellKeysOperation : ITasRevocableOperation {
public static CellKeysOperation FromSingleCell(CellKeysOperationKind kind, int index, TasKey key) {
return new CellKeysOperation(kind, index, index, key, key);
}
public static CellKeysOperation FromCellRange(CellKeysOperationKind kind, int startIndex, int endIndex, TasKey startKey, TasKey endKey) {
return new CellKeysOperation(kind, startIndex, endIndex, startKey, endKey);
}
private CellKeysOperation(CellKeysOperationKind kind, int startIndex, int endIndex, TasKey startKey, TasKey endKey) {
// Check arguments.
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex);
ArgumentOutOfRangeException.ThrowIfGreaterThan(startKey.ToIndex(), endKey.ToIndex());
// Setup members.
m_Kind = kind;
m_StartIndex = startIndex;
m_EndIndex = endIndex;
m_StartKey = startKey;
m_EndKey = endKey;
m_FramesBackup = null;
}
private CellKeysOperationKind m_Kind;
private int m_StartIndex, m_EndIndex;
private TasKey m_StartKey, m_EndKey;
private RawTasFrame[]? m_FramesBackup;
[MemberNotNullWhen(true, nameof(m_FramesBackup))]
public bool IsExecuted() {
return m_FramesBackup is not null;
}
public void Execute(ITasSequence seq) {
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Check index range.
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(m_EndIndex, seq.GetCount());
ArgumentOutOfRangeException.ThrowIfLessThan(m_StartIndex, 0);
// Do backup and set values at the same time
int backupIndex = 0;
var backups = new RawTasFrame[m_EndIndex - m_StartIndex + 1];
// Pre-build key list for fast fetching.
var keys = Enumerable.Range(m_StartKey.ToIndex(), m_EndKey.ToIndex() - m_StartKey.ToIndex() + 1).Select((i) => TasKey.FromIndex(i)).ToArray();
foreach (var frame in seq.BatchlyVisit(m_StartIndex, m_EndIndex)) {
// Do backup
frame.ToRawImplace(ref backups[backupIndex++]);
// Modify keys
foreach (var key in keys) {
switch (m_Kind) {
case CellKeysOperationKind.Set:
frame.SetKeyPressed(key, true);
break;
case CellKeysOperationKind.Unset:
frame.SetKeyPressed(key, false);
break;
case CellKeysOperationKind.Flip:
frame.FlipKeyPressed(key);
break;
}
}
}
// Assign backups
m_FramesBackup = backups;
}
public void Revoke(ITasSequence seq) {
if (!IsExecuted()) {
throw OperationUtils.RevokeEnvironment;
}
// Index range is checked,
// so we directly restore backup.
int backupIndex = 0;
foreach (var frame in seq.BatchlyVisit(m_StartIndex, m_EndIndex)) {
frame.FromRawImplace(m_FramesBackup[backupIndex++]);
}
// Clear backups
m_FramesBackup = null;
}
public int Occupation() {
return (m_EndIndex - m_StartIndex) * OperationUtils.SIZEOF_FRAME;
}
}
public class FrameFpsOperation : ITasRevocableOperation {
public static FrameFpsOperation FromSingleFrame(int index, uint fps) {
return new FrameFpsOperation(index, index, fps);
}
public static FrameFpsOperation FromFrameRange(int startIndex, int endIndex, uint fps) {
return new FrameFpsOperation(startIndex, endIndex, fps);
}
private FrameFpsOperation(int startIndex, int endIndex, uint fps) {
// Check arguments
if (!FpsConverter.IsValidFps(fps)) {
throw new ArgumentOutOfRangeException(nameof(fps));
}
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex);
// Assign arguments
m_StartIndex = startIndex;
m_EndIndex = endIndex;
m_DeltaTime = FpsConverter.ToDelta(fps);
}
private int m_StartIndex, m_EndIndex;
private float m_DeltaTime;
private float[]? m_DeltaTimesBackup;
[MemberNotNullWhen(true, nameof(m_DeltaTimesBackup))]
public bool IsExecuted() {
return m_DeltaTimesBackup is not null;
}
public void Execute(ITasSequence seq) {
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Check index range
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(m_EndIndex, seq.GetCount());
ArgumentOutOfRangeException.ThrowIfLessThan(m_StartIndex, 0);
// Do backup and set values at the same time
int backupIndex = 0;
var backups = new float[m_EndIndex - m_StartIndex + 1];
foreach (var frame in seq.BatchlyVisit(m_StartIndex, m_EndIndex)) {
// Do backup
backups[backupIndex++] = frame.GetTimeDelta();
// Modify delta time
frame.SetTimeDelta(m_DeltaTime);
}
// Assign backups
m_DeltaTimesBackup = backups;
}
public void Revoke(ITasSequence seq) {
if (!IsExecuted()) {
throw OperationUtils.RevokeEnvironment;
}
// Index range is checked,
// so we directly restore backup.
int backupIndex = 0;
foreach (var frame in seq.BatchlyVisit(m_StartIndex, m_EndIndex)) {
frame.SetTimeDelta(m_DeltaTimesBackup[backupIndex++]);
}
// Clear backups
m_DeltaTimesBackup = null;
}
public int Occupation() {
return (m_EndIndex - m_StartIndex) * OperationUtils.SIZEOF_DELTA_TIME;
}
}
public class RemoveFrameOperation : ITasRevocableOperation {
public RemoveFrameOperation(int startIndex, int endIndex) {
// Check arguments
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex);
// Assign arguments
m_StartIndex = startIndex;
m_EndIndex = endIndex;
}
private int m_StartIndex, m_EndIndex;
private RawTasFrame[]? m_FramesBackup;
[MemberNotNullWhen(true, nameof(m_FramesBackup))]
public bool IsExecuted() {
return m_FramesBackup is not null;
}
public void Execute(ITasSequence seq) {
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Check index range
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(m_EndIndex, seq.GetCount());
ArgumentOutOfRangeException.ThrowIfLessThan(m_StartIndex, 0);
// Do backups
int backupIndex = 0;
var backups = new RawTasFrame[m_EndIndex - m_StartIndex + 1];
foreach (var frame in seq.BatchlyVisit(m_StartIndex, m_EndIndex)) {
frame.ToRawImplace(ref backups[backupIndex++]);
}
// Do remove
seq.Remove(m_StartIndex, m_EndIndex);
// Assign backups
m_FramesBackup = backups;
}
public void Revoke(ITasSequence seq) {
if (!IsExecuted()) {
throw OperationUtils.RevokeEnvironment;
}
// Index range is checked,
// so we directly restore backup.
// Build iterator first
var iter = m_FramesBackup.Select((frame) => TasFrame.FromRaw(frame));
var exactSizedIter = new ExactSizeEnumerableAdapter<TasFrame>(iter, m_EndIndex - m_StartIndex + 1);
// Insert at start index
seq.Insert(m_StartIndex, exactSizedIter);
// Clear backups
m_FramesBackup = null;
}
public int Occupation() {
return (m_EndIndex - m_StartIndex) * OperationUtils.SIZEOF_FRAME;
}
}
public enum AddFrameOperationKind {
Before, After
}
public class AddFrameOperation : ITasRevocableOperation {
public AddFrameOperation(AddFrameOperationKind kind, int index, uint fps, int count) {
// Check argument
if (!FpsConverter.IsValidFps(fps)) {
throw new ArgumentOutOfRangeException(nameof(fps));
}
ArgumentOutOfRangeException.ThrowIfNegative(count);
// Assign argument
m_Kind = kind;
m_Index = index;
m_Fps = fps;
m_Count = count;
m_IsExecuted = false;
}
private AddFrameOperationKind m_Kind;
private int m_Index;
private uint m_Fps;
private int m_Count;
private bool m_IsExecuted;
public bool IsExecuted() {
return m_IsExecuted;
}
public void Execute(ITasSequence seq) {
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Check arguments
// If we add before some frame, the valid index can be [0, count],
// however, if we add after some frame, the valid index is [0, count),
switch (m_Kind) {
case AddFrameOperationKind.Before:
ArgumentOutOfRangeException.ThrowIfGreaterThan(m_Index, seq.GetCount());
break;
case AddFrameOperationKind.After:
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(m_Index, seq.GetCount());
break;
default:
throw new UnreachableException("Unknown AddFrameOperationKind");
}
// Skip if count is zero.
if (m_Count != 0) {
// Prepare data builder.
var iter = Enumerable.Range(0, m_Count).Select((_) => TasFrame.FromFps(m_Fps));
var exactSizedIter = new ExactSizeEnumerableAdapter<TasFrame>(iter, m_Count);
// Compute the insert index
var index = m_Kind switch {
AddFrameOperationKind.Before => m_Index,
AddFrameOperationKind.After => m_Index + 1,
_ => throw new UnreachableException("Unknown AddFrameOperationKind"),
};
seq.Insert(index, exactSizedIter);
}
// Set status
m_IsExecuted = true;
}
public void Revoke(ITasSequence seq) {
if (!IsExecuted()) {
throw OperationUtils.RevokeEnvironment;
}
// Arguments were checked so we directly resotre them.
// If we inserted count is not zero, remove inserted frames, otherwise do nothing.
if (m_Count != 0) {
// Compute the index for removing
var index = m_Kind switch {
AddFrameOperationKind.Before => m_Index,
AddFrameOperationKind.After => m_Index + 1,
_ => throw new UnreachableException("Unknown AddFrameOperationKind"),
};
// Execute removing.
seq.Remove(index, index + m_Count - 1);
}
// Modify execution status
m_IsExecuted = false;
}
public int Occupation() {
return OperationUtils.SIZEOF_FRAME;
}
}
public enum InsertFrameOperationKind {
Before, After
}
public class InsertFrameOperation : ITasRevocableOperation {
public InsertFrameOperation(InsertFrameOperationKind kind, int index, IExactSizeEnumerable<TasFrame> frames) {
m_Kind = kind;
m_Index = index;
m_InsertedFrames = frames.Select((frame) => frame.ToRaw()).ToArray();
m_IsExecuted = false;
}
private InsertFrameOperationKind m_Kind;
private int m_Index;
private RawTasFrame[] m_InsertedFrames;
private bool m_IsExecuted;
public bool IsExecuted() {
return m_IsExecuted;
}
public void Execute(ITasSequence seq) {
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Check arguments
// If we insert before some frame, the valid index can be [0, count],
// however, if we insert after some frame, the valid index is [0, count),
switch (m_Kind) {
case InsertFrameOperationKind.Before:
ArgumentOutOfRangeException.ThrowIfGreaterThan(m_Index, seq.GetCount());
break;
case InsertFrameOperationKind.After:
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(m_Index, seq.GetCount());
break;
default:
throw new UnreachableException("Unknown InsertFrameOperationKind");
}
// Skip if count is zero
var count = m_InsertedFrames.Length;
if (count != 0) {
// Prepare iterator
var iter = m_InsertedFrames.Select((frame) => TasFrame.FromRaw(frame));
var exactSizedIter = new ExactSizeEnumerableAdapter<TasFrame>(iter, count);
// Compute the insert index
var index = m_Kind switch {
InsertFrameOperationKind.Before => m_Index,
InsertFrameOperationKind.After => m_Index + 1,
_ => throw new UnreachableException("Unknown InsertFrameOperationKind"),
};
// Execute inserting.
seq.Insert(index, exactSizedIter);
}
// Set execution status
m_IsExecuted = true;
}
public void Revoke(ITasSequence seq) {
if (!IsExecuted()) {
throw OperationUtils.RevokeEnvironment;
}
// Arguments were checked so we directly restore them.
var count = m_InsertedFrames.Length;
if (count != 0) {
// Compute the index for removing
var index = m_Kind switch {
InsertFrameOperationKind.Before => m_Index,
InsertFrameOperationKind.After => m_Index + 1,
_ => throw new UnreachableException("Unknown InsertFrameOperationKind"),
};
// Execute removing.
seq.Remove(index, index + count - 1);
}
// Modify execution status
m_IsExecuted = false;
}
public int Occupation() {
return m_InsertedFrames.Length * OperationUtils.SIZEOF_FRAME;
}
}
public class ClearKeysOperation : ITasOperation {
public ClearKeysOperation() {
m_IsExecuted = false;
}
private bool m_IsExecuted;
public void Execute(ITasSequence seq) {
// Check execution status first.
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Execute operation
foreach (var frame in seq) {
frame.ClearKeyPressed();
}
m_IsExecuted = true;
}
public bool IsExecuted() {
return m_IsExecuted;
}
}
public class UniformFpsOperation : ITasOperation {
public UniformFpsOperation(uint fps) {
// Check arguments
if (!FpsConverter.IsValidFps(fps)) {
throw new ArgumentOutOfRangeException(nameof(fps));
}
// Assign arguments
m_DeltaTime = FpsConverter.ToDelta(fps);
m_IsExecuted = false;
}
private float m_DeltaTime;
private bool m_IsExecuted;
public void Execute(ITasSequence seq) {
// Check execution status first.
if (IsExecuted()) {
throw OperationUtils.ExecutionEnvironment;
}
// Execute operation
foreach (var frame in seq) {
frame.SetTimeDelta(m_DeltaTime);
}
m_IsExecuted = true;
}
public bool IsExecuted() {
return m_IsExecuted;
}
}
}

View File

@@ -0,0 +1,425 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
/// <summary>
/// 所有用于在内存中存储TAS帧的结构都必须实现此interface。
/// </summary>
public interface ITasSequence : IEnumerable<TasFrame> {
/// <summary>
/// 访问给定索引的帧的值。
/// </summary>
/// <remarks>
/// 实现此函数时需要格外注意以下事项:
/// <para/>
/// 该函数应当保证在访问临近项时有较高的效率。
/// <para/>
/// 该函数理论上的复杂度应为O(1)。
/// </remarks>
/// <param name="index">要访问的单元的索引。</param>
/// <returns>被访问的单元。</returns>
/// <exception cref="IndexOutOfRangeException">给定的索引无效。</exception>
TasFrame Visit(int index);
/// <summary>
/// 按顺序访问给定索引区间内的帧的值。
/// </summary>
/// <remarks>
/// 实现此函数时需要格外注意以下事项:
/// <para/>
/// 该函数如果可以进行顺序访问优化,则应当优化。
/// 即使用此函数可以获得等于或大于单独一次使用<see cref="Visit(int)"/>函数。
/// <para/>
/// 该函数理论上的复杂度应为O(1)。
/// </remarks>
/// <param name="startIndex">要访问的帧区间的起始索引(包含)。</param>
/// <param name="endIndex">要访问的帧区间的终止索引(包含)</param>
/// <exception cref="IndexOutOfRangeException">给定的索引无效。</exception>
IExactSizeEnumerable<TasFrame> BatchlyVisit(int startIndex, int endIndex);
/// <summary>
/// 在给定的帧索引<b>之前</b>插入给定的项目。
/// </summary>
/// <remarks>
/// 实现此函数时需要格外注意以下事项:
/// <para/>
/// 按照函数约定如果要在头部插入数据则可以通过指定0来实现。
/// 然而对于在尾部插入数据,或在空的存储中插入数据,可以指定存储结构的长度来实现。
/// 即指定<c>(最大Index + 1)</c>作为参数来实现。
/// <para/>
/// 该函数理论上的复杂度应为O(1)。
/// </remarks>
/// <param name="index">要在前方插入数据的元素的索引。</param>
/// <param name="items">要插入的元素的迭代器。</param>
/// <exception cref="IndexOutOfRangeException">给定的索引无效。</exception>
void Insert(int index, IExactSizeEnumerable<TasFrame> items);
/// <summary>
/// 从序列中移出给定帧区间的元素。
/// </summary>
/// <remarks>
/// 实现此函数时需要格外注意以下事项:
/// <para/>
/// 该函数理论上的复杂度应为O(1)。
/// </remarks>
/// <param name="startIndex">要移除的帧区间的起始索引(包含)。</param>
/// <param name="endIndex">要移除的帧区间的终止索引(包含)</param>
/// <exception cref="IndexOutOfRangeException">给定的索引无效。</exception>
void Remove(int startIndex, int endIndex);
/// <summary>
/// 清空存储结构。
/// </summary>
void Clear();
/// <summary>
/// 获取当前存储的TAS帧的个数。
/// </summary>
/// <returns>存储的TAS帧的个数。</returns>
int GetCount();
/// <summary>
/// 获取当前存储结构是不是空的。
/// </summary>
/// <returns>如果是空的就返回true否则返回false。</returns>
bool IsEmpty();
}
// TODO:
// We may introduce ITasSequenceSlice to have iterator on a specific range.
// We also need introduce a new function in ITasSequence to fetch this instance.
/// <summary>
/// 基于Gap Buffer思想的TAS存储器。
/// </summary>
/// <remarks>
/// 其实就是把List的InsertRange的复杂度从O(n*m)修正为O(n)。
/// </remarks>
public class GapBufferSequence : ITasSequence, IEnumerable<TasFrame> {
public GapBufferSequence() {
// Do nothing.
}
public TasFrame Visit(int index) {
throw new NotImplementedException();
}
public IExactSizeEnumerable<TasFrame> BatchlyVisit(int startIndex, int endIndex) {
throw new NotImplementedException();
}
public void Insert(int index, IExactSizeEnumerable<TasFrame> items) {
throw new NotImplementedException();
}
public void Remove(int startIndex, int endIndex) {
throw new NotImplementedException();
}
public void Clear() {
throw new NotImplementedException();
}
public int GetCount() {
throw new NotImplementedException();
}
public bool IsEmpty() {
throw new NotImplementedException();
}
public IEnumerator<TasFrame> GetEnumerator() {
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
/// <summary>
/// 基于简单的List的TAS存储器。
/// </summary>
/// <remarks>
/// 由于List的InsertRange的复杂度是O(n*m),可能不符合要求。
/// </remarks>
public class ListTasSequence : ITasSequence, IEnumerable<TasFrame> {
public ListTasSequence() {
m_Container = new List<TasFrame>();
}
private List<TasFrame> m_Container;
public TasFrame Visit(int index) {
if (index >= m_Container.Count || index < 0) {
throw new IndexOutOfRangeException("Invalid index for frame.");
} else {
return m_Container[index];
}
}
private IEnumerable<TasFrame> BatchlyVisitEx(int startIndex, int endIndex) {
if (endIndex < startIndex || startIndex < 0 || endIndex >= m_Container.Count) {
throw new IndexOutOfRangeException("Invalid index for frame.");
}
// Iterate items one by one.
for (int i = startIndex; i <= endIndex; ++i) {
yield return m_Container[i];
}
}
public IExactSizeEnumerable<TasFrame> BatchlyVisit(int startIndex, int endIndex) {
return new ExactSizeEnumerableAdapter<TasFrame>(BatchlyVisitEx(startIndex, endIndex), endIndex - startIndex + 1);
}
public void Insert(int index, IExactSizeEnumerable<TasFrame> items) {
if (index == m_Container.Count) {
m_Container.AddRange(items);
} else {
if (index > m_Container.Count || index < 0) {
throw new IndexOutOfRangeException("Invalid index for frame.");
} else {
m_Container.InsertRange(index, items);
}
}
}
public void Remove(int startIndex, int endIndex) {
if (endIndex < startIndex || startIndex < 0 || endIndex >= m_Container.Count) {
throw new IndexOutOfRangeException("Invalid index for frame.");
} else {
m_Container.RemoveRange(startIndex, endIndex - startIndex + 1);
}
}
public void Clear() {
m_Container.Clear();
}
public int GetCount() {
return m_Container.Count;
}
public bool IsEmpty() {
return GetCount() == 0;
}
public IEnumerator<TasFrame> GetEnumerator() {
return m_Container.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
/// <summary>
/// 传统的基于LinkedList的TAS存储器。
/// </summary>
public class LegacyTasSequence : ITasSequence, IEnumerable<TasFrame> {
public LegacyTasSequence() {
m_Container = new LinkedList<TasFrame>();
m_Cursor = null;
}
private class LinkedListCursor<T> {
public LinkedListCursor(LinkedListNode<T> node, int index) {
this.Node = node;
this.Index = index;
}
public LinkedListNode<T> Node;
public int Index;
}
private LinkedList<TasFrame> m_Container;
private LinkedListCursor<TasFrame>? m_Cursor;
private enum NodeSeekOrigin {
Head,
Cursor,
Tail,
}
private struct NodeSeekInfo : IComparable<NodeSeekInfo> {
public required NodeSeekOrigin Origin;
public required int Offset;
public int CompareTo(NodeSeekInfo other) {
return Math.Abs(this.Offset).CompareTo(Math.Abs(other.Offset));
}
}
/// <summary>
/// 快速将内部游标移动到指定Index并更新与之匹配的Index。
/// </summary>
/// <param name="desiredIndex"></param>
/// <exception cref="Exception"></exception>
[MemberNotNull(nameof(m_Cursor))]
private void MoveToIndex(int desiredIndex) {
// 检查基本环境
if (desiredIndex < 0 || desiredIndex >= GetCount())
throw new IndexOutOfRangeException("Invalid index for frame.");
if (m_Cursor is null || IsEmpty())
throw new InvalidOperationException("Can not move cursor when container is empty.");
// 创建三个候选方案。
var candidates = new NodeSeekInfo[3] {
new NodeSeekInfo() { Origin = NodeSeekOrigin.Head, Offset = desiredIndex },
new NodeSeekInfo() { Origin = NodeSeekOrigin.Tail, Offset = desiredIndex - (GetCount() - 1) },
new NodeSeekInfo() { Origin = NodeSeekOrigin.Cursor, Offset = desiredIndex - m_Cursor.Index },
};
// 确定哪个候选方案最短。
var bestCandidate = candidates.Min();
// 用最短候选方案移动。
int pickedOffset = bestCandidate.Offset;
LinkedListNode<TasFrame> pickedNode = bestCandidate.Origin switch {
NodeSeekOrigin.Head => m_Container.First.Unwrap(),
NodeSeekOrigin.Cursor => m_Cursor.Node,
NodeSeekOrigin.Tail => m_Container.Last.Unwrap(),
_ => throw new UnreachableException("Unknown NodeSeekOrigin"),
};
int alreadyMoved = 0;
if (pickedOffset < 0) {
while (alreadyMoved != pickedOffset) {
pickedNode = pickedNode.Previous.Unwrap();
alreadyMoved--;
}
} else if (pickedOffset > 0) {
while (alreadyMoved != pickedOffset) {
pickedNode = pickedNode.Next.Unwrap();
alreadyMoved++;
}
}
// 设置Cursor
m_Cursor = new LinkedListCursor<TasFrame>(pickedNode, desiredIndex);
}
public TasFrame Visit(int index) {
if (index >= m_Container.Count || index < 0) {
throw new IndexOutOfRangeException("Invalid index for frame.");
} else {
MoveToIndex(index);
return m_Cursor.Node.Value;
}
}
private IEnumerable<TasFrame> BatchlyVisitEx(int startIndex, int endIndex) {
if (endIndex < startIndex || startIndex < 0 || endIndex >= m_Container.Count) {
throw new IndexOutOfRangeException("Invalid index for frame.");
}
// We move to start index first.
MoveToIndex(startIndex);
// Then we copy its reference
LinkedListNode<TasFrame>? node = m_Cursor.Node;
// Then compute count
var count = endIndex - startIndex + 1;
// Now we can iterate items one by one.
for (int i = 0; i < count; ++i) {
node = node.Unwrap();
yield return node.Unwrap().Value;
node = node.Next;
}
}
public IExactSizeEnumerable<TasFrame> BatchlyVisit(int startIndex, int endIndex) {
return new ExactSizeEnumerableAdapter<TasFrame>(BatchlyVisitEx(startIndex, endIndex), endIndex - startIndex + 1);
}
public void Insert(int index, IExactSizeEnumerable<TasFrame> items) {
// YYC MARK:
// We must test the equal first, to handle back appending properly.
if (index == m_Container.Count) {
foreach (TasFrame item in items) {
m_Container.AddLast(item);
}
var pendingCursor = m_Container.First;
if (pendingCursor is null) {
m_Cursor = null;
} else {
m_Cursor = new LinkedListCursor<TasFrame>(pendingCursor, 0);
}
} else {
if (index >= m_Container.Count || index < 0) {
throw new IndexOutOfRangeException("Invalid index for frame.");
} else {
MoveToIndex(index);
foreach (TasFrame item in items) {
m_Container.AddBefore(m_Cursor.Node, item);
}
m_Cursor.Index += items.GetCount();
}
}
}
public void Remove(int startIndex, int endIndex) {
if (endIndex < startIndex || startIndex < 0 || endIndex >= m_Container.Count) {
throw new IndexOutOfRangeException("Invalid index for frame.");
}
// Compute count and move to index.
var count = endIndex - startIndex + 1;
MoveToIndex(startIndex);
// 我们总是获取要删除的项目的前一项来作为参照。
// 如果获取到的是null则说明是正在删第一项从m_Container里获取First来删除就行
// 否则就继续用这个Node的Next来删除。
var prevNode = m_Cursor.Node.Previous;
if (prevNode is null) {
for (int i = 0; i < count; ++i) {
m_Container.RemoveFirst();
}
} else {
for (int i = 0; i < count; ++i) {
m_Container.Remove(prevNode.Next.Unwrap());
}
}
// 然后设置Cursor和Index
if (IsEmpty()) {
// 如果全部删完了,就清除这两个的设置。
m_Cursor = null;
} else {
if (prevNode is null) {
// 如果是按头部删除的则直接获取头部及其Index。
m_Cursor = new LinkedListCursor<TasFrame>(m_Container.First.Unwrap(), 0);
} else {
// 否则就以prevNode为当前CursorIndex--为对应Index。
m_Cursor.Node = prevNode;
--m_Cursor.Index;
}
}
}
public void Clear() {
m_Container.Clear();
m_Cursor = null;
}
public int GetCount() {
return m_Container.Count;
}
public bool IsEmpty() {
return GetCount() == 0;
}
public IEnumerator<TasFrame> GetEnumerator() {
return m_Container.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
}

View File

@@ -0,0 +1,177 @@
using CommunityToolkit.HighPerformance;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Backend {
public static class TasStorage {
/// <summary>
/// Initialize given TAS sequence with given count frame which has given FPS.
/// </summary>
/// <param name="seq">The TAS sequence to initialize.</param>
/// <param name="count">The count of frame.</param>
/// <param name="fps">The FPS of frame.</param>
public static void Init(ITasSequence seq, int count, uint fps) {
var frame = TasFrame.FromFps(fps);
var iter = Enumerable.Range(0, count).Select((_) => frame.Clone());
var exactSizeIter = new ExactSizeEnumerableAdapter<TasFrame>(iter, count);
seq.Insert(seq.GetCount(), exactSizeIter);
}
internal const int SIZEOF_I32 = sizeof(int);
internal const int SIZEOF_F32 = sizeof(float);
internal const int SIZEOF_U32 = sizeof(uint);
internal const int SIZEOF_RAW_TAS_FRAME = SIZEOF_F32 + SIZEOF_U32;
/// <summary>
/// Save given TAS sequence into given file path.
/// </summary>
/// <param name="filepath">The path to file for saving.</param>
/// <param name="seq">The TAS sequence to save.</param>
/// <exception cref="Exception">Any exception occurs when saving.</exception>
public static void Save(string filepath, ITasSequence seq) {
using (var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) {
Save(fs, seq);
fs.Close();
}
}
/// <summary>
/// Save given TAS sequence into given file stream.
/// </summary>
/// <param name="fs">The file stream for saving.</param>
/// <param name="seq">The TAS sequence to save.</param>
/// <exception cref="Exception">Any exception occurs when saving.</exception>
public static void Save(Stream fs, ITasSequence seq) {
var totalByte = seq.GetCount() * SIZEOF_RAW_TAS_FRAME;
fs.Write(BitConverter.GetBytes(totalByte), 0, SIZEOF_I32);
using (var zo = new Ionic.Zlib.ZlibStream(fs, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.Level9, true)) {
foreach (var item in seq) {
var rawItem = item.ToRaw();
zo.Write(BitConverter.GetBytes(rawItem.TimeDelta), 0, SIZEOF_F32);
zo.Write(BitConverter.GetBytes(rawItem.KeyFlags), 0, SIZEOF_U32);
}
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();
}
/// <summary>
/// Load TAS sequence from given file path into given sequence.
/// </summary>
/// <param name="filepath">The path to file for loading.</param>
/// <param name="seq">The TAS sequence to load.</param>
/// <exception cref="Exception">Any exception occurs when loading.</exception>
public static void Load(string filepath, ITasSequence seq) {
using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
Load(fs, seq);
fs.Close();
}
}
/// <summary>
/// Load TAS sequence from given file stream into given sequence.
/// </summary>
/// <param name="fs">The file stream for loading.</param>
/// <param name="seq">The TAS sequence to load.</param>
/// <exception cref="Exception">Any exception occurs when loading.</exception>
public static void Load(Stream fs, ITasSequence seq) {
// Read total bytes
var lenCache = new byte[SIZEOF_I32];
fs.Read(lenCache, 0, 4);
int expectedLength = BitConverter.ToInt32(lenCache, 0);
// Check length and compute count
int expectedCount = Math.DivRem(expectedLength, SIZEOF_RAW_TAS_FRAME, out var remainder);
ArgumentOutOfRangeException.ThrowIfNotEqual(remainder, 0);
using (var mem = new MemoryStream()) {
using (var zo = new Ionic.Zlib.ZlibStream(mem, Ionic.Zlib.CompressionMode.Decompress, true)) {
CopyStream(fs, zo);
zo.Close();
}
var memWrapper = new EnumerableMemoryStream(mem, expectedCount);
seq.Clear();
seq.Insert(0, memWrapper);
mem.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();
}
private const int STREAM_COPY_CHUNK_SIZE = 10240;
private static void CopyStream(Stream origin, Stream target) {
var buffer = new byte[STREAM_COPY_CHUNK_SIZE];
int len;
while ((len = origin.Read(buffer, 0, STREAM_COPY_CHUNK_SIZE)) > 0) {
target.Write(buffer, 0, len);
}
//target.Flush();
}
private sealed class EnumerableMemoryStream : IExactSizeEnumerable<TasFrame> {
public EnumerableMemoryStream(MemoryStream mem, int frameCnt) {
m_MemoryStream = mem;
m_FrameCount = frameCnt;
}
private MemoryStream m_MemoryStream;
private int m_FrameCount;
public IEnumerator<TasFrame> GetEnumerator() {
// Get the view of underlying array
var memory = m_MemoryStream.GetBuffer().AsMemory();
// Get the span which actually storing the data,
// because the length of buffer is equal or longer than the length of all stored data.
var exactMemory = memory.Slice(0, m_FrameCount * SIZEOF_RAW_TAS_FRAME);
// Convert to raw frame type.
var frameMemory = exactMemory.Cast<byte, RawTasFrame>();
// Map it and return.
return MemoryMarshal.ToEnumerable<RawTasFrame>(frameMemory).Select((rawFrame) => TasFrame.FromRaw(rawFrame)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public int GetCount() {
return m_FrameCount;
}
}
}
}

View File

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>Frontend\Assets\App.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Resource Include="Frontend\Assets\*.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="DotNetZip" Version="1.9.1.8" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.5" />
</ItemGroup>
<ItemGroup>
<Folder Include="Frontend\Models\" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Some files were not shown because too many files have changed in this diff Show More