Browse Source

Merge pull request #414 from PixiEditor/prototype-integration

Prototype integration
Krzysztof Krysiński 2 years ago
parent
commit
00d4de7456
100 changed files with 0 additions and 4844 deletions
  1. 0 11
      PixiEditor.UpdateInstaller/App.xaml.cs
  2. 0 27
      PixiEditor.UpdateInstaller/Extensions.cs
  3. 0 43
      PixiEditor.UpdateInstaller/MainWindow.xaml.cs
  4. 0 17
      PixiEditor.UpdateInstaller/ViewModelBase.cs
  5. 0 60
      PixiEditor.UpdateInstaller/ViewModelMain.cs
  6. 0 16
      PixiEditor.UpdateModule/Asset.cs
  7. 0 30
      PixiEditor.UpdateModule/ReleaseInfo.cs
  8. 0 26
      PixiEditor.UpdateModule/UpdateChannel.cs
  9. 0 105
      PixiEditor.UpdateModule/UpdateChecker.cs
  10. 0 65
      PixiEditor.UpdateModule/UpdateDownloader.cs
  11. 0 73
      PixiEditor.UpdateModule/UpdateInstaller.cs
  12. 0 14
      PixiEditor.UpdateModule/UpdateProgressChangedEventArgs.cs
  13. 0 210
      PixiEditor.sln
  14. 0 131
      PixiEditor/App.xaml.cs
  15. 0 30
      PixiEditor/Exceptions/CorruptedFileException.cs
  16. 0 33
      PixiEditor/Helpers/Behaviours/ClearFocusOnClickBehavior.cs
  17. 0 38
      PixiEditor/Helpers/Behaviours/GlobalShortcutFocusBehavior.cs
  18. 0 33
      PixiEditor/Helpers/Behaviours/TextBlockExtensions.cs
  19. 0 133
      PixiEditor/Helpers/Behaviours/TextBoxFocusBehavior.cs
  20. 0 21
      PixiEditor/Helpers/BindingProxy.cs
  21. 0 45
      PixiEditor/Helpers/ClipboardHelper.cs
  22. 0 27
      PixiEditor/Helpers/Converters/BoolToIntConverter.cs
  23. 0 24
      PixiEditor/Helpers/Converters/CountToVisibilityConverter.cs
  24. 0 19
      PixiEditor/Helpers/Converters/DebugConverter.cs
  25. 0 20
      PixiEditor/Helpers/Converters/DoubleToIntConverter.cs
  26. 0 18
      PixiEditor/Helpers/Converters/EmptyStringToVisibilityConverter.cs
  27. 0 37
      PixiEditor/Helpers/Converters/EnumBooleanConverter.cs
  28. 0 29
      PixiEditor/Helpers/Converters/EnumToStringConverter.cs
  29. 0 27
      PixiEditor/Helpers/Converters/EqualityBoolToVisibilityConverter.cs
  30. 0 42
      PixiEditor/Helpers/Converters/FileExtensionToColorConverter.cs
  31. 0 18
      PixiEditor/Helpers/Converters/FloorConverter.cs
  32. 0 28
      PixiEditor/Helpers/Converters/FormattedColorConverter.cs
  33. 0 23
      PixiEditor/Helpers/Converters/IndentConverter.cs
  34. 0 23
      PixiEditor/Helpers/Converters/IndexOfConverter.cs
  35. 0 23
      PixiEditor/Helpers/Converters/IndexToAssociatedKeyConverter.cs
  36. 0 20
      PixiEditor/Helpers/Converters/IntToPickerTypeConverter.cs
  37. 0 18
      PixiEditor/Helpers/Converters/IntToViewportRectConverter.cs
  38. 0 17
      PixiEditor/Helpers/Converters/InverseBooleanConverter.cs
  39. 0 17
      PixiEditor/Helpers/Converters/IsSpecifiedTypeConverter.cs
  40. 0 26
      PixiEditor/Helpers/Converters/KeyToStringConverter.cs
  41. 0 53
      PixiEditor/Helpers/Converters/LayerStructureToGroupsConverter.cs
  42. 0 112
      PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs
  43. 0 26
      PixiEditor/Helpers/Converters/MarkupConverter.cs
  44. 0 19
      PixiEditor/Helpers/Converters/MultiValueMarkupConverter.cs
  45. 0 23
      PixiEditor/Helpers/Converters/NotNullToBoolConverter.cs
  46. 0 26
      PixiEditor/Helpers/Converters/NotNullToVisibilityConverter.cs
  47. 0 15
      PixiEditor/Helpers/Converters/NullToVisibilityConverter.cs
  48. 0 31
      PixiEditor/Helpers/Converters/OppositeVisibilityConverter.cs
  49. 0 23
      PixiEditor/Helpers/Converters/PaletteItemsToWidthConverter.cs
  50. 0 32
      PixiEditor/Helpers/Converters/SKColorToMediaColorConverter.cs
  51. 0 23
      PixiEditor/Helpers/Converters/SingleInstanceConverter.cs
  52. 0 20
      PixiEditor/Helpers/Converters/SingleInstanceMultiValueConverter.cs
  53. 0 20
      PixiEditor/Helpers/Converters/ThresholdVisibilityConverter.cs
  54. 0 34
      PixiEditor/Helpers/Converters/ToolSizeToIntConverter.cs
  55. 0 23
      PixiEditor/Helpers/Converters/ViewboxInverseTransformConverter.cs
  56. 0 27
      PixiEditor/Helpers/Converters/WidthToBitmapScalingModeConverter.cs
  57. 0 22
      PixiEditor/Helpers/Converters/ZoomLevelToBitmapScalingModeConverter.cs
  58. 0 22
      PixiEditor/Helpers/Converters/ZoomToViewportConverter.cs
  59. 0 85
      PixiEditor/Helpers/CoordinatesHelper.cs
  60. 0 102
      PixiEditor/Helpers/CrashHelper.cs
  61. 0 61
      PixiEditor/Helpers/DependencyInjectionHelper.cs
  62. 0 36
      PixiEditor/Helpers/DesignCommandHelpers.cs
  63. 0 168
      PixiEditor/Helpers/EllipseGenerator.cs
  64. 0 13
      PixiEditor/Helpers/ExecutionTrigger.cs
  65. 0 30
      PixiEditor/Helpers/Extensions/DictionaryHelper.cs
  66. 0 19
      PixiEditor/Helpers/Extensions/DirectoryExtensions.cs
  67. 0 36
      PixiEditor/Helpers/Extensions/EnumHelpers.cs
  68. 0 97
      PixiEditor/Helpers/Extensions/EnumerableHelpers.cs
  69. 0 60
      PixiEditor/Helpers/Extensions/Int32RectHelper.cs
  70. 0 167
      PixiEditor/Helpers/Extensions/ParserHelpers.cs
  71. 0 73
      PixiEditor/Helpers/Extensions/PixelFormatHelper.cs
  72. 0 13
      PixiEditor/Helpers/Extensions/SKRectIHelper.cs
  73. 0 69
      PixiEditor/Helpers/Extensions/ServiceCollectionHelpers.cs
  74. 0 14
      PixiEditor/Helpers/Extensions/SkiaWPFHelpers.cs
  75. 0 32
      PixiEditor/Helpers/Extensions/StringHelpers.cs
  76. 0 15
      PixiEditor/Helpers/Extensions/ToolbarHelpers.cs
  77. 0 149
      PixiEditor/Helpers/GlobalMouseHook.cs
  78. 0 86
      PixiEditor/Helpers/InputKeyHelpers.cs
  79. 0 31
      PixiEditor/Helpers/PaletteHelpers.cs
  80. 0 19
      PixiEditor/Helpers/ProcessHelpers.cs
  81. 0 71
      PixiEditor/Helpers/RelayCommand.cs
  82. 0 46
      PixiEditor/Helpers/SelectionHelpers.cs
  83. 0 20
      PixiEditor/Helpers/SizeCalculator.cs
  84. 0 13
      PixiEditor/Helpers/StringExtensions.cs
  85. 0 97
      PixiEditor/Helpers/SupportedFilesHelper.cs
  86. 0 28
      PixiEditor/Helpers/UI/DocumentsTemplateSelector.cs
  87. 0 20
      PixiEditor/Helpers/UI/PanelsStyleSelector.cs
  88. 0 45
      PixiEditor/Helpers/UI/ReversedOrderStackPanel.cs
  89. 0 21
      PixiEditor/Helpers/UI/TreeViewItemHelper.cs
  90. 0 48
      PixiEditor/Helpers/VersionHelpers.cs
  91. 0 101
      PixiEditor/Helpers/WindowSizeHelper.cs
  92. 0 155
      PixiEditor/Models/Colors/ExColor.cs
  93. 0 17
      PixiEditor/Models/Commands/Attributes/Commands/DebugAttribute.cs
  94. 0 22
      PixiEditor/Models/Commands/Attributes/Commands/GroupAttribute.cs
  95. 0 27
      PixiEditor/Models/Commands/Attributes/Commands/InternalAttribute.cs
  96. 0 84
      PixiEditor/Models/Commands/CommandCollection.cs
  97. 0 358
      PixiEditor/Models/Commands/CommandController.cs
  98. 0 55
      PixiEditor/Models/Commands/CommandGroup.cs
  99. 0 16
      PixiEditor/Models/Commands/Commands/BasicCommand.cs
  100. 0 57
      PixiEditor/Models/Commands/Commands/Command.cs

+ 0 - 11
PixiEditor.UpdateInstaller/App.xaml.cs

@@ -1,11 +0,0 @@
-using System.Windows;
-
-namespace PixiEditor.UpdateInstaller
-{
-    /// <summary>
-    ///     Interaction logic for App.xaml.
-    /// </summary>
-    public partial class App : Application
-    {
-    }
-}

+ 0 - 27
PixiEditor.UpdateInstaller/Extensions.cs

@@ -1,27 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace PixiEditor.UpdateInstaller
-{
-    public static class Extensions
-    {
-        private const int MaxPath = 255;
-
-        public static string GetExecutablePath()
-        {
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            {
-                StringBuilder sb = new StringBuilder(MaxPath);
-                GetModuleFileName(IntPtr.Zero, sb, MaxPath);
-                return sb.ToString();
-            }
-
-            return Process.GetCurrentProcess().MainModule?.FileName;
-        }
-
-        [DllImport("kernel32.dll")]
-        private static extern uint GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize);
-    }
-}

+ 0 - 43
PixiEditor.UpdateInstaller/MainWindow.xaml.cs

@@ -1,43 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Threading.Tasks;
-using System.Windows;
-
-namespace PixiEditor.UpdateInstaller
-{
-    /// <summary>
-    ///     Interaction logic for MainWindow.xaml.
-    /// </summary>
-    public partial class MainWindow
-    {
-        public MainWindow()
-        {
-            InitializeComponent();
-            DataContext = new ViewModelMain();
-        }
-
-        private async void Window_Loaded(object sender, RoutedEventArgs e)
-        {
-            ViewModelMain vmm = (ViewModelMain)DataContext;
-            await Task.Run(() =>
-            {
-                try
-                {
-                    vmm.InstallUpdate();
-                }
-                catch (Exception ex)
-                {
-                    MessageBox.Show(ex.Message, "Update error", MessageBoxButton.OK, MessageBoxImage.Error);
-                    File.AppendAllText("ErrorLog.txt", $"Error PixiEditor.UpdateInstaller: {DateTime.Now}\n{ex.Message}\n{ex.StackTrace}\n-----\n");
-                }
-                finally
-                {
-                    string pixiEditorExecutablePath = Directory.GetFiles(vmm.UpdateDirectory, "PixiEditor.exe")[0];
-                    Process.Start(pixiEditorExecutablePath);
-                }
-            });
-            Close();
-        }
-    }
-}

+ 0 - 17
PixiEditor.UpdateInstaller/ViewModelBase.cs

@@ -1,17 +0,0 @@
-using System.ComponentModel;
-
-namespace PixiEditor.UpdateInstaller
-{
-    public class ViewModelBase : INotifyPropertyChanged
-    {
-        public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
-
-        protected void RaisePropertyChanged(string property)
-        {
-            if (property != null)
-            {
-                PropertyChanged(this, new PropertyChangedEventArgs(property));
-            }
-        }
-    }
-}

+ 0 - 60
PixiEditor.UpdateInstaller/ViewModelMain.cs

@@ -1,60 +0,0 @@
-using System;
-using System.IO;
-using PixiEditor.UpdateModule;
-
-namespace PixiEditor.UpdateInstaller
-{
-    public class ViewModelMain : ViewModelBase
-    {
-        private float progressValue;
-
-        public ViewModelMain()
-        {
-            Current = this;
-
-            string updateDirectory = Path.GetDirectoryName(Extensions.GetExecutablePath());
-
-#if DEBUG
-            updateDirectory = Environment.GetCommandLineArgs()[1];
-#endif
-            UpdateDirectory = updateDirectory;
-        }
-
-        public ViewModelMain Current { get; private set; }
-
-        public UpdateModule.UpdateInstaller Installer { get; set; }
-
-        public string UpdateDirectory { get; private set; }
-
-        public float ProgressValue
-        {
-            get => progressValue;
-            set
-            {
-                progressValue = value;
-                RaisePropertyChanged(nameof(ProgressValue));
-            }
-        }
-
-        public void InstallUpdate()
-        {
-            string[] files = Directory.GetFiles(UpdateDownloader.DownloadLocation, "update-*.zip");
-
-            if (files.Length > 0)
-            {
-                Installer = new UpdateModule.UpdateInstaller(files[0], UpdateDirectory);
-                Installer.ProgressChanged += Installer_ProgressChanged;
-                Installer.Install();
-            }
-            else
-            {
-                ProgressValue = 100;
-            }
-        }
-
-        private void Installer_ProgressChanged(object sender, UpdateProgressChangedEventArgs e)
-        {
-            ProgressValue = e.Progress;
-        }
-    }
-}

+ 0 - 16
PixiEditor.UpdateModule/Asset.cs

@@ -1,16 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace PixiEditor.UpdateModule
-{
-    public class Asset
-    {
-        [JsonPropertyName("url")]
-        public string Url { get; set; }
-
-        [JsonPropertyName("name")]
-        public string Name { get; set; }
-
-        [JsonPropertyName("content_type")]
-        public string ContentType { get; set; }
-    }
-}

+ 0 - 30
PixiEditor.UpdateModule/ReleaseInfo.cs

@@ -1,30 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace PixiEditor.UpdateModule
-{
-    public class ReleaseInfo
-    {
-        public ReleaseInfo()
-        {
-        }
-
-        public ReleaseInfo(bool dataFetchSuccessful)
-        {
-            WasDataFetchSuccessful = dataFetchSuccessful;
-        }
-
-        [JsonPropertyName("tag_name")]
-        public string TagName { get; set; }
-
-        [JsonPropertyName("draft")]
-        public bool IsDraft { get; set; }
-
-        [JsonPropertyName("prerelease")]
-        public bool IsPrerelease { get; set; }
-
-        [JsonPropertyName("assets")]
-        public Asset[] Assets { get; set; }
-
-        public bool WasDataFetchSuccessful { get; set; } = true;
-    }
-}

+ 0 - 26
PixiEditor.UpdateModule/UpdateChannel.cs

@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.UpdateModule
-{
-    public class UpdateChannel
-    {
-        public string Name { get; }
-        public string RepositoryOwner { get; }
-        public string RepositoryName { get; }
-        public string ApiUrl { get; } 
-        public string IncompatibleFileApiUrl { get; }
-
-        public UpdateChannel(string name, string repositoryOwner, string repositoryName)
-        {
-            Name = name;
-            RepositoryOwner = repositoryOwner;
-            RepositoryName = repositoryName;
-            ApiUrl = $"https://api.github.com/repos/{repositoryOwner}/{repositoryName}/releases/latest";
-            IncompatibleFileApiUrl = "https://raw.githubusercontent.com/" + $"{repositoryOwner}/{repositoryName}/" + "{0}/incompatible.json";
-        }
-    }
-}

+ 0 - 105
PixiEditor.UpdateModule/UpdateChecker.cs

@@ -1,105 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace PixiEditor.UpdateModule
-{
-    public class UpdateChecker
-    {
-        public UpdateChecker(string currentVersionTag, UpdateChannel channel)
-        {
-            CurrentVersionTag = currentVersionTag;
-            Channel = channel;
-        }
-
-        public ReleaseInfo LatestReleaseInfo { get; private set; }
-
-        public UpdateChannel Channel { get; set; }
-
-        public string CurrentVersionTag { get; }
-
-        /// <summary>
-        ///     Compares version strings and returns true if newVer > originalVer.
-        /// </summary>
-        /// <param name="originalVer">Version to compare.</param>
-        /// <param name="newVer">Version to compare with.</param>
-        /// <returns>True if semantic version is higher.</returns>
-        public static bool VersionBigger(string originalVer, string newVer)
-        {
-            if (!ParseVersionString(originalVer, out float ver1))
-            {
-                return false;
-            }
-
-            if (ParseVersionString(newVer, out float ver2))
-            {
-                return ver2 > ver1;
-            }
-
-            return false;
-        }
-
-        public async Task<bool> CheckUpdateAvailable()
-        {
-            LatestReleaseInfo = await GetLatestReleaseInfoAsync(Channel.ApiUrl);
-            return CheckUpdateAvailable(LatestReleaseInfo);
-        }
-
-        public bool CheckUpdateAvailable(ReleaseInfo latestRelease)
-        {
-            return latestRelease.WasDataFetchSuccessful && VersionBigger(CurrentVersionTag, latestRelease.TagName);
-        }
-
-        public bool IsUpdateCompatible(string[] incompatibleVersions)
-        {
-            return !incompatibleVersions.Select(x => x.Trim()).Contains(CurrentVersionTag[..7].Trim());
-        }
-
-        public async Task<bool> IsUpdateCompatible()
-        {
-            string[] incompatibleVersions = await GetUpdateIncompatibleVersionsAsync(LatestReleaseInfo.TagName);
-            return IsUpdateCompatible(incompatibleVersions);
-        }
-
-        public async Task<string[]> GetUpdateIncompatibleVersionsAsync(string tag)
-        {
-            using (HttpClient client = new HttpClient())
-            {
-                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
-                HttpResponseMessage response = await client.GetAsync(string.Format(Channel.IncompatibleFileApiUrl, tag));
-                if (response.StatusCode == HttpStatusCode.OK)
-                {
-                    string content = await response.Content.ReadAsStringAsync();
-                    return JsonSerializer.Deserialize<string[]>(content);
-                }
-            }
-
-            return Array.Empty<string>();
-        }
-
-        private static async Task<ReleaseInfo> GetLatestReleaseInfoAsync(string apiUrl)
-        {
-            using (HttpClient client = new HttpClient())
-            {
-                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
-                HttpResponseMessage response = await client.GetAsync(apiUrl);
-                if (response.StatusCode == HttpStatusCode.OK)
-                {
-                    string content = await response.Content.ReadAsStringAsync();
-                    return JsonSerializer.Deserialize<ReleaseInfo>(content);
-                }
-            }
-
-            return new ReleaseInfo(false);
-        }
-
-        private static bool ParseVersionString(string versionString, out float version)
-        {
-            return float.TryParse(versionString[..7].Replace(".", string.Empty).Insert(1, "."), NumberStyles.Any, CultureInfo.InvariantCulture, out version);
-        }
-    }
-}

+ 0 - 65
PixiEditor.UpdateModule/UpdateDownloader.cs

@@ -1,65 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-
-namespace PixiEditor.UpdateModule
-{
-    public static class UpdateDownloader
-    {
-        public static string DownloadLocation { get; } = Path.Join(Path.GetTempPath(), "PixiEditor");
-
-        public static async Task DownloadReleaseZip(ReleaseInfo release)
-        {
-            Asset matchingAsset = GetMatchingAsset(release);
-
-            using (HttpClient client = new HttpClient())
-            {
-                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
-                client.DefaultRequestHeaders.Add("Accept", "application/octet-stream");
-                var response = await client.GetAsync(matchingAsset.Url);
-                if (response.StatusCode == HttpStatusCode.OK)
-                {
-                    byte[] bytes = await response.Content.ReadAsByteArrayAsync();
-                    CreateTempDirectory();
-                    File.WriteAllBytes(Path.Join(DownloadLocation, $"update-{release.TagName}.zip"), bytes);
-                }
-            }
-        }
-
-        public static async Task DownloadInstaller(ReleaseInfo info)
-        {
-            Asset matchingAsset = GetMatchingAsset(info, "application/x-msdownload");
-
-            using (HttpClient client = new HttpClient())
-            {
-                client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
-                client.DefaultRequestHeaders.Add("Accept", "application/octet-stream");
-                var response = await client.GetAsync(matchingAsset.Url);
-                if (response.StatusCode == HttpStatusCode.OK)
-                {
-                    byte[] bytes = await response.Content.ReadAsByteArrayAsync();
-                    CreateTempDirectory();
-                    File.WriteAllBytes(Path.Join(DownloadLocation, $"update-{info.TagName}.exe"), bytes);
-                }
-            }
-        }
-
-        public static void CreateTempDirectory()
-        {
-            if (!Directory.Exists(DownloadLocation))
-            {
-                Directory.CreateDirectory(DownloadLocation);
-            }
-        }
-
-        private static Asset GetMatchingAsset(ReleaseInfo release, string assetType = "zip")
-        {
-            string arch = IntPtr.Size == 8 ? "x64" : "x86";
-            return release.Assets.First(x => x.ContentType.Contains(assetType)
-            && x.Name.Contains(arch));
-        }
-    }
-}

+ 0 - 73
PixiEditor.UpdateModule/UpdateInstaller.cs

@@ -1,73 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.IO.Compression;
-
-namespace PixiEditor.UpdateModule
-{
-    public class UpdateInstaller
-    {
-        public const string TargetDirectoryName = "UpdateFiles";
-
-        private float progress = 0;
-
-        public UpdateInstaller(string archiveFileName, string targetDirectory)
-        {
-            ArchiveFileName = archiveFileName;
-            TargetDirectory = targetDirectory;
-        }
-
-        public event EventHandler<UpdateProgressChangedEventArgs> ProgressChanged;
-
-        public static string UpdateFilesPath { get; set; } = Path.Join(UpdateDownloader.DownloadLocation, TargetDirectoryName);
-
-        public float Progress
-        {
-            get => progress;
-            set
-            {
-                progress = value;
-                ProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(value));
-            }
-        }
-
-        public string ArchiveFileName { get; set; }
-
-        public string TargetDirectory { get; set; }
-
-        public void Install()
-        {
-            var processes = Process.GetProcessesByName("PixiEditor");
-            if (processes.Length > 0)
-            {
-                processes[0].WaitForExit();
-            }
-
-            ZipFile.ExtractToDirectory(ArchiveFileName, UpdateFilesPath, true);
-            Progress = 25; // 25% for unzip
-            string dirWithFiles = Directory.GetDirectories(UpdateFilesPath)[0];
-            string[] files = Directory.GetFiles(dirWithFiles);
-            CopyFilesToDestination(files);
-            DeleteArchive();
-            Progress = 100;
-        }
-
-        private void DeleteArchive()
-        {
-            File.Delete(ArchiveFileName);
-            Directory.Delete(UpdateFilesPath, true);
-        }
-
-        private void CopyFilesToDestination(string[] files)
-        {
-            float fileCopiedVal = 74f / files.Length; // 74% is reserved for copying
-            string destinationDir = TargetDirectory;
-            foreach (string file in files)
-            {
-                string targetFileName = Path.GetFileName(file);
-                File.Copy(file, Path.Join(destinationDir, targetFileName), true);
-                Progress += fileCopiedVal;
-            }
-        }
-    }
-}

+ 0 - 14
PixiEditor.UpdateModule/UpdateProgressChangedEventArgs.cs

@@ -1,14 +0,0 @@
-using System;
-
-namespace PixiEditor.UpdateModule
-{
-    public class UpdateProgressChangedEventArgs : EventArgs
-    {
-        public UpdateProgressChangedEventArgs(float progress)
-        {
-            Progress = progress;
-        }
-
-        public float Progress { get; set; }
-    }
-}

+ 0 - 210
PixiEditor.sln

@@ -1,210 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.1.31911.260
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixiEditor", "PixiEditor\PixiEditor.csproj", "{2CCDDE79-06CB-4771-AF85-7B25313EBA30}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixiEditor.UpdateInstaller", "PixiEditor.UpdateInstaller\PixiEditor.UpdateInstaller.csproj", "{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixiEditor.UpdateModule", "PixiEditor.UpdateModule\PixiEditor.UpdateModule.csproj", "{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PixiEditorTests", "PixiEditorTests\PixiEditorTests.csproj", "{5193C1C1-8362-40FD-802B-E097E8C88082}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildConfiguration", "BuildConfiguration", "{9337E60D-8425-4E87-950C-F07A09518081}"
-	ProjectSection(SolutionItems) = preProject
-		Custom.ruleset = Custom.ruleset
-		Directory.Build.props = Directory.Build.props
-		stylecop.json = stylecop.json
-	EndProjectSection
-EndProject
-Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "PixiEditor.MSIX", "PixiEditor.MSIX\PixiEditor.MSIX.wapproj", "{1F97F972-F9E8-4F35-A8B5-3F71408D2230}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Debug|x64 = Debug|x64
-		Debug|x86 = Debug|x86
-		Dev Release|Any CPU = Dev Release|Any CPU
-		Dev Release|x64 = Dev Release|x64
-		Dev Release|x86 = Dev Release|x86
-		MSIX Debug|Any CPU = MSIX Debug|Any CPU
-		MSIX Debug|x64 = MSIX Debug|x64
-		MSIX Debug|x86 = MSIX Debug|x86
-		MSIX|Any CPU = MSIX|Any CPU
-		MSIX|x64 = MSIX|x64
-		MSIX|x86 = MSIX|x86
-		Release|Any CPU = Release|Any CPU
-		Release|x64 = Release|x64
-		Release|x86 = Release|x86
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|x64.ActiveCfg = Debug|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|x64.Build.0 = Debug|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|x86.ActiveCfg = Debug|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Debug|x86.Build.0 = Debug|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|Any CPU.ActiveCfg = Dev Release|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|Any CPU.Build.0 = Dev Release|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|x64.ActiveCfg = Dev Release|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|x64.Build.0 = Dev Release|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|x86.ActiveCfg = Dev Release|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Dev Release|x86.Build.0 = Dev Release|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|Any CPU.ActiveCfg = MSIX Debug|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|Any CPU.Build.0 = MSIX Debug|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|x64.ActiveCfg = MSIX Debug|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|x64.Build.0 = MSIX Debug|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|x86.ActiveCfg = Debug|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX Debug|x86.Build.0 = Debug|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|Any CPU.ActiveCfg = MSIX|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|Any CPU.Build.0 = MSIX|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|x64.ActiveCfg = MSIX|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|x64.Build.0 = MSIX|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|x86.ActiveCfg = Release|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.MSIX|x86.Build.0 = Release|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|x64.ActiveCfg = Release|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|x64.Build.0 = Release|x64
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|x86.ActiveCfg = Release|x86
-		{2CCDDE79-06CB-4771-AF85-7B25313EBA30}.Release|x86.Build.0 = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|x64.ActiveCfg = Debug|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|x64.Build.0 = Debug|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|x86.ActiveCfg = Debug|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Debug|x86.Build.0 = Debug|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|Any CPU.ActiveCfg = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|Any CPU.Build.0 = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|x64.ActiveCfg = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|x64.Build.0 = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|x86.ActiveCfg = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Dev Release|x86.Build.0 = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|Any CPU.Build.0 = Debug|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|x64.ActiveCfg = Debug|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|x64.Build.0 = Debug|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|x86.ActiveCfg = Debug|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX Debug|x86.Build.0 = Debug|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|Any CPU.ActiveCfg = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|Any CPU.Build.0 = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|x64.ActiveCfg = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|x64.Build.0 = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|x86.ActiveCfg = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.MSIX|x86.Build.0 = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|Any CPU.Build.0 = Release|Any CPU
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|x64.ActiveCfg = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|x64.Build.0 = Release|x64
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|x86.ActiveCfg = Release|x86
-		{41B40602-2E8C-4B76-9BDB-B9FDE686ACCE}.Release|x86.Build.0 = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|x64.ActiveCfg = Debug|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|x64.Build.0 = Debug|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|x86.ActiveCfg = Debug|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Debug|x86.Build.0 = Debug|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|Any CPU.ActiveCfg = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|Any CPU.Build.0 = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|x64.ActiveCfg = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|x64.Build.0 = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|x86.ActiveCfg = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Dev Release|x86.Build.0 = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|Any CPU.Build.0 = Debug|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|x64.ActiveCfg = Debug|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|x64.Build.0 = Debug|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|x86.ActiveCfg = Debug|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX Debug|x86.Build.0 = Debug|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|Any CPU.ActiveCfg = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|Any CPU.Build.0 = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|x64.ActiveCfg = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|x64.Build.0 = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|x86.ActiveCfg = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.MSIX|x86.Build.0 = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|Any CPU.Build.0 = Release|Any CPU
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|x64.ActiveCfg = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|x64.Build.0 = Release|x64
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|x86.ActiveCfg = Release|x86
-		{80BB2920-3DC0-406C-9E2B-30B08D5CC7A8}.Release|x86.Build.0 = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|x64.ActiveCfg = Debug|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|x64.Build.0 = Debug|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|x86.ActiveCfg = Debug|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Debug|x86.Build.0 = Debug|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|Any CPU.Build.0 = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|x64.ActiveCfg = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|x64.Build.0 = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|x86.ActiveCfg = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Dev Release|x86.Build.0 = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|x64.ActiveCfg = Debug|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|x64.Build.0 = Debug|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|x86.ActiveCfg = Debug|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX Debug|x86.Build.0 = Debug|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|Any CPU.ActiveCfg = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|Any CPU.Build.0 = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|x64.ActiveCfg = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|x64.Build.0 = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|x86.ActiveCfg = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.MSIX|x86.Build.0 = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|x64.ActiveCfg = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|x64.Build.0 = Release|x64
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|x86.ActiveCfg = Release|x86
-		{5193C1C1-8362-40FD-802B-E097E8C88082}.Release|x86.Build.0 = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x64.ActiveCfg = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x64.Build.0 = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x64.Deploy.0 = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x86.ActiveCfg = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x86.Build.0 = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Debug|x86.Deploy.0 = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|Any CPU.ActiveCfg = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|Any CPU.Build.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|Any CPU.Deploy.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x64.ActiveCfg = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x64.Build.0 = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x64.Deploy.0 = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x86.ActiveCfg = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x86.Build.0 = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Dev Release|x86.Deploy.0 = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|Any CPU.Build.0 = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|Any CPU.Deploy.0 = Debug|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x64.ActiveCfg = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x64.Build.0 = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x64.Deploy.0 = Debug|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x86.ActiveCfg = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x86.Build.0 = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX Debug|x86.Deploy.0 = Debug|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|Any CPU.ActiveCfg = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|Any CPU.Build.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|Any CPU.Deploy.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x64.ActiveCfg = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x64.Build.0 = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x64.Deploy.0 = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x86.ActiveCfg = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x86.Build.0 = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.MSIX|x86.Deploy.0 = Release|x86
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Release|Any CPU.Build.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Release|Any CPU.Deploy.0 = Release|Any CPU
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Release|x64.ActiveCfg = Release|x64
-		{1F97F972-F9E8-4F35-A8B5-3F71408D2230}.Release|x86.ActiveCfg = Release|x86
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-	GlobalSection(ExtensibilityGlobals) = postSolution
-		SolutionGuid = {D04B4AB0-CA33-42FD-A909-79966F9255C5}
-	EndGlobalSection
-EndGlobal

+ 0 - 131
PixiEditor/App.xaml.cs

@@ -1,131 +0,0 @@
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Dialogs;
-using PixiEditor.Models.Enums;
-using PixiEditor.ViewModels;
-using PixiEditor.Views.Dialogs;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Windows;
-using PixiEditor.Models.Controllers;
-using PixiEditor.Models.UserPreferences;
-
-namespace PixiEditor
-{
-    /// <summary>
-    ///     Interaction logic for App.xaml.
-    /// </summary>
-    public partial class App : Application
-    {
-        /// <summary>The event mutex name.</summary>
-        private const string UniqueEventName = "33f1410b-2ad7-412a-a468-34fe0a85747c";
-
-        /// <summary>The unique mutex name.</summary>
-        private const string UniqueMutexName = "ab2afe27-b9ee-4f03-a1e4-c18da16a349c";
-
-        /// <summary>The event wait handle.</summary>
-        private EventWaitHandle _eventWaitHandle;
-
-        private string passedArgsFile = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PixiEditor", ".passedArgs");
-
-        /// <summary>The mutex.</summary>
-        private Mutex _mutex;
-
-        protected override void OnStartup(StartupEventArgs e)
-        {
-            if (HandleNewInstance())
-            {
-                StartupArgs.Args = e.Args.ToList();
-                string arguments = string.Join(' ', e.Args);
-
-                if (ParseArgument("--crash (\"?)([A-z0-9:\\/\\ -_.]+)\\1", arguments, out Group[] groups))
-                {
-                    CrashReport report = CrashReport.Parse(groups[2].Value);
-                    MainWindow = new CrashReportDialog(report);
-                }
-                else
-                {
-                    MainWindow = new MainWindow();
-                }
-
-                MainWindow.Show();
-            }
-        }
-
-        private bool HandleNewInstance()
-        {
-            bool isOwned;
-            _mutex = new Mutex(true, UniqueMutexName, out isOwned);
-            _eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName);
-
-            GC.KeepAlive(_mutex);
-
-            if (isOwned)
-            {
-                var thread = new Thread(
-                    () =>
-                    {
-                        while (_eventWaitHandle.WaitOne())
-                        {
-                            Current.Dispatcher.BeginInvoke(
-                                (Action)(() =>
-                                {
-                                    MainWindow mainWindow = ((MainWindow)Current.MainWindow);
-                                    if (mainWindow != null)
-                                    {
-                                        mainWindow.BringToForeground();
-                                        StartupArgs.Args = File.ReadAllText(passedArgsFile).Split(' ').ToList();
-                                        File.Delete(passedArgsFile);
-                                        StartupArgs.Args.Add("--openedInExisting");
-                                        mainWindow.DataContext.OnStartupCommand.Execute(null);
-                                    }
-                                }));
-                        }
-                    })
-                {
-                    // It is important mark it as background otherwise it will prevent app from exiting.
-                    IsBackground = true
-                };
-
-                thread.Start();
-                return true;
-            }
-
-            // Notify other instance so it could bring itself to foreground.
-            File.WriteAllText(passedArgsFile, string.Join(' ', Environment.GetCommandLineArgs()));
-            _eventWaitHandle.Set();
-
-            // Terminate this instance.
-            Shutdown();
-            return false;
-        }
-
-        protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
-        {
-            base.OnSessionEnding(e);
-
-            if (ViewModelMain.Current.BitmapManager.Documents.Any(x => !x.ChangesSaved))
-            {
-                ConfirmationType confirmation = ConfirmationDialog.Show($"{e.ReasonSessionEnding} with unsaved data. Are you sure?", $"{e.ReasonSessionEnding}");
-                e.Cancel = confirmation != ConfirmationType.Yes;
-            }
-        }
-
-        private bool ParseArgument(string pattern, string args, out Group[] groups)
-        {
-            Match match = Regex.Match(args, pattern, RegexOptions.IgnoreCase);
-            groups = null;
-
-            if (match.Success)
-            {
-                groups = match.Groups.Values.ToArray();
-            }
-
-            return match.Success;
-        }
-    }
-}

+ 0 - 30
PixiEditor/Exceptions/CorruptedFileException.cs

@@ -1,30 +0,0 @@
-using System;
-
-namespace PixiEditor.Exceptions
-{
-    [Serializable]
-    public class CorruptedFileException : Exception
-    {
-        public CorruptedFileException()
-            : base("The file you've chosen might be corrupted.")
-        {
-        }
-
-        public CorruptedFileException(string message)
-            : base(message)
-        {
-        }
-
-        public CorruptedFileException(string message, Exception inner)
-            : base(message, inner)
-        {
-        }
-
-        protected CorruptedFileException(
-          System.Runtime.Serialization.SerializationInfo info,
-          System.Runtime.Serialization.StreamingContext context)
-            : base(info, context)
-        {
-        }
-    }
-}

+ 0 - 33
PixiEditor/Helpers/Behaviours/ClearFocusOnClickBehavior.cs

@@ -1,33 +0,0 @@
-using PixiEditor.Models.Controllers;
-using System.Windows;
-using System.Windows.Input;
-using System.Windows.Interactivity;
-
-namespace PixiEditor.Helpers.Behaviours
-{
-    public class ClearFocusOnClickBehavior : Behavior<FrameworkElement>
-    {
-        protected override void OnAttached()
-        {
-            base.OnAttached();
-            AssociatedObject.MouseDown += AssociatedObject_MouseDown;
-            AssociatedObject.LostKeyboardFocus += AssociatedObject_LostKeyboardFocus;
-        }
-
-        private void AssociatedObject_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
-        {
-            
-        }
-
-        protected override void OnDetaching()
-        {
-            AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
-        }
-
-        private void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
-        {
-            AssociatedObject.Focus();
-            ShortcutController.UnblockShortcutExecutionAll();
-        }
-    }
-}

+ 0 - 38
PixiEditor/Helpers/Behaviours/GlobalShortcutFocusBehavior.cs

@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Interactivity;
-using PixiEditor.Models.Controllers;
-
-namespace PixiEditor.Helpers.Behaviours
-{
-    public class GlobalShortcutFocusBehavior : Behavior<FrameworkElement>
-    {
-        protected override void OnAttached()
-        {
-            base.OnAttached();
-            AssociatedObject.GotKeyboardFocus += AssociatedObject_GotKeyboardFocus;
-            AssociatedObject.LostKeyboardFocus += AssociatedObject_LostKeyboardFocus;
-        }
-
-        protected override void OnDetaching()
-        {
-            base.OnDetaching();
-            AssociatedObject.GotKeyboardFocus -= AssociatedObject_GotKeyboardFocus;
-            AssociatedObject.LostKeyboardFocus -= AssociatedObject_LostKeyboardFocus;
-        }
-
-        private void AssociatedObject_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
-        {
-            ShortcutController.UnblockShortcutExecution("GlobalShortcutFocusBehavior");
-        }
-
-        private void AssociatedObject_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
-        {
-            ShortcutController.BlockShortcutExection("GlobalShortcutFocusBehavior");
-        }
-    }
-}

+ 0 - 33
PixiEditor/Helpers/Behaviours/TextBlockExtensions.cs

@@ -1,33 +0,0 @@
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-
-namespace PixiEditor.Helpers.Behaviours
-{
-    public static class TextBlockExtensions
-    {
-        public static IEnumerable<Inline> GetBindableInlines(DependencyObject obj)
-        {
-            return (IEnumerable<Inline>)obj.GetValue(BindableInlinesProperty);
-        }
-
-        public static void SetBindableInlines(DependencyObject obj, IEnumerable<Inline> value)
-        {
-            obj.SetValue(BindableInlinesProperty, value);
-        }
-
-        public static readonly DependencyProperty BindableInlinesProperty =
-            DependencyProperty.RegisterAttached("BindableInlines", typeof(IEnumerable<Inline>), typeof(TextBlockExtensions), new PropertyMetadata(null, OnBindableInlinesChanged));
-
-        private static void OnBindableInlinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
-        {
-            if (d is not TextBlock target)
-            {
-                return;
-            }
-
-            target.Inlines.Clear();
-            target.Inlines.AddRange((System.Collections.IEnumerable)e.NewValue);
-        }
-    }
-}

+ 0 - 133
PixiEditor/Helpers/Behaviours/TextBoxFocusBehavior.cs

@@ -1,133 +0,0 @@
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Interactivity;
-
-namespace PixiEditor.Helpers.Behaviours
-{
-    internal class TextBoxFocusBehavior : Behavior<TextBox>
-    {
-        public static readonly DependencyProperty SelectOnMouseClickProperty =
-            DependencyProperty.Register(
-                nameof(SelectOnMouseClick),
-                typeof(bool),
-                typeof(TextBoxFocusBehavior),
-                new PropertyMetadata(false));
-
-        public static readonly DependencyProperty ConfirmOnEnterProperty =
-            DependencyProperty.Register(
-                nameof(ConfirmOnEnter),
-                typeof(bool),
-                typeof(TextBoxFocusBehavior),
-                new PropertyMetadata(false));
-
-        public static readonly DependencyProperty DeselectOnFocusLossProperty =
-            DependencyProperty.Register(
-                nameof(DeselectOnFocusLoss),
-                typeof(bool),
-                typeof(TextBoxFocusBehavior),
-                new PropertyMetadata(false));
-
-        public bool SelectOnMouseClick
-        {
-            get => (bool)GetValue(SelectOnMouseClickProperty);
-            set => SetValue(SelectOnMouseClickProperty, value);
-        }
-
-        public bool ConfirmOnEnter
-        {
-            get => (bool)GetValue(ConfirmOnEnterProperty);
-            set => SetValue(ConfirmOnEnterProperty, value);
-        }
-        public bool DeselectOnFocusLoss
-        {
-            get => (bool)GetValue(DeselectOnFocusLossProperty);
-            set => SetValue(DeselectOnFocusLossProperty, value);
-        }
-
-        public static readonly DependencyProperty FocusNextProperty = DependencyProperty.Register(nameof(FocusNext), typeof(bool), typeof(TextBoxFocusBehavior), new PropertyMetadata(false));
-
-        public bool FocusNext
-        {
-            get { return (bool)GetValue(FocusNextProperty); }
-            set { SetValue(FocusNextProperty, value); }
-        }
-
-        protected override void OnAttached()
-        {
-            base.OnAttached();
-            AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
-            AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
-            AssociatedObject.LostFocus += AssociatedObject_LostFocus;
-            AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
-            AssociatedObject.KeyUp += AssociatedObject_KeyUp;
-        }
-
-        protected override void OnDetaching()
-        {
-            base.OnDetaching();
-            AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
-            AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
-            AssociatedObject.LostFocus -= AssociatedObject_LostFocus;
-            AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
-            AssociatedObject.KeyUp -= AssociatedObject_KeyUp;
-        }
-
-        // Converts number to proper format if enter is clicked and moves focus to next object
-        private void AssociatedObject_KeyUp(object sender, KeyEventArgs e)
-        {
-            if (e.Key != Key.Enter || !ConfirmOnEnter)
-                return;
-
-            RemoveFocus();
-        }
-
-        private void RemoveFocus()
-        {
-            if (!FocusNext)
-            {
-                MainWindow.Current.mainGrid.Focus();
-            }
-            else
-            {
-                AssociatedObject.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
-            }
-
-        }
-
-        private void AssociatedObjectGotKeyboardFocus(
-            object sender,
-            KeyboardFocusChangedEventArgs e)
-        {
-            if (SelectOnMouseClick || e.KeyboardDevice.IsKeyDown(Key.Tab))
-                AssociatedObject.SelectAll();
-        }
-
-        private void AssociatedObjectGotMouseCapture(
-            object sender,
-            MouseEventArgs e)
-        {
-            if (SelectOnMouseClick)
-                AssociatedObject.SelectAll();
-        }
-
-        private void AssociatedObject_LostFocus(object sender, RoutedEventArgs e)
-        {
-            if (DeselectOnFocusLoss)
-                AssociatedObject.Select(0, 0);
-            RemoveFocus();
-        }
-
-        private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
-        {
-            if (!SelectOnMouseClick)
-                return;
-
-            if (!AssociatedObject.IsKeyboardFocusWithin)
-            {
-                AssociatedObject.Focus();
-                e.Handled = true;
-            }
-        }
-    }
-}

+ 0 - 21
PixiEditor/Helpers/BindingProxy.cs

@@ -1,21 +0,0 @@
-using System.Windows;
-
-namespace PixiEditor.Helpers
-{
-    public class BindingProxy : Freezable
-    {
-        protected override Freezable CreateInstanceCore()
-        {
-            return new BindingProxy();
-        }
-
-        public object Data
-        {
-            get { return (object)GetValue(DataProperty); }
-            set { SetValue(DataProperty, value); }
-        }
-
-        public static readonly DependencyProperty DataProperty =
-            DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
-    }
-}

+ 0 - 45
PixiEditor/Helpers/ClipboardHelper.cs

@@ -1,45 +0,0 @@
-using System.Windows;
-
-namespace PixiEditor.Helpers
-{
-    class ClipboardHelper
-    {
-        public static bool TrySetDataObject(DataObject obj, bool copy)
-        {
-            try
-            {
-                Clipboard.SetDataObject(obj, copy);
-                return true;
-            }
-            catch
-            {
-                return false;
-            }
-        }
-
-        public static DataObject TryGetDataObject()
-        {
-            try
-            {
-                return (DataObject)Clipboard.GetDataObject();
-            }
-            catch
-            {
-                return null;
-            }
-        }
-
-        public static bool TryClear()
-        {
-            try
-            {
-                Clipboard.Clear();
-                return true;
-            }
-            catch
-            {
-                return false;
-            }
-        }
-    }
-}

+ 0 - 27
PixiEditor/Helpers/Converters/BoolToIntConverter.cs

@@ -1,27 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class BoolToIntConverter
-        : SingleInstanceConverter<BoolToIntConverter>
-    {
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value.ToString() == "0";
-        }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is bool boolean)
-            {
-                if (boolean == false)
-                {
-                    return 0;
-                }
-            }
-
-            return 1;
-        }
-    }
-}

+ 0 - 24
PixiEditor/Helpers/Converters/CountToVisibilityConverter.cs

@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class CountToVisibilityConverter : SingleInstanceConverter<CountToVisibilityConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is int intVal)
-            {
-                return intVal == 0 ? Visibility.Visible : Visibility.Collapsed;
-            }
-
-            return Visibility.Visible;
-        }
-    }
-}

+ 0 - 19
PixiEditor/Helpers/Converters/DebugConverter.cs

@@ -1,19 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class DebugConverter
-        : SingleInstanceConverter<DebugConverter>
-    {
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value;
-        }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value;
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/Converters/DoubleToIntConverter.cs

@@ -1,20 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class DoubleToIntConverter :
-        SingleInstanceConverter<DoubleToIntConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is double or float)
-            {
-                double val = (double)value;
-                return (int)val;
-            }
-
-            return value;
-        }
-    }
-}

+ 0 - 18
PixiEditor/Helpers/Converters/EmptyStringToVisibilityConverter.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class EmptyStringToVisibilityConverter :
-        SingleInstanceConverter<EmptyStringToVisibilityConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return
-                string.IsNullOrEmpty((string)value)
-                ? Visibility.Collapsed
-                : Visibility.Visible;
-        }
-    }
-}

+ 0 - 37
PixiEditor/Helpers/Converters/EnumBooleanConverter.cs

@@ -1,37 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class EnumBooleanConverter : SingleInstanceConverter<EnumBooleanConverter>
-    {
-        #region IValueConverter Members
-        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-        {
-            string parameterString = parameter as string;
-            if (parameterString == null)
-                return DependencyProperty.UnsetValue;
-
-            if (Enum.IsDefined(value.GetType(), value) == false)
-                return DependencyProperty.UnsetValue;
-
-            object parameterValue = Enum.Parse(value.GetType(), parameterString);
-
-            return parameterValue.Equals(value);
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-        {
-            string parameterString = parameter as string;
-            if (parameterString == null)
-                return DependencyProperty.UnsetValue;
-
-            return Enum.Parse(targetType, parameterString);
-        }
-        #endregion
-    }
-}

+ 0 - 29
PixiEditor/Helpers/Converters/EnumToStringConverter.cs

@@ -1,29 +0,0 @@
-using PixiEditor.Models.Enums;
-using System;
-
-namespace PixiEditor.Helpers.Converters
-{
-    internal class EnumToStringConverter : SingleInstanceConverter<EnumToStringConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-        {
-            try
-            {
-                var type = value.GetType();
-                if (type == typeof(SizeUnit))
-                {
-                    var valueCasted = (SizeUnit)value;
-                    if (valueCasted == SizeUnit.Percentage)
-                        return "%";
-
-                    return "px";
-                }
-                return Enum.GetName((value.GetType()), value);
-            }
-            catch
-            {
-                return string.Empty;
-            }
-        }
-    }
-}

+ 0 - 27
PixiEditor/Helpers/Converters/EqualityBoolToVisibilityConverter.cs

@@ -1,27 +0,0 @@
-using System.Globalization;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class EqualityBoolToVisibilityConverter : MarkupConverter
-    {
-        public bool Invert { get; set; }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value == null)
-                return Invert;
-
-            if (value.GetType().IsAssignableTo(typeof(Enum)) && parameter is string s)
-            {
-                parameter = Enum.Parse(value.GetType(), s);
-            }
-            else
-            {
-                parameter = System.Convert.ChangeType(parameter, value.GetType());
-            }
-
-            return value.Equals(parameter) != Invert ? Visibility.Visible : Visibility.Collapsed;
-        }
-    }
-}

+ 0 - 42
PixiEditor/Helpers/Converters/FileExtensionToColorConverter.cs

@@ -1,42 +0,0 @@
-using PixiEditor.Models.Enums;
-using System.Globalization;
-using System.IO;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class FileExtensionToColorConverter :
-        SingleInstanceConverter<FileExtensionToColorConverter>
-    {
-        private static readonly Dictionary<string, SolidColorBrush> extensionsToBrushes;
-        public static readonly SolidColorBrush UnknownBrush = ColorBrush(100, 100, 100);
-
-        static FileExtensionToColorConverter()
-        {
-            extensionsToBrushes = new Dictionary<string, SolidColorBrush>();
-            AssignFormatToBrush(FileType.Unset, UnknownBrush);
-            AssignFormatToBrush(FileType.Pixi, ColorBrush(226, 1, 45));
-            AssignFormatToBrush(FileType.Png, ColorBrush(56, 108, 254));
-            AssignFormatToBrush(FileType.Jpeg, ColorBrush(36, 179, 66));
-            AssignFormatToBrush(FileType.Bmp, ColorBrush(255, 140, 0));
-            AssignFormatToBrush(FileType.Gif, ColorBrush(180, 0, 255));
-        }
-        static void AssignFormatToBrush(FileType format, SolidColorBrush brush)
-        {
-            SupportedFilesHelper.GetFileTypeDialogData(format).Extensions.ForEach(i => extensionsToBrushes[i] = brush);
-        }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
-            GetBrush((string)value);
-
-        public static Brush GetBrush(string path)
-        {
-            return extensionsToBrushes.GetValueOrDefault(Path.GetExtension(path).ToLower(), UnknownBrush);
-        }
-
-        private static SolidColorBrush ColorBrush(byte r, byte g, byte b)
-        {
-            return new SolidColorBrush(Color.FromRgb(r, g, b));
-        }
-    }
-}

+ 0 - 18
PixiEditor/Helpers/Converters/FloorConverter.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class FloorConverter : SingleInstanceConverter<FloorConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return Math.Floor((double)value);
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value;
-        }
-    }
-}

+ 0 - 28
PixiEditor/Helpers/Converters/FormattedColorConverter.cs

@@ -1,28 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class FormattedColorConverter
-        : SingleInstanceMultiValueConverter<FormattedColorConverter>
-    {
-        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (values == null ||
-                values.Length <= 1 ||
-                values[0] is not Color color ||
-                values[1] is not string format)
-            {
-                return "";
-            }
-
-            return format.ToLowerInvariant() switch
-            {
-                "hex" => color.ToString(),
-                "rgba" => $"({color.R}, {color.G}, {color.B}, {color.A})",
-                _ => "",
-            };
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/IndentConverter.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class IndentConverter
-        : SingleInstanceConverter<IndentConverter>
-    {
-        private const int IndentSize = 20;
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return new GridLength(((GridLength)value).Value + IndentSize);
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return Binding.DoNothing;
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/IndexOfConverter.cs

@@ -1,23 +0,0 @@
-using PixiEditor.Models.Layers;
-using PixiEditor.ViewModels;
-using System;
-using System.Globalization;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class IndexOfConverter
-        : SingleInstanceConverter<IndexOfConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is Layer layer && ViewModelMain.Current.BitmapManager.ActiveDocument != null)
-            {
-                int index = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.IndexOf(layer);
-                return index;
-            }
-
-            return Binding.DoNothing;
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/IndexToAssociatedKeyConverter.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class IndexToAssociatedKeyConverter : SingleInstanceConverter<IndexToAssociatedKeyConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if(value is int index && index < 10)
-            {
-                if (index == 9) return 0;
-                return (int?)index + 1;
-            }
-
-            return (int?)null;
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/Converters/IntToPickerTypeConverter.cs

@@ -1,20 +0,0 @@
-using ColorPicker.Models;
-using System;
-using System.Globalization;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class IntToPickerTypeConverter
-        : SingleInstanceConverter<IntToPickerTypeConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return (PickerType)value;
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return (int)value;
-        }
-    }
-}

+ 0 - 18
PixiEditor/Helpers/Converters/IntToViewportRectConverter.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class IntToViewportRectConverter
-        : SingleInstanceConverter<IntToViewportRectConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return parameter is string and "vertical"
-                   ? new Rect(0, 0, 1d / (int)value, 1d)
-                   : (object)new Rect(0, 0, 1d, 1d / (int)value);
-        }
-    }
-}

+ 0 - 17
PixiEditor/Helpers/Converters/InverseBooleanConverter.cs

@@ -1,17 +0,0 @@
-using System;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    [ValueConversion(typeof(bool), typeof(bool))]
-    public class InverseBooleanConverter
-        : SingleInstanceConverter<InverseBooleanConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-        {
-            return targetType != typeof(bool)
-                   ? throw new InvalidOperationException("The target must be a boolean")
-                   : !(bool)value;
-        }
-    }
-}

+ 0 - 17
PixiEditor/Helpers/Converters/IsSpecifiedTypeConverter.cs

@@ -1,17 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    [ValueConversion(typeof(object), typeof(bool))]
-    public class IsSpecifiedTypeConverter : MarkupConverter
-    {
-        public Type SpecifiedType { get; set; }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value != null && value.GetType() == SpecifiedType;
-        }
-    }
-}

+ 0 - 26
PixiEditor/Helpers/Converters/KeyToStringConverter.cs

@@ -1,26 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Input;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class KeyToStringConverter
-        : SingleInstanceConverter<KeyToStringConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is Key key)
-            {
-                return InputKeyHelpers.GetKeyboardKey(key);
-            }
-            else if (value is ModifierKeys)
-            {
-                return value.ToString();
-            }
-            else
-            {
-                return string.Empty;
-            }
-        }
-    }
-}

+ 0 - 53
PixiEditor/Helpers/Converters/LayerStructureToGroupsConverter.cs

@@ -1,53 +0,0 @@
-using PixiEditor.Helpers.Extensions;
-using PixiEditor.Models.Layers;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Globalization;
-using System.Linq;
-using System.Windows.Data;
-using PixiEditor.Models.DataHolders;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class LayerStructureToGroupsConverter
-        : SingleInstanceMultiValueConverter<LayerStructureToGroupsConverter>
-    {
-        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (values[0] is not LayerStructure structure)
-            {
-                return Binding.DoNothing;
-            }
-
-            return GetSubGroups(structure.Groups);
-        }
-
-        private System.Collections.ObjectModel.ObservableCollection<GuidStructureItem> GetSubGroups(IEnumerable<GuidStructureItem> groups)
-        {
-            WpfObservableRangeCollection<GuidStructureItem> finalGroups = new WpfObservableRangeCollection<GuidStructureItem>();
-            foreach (var group in groups)
-            {
-                finalGroups.AddRange(GetSubGroups(group));
-            }
-
-            return finalGroups;
-        }
-
-        private IEnumerable<GuidStructureItem> GetSubGroups(GuidStructureItem group)
-        {
-            List<GuidStructureItem> groups = new List<GuidStructureItem>() { group };
-
-            foreach (var subGroup in group.Subgroups)
-            {
-                groups.Add(subGroup);
-                if (subGroup.Subgroups.Count > 0)
-                {
-                    groups.AddRange(GetSubGroups(subGroup));
-                }
-            }
-
-            return groups.Distinct();
-        }
-    }
-}

+ 0 - 112
PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs

@@ -1,112 +0,0 @@
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Layers;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    // TODO: Implement rebuilding only changed items instead whole tree
-    public class LayersToStructuredLayersConverter
-        : MultiValueMarkupConverter
-    {
-        private static StructuredLayerTree cachedTree;
-        private List<Guid> lastLayerGuids = new List<Guid>();
-        private IList<Layer> lastLayers = new List<Layer>();
-        private WpfObservableRangeCollection<GuidStructureItem> lastStructure = new WpfObservableRangeCollection<GuidStructureItem>();
-
-        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (values[0] is WpfObservableRangeCollection<Layer> layers && values[1] is LayerStructure structure)
-            {
-                if (cachedTree == null)
-                {
-                    cachedTree = new StructuredLayerTree(layers, structure);
-                }
-
-                if (TryFindStructureDifferences(structure) ||
-                    lastLayerGuids.Count != layers.Count ||
-                    LayerOrderIsDifferent(layers) ||
-                    LayersAreDifferentObjects(layers, lastLayers))
-                {
-                    cachedTree = new StructuredLayerTree(layers, structure);
-                    lastLayers = layers;
-                    lastLayerGuids = layers.Select(x => x.GuidValue).ToList();
-                    lastStructure = structure.CloneGroups();
-                }
-
-                return cachedTree.RootDirectoryItems;
-            }
-
-            return DependencyProperty.UnsetValue;
-        }
-
-        public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new ArgumentException("Value is not a StructuredLayerTree");
-        }
-
-        private bool LayerOrderIsDifferent(IList<Layer> layers)
-        {
-            var guids = layers.Select(x => x.GuidValue).ToArray();
-            return !guids.SequenceEqual(lastLayerGuids);
-        }
-
-        /// <summary>
-        /// This should trigger if you open and close the same files twice.
-        /// Even though the layers are technically the same, having two different objects screws things up down the line.
-        /// </summary>
-        private bool LayersAreDifferentObjects(IList<Layer> layers, IList<Layer> lastLayers)
-        {
-            for (int i = 0; i < layers.Count; i++)
-            {
-                if (layers[i] != lastLayers[i])
-                    return true;
-            }
-            return false;
-        }
-
-        private bool TryFindStructureDifferences(LayerStructure structure)
-        {
-            bool structureModified = false;
-
-            if (lastStructure.Count != structure.Groups.Count)
-            {
-                return true;
-            }
-
-
-            foreach (GuidStructureItem treeItem in lastStructure)
-            {
-                var matchingGroup = structure.Groups.FirstOrDefault(x => x.GroupGuid == treeItem.GroupGuid);
-                List<GuidStructureItem> changedGroups = new List<GuidStructureItem>();
-                if (matchingGroup == null || StructureMismatch(treeItem, matchingGroup))
-                {
-                    structureModified = true;
-                }
-
-            }
-
-            return structureModified;
-        }
-
-        private bool StructureMismatch(GuidStructureItem first, GuidStructureItem second)
-        {
-            bool rootMismatch = first.EndLayerGuid != second.EndLayerGuid || first.StartLayerGuid != second.StartLayerGuid || first.IsVisible != second.IsVisible || first.IsExpanded != second.IsExpanded || first.Opacity != second.Opacity || first.Subgroups.Count != second.Subgroups.Count || second.Name != first.Name;
-
-            if (!rootMismatch && first.Subgroups.Count > 0)
-            {
-                for (int i = 0; i < first.Subgroups.Count; i++)
-                {
-                    if (StructureMismatch(first.Subgroups[i], second.Subgroups[i]))
-                    {
-                        return true;
-                    }
-                }
-            }
-            return rootMismatch;
-        }
-    }
-}

+ 0 - 26
PixiEditor/Helpers/Converters/MarkupConverter.cs

@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Data;
-using System.Windows.Markup;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public abstract class MarkupConverter : MarkupExtension, IValueConverter
-    {
-        public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture);
-
-        public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override object ProvideValue(IServiceProvider serviceProvider)
-        {
-            return this;
-        }
-    }
-}

+ 0 - 19
PixiEditor/Helpers/Converters/MultiValueMarkupConverter.cs

@@ -1,19 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Data;
-using System.Windows.Markup;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public abstract class MultiValueMarkupConverter : MarkupExtension, IMultiValueConverter
-    {
-        public abstract object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);
-
-        public virtual object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override object ProvideValue(IServiceProvider serviceProvider) => this;
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/NotNullToBoolConverter.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    [ValueConversion(typeof(object), typeof(bool))]
-    public class NotNullToBoolConverter
-        : SingleInstanceConverter<NotNullToBoolConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            bool result = value is not null;
-
-            return parameter is null ? result : !result;
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value;
-        }
-    }
-}

+ 0 - 26
PixiEditor/Helpers/Converters/NotNullToVisibilityConverter.cs

@@ -1,26 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    [ValueConversion(typeof(object), typeof(Visibility))]
-    public class NotNullToVisibilityConverter
-        : MarkupConverter
-    {
-        public bool Inverted { get; set; }
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            bool isNull = value is not null;
-
-            if (Inverted)
-            {
-                isNull = !isNull;
-            }
-
-            return isNull ? Visibility.Visible : Visibility.Collapsed;
-        }
-    }
-}

+ 0 - 15
PixiEditor/Helpers/Converters/NullToVisibilityConverter.cs

@@ -1,15 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class NullToVisibilityConverter
-        : SingleInstanceConverter<NullToVisibilityConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value is null ? Visibility.Visible : Visibility.Collapsed;
-        }
-    }
-}

+ 0 - 31
PixiEditor/Helpers/Converters/OppositeVisibilityConverter.cs

@@ -1,31 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class OppositeVisibilityConverter
-        : SingleInstanceConverter<OppositeVisibilityConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value.ToString().ToLower() == "visible")
-            {
-                return Visibility.Hidden;
-            }
-
-            return Visibility.Visible;
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is Visibility visibility)
-            {
-                return visibility == Visibility.Visible ? "Hidden" : "Visible";
-            }
-
-            return null;
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/PaletteItemsToWidthConverter.cs

@@ -1,23 +0,0 @@
-using SkiaSharp;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class PaletteItemsToWidthConverter : SingleInstanceConverter<PaletteItemsToWidthConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if(value is IList<SKColor> colors && colors.Count == 0)
-            {
-                return 0;
-            }
-
-            return 120;
-        }
-    }
-}

+ 0 - 32
PixiEditor/Helpers/Converters/SKColorToMediaColorConverter.cs

@@ -1,32 +0,0 @@
-using SkiaSharp;
-using System;
-using System.Globalization;
-using System.Windows.Data;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class SKColorToMediaColorConverter : SingleInstanceConverter<SKColorToMediaColorConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            var skcolor = (SKColor)value;
-            var color = Color.FromArgb(skcolor.Alpha, skcolor.Red, skcolor.Green, skcolor.Blue);
-
-            if (targetType == typeof(Brush))
-            {
-                return new SolidColorBrush(color);
-            }
-            else
-            {
-                return color;
-            }
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            var color = (Color)value;
-            return new SKColor(color.R, color.G, color.B, color.A);
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/SingleInstanceConverter.cs

@@ -1,23 +0,0 @@
-using System;
-
-namespace PixiEditor.Helpers.Converters
-{
-    /// <summary>
-    /// Use this if you want to share the same converter over the whole application. <para/> Do not use this if your converter has properties.
-    /// </summary>
-    public abstract class SingleInstanceConverter<TThis> : MarkupConverter
-        where TThis : SingleInstanceConverter<TThis>
-    {
-        private static SingleInstanceConverter<TThis> instance;
-
-        public override object ProvideValue(IServiceProvider serviceProvider)
-        {
-            if (instance is null)
-            {
-                instance = this;
-            }
-
-            return instance;
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/Converters/SingleInstanceMultiValueConverter.cs

@@ -1,20 +0,0 @@
-using System;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public abstract class SingleInstanceMultiValueConverter<TThis> : MultiValueMarkupConverter
-        where TThis : SingleInstanceMultiValueConverter<TThis>
-    {
-        private static SingleInstanceMultiValueConverter<TThis> instance;
-
-        public override object ProvideValue(IServiceProvider serviceProvider)
-        {
-            if (instance is null)
-            {
-                instance = this;
-            }
-
-            return instance;
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/Converters/ThresholdVisibilityConverter.cs

@@ -1,20 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class ThresholdVisibilityConverter
-        : MarkupConverter
-    {
-        public double Threshold { get; set; } = 100;
-        public bool CheckIfLess { get; set; } = false;
-
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return CheckIfLess
-                   ? (double)value < Threshold ? Visibility.Visible : Visibility.Hidden
-                   : (double)value >= Threshold ? Visibility.Visible : Visibility.Hidden;
-        }
-    }
-}

+ 0 - 34
PixiEditor/Helpers/Converters/ToolSizeToIntConverter.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Globalization;
-using System.Text.RegularExpressions;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    [ValueConversion(typeof(string), typeof(int))]
-    internal class ToolSizeToIntConverter
-        : SingleInstanceConverter<ToolSizeToIntConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            return value.ToString();
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is not string s)
-            {
-                return null;
-            }
-
-            Match match = Regex.Match(s, @"\d+");
-
-            if (!match.Success)
-            {
-                return null;
-            }
-
-            return int.Parse(match.Groups[0].ValueSpan);
-        }
-    }
-}

+ 0 - 23
PixiEditor/Helpers/Converters/ViewboxInverseTransformConverter.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    class ViewboxInverseTransformConverter : MultiValueMarkupConverter
-    {
-        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            var transform = ((ContainerVisual)VisualTreeHelper.GetChild((DependencyObject)values[0], 0)).Transform;
-            if (transform == null)
-                return DependencyProperty.UnsetValue;
-            return transform.Inverse;
-        }
-
-        public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}

+ 0 - 27
PixiEditor/Helpers/Converters/WidthToBitmapScalingModeConverter.cs

@@ -1,27 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    internal class WidthToBitmapScalingModeConverter : SingleInstanceMultiValueConverter<WidthToBitmapScalingModeConverter>
-    {
-        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            int? pixelWidth = values[0] as int?;
-            double? actualWidth = values[1] as double?;
-            if (pixelWidth == null || actualWidth == null)
-                return DependencyProperty.UnsetValue;
-            double zoomLevel = actualWidth.Value / pixelWidth.Value;
-            if (zoomLevel < 1)
-                return BitmapScalingMode.HighQuality;
-            return BitmapScalingMode.NearestNeighbor;
-        }
-
-        public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}

+ 0 - 22
PixiEditor/Helpers/Converters/ZoomLevelToBitmapScalingModeConverter.cs

@@ -1,22 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Converters
-{
-    internal class ZoomLevelToBitmapScalingModeConverter : SingleInstanceConverter<ZoomLevelToBitmapScalingModeConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            double zoomLevel = (double)value;
-            if (zoomLevel < 1)
-                return BitmapScalingMode.HighQuality;
-            return BitmapScalingMode.NearestNeighbor;
-        }
-
-        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}

+ 0 - 22
PixiEditor/Helpers/Converters/ZoomToViewportConverter.cs

@@ -1,22 +0,0 @@
-using System;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Data;
-
-namespace PixiEditor.Helpers.Converters
-{
-    public class ZoomToViewportConverter
-        : SingleInstanceConverter<ZoomToViewportConverter>
-    {
-        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (value is double scale)
-            {
-                double newSize = Math.Clamp((double)parameter / scale, 1, 9999);
-                return new Rect(0, 0, newSize, newSize);
-            }
-
-            return Binding.DoNothing;
-        }
-    }
-}

+ 0 - 85
PixiEditor/Helpers/CoordinatesHelper.cs

@@ -1,85 +0,0 @@
-using PixiEditor.Models.Position;
-using System;
-using System.Collections.Generic;
-
-namespace PixiEditor.Helpers
-{
-    internal class CoordinatesHelper
-    {
-        public static (Coordinates, Coordinates) GetSquareOrLineCoordinates(IReadOnlyList<Coordinates> coords)
-        {
-            if (DoCoordsFormLine(coords))
-            {
-                return GetLineCoordinates(coords);
-            }
-            return GetSquareCoordiantes(coords);
-        }
-
-        private static bool DoCoordsFormLine(IReadOnlyList<Coordinates> coords)
-        {
-            var p1 = coords[0];
-            var p2 = coords[^1];
-            //find delta and mirror to first quadrant
-            float dX = Math.Abs(p2.X - p1.X);
-            float dY = Math.Abs(p2.Y - p1.Y);
-
-            //normalize
-            float length = (float)Math.Sqrt(dX * dX + dY * dY);
-            if (length == 0)
-                return false;
-            dX = dX / length;
-            dY = dY / length;
-
-            return dX < 0.25f || dY < 0.25f; //angle < 15 deg or angle > 75 deg (sin 15 ~= 0.25)
-        }
-
-        public static (Coordinates, Coordinates) GetLineCoordinates(IReadOnlyList<Coordinates> mouseMoveCords)
-        {
-            int xStart = mouseMoveCords[0].X;
-            int yStart = mouseMoveCords[0].Y;
-
-            int xEnd = mouseMoveCords[^1].X;
-            int yEnd = mouseMoveCords[^1].Y;
-
-
-            if (Math.Abs(xStart - xEnd) > Math.Abs(yStart - yEnd))
-            {
-                yEnd = yStart;
-            }
-            else
-            {
-                xEnd = xStart;
-            }
-            return (new(xStart, yStart), new(xEnd, yEnd));
-        }
-
-        /// <summary>
-        ///     Extracts square from rectangle mouse drag, used to draw symmetric shapes.
-        /// </summary>
-        public static (Coordinates, Coordinates) GetSquareCoordiantes(IReadOnlyList<Coordinates> mouseMoveCords)
-        {
-            var end = mouseMoveCords[^1];
-            var start = mouseMoveCords[0];
-
-            //find delta and mirror to first quadrant
-            var dX = Math.Abs(start.X - end.X);
-            var dY = Math.Abs(start.Y - end.Y);
-
-            float sqrt2 = (float)Math.Sqrt(2);
-            //vector of length 1 at 45 degrees;
-            float diagX, diagY;
-            diagX = diagY = 1 / sqrt2;
-
-            //dot product of delta and diag, returns length of [delta projected onto diag]
-            float projectedLength = diagX * dX + diagY * dY;
-            //project above onto axes
-            float axisLength = projectedLength / sqrt2;
-
-            //final coords
-            float x = -Math.Sign(start.X - end.X) * axisLength;
-            float y = -Math.Sign(start.Y - end.Y) * axisLength;
-            end = new Coordinates((int)x + start.X, (int)y + start.Y);
-            return (start, end);
-        }
-    }
-}

+ 0 - 102
PixiEditor/Helpers/CrashHelper.cs

@@ -1,102 +0,0 @@
-using ByteSizeLib;
-using Hardware.Info;
-using PixiEditor.Models.DataHolders;
-using System;
-using System.Globalization;
-using System.Text;
-
-namespace PixiEditor.Helpers
-{
-    public class CrashHelper
-    {
-        private readonly IHardwareInfo hwInfo;
-
-        public static void SaveCrashInfo(Exception exception)
-        {
-            CrashReport report = CrashReport.Generate(exception);
-            report.TrySave();
-            report.RestartToCrashReport();
-        }
-
-        public CrashHelper()
-        {
-            hwInfo = new HardwareInfo();
-        }
-
-        public void GetCPUInformation(StringBuilder builder)
-        {
-            builder.AppendLine("CPU:");
-            hwInfo.RefreshCPUList(false);
-
-            foreach (var processor in hwInfo.CpuList)
-            {
-                builder
-                    .AppendLine($"  Name: {processor.Name}")
-                    .AppendLine($"  Speed: {(processor.CurrentClockSpeed / 1000f).ToString("F2", CultureInfo.InvariantCulture)} GHz")
-                    .AppendLine($"  Max Speed: {(processor.MaxClockSpeed / 1000f).ToString("F2", CultureInfo.InvariantCulture)} GHz")
-                    .AppendLine();
-            }
-        }
-
-        public void GetGPUInformation(StringBuilder builder)
-        {
-            builder.AppendLine("GPU:");
-            hwInfo.RefreshVideoControllerList();
-
-            foreach (var gpu in hwInfo.VideoControllerList)
-            {
-                builder
-                    .AppendLine($"  Name: {gpu.Name}")
-                    .AppendLine($"  Driver: {gpu.DriverVersion}")
-                    .AppendLine();
-            }
-        }
-
-        public void GetMemoryInformation(StringBuilder builder)
-        {
-            builder.AppendLine("Memory:");
-            hwInfo.RefreshMemoryStatus();
-
-            var memInfo = hwInfo.MemoryStatus;
-
-            builder
-                .AppendLine($"  Available: {new ByteSize(memInfo.AvailablePhysical).ToString("", CultureInfo.InvariantCulture)}")
-                .AppendLine($"  Total: {new ByteSize(memInfo.TotalPhysical).ToString("", CultureInfo.InvariantCulture)}");
-        }
-
-        public static void AddExceptionMessage(StringBuilder builder, Exception e)
-        {
-            builder
-                .AppendLine("\n-------Crash message-------")
-                .Append(e.GetType().ToString())
-                .Append(": ")
-                .AppendLine(e.Message);
-            {
-                var innerException = e.InnerException;
-                while (innerException != null)
-                {
-                    builder
-                        .Append("\n-----Inner exception-----\n")
-                        .Append(innerException.GetType().ToString())
-                        .Append(": ")
-                        .Append(innerException.Message);
-                    innerException = innerException.InnerException;
-                }
-            }
-
-            builder
-                .Append("\n\n-------Stack trace-------\n")
-                .Append(e.StackTrace);
-            {
-                var innerException = e.InnerException;
-                while (innerException != null)
-                {
-                    builder
-                        .Append("\n-----Inner exception-----\n")
-                        .Append(innerException.StackTrace);
-                    innerException = innerException.InnerException;
-                }
-            }
-        }
-    }
-}

+ 0 - 61
PixiEditor/Helpers/DependencyInjectionHelper.cs

@@ -1,61 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-
-namespace PixiEditor.Helpers
-{
-    public static class DependencyInjectionHelper
-    {
-        public static T Inject<T>(this IServiceProvider provider)
-            => (T)Inject(provider, typeof(T));
-
-#nullable enable
-
-        public static object Inject(this IServiceProvider provider, Type type)
-        {
-            ConstructorInfo constructor = FindConstructorOrDefault(provider, type);
-
-            List<object?> parameters = new List<object?>();
-
-            foreach (Type argumentType in constructor.GetParameters().Select(x => x.ParameterType))
-            {
-                parameters.Add(provider.GetRequiredService(argumentType));
-            }
-
-            return constructor.Invoke(parameters.ToArray());
-        }
-
-#nullable disable
-
-        private static ConstructorInfo FindConstructorOrDefault(IServiceProvider provider, Type type)
-        {
-            ConstructorInfo foundConstructor = default;
-
-            foreach (ConstructorInfo info in type.GetConstructors())
-            {
-                if (HasParameters(provider, info.GetParameters()))
-                {
-                    foundConstructor = info;
-                    break;
-                }
-            }
-
-            return foundConstructor;
-        }
-
-        private static bool HasParameters(IServiceProvider provider, IEnumerable<ParameterInfo> parameters)
-        {
-            foreach (ParameterInfo parameter in parameters)
-            {
-                if (provider.GetService(parameter.ParameterType) is null)
-                {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-}

+ 0 - 36
PixiEditor/Helpers/DesignCommandHelpers.cs

@@ -1,36 +0,0 @@
-using PixiEditor.Models.Commands;
-using CommandAttribute = PixiEditor.Models.Commands.Attributes.Command;
-using System.Reflection;
-using PixiEditor.Models.Commands.Exceptions;
-
-namespace PixiEditor.Helpers
-{
-    /// <summary>
-    /// Helps with debugging when using XAML
-    /// </summary>
-    public static class DesignCommandHelpers
-    {
-        private static IEnumerable<CommandAttribute.CommandAttribute> _commands;
-
-        public static CommandAttribute.CommandAttribute GetCommandAttribute(string name)
-        {
-            if (_commands == null)
-            {
-                _commands = Assembly
-                    .GetAssembly(typeof(CommandController))
-                    .GetTypes()
-                    .SelectMany(x => x.GetMethods())
-                    .SelectMany(x => x.GetCustomAttributes<CommandAttribute.CommandAttribute>());
-            }
-
-            var command = _commands.SingleOrDefault(x => x.InternalName == name || x.InternalName == $"#DEBUG#{name}");
-
-            if (command == null)
-            {
-                throw new CommandNotFoundException(name);
-            }
-
-            return command;
-        }
-    }
-}

+ 0 - 168
PixiEditor/Helpers/EllipseGenerator.cs

@@ -1,168 +0,0 @@
-using PixiEditor.Models.Position;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.Helpers
-{
-    internal static class EllipseGenerator
-    {
-        public static List<DoubleCoords> SplitEllipseIntoLines(List<Coordinates> ellipse)
-        {
-            List<DoubleCoords> lines = new();
-            var sorted = ellipse.OrderBy(
-                a => a,
-                Comparer<Coordinates>.Create((a, b) => a.Y != b.Y ? a.Y - b.Y : a.X - b.X)
-                );
-
-            int minX = int.MaxValue;
-            int maxX = int.MinValue;
-            Coordinates? prev = null;
-            foreach (var point in sorted)
-            {
-                if (prev.HasValue && point.Y != prev.Value.Y)
-                {
-                    int prevY = prev.Value.Y;
-                    lines.Add(new DoubleCoords(new(minX, prevY), new(maxX, prevY)));
-                    minX = int.MaxValue;
-                    maxX = int.MinValue;
-                }
-                minX = Math.Min(point.X, minX);
-                maxX = Math.Max(point.X, maxX);
-                prev = point;
-            }
-            lines.Add(new DoubleCoords(new(minX, prev.Value.Y), new(maxX, prev.Value.Y)));
-            return lines;
-        }
-        public static List<Coordinates> GenerateEllipseFromRect(DoubleCoords rect, List<Coordinates> listToFill = null)
-        {
-            float radiusX = (rect.Coords2.X - rect.Coords1.X) / 2.0f;
-            float radiusY = (rect.Coords2.Y - rect.Coords1.Y) / 2.0f;
-            float centerX = (rect.Coords1.X + rect.Coords2.X + 1) / 2.0f;
-            float centerY = (rect.Coords1.Y + rect.Coords2.Y + 1) / 2.0f;
-            return GenerateMidpointEllipse(radiusX, radiusY, centerX, centerY, listToFill);
-        }
-
-        /// <summary>
-        /// Draws an ellipse using it's center and radii
-        ///
-        /// Here is a usage example:
-        /// Let's say you want an ellipse that's 3 pixels wide and 3 pixels tall located in the top right corner of the canvas
-        /// It's center is at (1.5; 1.5). That's in the middle of a pixel
-        /// The radii are both equal to 1. Notice that it's 1 and not 1.5, since we want the ellipse to land in the middle of the pixel, not outside of it.
-        /// See desmos (note the inverted y axis): https://www.desmos.com/calculator/tq9uqg0hcq
-        ///
-        /// Another example:
-        /// 4x4 ellipse in the top right corner of the canvas
-        /// Center is at (2; 2). It's a place where 4 pixels meet
-        /// Both radii are 1.5. Making them 2 would make the ellipse touch the edges of pixels, whereas we want it to stay in the middle
-        /// </summary>
-        public static List<Coordinates> GenerateMidpointEllipse(
-            double halfWidth,
-            double halfHeight,
-            double centerX,
-            double centerY,
-            List<Coordinates> listToFill = null)
-        {
-            listToFill ??= new List<Coordinates>();
-            if (halfWidth < 1 || halfHeight < 1)
-            {
-                AddFallbackRectangle(halfWidth, halfHeight, centerX, centerY, listToFill);
-                return listToFill;
-            }
-
-            // ellipse formula: halfHeight^2 * x^2 + halfWidth^2 * y^2 - halfHeight^2 * halfWidth^2 = 0
-
-            // Make sure we are always at the center of a pixel
-            double currentX = Math.Ceiling(centerX - 0.5) + 0.5;
-            double currentY = centerY + halfHeight;
-
-
-            double currentSlope;
-
-            // from PI/2 to PI/4
-            do
-            {
-                AddRegionPoints(listToFill, currentX, centerX, currentY, centerY);
-
-                // calculate next pixel coords
-                currentX++;
-
-                if ((Math.Pow(halfHeight, 2) * Math.Pow(currentX - centerX, 2)) +
-                    (Math.Pow(halfWidth, 2) * Math.Pow(currentY - centerY - 0.5, 2)) -
-                    (Math.Pow(halfWidth, 2) * Math.Pow(halfHeight, 2)) >= 0)
-                {
-                    currentY--;
-                }
-
-                // calculate how far we've advanced
-                double derivativeX = 2 * Math.Pow(halfHeight, 2) * (currentX - centerX);
-                double derivativeY = 2 * Math.Pow(halfWidth, 2) * (currentY - centerY);
-                currentSlope = -(derivativeX / derivativeY);
-            }
-            while (currentSlope > -1 && currentY - centerY > 0.5);
-
-            // from PI/4 to 0
-            while (currentY - centerY >= 0)
-            {
-                AddRegionPoints(listToFill, currentX, centerX, currentY, centerY);
-
-                currentY--;
-                if ((Math.Pow(halfHeight, 2) * Math.Pow(currentX - centerX + 0.5, 2)) +
-                    (Math.Pow(halfWidth, 2) * Math.Pow(currentY - centerY, 2)) -
-                    (Math.Pow(halfWidth, 2) * Math.Pow(halfHeight, 2)) < 0)
-                {
-                    currentX++;
-                }
-            }
-
-            return listToFill;
-        }
-
-        private static void AddFallbackRectangle(double halfWidth, double halfHeight, double centerX, double centerY, List<Coordinates> coordinates)
-        {
-            int left = (int)Math.Floor(centerX - halfWidth);
-            int top = (int)Math.Floor(centerY - halfHeight);
-            int right = (int)Math.Floor(centerX + halfWidth);
-            int bottom = (int)Math.Floor(centerY + halfHeight);
-
-            for (int x = left; x <= right; x++)
-            {
-                coordinates.Add(new Coordinates(x, top));
-                coordinates.Add(new Coordinates(x, bottom));
-            }
-
-            for (int y = top; y <= bottom; y++)
-            {
-                coordinates.Add(new Coordinates(left, y));
-                coordinates.Add(new Coordinates(right, y));
-            }
-        }
-
-        private static void AddRegionPoints(List<Coordinates> coordinates, double x, double xc, double y, double yc)
-        {
-            int xFloor = (int)Math.Floor(x);
-            int yFloor = (int)Math.Floor(y);
-            int xFloorInv = (int)Math.Floor(-x + 2 * xc);
-            int yFloorInv = (int)Math.Floor(-y + 2 * yc);
-
-            //top and bottom or left and right
-            if (xFloor == xFloorInv || yFloor == yFloorInv)
-            {
-                coordinates.Add(new Coordinates(xFloor, yFloor));
-                coordinates.Add(new Coordinates(xFloorInv, yFloorInv));
-            }
-            //part of the arc
-            else
-            {
-                coordinates.Add(new Coordinates(xFloor, yFloor));
-                coordinates.Add(new Coordinates(xFloorInv, yFloorInv));
-                coordinates.Add(new Coordinates(xFloorInv, yFloor));
-                coordinates.Add(new Coordinates(xFloor, yFloorInv));
-            }
-        }
-    }
-}

+ 0 - 13
PixiEditor/Helpers/ExecutionTrigger.cs

@@ -1,13 +0,0 @@
-using System;
-
-namespace PixiEditor.Helpers
-{
-    public class ExecutionTrigger<T>
-    {
-        public event EventHandler<T> Triggered;
-        public void Execute(object sender, T args)
-        {
-            Triggered?.Invoke(sender, args);
-        }
-    }
-}

+ 0 - 30
PixiEditor/Helpers/Extensions/DictionaryHelper.cs

@@ -1,30 +0,0 @@
-using System.Collections.Generic;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class DictionaryHelper
-    {
-        public static void AddRangeOverride<TKey, TValue>(
-            this IDictionary<TKey, TValue> dict,
-            IDictionary<TKey, TValue> dictToAdd)
-        {
-            foreach (KeyValuePair<TKey, TValue> item in dictToAdd)
-            {
-                dict[item.Key] = item.Value;
-            }
-        }
-
-        public static void AddRangeNewOnly<TKey, TValue>(
-            this IDictionary<TKey, TValue> dict,
-            IDictionary<TKey, TValue> dictToAdd)
-        {
-            foreach (KeyValuePair<TKey, TValue> item in dictToAdd)
-            {
-                if (!dict.ContainsKey(item.Key))
-                {
-                    dict.Add(item.Key, item.Value);
-                }
-            }
-        }
-    }
-}

+ 0 - 19
PixiEditor/Helpers/Extensions/DirectoryExtensions.cs

@@ -1,19 +0,0 @@
-using System.Linq;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class DirectoryExtensions
-    {
-        /// <summary>
-        ///     Gets files in directory with multiple filters.
-        /// </summary>
-        /// <param name="sourceFolder">Folder to get files from.</param>
-        /// <param name="filters">Filters separated by '|' character.</param>
-        /// <param name="searchOption">Search option for directory.</param>
-        /// <returns>List of file paths found.</returns>
-        public static string[] GetFiles(string sourceFolder, string filters, System.IO.SearchOption searchOption)
-        {
-            return filters.Split('|').SelectMany(filter => System.IO.Directory.GetFiles(sourceFolder, $"*{filter}", searchOption)).ToArray();
-        }
-    }
-}

+ 0 - 36
PixiEditor/Helpers/Extensions/EnumHelpers.cs

@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class EnumHelpers
-    {
-        public static IEnumerable<T> GetFlags<T>(this T e)
-               where T : Enum
-        {
-            return Enum.GetValues(e.GetType()).Cast<T>().Where(x => e.HasFlag(x));
-        }
-
-        public static string GetDescription<T>(this T enumValue)
-            where T : struct, Enum
-        {
-            var description = enumValue.ToString();
-            var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
-
-            if (fieldInfo != null)
-            {
-                var attrs = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), true);
-                if (attrs != null && attrs.Length > 0)
-                {
-                    description = ((DescriptionAttribute)attrs[0]).Description;
-                }
-            }
-
-            return description;
-        }
-    }
-}

+ 0 - 97
PixiEditor/Helpers/Extensions/EnumerableHelpers.cs

@@ -1,97 +0,0 @@
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class EnumerableHelpers
-    {
-        /// <summary>
-        /// Get's the item at the <paramref name="index"/> if it matches the <paramref name="predicate"/> or the first that matches after the <paramref name="index"/>.
-        /// </summary>
-        /// <param name="overrun">Should the enumerator start from the bottom if it can't find the first item in the higher part</param>
-        /// <returns>The first item or null if no item can be found.</returns>
-        public static T IndexOrNext<T>(this IEnumerable<T> collection, Predicate<T> predicate, int index, bool overrun = true)
-        {
-            if (index < 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            var enumerator = collection.GetEnumerator();
-
-            // Iterate to the target index
-            for (int i = 0; i < index; i++)
-            {
-                if (!enumerator.MoveNext())
-                {
-                    return default;
-                }
-            }
-
-            while (enumerator.MoveNext())
-            {
-                if (predicate(enumerator.Current))
-                {
-                    return enumerator.Current;
-                }
-            }
-
-            if (!overrun)
-            {
-                return default;
-            }
-
-            enumerator.Reset();
-
-            for (int i = 0; i < index; i++)
-            {
-                enumerator.MoveNext();
-                if (predicate(enumerator.Current))
-                {
-                    return enumerator.Current;
-                }
-            }
-
-            return default;
-        }
-
-        /// <summary>
-        /// Get's the item at the <paramref name="index"/> if it matches the <paramref name="predicate"/> or the first item that matches before the <paramref name="index"/>.
-        /// </summary>
-        /// <param name="underrun">Should the enumerator start from the top if it can't find the first item in the lower part</param>
-        /// <returns>The first item or null if no item can be found.</returns>
-        public static T IndexOrPrevious<T>(this IEnumerable<T> collection, Predicate<T> predicate, int index, bool underrun = true)
-        {
-            if (index < 0)
-            {
-                throw new ArgumentOutOfRangeException(nameof(index));
-            }
-
-            var enumerator = collection.GetEnumerator();
-            T[] previousItems = new T[index + 1];
-
-            // Iterate to the target index
-            for (int i = 0; i <= index; i++)
-            {
-                if (!enumerator.MoveNext())
-                {
-                    return default;
-                }
-
-                previousItems[i] = enumerator.Current;
-            }
-
-            for (int i = index; i >= 0; i--)
-            {
-                if (predicate(previousItems[i]))
-                {
-                    return previousItems[i];
-                }
-            }
-
-            if (!underrun)
-            {
-                return default;
-            }
-
-            return IndexOrNext(collection, predicate, index, false);
-        }
-    }
-}

+ 0 - 60
PixiEditor/Helpers/Extensions/Int32RectHelper.cs

@@ -1,60 +0,0 @@
-using SkiaSharp;
-using System;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class Int32RectHelper
-    {
-        public static Int32Rect Intersect(this Int32Rect rect, Int32Rect other)
-        {
-            int rectX2 = rect.X + rect.Width;
-            int rectY2 = rect.Y + rect.Height;
-
-            int otherX2 = other.X + other.Width;
-            int otherY2 = other.Y + other.Height;
-
-            int maxX1 = Math.Max(rect.X, other.X);
-            int maxY1 = Math.Max(rect.Y, other.Y);
-
-            int minX2 = Math.Min(rectX2, otherX2);
-            int minY2 = Math.Min(rectY2, otherY2);
-
-            int width = minX2 - maxX1;
-            int height = minY2 - maxY1;
-
-            if (width <= 0 || height <= 0)
-                return Int32Rect.Empty;
-
-            return new Int32Rect(maxX1, maxY1, width, height);
-        }
-
-        public static Int32Rect Expand(this Int32Rect rect, Int32Rect other)
-        {
-            int rectX2 = rect.X + rect.Width;
-            int rectY2 = rect.Y + rect.Height;
-
-            int otherX2 = other.X + other.Width;
-            int otherY2 = other.Y + other.Height;
-
-            int minX1 = Math.Min(rect.X, other.X);
-            int minY1 = Math.Min(rect.Y, other.Y);
-
-            int maxX2 = Math.Max(rectX2, otherX2);
-            int maxY2 = Math.Max(rectY2, otherY2);
-
-            int width = maxX2 - minX1;
-            int height = maxY2 - minY1;
-
-            if (width <= 0 || height <= 0)
-                return Int32Rect.Empty;
-
-            return new Int32Rect(minX1, minY1, width, height);
-        }
-
-        public static SKRectI ToSKRectI(this Int32Rect rect)
-        {
-            return new SKRectI(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
-        }
-    }
-}

+ 0 - 167
PixiEditor/Helpers/Extensions/ParserHelpers.cs

@@ -1,167 +0,0 @@
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Layers;
-using PixiEditor.Parser;
-using PixiEditor.Parser.Skia;
-using SkiaSharp;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class ParserHelpers
-    {
-        public static Document ToDocument(this SerializableDocument serializableDocument)
-        {
-            Document document = new Document(serializableDocument.Width, serializableDocument.Height)
-            {
-                Layers = serializableDocument.ToLayers(),
-                Swatches = new WpfObservableRangeCollection<SKColor>(serializableDocument.Swatches.ToSKColors()),
-                Palette = new WpfObservableRangeCollection<SKColor>(serializableDocument.Palette.ToSKColors())
-            };
-
-            document.LayerStructure.Groups = serializableDocument.ToGroups(document);
-
-            if (document.Layers.Count > 0)
-            {
-                document.SetMainActiveLayer(0);
-            }
-            document.Renderer.ForceRerender();
-
-            return document;
-        }
-
-        public static WpfObservableRangeCollection<Layer> ToLayers(this SerializableDocument document)
-        {
-            WpfObservableRangeCollection<Layer> layers = new();
-            foreach (SerializableLayer slayer in document)
-            {
-                layers.Add(slayer.ToLayer(document.Width, document.Height));
-            }
-
-            return layers;
-        }
-
-        public static Layer ToLayer(this SerializableLayer layer, int maxWidth, int maxHeight)
-        {
-            return new Layer(layer.Name, new Surface(layer.ToSKImage()), maxWidth, maxHeight)
-            {
-                Opacity = layer.Opacity,
-                IsVisible = layer.IsVisible,
-                Offset = new(layer.OffsetX, layer.OffsetY, 0, 0),
-            };
-        }
-
-        public static WpfObservableRangeCollection<GuidStructureItem> ToGroups(this SerializableDocument sdocument, Document document)
-        {
-            WpfObservableRangeCollection<GuidStructureItem> groups = new();
-
-            if (sdocument.Groups == null)
-            {
-                return groups;
-            }
-
-            foreach (SerializableGroup sgroup in sdocument.Groups)
-            {
-                groups.Add(sgroup.ToGroup(null, document));
-            }
-
-            return groups;
-        }
-
-        public static GuidStructureItem ToGroup(this SerializableGroup sgroup, GuidStructureItem parent, Document document)
-        {
-            GuidStructureItem group = new GuidStructureItem(sgroup.Name, Guid.Empty)
-            {
-                Opacity = sgroup.Opacity,
-                IsVisible = sgroup.IsVisible,
-                Parent = parent,
-                StartLayerGuid = document.Layers[sgroup.StartLayer].GuidValue,
-                EndLayerGuid = document.Layers[sgroup.EndLayer].GuidValue
-            };
-
-            group.Subgroups = new(sgroup.Subgroups.ToGroups(document, group));
-
-            return group;
-        }
-
-        public static SerializableDocument ToSerializable(this Document document)
-        {
-            return new SerializableDocument(document.Width, document.Height,
-                                            document.LayerStructure.Groups.ToSerializable(document),
-                                            document.Layers.ToSerializable())
-                .AddSwatches(document.Swatches)
-                .AddPalette(document.Palette);
-        }
-
-        public static IEnumerable<SerializableLayer> ToSerializable(this IEnumerable<Layer> layers)
-        {
-            foreach (Layer layer in layers)
-            {
-                yield return layer.ToSerializable();
-            }
-        }
-
-        public static SerializableLayer ToSerializable(this Layer layer)
-        {
-            return new SerializableLayer(layer.Width, layer.Height, layer.OffsetX, layer.OffsetY)
-            {
-                IsVisible = layer.IsVisible,
-                Opacity = layer.Opacity,
-                Name = layer.Name
-            }.FromSKImage(layer.LayerBitmap.SkiaSurface.Snapshot());
-        }
-
-        public static IEnumerable<SerializableGroup> ToSerializable(this IEnumerable<GuidStructureItem> groups, Document document)
-        {
-            foreach (GuidStructureItem group in groups)
-            {
-                yield return group.ToSerializable(document);
-            }
-        }
-
-        public static SerializableGroup ToSerializable(this GuidStructureItem group, Document document)
-        {
-            SerializableGroup serializable = new SerializableGroup(group.Name, group.Subgroups.ToSerializable(document))
-            {
-                Opacity = group.Opacity,
-                IsVisible = group.IsVisible
-            };
-
-            for (int i = 0; i < document.Layers.Count; i++)
-            {
-                if (group.StartLayerGuid == document.Layers[i].GuidValue)
-                {
-                    serializable.StartLayer = i;
-                }
-
-                if (group.EndLayerGuid == document.Layers[i].GuidValue)
-                {
-                    serializable.EndLayer = i;
-                }
-            }
-
-            return serializable;
-        }
-
-        private static IEnumerable<GuidStructureItem> ToGroups(this IEnumerable<SerializableGroup> groups, Document document, GuidStructureItem parent)
-        {
-            foreach (SerializableGroup sgroup in groups)
-            {
-                yield return sgroup.ToGroup(parent, document);
-            }
-        }
-
-        private static SerializableDocument AddSwatches(this SerializableDocument document, IEnumerable<SKColor> colors)
-        {
-            document.Swatches.AddRange(colors);
-            return document;
-        }
-
-        private static SerializableDocument AddPalette(this SerializableDocument document, IEnumerable<SKColor> palette)
-        {
-            document.Palette.AddRange(palette);
-            return document;
-        }
-    }
-}

+ 0 - 73
PixiEditor/Helpers/Extensions/PixelFormatHelper.cs

@@ -1,73 +0,0 @@
-using SkiaSharp;
-using System;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class PixelFormatHelper
-    {
-        public static SKColorType ToSkia(this PixelFormat format, out SKAlphaType alphaType)
-        {
-            if (TryToSkia(format, out SKColorType color, out alphaType))
-            {
-                return color;
-            }
-            else
-            {
-                throw new NotImplementedException($"Skia does not support the '{format}' format");
-            }
-        }
-
-        public static bool TryToSkia(this PixelFormat format, out SKColorType colorType, out SKAlphaType alphaType)
-        {
-            if (format == PixelFormats.Rgba64)
-            {
-                alphaType = SKAlphaType.Unpremul;
-                colorType = SKColorType.Rgba16161616;
-                return true;
-            }
-            else if (format == PixelFormats.Bgra32)
-            {
-                alphaType = SKAlphaType.Unpremul;
-                colorType = SKColorType.Bgra8888;
-                return true;
-            }
-            else if (format == PixelFormats.Default)
-            {
-                alphaType = SKAlphaType.Unpremul;
-                colorType = SKColorType.RgbaF16;
-                return true;
-            }
-            else if (format == PixelFormats.Gray8)
-            {
-                alphaType = SKAlphaType.Opaque;
-                colorType = SKColorType.Gray8;
-                return true;
-            }
-            else if (format == PixelFormats.Pbgra32)
-            {
-                alphaType = SKAlphaType.Premul;
-                colorType = SKColorType.Bgra8888;
-                return true;
-            }
-            else if (format == PixelFormats.Bgr101010 || format == PixelFormats.Bgr24 || format == PixelFormats.Bgr32 || format == PixelFormats.Bgr555 ||
-                     format == PixelFormats.Bgr565 || format == PixelFormats.BlackWhite || format == PixelFormats.Cmyk32 || format == PixelFormats.Gray16 ||
-                     format == PixelFormats.Gray2 || format == PixelFormats.Gray32Float || format == PixelFormats.Gray4 || format == PixelFormats.Indexed1 ||
-                     format == PixelFormats.Indexed2 || format == PixelFormats.Indexed4 || format == PixelFormats.Indexed8 || format == PixelFormats.Prgba128Float ||
-                     format == PixelFormats.Prgba64 || format == PixelFormats.Rgb128Float || format == PixelFormats.Rgb24 || format == PixelFormats.Rgb48 ||
-                     format == PixelFormats.Rgba128Float)
-            {
-                alphaType = SKAlphaType.Unknown;
-                colorType = SKColorType.Unknown;
-                return false;
-            }
-
-            throw new NotImplementedException($"'{format}' has not been implemented by {nameof(PixelFormatHelper)}.{nameof(TryToSkia)}()");
-        }
-
-        public static bool IsSkiaSupported(this PixelFormat format)
-        {
-            return TryToSkia(format, out _, out _);
-        }
-    }
-}

+ 0 - 13
PixiEditor/Helpers/Extensions/SKRectIHelper.cs

@@ -1,13 +0,0 @@
-using SkiaSharp;
-using System.Windows;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class SKRectIHelper
-    {
-        public static Int32Rect ToInt32Rect(this SKRectI rect)
-        {
-            return new Int32Rect(rect.Left, rect.Top, rect.Width, rect.Height);
-        }
-    }
-}

+ 0 - 69
PixiEditor/Helpers/Extensions/ServiceCollectionHelpers.cs

@@ -1,69 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using PixiEditor.Models.Commands;
-using PixiEditor.Models.Controllers;
-using PixiEditor.Models.DataProviders;
-using PixiEditor.Models.IO;
-using PixiEditor.Models.IO.ClsFile;
-using PixiEditor.Models.IO.JascPalFile;
-using PixiEditor.Models.Services;
-using PixiEditor.Models.Tools;
-using PixiEditor.Models.Tools.Tools;
-using PixiEditor.Models.UserPreferences;
-using PixiEditor.ViewModels;
-using PixiEditor.ViewModels.SubViewModels.Main;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class ServiceCollectionHelpers
-    {
-        /// <summary>
-        /// Add's all the services required to fully run PixiEditor's MainWindow
-        /// </summary>
-        public static IServiceCollection AddPixiEditor(this IServiceCollection collection) => collection
-                .AddSingleton<ViewModelMain>()
-                .AddSingleton<IPreferences, PreferencesSettings>()
-                // View Models
-                .AddSingleton<StylusViewModel>()
-                .AddSingleton<WindowViewModel>()
-                .AddSingleton<ToolsViewModel>()
-                .AddSingleton<FileViewModel>()
-                .AddSingleton<UpdateViewModel>()
-                .AddSingleton<IoViewModel>()
-                .AddSingleton<LayersViewModel>()
-                .AddSingleton<ClipboardViewModel>()
-                .AddSingleton<UndoViewModel>()
-                .AddSingleton<SelectionViewModel>()
-                .AddSingleton<ViewportViewModel>()
-                .AddSingleton<ColorsViewModel>()
-                .AddSingleton<DocumentViewModel>()
-                .AddSingleton<RegistryViewModel>()
-                .AddSingleton(static x => new DiscordViewModel(x.GetService<ViewModelMain>(), "764168193685979138"))
-                .AddSingleton<DebugViewModel>()
-                .AddSingleton<SearchViewModel>()
-                // Controllers
-                .AddSingleton<ShortcutController>()
-                .AddSingleton<CommandController>()
-                .AddSingleton<BitmapManager>()
-                // Tools
-                .AddSingleton<Tool, MoveViewportTool>()
-                .AddSingleton<Tool, MoveTool>()
-                .AddSingleton<Tool, PenTool>()
-                .AddSingleton<Tool, SelectTool>()
-                .AddSingleton<Tool, MagicWandTool>()
-                .AddSingleton<Tool, FloodFillTool>()
-                .AddSingleton<Tool, LineTool>()
-                .AddSingleton<Tool, CircleTool>()
-                .AddSingleton<Tool, RectangleTool>()
-                .AddSingleton<Tool, EraserTool>()
-                .AddSingleton<Tool, ColorPickerTool>()
-                .AddSingleton<Tool, BrightnessTool>()
-                .AddSingleton<Tool, ZoomTool>()
-                // Palette Parsers
-                .AddSingleton<PaletteFileParser, JascFileParser>()
-                .AddSingleton<PaletteFileParser, ClsFileParser>()
-                // Palette data sources
-                .AddSingleton<PaletteListDataSource, LocalPalettesFetcher>()
-                // Other
-                .AddSingleton<DocumentProvider>();
-    }
-}

+ 0 - 14
PixiEditor/Helpers/Extensions/SkiaWPFHelpers.cs

@@ -1,14 +0,0 @@
-using SkiaSharp;
-using System.Windows.Media;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class SkiaWPFHelpers
-    {
-        public static SKColor ToOpaqueSKColor(this Color color) => new(color.R, color.G, color.B);
-        public static SKColor ToSKColor(this Color color) => new(color.R, color.G, color.B, color.A);
-
-        public static Color ToOpaqueColor(this SKColor color) => Color.FromRgb(color.Red, color.Green, color.Blue);
-        public static Color ToColor(this SKColor color) => Color.FromArgb(color.Alpha, color.Red, color.Green, color.Blue);
-    }
-}

+ 0 - 32
PixiEditor/Helpers/Extensions/StringHelpers.cs

@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class StringHelpers
-    {
-        public static string AddSpacesBeforeUppercaseLetters(this string text)
-        {
-            if (string.IsNullOrWhiteSpace(text))
-                return "";
-
-            StringBuilder newText = new StringBuilder(text.Length * 2);
-            newText.Append(text[0]);
-            for (int i = 1; i < text.Length; i++)
-            {
-                if (char.IsUpper(text[i]) && text[i - 1] != ' ')
-                    newText.Append(' ');
-                newText.Append(text[i]);
-            }
-            return newText.ToString();
-        }
-
-        public static string Limit(this string value, int maxLenght)
-        {
-            return value.Length > maxLenght ? value.Substring(0, maxLenght) : value;
-        }
-    }
-}

+ 0 - 15
PixiEditor/Helpers/Extensions/ToolbarHelpers.cs

@@ -1,15 +0,0 @@
-using System;
-using PixiEditor.Models.Tools.ToolSettings.Settings;
-using PixiEditor.Models.Tools.ToolSettings.Toolbars;
-
-namespace PixiEditor.Helpers.Extensions
-{
-    public static class ToolbarHelpers
-    {
-        public static EnumSetting<TEnum> GetEnumSetting<TEnum>(this Toolbar toolbar, string name)
-            where TEnum : struct, Enum
-        {
-            return toolbar.GetSetting<EnumSetting<TEnum>>(name);
-        }
-    }
-}

+ 0 - 149
PixiEditor/Helpers/GlobalMouseHook.cs

@@ -1,149 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-using System.Windows;
-using System.Windows.Input;
-using System.Windows.Threading;
-
-namespace PixiEditor.Helpers
-{
-    public delegate void MouseUpEventHandler(object sender, Point p, MouseButton button);
-
-    // see https://stackoverflow.com/questions/22659925/how-to-capture-mouseup-event-outside-the-wpf-window
-    [ExcludeFromCodeCoverage]
-    public static class GlobalMouseHook
-    {
-        private const int WH_MOUSE_LL = 14;
-        private const int WM_LBUTTONUP = 0x0202;
-        private const int WM_MBUTTONUP = 0x0208;
-        private const int WM_RBUTTONUP = 0x0205;
-
-        private static int mouseHookHandle;
-        private static HookProc mouseDelegate;
-
-        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
-
-        public static event MouseUpEventHandler OnMouseUp
-        {
-            add
-            { 
-// disable low-level hook in debug to prevent mouse lag when pausing in debugger
-#if !DEBUG
-                Subscribe();
-#endif
-                MouseUp += value;
-            }
-
-            remove
-            {
-                MouseUp -= value;
-#if !DEBUG
-                Unsubscribe();
-#endif
-            }
-        }
-
-        private static event MouseUpEventHandler MouseUp;
-
-        public static void RaiseMouseUp()
-        {
-            MouseUp?.Invoke(default, default, default);
-        }
-
-        private static void Unsubscribe()
-        {
-            if (mouseHookHandle != 0)
-            {
-                int result = UnhookWindowsHookEx(mouseHookHandle);
-                mouseHookHandle = 0;
-                mouseDelegate = null;
-                if (result == 0)
-                {
-                    int errorCode = Marshal.GetLastWin32Error();
-                    throw new Win32Exception(errorCode);
-                }
-            }
-        }
-
-        private static void Subscribe()
-        {
-            if (mouseHookHandle == 0)
-            {
-                mouseDelegate = MouseHookProc;
-                mouseHookHandle = SetWindowsHookEx(
-                    WH_MOUSE_LL,
-                    mouseDelegate,
-                    GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),
-                    0);
-                if (mouseHookHandle == 0)
-                {
-                    int errorCode = Marshal.GetLastWin32Error();
-                    throw new Win32Exception(errorCode);
-                }
-            }
-        }
-
-        private static int MouseHookProc(int nCode, int wParam, IntPtr lParam)
-        {
-            if (nCode >= 0)
-            {
-                MSLLHOOKSTRUCT mouseHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
-                if (wParam == WM_LBUTTONUP || wParam == WM_MBUTTONUP || wParam == WM_RBUTTONUP)
-                {
-                    if (MouseUp != null)
-                    {
-
-                        MouseButton button = wParam == WM_LBUTTONUP ? MouseButton.Left
-                            : wParam == WM_MBUTTONUP ? MouseButton.Middle : MouseButton.Right;
-                        Dispatcher.CurrentDispatcher.BeginInvoke(() =>
-                            MouseUp.Invoke(null, new Point(mouseHookStruct.Pt.X, mouseHookStruct.Pt.Y), button));
-                    }
-                }
-            }
-
-            return CallNextHookEx(mouseHookHandle, nCode, wParam, lParam);
-        }
-
-        [DllImport(
-            "user32.dll",
-            CharSet = CharSet.Auto,
-            CallingConvention = CallingConvention.StdCall,
-            SetLastError = true)]
-        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
-
-        [DllImport(
-            "user32.dll",
-            CharSet = CharSet.Auto,
-            CallingConvention = CallingConvention.StdCall,
-            SetLastError = true)]
-        private static extern int UnhookWindowsHookEx(int idHook);
-
-        [DllImport(
-            "user32.dll",
-            CharSet = CharSet.Auto,
-            CallingConvention = CallingConvention.StdCall)]
-        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
-
-        [DllImport("kernel32.dll")]
-        private static extern IntPtr GetModuleHandle(string name);
-
-        [StructLayout(LayoutKind.Sequential)]
-        private struct POINT
-        {
-            public int X;
-            public int Y;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        private struct MSLLHOOKSTRUCT
-        {
-            public POINT Pt;
-            public uint MouseData;
-            public uint Flags;
-            public uint Time;
-            public IntPtr DwExtraInfo;
-        }
-    }
-}

+ 0 - 86
PixiEditor/Helpers/InputKeyHelpers.cs

@@ -1,86 +0,0 @@
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Windows.Input;
-
-namespace PixiEditor.Helpers
-{
-    public static class InputKeyHelpers
-    {
-        /// <summary>
-        /// Returns the charcter of the <paramref name="key"/> mapped to the users keyboard layout
-        /// </summary>
-        public static string GetKeyboardKey(Key key) => GetKeyboardKey(key, CultureInfo.CurrentCulture);
-
-        public static string GetKeyboardKey(Key key, CultureInfo culture) => key switch
-        {
-            >= Key.NumPad0 and <= Key.Divide => $"Num {GetMappedKey(key, culture)}",
-            Key.Space => nameof(Key.Space),
-            Key.Tab => nameof(Key.Tab),
-            Key.Back => "Backspace",
-            Key.Escape => "Esc",
-            _ => GetMappedKey(key, culture),
-        };
-
-        private static string GetMappedKey(Key key, CultureInfo culture)
-        {
-            int virtualKey = KeyInterop.VirtualKeyFromKey(key);
-            byte[] keyboardState = new byte[256];
-
-            uint scanCode = MapVirtualKeyExW((uint)virtualKey, MapType.MAPVK_VK_TO_VSC, culture.KeyboardLayoutId);
-            StringBuilder stringBuilder = new(3);
-
-            int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0);
-
-            string stringResult;
-
-            stringResult = result switch
-            {
-                0 => key.ToString(),
-                -1 => stringBuilder.ToString().ToUpper(),
-                _ => stringBuilder[result - 1].ToString().ToUpper()
-            };
-
-            return stringResult;
-        }
-
-        private enum MapType : uint
-        {
-            /// <summary>
-            /// The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.
-            /// </summary>
-            MAPVK_VK_TO_VSC = 0x0,
-
-            /// <summary>
-            /// The uCode parameter is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, the function returns 0.
-            /// </summary>
-            MAPVK_VSC_TO_VK = 0x1,
-
-            /// <summary>
-            /// The uCode parameter is a virtual-key code and is translated into an unshifted character value in the low order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.
-            /// </summary>
-            MAPVK_VK_TO_CHAR = 0x2,
-
-            /// <summary>
-            /// The uCode parameter is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.
-            /// </summary>
-            MAPVK_VSC_TO_VK_EX = 0x3,
-        }
-
-        [DllImport("user32.dll")]
-        private static extern int ToUnicode(
-            uint wVirtKey,
-            uint wScanCode,
-            byte[] lpKeyState,
-            [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)]
-            StringBuilder pwszBuff,
-            int cchBuff,
-            uint wFlags);
-
-        [DllImport("user32.dll")]
-        private static extern bool GetKeyboardState(byte[] lpKeyState);
-
-        [DllImport("user32.dll")]
-        private static extern uint MapVirtualKeyExW(uint uCode, MapType uMapType, int hkl);
-    }
-}

+ 0 - 31
PixiEditor/Helpers/PaletteHelpers.cs

@@ -1,31 +0,0 @@
-using PixiEditor.Models.IO;
-
-namespace PixiEditor.Helpers
-{
-    public static class PaletteHelpers
-    {
-        public static string GetFilter(IList<PaletteFileParser> parsers, bool includeCommon)
-        {
-            string filter = "";
-
-            if (includeCommon)
-            {
-                List<string> allSupportedFormats = new();
-                foreach (var parser in parsers)
-                {
-                    allSupportedFormats.AddRange(parser.SupportedFileExtensions);
-                }
-                string allSupportedFormatsString = string.Join(';', allSupportedFormats).Replace(".", "*.");
-                filter += $"Palette Files ({allSupportedFormatsString})|{allSupportedFormatsString}|";
-            }
-
-            foreach (var parser in parsers)
-            {
-                string supportedFormats = string.Join(';', parser.SupportedFileExtensions).Replace(".", "*.");
-                filter += $"{parser.FileName} ({supportedFormats})|{supportedFormats}|";
-            }
-
-            return filter.Remove(filter.Length - 1);
-        }
-    }
-}

+ 0 - 19
PixiEditor/Helpers/ProcessHelpers.cs

@@ -1,19 +0,0 @@
-using System;
-using System.Diagnostics;
-
-namespace PixiEditor.Helpers
-{
-    public static class ProcessHelpers
-    {
-        public static void ShellExecute(string url)
-        {
-            Process.Start(new ProcessStartInfo
-            {
-                FileName = url,
-                UseShellExecute = true
-            });
-        }
-
-        public static void ShellExecuteEV(string path) => ShellExecute(Environment.ExpandEnvironmentVariables(path));
-    }
-}

+ 0 - 71
PixiEditor/Helpers/RelayCommand.cs

@@ -1,71 +0,0 @@
-using System;
-using System.Windows.Input;
-
-namespace PixiEditor.Helpers
-{
-    public class RelayCommand<T> : ICommand
-    {
-        private readonly Action<T> execute;
-        private readonly Predicate<T> canExecute;
-
-        public RelayCommand(Action<T> execute)
-            : this(execute, null)
-        {
-        }
-
-        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
-        {
-            if (execute == null)
-            {
-                throw new ArgumentNullException("execute");
-            }
-
-            this.execute = execute;
-            this.canExecute = canExecute;
-        }
-
-        public event EventHandler CanExecuteChanged
-        {
-            add => CommandManager.RequerySuggested += value;
-            remove => CommandManager.RequerySuggested -= value;
-        }
-
-        public bool CanExecute(T parameter)
-        {
-            return canExecute == null ? true : canExecute(parameter);
-        }
-
-        public bool CanExecute(object parameter)
-        {
-            if (canExecute == null) return true;
-            if(parameter != null && parameter is not T)
-            {
-                throw new ArgumentException("Provided parameter type does not match RelayCommand parameter type");
-            }
-
-            return CanExecute((T)parameter);
-        }
-
-        public void Execute(T parameter)
-        {
-            execute(parameter);
-        }
-
-        public void Execute(object parameter)
-        {
-            if (parameter != null && parameter is not T)
-            {
-                throw new ArgumentException("Provided parameter type does not match RelayCommand parameter type");
-            }
-
-            Execute((T)parameter);
-        }
-    }
-
-    public class RelayCommand : RelayCommand<object>
-    {
-        public RelayCommand(Action<object> execute, Predicate<object> canExecute) : base(execute, canExecute) { }
-
-        public RelayCommand(Action<object> execute) : base(execute) { }
-    }
-}

+ 0 - 46
PixiEditor/Helpers/SelectionHelpers.cs

@@ -1,46 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Enums;
-using PixiEditor.Models.Position;
-using PixiEditor.Models.Undo;
-
-namespace PixiEditor.Helpers
-{
-    public static class SelectionHelpers
-    {
-        public static void AddSelectionUndoStep(Document document, IEnumerable<Coordinates> oldPoints, SelectionType mode)
-        {
-            if (mode == SelectionType.New && document.ActiveSelection.SelectedPoints.Count != 0)
-            {
-                if (oldPoints.Any())
-                {
-                    // Add empty selection as the old one get's fully deleted first
-                    document.UndoManager.AddUndoChange(
-                        new Change(
-                            SetSelectionProcess, new object[] { document, new List<Coordinates>(oldPoints) },
-                            SetSelectionProcess, new object[] { document, new List<Coordinates>() }));
-                }
-
-                document.UndoManager.AddUndoChange(
-                    new Change(
-                        SetSelectionProcess, new object[] { document, new List<Coordinates>() },
-                        SetSelectionProcess, new object[] { document, new List<Coordinates>(document.ActiveSelection.SelectedPoints) }));
-            }
-            else
-            {
-                document.UndoManager.AddUndoChange(
-                    new Change(
-                        SetSelectionProcess, new object[] { document, oldPoints is null ? new List<Coordinates>() : new List<Coordinates>(oldPoints) },
-                        SetSelectionProcess, new object[] { document, new List<Coordinates>(document.ActiveSelection.SelectedPoints) }));
-            }
-        }
-
-        private static void SetSelectionProcess(object[] arguments)
-        {
-            Document document = (Document)arguments[0];
-
-            document.ActiveSelection.SetSelection((IEnumerable<Coordinates>)arguments[1], SelectionType.New);
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/SizeCalculator.cs

@@ -1,20 +0,0 @@
-using System;
-
-namespace PixiEditor.Helpers
-{
-    public static class SizeCalculator
-    {
-        public static System.Drawing.Size CalcAbsoluteFromPercentage(float percentage, System.Drawing.Size currentSize)
-        {
-            float percFactor = percentage / 100f;
-            float newWidth = currentSize.Width * percFactor;
-            float newHeight = currentSize.Height * percFactor;
-            return new System.Drawing.Size((int)MathF.Round(newWidth), (int)MathF.Round(newHeight));
-        }
-
-        public static int CalcPercentageFromAbsolute(int initAbsoluteSize, int currentAbsoluteSize)
-        {
-            return (int)((float)currentAbsoluteSize * 100) / initAbsoluteSize;
-        }
-    }
-}

+ 0 - 13
PixiEditor/Helpers/StringExtensions.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Linq;
-
-namespace PixiEditor.Helpers
-{
-    public static class StringExtensions
-    {
-        public static string Reverse(this string s)
-        {
-            return new string(s.Reverse<char>().ToArray());
-        }
-    }
-}

+ 0 - 97
PixiEditor/Helpers/SupportedFilesHelper.cs

@@ -1,97 +0,0 @@
-using PixiEditor.Models.Enums;
-using PixiEditor.Models.IO;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace PixiEditor.Helpers
-{
-    public class SupportedFilesHelper
-    {
-        static Dictionary<FileType, FileTypeDialogData> fileTypeDialogsData;
-        static List<FileTypeDialogData> allFileTypeDialogsData;
-        public static string[] AllSupportedExtensions { get; private set; }
-        public static string[] PrimaryExtensions { get; private set; }
-
-        static SupportedFilesHelper()
-        {
-            fileTypeDialogsData = new Dictionary<FileType, FileTypeDialogData>();
-            allFileTypeDialogsData = new List<FileTypeDialogData>();
-
-            var allFormats = Enum.GetValues(typeof(FileType)).Cast<FileType>().ToList();
-
-            foreach (var format in allFormats)
-            {
-                var fileTypeDialogData = new FileTypeDialogData(format);
-                if (format != FileType.Unset)
-                    fileTypeDialogsData[format] = fileTypeDialogData;
-
-                allFileTypeDialogsData.Add(fileTypeDialogData);
-            }
-
-            AllSupportedExtensions = fileTypeDialogsData.SelectMany(i => i.Value.Extensions).ToArray();
-            PrimaryExtensions = fileTypeDialogsData.Select(i => i.Value.PrimaryExtension).ToArray();
-        }
-
-        public static FileTypeDialogData GetFileTypeDialogData(FileType type)
-        {
-            return allFileTypeDialogsData.Where(i => i.FileType == type).Single();
-        }
-
-        public static bool IsSupportedFile(string path)
-        {
-            var ext = Path.GetExtension(path.ToLower());
-            return IsExtensionSupported(ext);
-        }
-
-        public static bool IsExtensionSupported(string fileExtension)
-        {
-            return AllSupportedExtensions.Contains(fileExtension);
-        }
-        public static FileType ParseImageFormat(string extension)
-        {
-            var allExts = fileTypeDialogsData.Values.ToList();
-            var fileData = allExts.Where(i => i.Extensions.Contains(extension)).SingleOrDefault();
-            if (fileData != null)
-                return fileData.FileType;
-            return FileType.Unset;
-        }
-
-        public static List<FileTypeDialogData> GetAllSupportedFileTypes(bool includePixi)
-        {
-            var allExts = fileTypeDialogsData.Values.ToList();
-            if (!includePixi)
-                allExts.RemoveAll(item => item.FileType == FileType.Pixi);
-            return allExts;
-        }
-
-        public static string BuildSaveFilter(bool includePixi)
-        {
-            var allSupportedExtensions = GetAllSupportedFileTypes(includePixi);
-            var filter = string.Join("|", allSupportedExtensions.Select(i => i.SaveFilter));
-
-            return filter;
-        }
-
-        public static FileType GetSaveFileTypeFromFilterIndex(bool includePixi, int filterIndex)
-        {
-            var allSupportedExtensions = GetAllSupportedFileTypes(includePixi);
-            //filter index starts at 1 for some reason
-            int index = filterIndex - 1;
-            if (allSupportedExtensions.Count <= index)
-                return FileType.Unset;
-            return allSupportedExtensions[index].FileType;
-        }
-
-        public static string BuildOpenFilter()
-        {
-            var any = new FileTypeDialogDataSet(FileTypeDialogDataSet.SetKind.Any).GetFormattedTypes();
-            var pixi = new FileTypeDialogDataSet(FileTypeDialogDataSet.SetKind.Pixi).GetFormattedTypes();
-            var images = new FileTypeDialogDataSet(FileTypeDialogDataSet.SetKind.Images).GetFormattedTypes();
-
-            var filter = any + "|" + pixi + "|" + images;
-            return filter;
-        }
-    }
-}

+ 0 - 28
PixiEditor/Helpers/UI/DocumentsTemplateSelector.cs

@@ -1,28 +0,0 @@
-using System.Windows;
-using System.Windows.Controls;
-using AvalonDock.Layout;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.ViewModels;
-
-namespace PixiEditor.Helpers.UI
-{
-    public class DocumentsTemplateSelector : DataTemplateSelector
-    {
-        public DocumentsTemplateSelector()
-        {
-
-        }
-
-        public DataTemplate DocumentsViewTemplate { get; set; }
-
-        public override DataTemplate SelectTemplate(object item, DependencyObject container)
-        {
-            if (item is Document)
-            {
-                return DocumentsViewTemplate;
-            }
-
-            return base.SelectTemplate(item, container);
-        }
-    }
-}

+ 0 - 20
PixiEditor/Helpers/UI/PanelsStyleSelector.cs

@@ -1,20 +0,0 @@
-using System.Windows;
-using System.Windows.Controls;
-using PixiEditor.Models.DataHolders;
-
-namespace PixiEditor.Helpers.UI
-{
-    public class PanelsStyleSelector : StyleSelector
-    {
-        public Style DocumentTabStyle { get; set; }
-
-        public override Style SelectStyle(object item, DependencyObject container)
-        {
-            if (item is Document)
-            {
-                return DocumentTabStyle;
-            }
-            return base.SelectStyle(item, container);
-        }
-    }
-}

+ 0 - 45
PixiEditor/Helpers/UI/ReversedOrderStackPanel.cs

@@ -1,45 +0,0 @@
-using System;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-
-namespace PixiEditor.Helpers.UI
-{
-    public class ReversedOrderStackPanel : StackPanel
-    {
-        protected override Size ArrangeOverride(Size arrangeSize)
-        {
-            bool fHorizontal = Orientation == Orientation.Horizontal;
-            Rect rcChild = new Rect(arrangeSize);
-            double previousChildSize = 0.0;
-
-            System.Collections.Generic.IEnumerable<UIElement> children = InternalChildren.Cast<UIElement>().Reverse();
-            foreach (UIElement child in children)
-            {
-                if (child == null)
-                {
-                    continue;
-                }
-
-                if (fHorizontal)
-                {
-                    rcChild.X += previousChildSize;
-                    previousChildSize = child.DesiredSize.Width;
-                    rcChild.Width = previousChildSize;
-                    rcChild.Height = Math.Max(arrangeSize.Height, child.DesiredSize.Height);
-                }
-                else
-                {
-                    rcChild.Y += previousChildSize;
-                    previousChildSize = child.DesiredSize.Height;
-                    rcChild.Height = previousChildSize;
-                    rcChild.Width = Math.Max(arrangeSize.Width, child.DesiredSize.Width);
-                }
-
-                child.Arrange(rcChild);
-            }
-
-            return arrangeSize;
-        }
-    }
-}

+ 0 - 21
PixiEditor/Helpers/UI/TreeViewItemHelper.cs

@@ -1,21 +0,0 @@
-using System.Windows;
-
-namespace PixiEditor.Helpers.UI
-{
-    public static class TreeViewItemHelper
-    {
-        public static GridLength GetIndent(DependencyObject obj)
-        {
-            return (GridLength)obj.GetValue(IndentProperty);
-        }
-
-        public static void SetIndent(DependencyObject obj, GridLength value)
-        {
-            obj.SetValue(IndentProperty, value);
-        }
-
-
-        public static readonly DependencyProperty IndentProperty =
-            DependencyProperty.RegisterAttached("Indent", typeof(GridLength), typeof(TreeViewItemHelper), new PropertyMetadata(new GridLength(0)));
-    }
-}

+ 0 - 48
PixiEditor/Helpers/VersionHelpers.cs

@@ -1,48 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Reflection;
-using System.Text;
-
-namespace PixiEditor.Helpers
-{
-    public static class VersionHelpers
-    {
-        public static Version GetCurrentAssemblyVersion() => Assembly.GetExecutingAssembly().GetName().Version;
-
-        public static string GetCurrentAssemblyVersion(Func<Version, string> toString) => toString(GetCurrentAssemblyVersion());
-
-        public static string GetCurrentAssemblyVersionString()
-        {
-            StringBuilder builder = new(GetCurrentAssemblyVersion().ToString());
-
-            bool isDone = false;
-
-            AppendDevBuild(builder, ref isDone);
-
-            if (isDone)
-            {
-                return builder.ToString();
-            }
-
-            AppendDebugBuild(builder, ref isDone);
-
-            return builder.ToString();
-        }
-
-        [Conditional("DEV_RELEASE")]
-        private static void AppendDevBuild(StringBuilder builder, ref bool done)
-        {
-            done = true;
-
-            builder.Append(" Dev Build");
-        }
-
-        [Conditional("DEBUG")]
-        private static void AppendDebugBuild(StringBuilder builder, ref bool done)
-        {
-            done = true;
-
-            builder.Append(" Debug Build");
-        }
-    }
-}

+ 0 - 101
PixiEditor/Helpers/WindowSizeHelper.cs

@@ -1,101 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace PixiEditor.Helpers
-{
-    static class WindowSizeHelper
-    {
-        public static IntPtr SetMaxSizeHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
-        {
-            // All windows messages (msg) can be found here
-            // https://docs.microsoft.com/de-de/windows/win32/winmsg/window-notifications
-            if (msg == WM_GETMINMAXINFO)
-            {
-                // We need to tell the system what our size should be when maximized. Otherwise it will
-                // cover the whole screen, including the task bar.
-                MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
-
-                // Adjust the maximized size and position to fit the work area of the correct monitor
-                IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
-
-                if (monitor != IntPtr.Zero)
-                {
-                    MONITORINFO monitorInfo = default;
-                    monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
-                    GetMonitorInfo(monitor, ref monitorInfo);
-                    RECT rcWorkArea = monitorInfo.rcWork;
-                    RECT rcMonitorArea = monitorInfo.rcMonitor;
-                    mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
-                    mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
-                    mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
-                    mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
-                }
-
-                Marshal.StructureToPtr(mmi, lParam, true);
-            }
-
-            return IntPtr.Zero;
-        }
-
-        private const int WM_GETMINMAXINFO = 0x0024;
-
-        private const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
-
-        [DllImport("user32.dll")]
-        private static extern IntPtr MonitorFromWindow(IntPtr handle, uint flags);
-
-        [DllImport("user32.dll")]
-        private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
-
-        [Serializable]
-        [StructLayout(LayoutKind.Sequential)]
-        private struct RECT
-        {
-            public int Left;
-            public int Top;
-            public int Right;
-            public int Bottom;
-
-            public RECT(int left, int top, int right, int bottom)
-            {
-                this.Left = left;
-                this.Top = top;
-                this.Right = right;
-                this.Bottom = bottom;
-            }
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        private struct MONITORINFO
-        {
-            public int cbSize;
-            public RECT rcMonitor;
-            public RECT rcWork;
-            public uint dwFlags;
-        }
-
-        [Serializable]
-        [StructLayout(LayoutKind.Sequential)]
-        private struct POINT
-        {
-            public int X;
-            public int Y;
-
-            public POINT(int x, int y)
-            {
-                this.X = x;
-                this.Y = y;
-            }
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        private struct MINMAXINFO
-        {
-            public POINT ptReserved;
-            public POINT ptMaxSize;
-            public POINT ptMaxPosition;
-            public POINT ptMinTrackSize;
-            public POINT ptMaxTrackSize;
-        }
-    }
-}

+ 0 - 155
PixiEditor/Models/Colors/ExColor.cs

@@ -1,155 +0,0 @@
-using SkiaSharp;
-using System;
-
-namespace PixiEditor.Models.Colors
-{
-    public static class ExColor
-    {
-        /// <summary>
-        ///     Creates color with corrected brightness.
-        /// </summary>
-        /// <param name="color">Color to correct.</param>
-        /// <param name="correctionFactor">
-        ///     The brightness correction factor. Must be between -1 and 1.
-        ///     Negative values produce darker colors.
-        /// </param>
-        /// <returns>
-        ///     Corrected <see cref="SKColor" /> structure.
-        /// </returns>
-        public static SKColor ChangeColorBrightness(SKColor color, float correctionFactor)
-        {
-            Tuple<int, float, float> hsl = RgbToHsl(color.Red, color.Green, color.Blue);
-            int h = hsl.Item1;
-            float s = hsl.Item2;
-            float l = hsl.Item3;
-
-            l = Math.Clamp(l + correctionFactor, 0, 100);
-            SKColor rgb = HslToRgb(h, s, l);
-
-            return new SKColor(rgb.Red, rgb.Green, rgb.Blue, color.Alpha);
-        }
-
-        /// <summary>
-        ///     Converts RGB to HSL.
-        /// </summary>
-        /// <param name="r">Red value.</param>
-        /// <param name="g">Green value.</param>
-        /// <param name="b">Blue value.</param>
-        /// <returns>Tuple with 3 values in order: h, s, l0.</returns>
-        public static Tuple<int, float, float> RgbToHsl(int r, int g, int b)
-        {
-            int h;
-            float s, l;
-            float dR = r / 255.0f;
-            float dG = g / 255.0f;
-            float dB = b / 255.0f;
-
-            float min = Math.Min(Math.Min(dR, dG), dB);
-            float max = Math.Max(Math.Max(dR, dG), dB);
-            float delta = max - min;
-
-            l = (max + min) / 2;
-
-            if (delta == 0)
-            {
-                h = 0;
-                s = 0.0f;
-            }
-            else
-            {
-                s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
-
-                float hue;
-
-                if (dR == max)
-                {
-                    hue = (dG - dB) / 6 / delta;
-                }
-                else if (dG == max)
-                {
-                    hue = (1.0f / 3) + ((dB - dR) / 6 / delta);
-                }
-                else
-                {
-                    hue = (2.0f / 3) + ((dR - dG) / 6 / delta);
-                }
-
-                if (hue < 0)
-                {
-                    hue += 1;
-                }
-
-                if (hue > 1)
-                {
-                    hue -= 1;
-                }
-
-                h = (int)(hue * 360);
-            }
-
-            return new Tuple<int, float, float>(h, s * 100, l * 100);
-        }
-
-        /// <summary>
-        ///     Converts HSL color format to RGB.
-        /// </summary>
-        /// <returns>RGB Color.</returns>
-        public static SKColor HslToRgb(int h, float s, float l)
-        {
-            s /= 100;
-            l /= 100;
-            byte r = 0;
-            byte g = 0;
-            byte b = 0;
-
-            if (s == 0)
-            {
-                r = g = b = (byte)(l * 255);
-            }
-            else
-            {
-                float v1, v2;
-                float hue = (float)h / 360;
-
-                v2 = l < 0.5 ? l * (1 + s) : l + s - (l * s);
-                v1 = (2 * l) - v2;
-
-                r = (byte)(255 * HueToRgb(v1, v2, hue + (1.0f / 3)));
-                g = (byte)(255 * HueToRgb(v1, v2, hue));
-                b = (byte)(255 * HueToRgb(v1, v2, hue - (1.0f / 3)));
-            }
-
-            return new SKColor(r, g, b);
-        }
-
-        private static float HueToRgb(float v1, float v2, float hue)
-        {
-            if (hue < 0)
-            {
-                hue += 1;
-            }
-
-            if (hue > 1)
-            {
-                hue -= 1;
-            }
-
-            if (6 * hue < 1)
-            {
-                return v1 + ((v2 - v1) * 6 * hue);
-            }
-
-            if (2 * hue < 1)
-            {
-                return v2;
-            }
-
-            if (3 * hue < 2)
-            {
-                return v1 + ((v2 - v1) * ((2.0f / 3) - hue) * 6);
-            }
-
-            return v1;
-        }
-    }
-}

+ 0 - 17
PixiEditor/Models/Commands/Attributes/Commands/DebugAttribute.cs

@@ -1,17 +0,0 @@
-namespace PixiEditor.Models.Commands.Attributes
-{
-    public partial class Command
-    {
-        public class DebugAttribute : BasicAttribute
-        {
-            public DebugAttribute(string internalName, string displayName, string description) : base($"#DEBUG#{internalName}", displayName, description)
-            {
-            }
-
-            public DebugAttribute(string internalName, object parameter, string displayName, string description)
-                : base($"#DEBUG#{internalName}", parameter, displayName, description)
-            {
-            }
-        }
-    }
-}

+ 0 - 22
PixiEditor/Models/Commands/Attributes/Commands/GroupAttribute.cs

@@ -1,22 +0,0 @@
-namespace PixiEditor.Models.Commands.Attributes
-{
-    public partial class Command
-    {
-        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
-        public class GroupAttribute : Attribute
-        {
-            public string InternalName { get; }
-
-            public string DisplayName { get; }
-
-            /// <summary>
-            /// Groups all commands that start with the name <paramref name="internalName"/>
-            /// </summary>
-            public GroupAttribute(string internalName, string displayName)
-            {
-                InternalName = internalName;
-                DisplayName = displayName;
-            }
-        }
-    }
-}

+ 0 - 27
PixiEditor/Models/Commands/Attributes/Commands/InternalAttribute.cs

@@ -1,27 +0,0 @@
-namespace PixiEditor.Models.Commands.Attributes
-{
-    public partial class Command
-    {
-        /// <summary>
-        /// A command that is not shown in the UI
-        /// </summary>
-        public class InternalAttribute : BasicAttribute
-        {
-            /// <summary>
-            /// A command that is not shown in the UI
-            /// </summary>
-            public InternalAttribute(string name)
-                : base(name, string.Empty, string.Empty)
-            {
-            }
-
-            /// <summary>
-            /// A command that is not shown in the UI
-            /// </summary>
-            public InternalAttribute(string name, object parameter)
-                : base(name, parameter, string.Empty, string.Empty)
-            {
-            }
-        }
-    }
-}

+ 0 - 84
PixiEditor/Models/Commands/CommandCollection.cs

@@ -1,84 +0,0 @@
-using PixiEditor.Models.DataHolders;
-using System.Collections;
-using System.Diagnostics;
-using System.Windows.Input;
-using OneOf.Types;
-
-namespace PixiEditor.Models.Commands
-{
-    [DebuggerDisplay("Count = {Count}")]
-    public class CommandCollection : ICollection<Command>
-    {
-        private readonly Dictionary<string, Command> _commandInternalNames;
-        private readonly OneToManyDictionary<KeyCombination, Command> _commandShortcuts;
-
-        public int Count => _commandInternalNames.Count;
-
-        public bool IsReadOnly => false;
-
-        public Command this[string name] => _commandInternalNames[name];
-
-        public IEnumerable<Command> this[KeyCombination shortcut] => _commandShortcuts[shortcut];
-
-        public CommandCollection()
-        {
-            _commandInternalNames = new();
-            _commandShortcuts = new();
-        }
-
-        public void Add(Command item)
-        {
-            _commandInternalNames.Add(item.InternalName, item);
-            _commandShortcuts.Add(item.Shortcut, item);
-        }
-
-        public void Clear()
-        {
-            _commandInternalNames.Clear();
-            _commandShortcuts.Clear();
-        }
-
-        public void ClearShortcuts() => _commandShortcuts.Clear();
-
-        public bool Contains(Command item) => _commandInternalNames.ContainsKey(item.InternalName);
-
-        public void CopyTo(Command[] array, int arrayIndex) => _commandInternalNames.Values.CopyTo(array, arrayIndex);
-
-        public IEnumerator<Command> GetEnumerator() => _commandInternalNames.Values.GetEnumerator();
-
-        public bool Remove(Command item)
-        {
-            bool anyRemoved = false;
-
-            anyRemoved |= _commandInternalNames.Remove(item.InternalName);
-            anyRemoved |= _commandShortcuts.Remove(item);
-
-            return anyRemoved;
-        }
-
-        public void AddShortcut(Command command, KeyCombination shortcut)
-        {
-            _commandShortcuts.Remove(KeyCombination.None, command);
-            _commandShortcuts.Add(shortcut, command);
-        }
-
-        public void RemoveShortcut(Command command, KeyCombination shortcut)
-        {
-            _commandShortcuts.Remove(shortcut, command);
-            _commandShortcuts.Add(KeyCombination.None, command);
-        }
-
-        public void ClearShortcut(KeyCombination shortcut)
-        {
-            if (shortcut is { Key: Key.None, Modifiers: ModifierKeys.None })
-                return;
-            _commandShortcuts.AddRange(KeyCombination.None, _commandShortcuts[shortcut]);
-            _commandShortcuts.Clear(shortcut);      
-        }
-
-        public IEnumerable<KeyValuePair<KeyCombination, IEnumerable<Command>>> GetShortcuts() =>
-            _commandShortcuts;
-
-        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-    }
-}

+ 0 - 358
PixiEditor/Models/Commands/CommandController.cs

@@ -1,358 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using PixiEditor.Models.Commands.Attributes;
-using PixiEditor.Models.Commands.Evaluators;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Tools;
-using System.IO;
-using System.Reflection;
-using System.Windows.Media;
-using CommandAttribute = PixiEditor.Models.Commands.Attributes.Command;
-
-namespace PixiEditor.Models.Commands
-{
-    public class CommandController
-    {
-        private readonly ShortcutFile shortcutFile;
-
-        public static CommandController Current { get; private set; }
-
-        public static string ShortcutsPath { get; private set; }
-
-        public CommandCollection Commands { get; }
-
-        public List<CommandGroup> CommandGroups { get; }
-
-        public Dictionary<string, CanExecuteEvaluator> CanExecuteEvaluators { get; }
-
-        public Dictionary<string, IconEvaluator> IconEvaluators { get; }
-
-        public CommandController(IServiceProvider services)
-        {
-            Current ??= this;
-
-            ShortcutsPath = Path.Join(
-                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
-                "PixiEditor",
-                "shortcuts.json");
-
-            shortcutFile = new(ShortcutsPath, this);
-
-            Commands = new();
-            CommandGroups = new();
-            CanExecuteEvaluators = new();
-            IconEvaluators = new();
-        }
-
-        public void Import(IEnumerable<KeyValuePair<KeyCombination, IEnumerable<string>>> shortcuts, bool save = true)
-        {
-            foreach (var shortcut in shortcuts)
-            {
-                foreach (var command in shortcut.Value)
-                {
-                    ReplaceShortcut(Commands[command], shortcut.Key);
-                }
-            }
-
-            if (save)
-            {
-                shortcutFile.SaveShortcuts();
-            }
-        }
-
-        private static List<(string internalName, string displayName)> FindCommandGroups(Type[] typesToSearchForAttributes)
-        {
-            List<(string internalName, string displayName)> result = new();
-
-            foreach (var type in typesToSearchForAttributes)
-            {
-                foreach (var group in type.GetCustomAttributes<CommandAttribute.GroupAttribute>())
-                {
-                    result.Add((group.InternalName, group.DisplayName));
-                }
-            }
-
-            return result;
-        }
-
-        private static void ForEachMethod
-            (Type[] typesToSearchForMethods, IServiceProvider serviceProvider, Action<MethodInfo, object> action)
-        {
-            foreach (var type in typesToSearchForMethods)
-            {
-                object serviceInstance = serviceProvider.GetService(type);
-                var methods = type.GetMethods();
-                foreach (var method in methods)
-                {
-                    action(method, serviceInstance);
-                }
-            }
-        }
-
-        public void Init(IServiceProvider serviceProvider)
-        {
-            KeyValuePair<KeyCombination, IEnumerable<string>>[] shortcuts = shortcutFile.LoadShortcuts()?.ToArray()
-                ?? Array.Empty<KeyValuePair<KeyCombination, IEnumerable<string>>>();
-
-            Type[] allTypesInPixiEditorAssembly = typeof(CommandController).Assembly.GetTypes();
-
-            List<(string internalName, string displayName)> commandGroupsData = FindCommandGroups(allTypesInPixiEditorAssembly);
-            OneToManyDictionary<string, Command> commands = new(); // internal name of the corr. group -> command in that group
-
-            // Find evaluators
-            ForEachMethod(allTypesInPixiEditorAssembly, serviceProvider, (methodInfo, maybeServiceInstance) =>
-            {
-                var evaluatorAttrs = methodInfo.GetCustomAttributes<Evaluator.EvaluatorAttribute>();
-                foreach (var attribute in evaluatorAttrs)
-                {
-                    switch (attribute)
-                    {
-                        case Evaluator.CanExecuteAttribute canExecuteAttribute:
-                            {
-                                var getRequiredEvaluatorsObjectsOfCurrentEvaluator =
-                                    (CommandController controller) =>
-                                        canExecuteAttribute.NamesOfRequiredCanExecuteEvaluators.Select(x => controller.CanExecuteEvaluators[x]);
-
-                                AddEvaluatorFactory<Evaluator.CanExecuteAttribute, CanExecuteEvaluator, bool>(
-                                    methodInfo,
-                                    maybeServiceInstance,
-                                    canExecuteAttribute,
-                                    CanExecuteEvaluators,
-                                    evaluateFunction => new CanExecuteEvaluator()
-                                    {
-                                        Name = attribute.Name,
-                                        Evaluate = evaluateFunctionArgument =>
-                                            evaluateFunction.Invoke(evaluateFunctionArgument) &&
-                                            getRequiredEvaluatorsObjectsOfCurrentEvaluator.Invoke(this).All(requiredEvaluator =>
-                                                requiredEvaluator.CallEvaluate(null, evaluateFunctionArgument))
-                                    });
-                                break;
-                            }
-                        case Evaluator.IconAttribute icon:
-                            AddEvaluator<Evaluator.IconAttribute, IconEvaluator, ImageSource>(methodInfo, maybeServiceInstance, icon, IconEvaluators);
-                            break;
-                    }
-                }
-            });
-
-            // Find basic commands
-            ForEachMethod(allTypesInPixiEditorAssembly, serviceProvider, (methodInfo, maybeServiceInstance) =>
-            {
-                var commandAttrs = methodInfo.GetCustomAttributes<CommandAttribute.CommandAttribute>();
-
-                foreach (var attribute in commandAttrs)
-                {
-                    if (attribute is CommandAttribute.BasicAttribute basic)
-                    {
-                        AddCommand(methodInfo, maybeServiceInstance, attribute, (isDebug, name, x, xCan, xIcon) => new Command.BasicCommand(x, xCan)
-                        {
-                            InternalName = name,
-                            IsDebug = isDebug,
-                            DisplayName = attribute.DisplayName,
-                            Description = attribute.Description,
-                            IconPath = attribute.IconPath,
-                            IconEvaluator = xIcon,
-                            DefaultShortcut = attribute.GetShortcut(),
-                            Shortcut = GetShortcut(name, attribute.GetShortcut()),
-                            Parameter = basic.Parameter,
-                        });
-                    }
-                }
-            });
-
-            // Find tool commands
-            foreach (var type in allTypesInPixiEditorAssembly)
-            {
-                if (!type.IsAssignableTo(typeof(Tool)))
-                    continue;
-
-                var toolAttr = type.GetCustomAttribute<CommandAttribute.ToolAttribute>();
-                if (toolAttr is null)
-                    continue;
-
-                Tool toolInstance = serviceProvider.GetServices<Tool>().First(x => x.GetType() == type);
-                string internalName = $"PixiEditor.Tools.Select.{type.Name}";
-
-                var command = new Command.ToolCommand()
-                {
-                    InternalName = internalName,
-                    DisplayName = $"Select {toolInstance.DisplayName} Tool",
-                    Description = $"Select {toolInstance.DisplayName} Tool",
-                    IconPath = $"@{toolInstance.ImagePath}",
-                    IconEvaluator = IconEvaluator.Default,
-                    TransientKey = toolAttr.Transient,
-                    DefaultShortcut = toolAttr.GetShortcut(),
-                    Shortcut = GetShortcut(internalName, toolAttr.GetShortcut()),
-                    ToolType = type,
-                };
-
-                Commands.Add(command);
-                AddCommandToCommandsCollection(command);
-            }
-
-            // save all commands into CommandGroups
-            foreach (var (groupInternalName, storedCommands) in commands)
-            {
-                var groupData = commandGroupsData.Where(group => group.internalName == groupInternalName).FirstOrDefault();
-                string groupDisplayName;
-                if (groupData == default)
-                    groupDisplayName = "Misc";
-                else
-                    groupDisplayName = groupData.displayName;
-                CommandGroups.Add(new(groupDisplayName, storedCommands));
-            }
-
-            KeyCombination GetShortcut(string internalName, KeyCombination defaultShortcut)
-                => shortcuts.FirstOrDefault(x => x.Value.Contains(internalName), new(defaultShortcut, null)).Key;
-
-            void AddCommandToCommandsCollection(Command command)
-            {
-                (string internalName, string displayName) group = commandGroupsData.FirstOrDefault(x => command.InternalName.StartsWith(x.internalName));
-                if (group == default)
-                    commands.Add("", command);
-                else
-                    commands.Add(group.internalName, command);
-            }
-
-            void AddEvaluator<TAttr, T, TParameter>(MethodInfo method, object instance, TAttr attribute, IDictionary<string, T> evaluators)
-                where T : Evaluator<TParameter>, new()
-                where TAttr : Evaluator.EvaluatorAttribute
-                => AddEvaluatorFactory<TAttr, T, TParameter>(method, instance, attribute, evaluators, x => new T() { Name = attribute.Name, Evaluate = x });
-
-            void AddEvaluatorFactory<TAttr, T, TParameter>(MethodInfo method, object serviceInstance, TAttr attribute, IDictionary<string, T> evaluators, Func<Func<object, TParameter>, T> factory)
-                where T : Evaluator<TParameter>, new()
-                where TAttr : Evaluator.EvaluatorAttribute
-            {
-                if (method.ReturnType != typeof(TParameter))
-                {
-                    throw new Exception($"Invalid return type for the CanExecute evaluator '{attribute.Name}' at {method.ReflectedType.FullName}.{method.Name}\nExpected '{typeof(TParameter).FullName}'");
-                }
-                else if (method.GetParameters().Length > 1)
-                {
-                    throw new Exception($"Too many parameters for the CanExecute evaluator '{attribute.Name}' at {method.ReflectedType.FullName}.{method.Name}");
-                }
-                else if (!method.IsStatic && serviceInstance is null)
-                {
-                    throw new Exception($"No type instance for the CanExecute evaluator '{attribute.Name}' at {method.ReflectedType.FullName}.{method.Name} found");
-                }
-
-                var parameters = method.GetParameters();
-
-                Func<object, TParameter> func;
-
-                if (parameters.Length == 1)
-                {
-                    func = x => (TParameter)method.Invoke(serviceInstance, new[] { CastParameter(x, parameters[0].ParameterType) });
-                }
-                else
-                {
-                    func = x => (TParameter)method.Invoke(serviceInstance, null);
-                }
-
-                T evaluator = factory(func);
-
-                evaluators.Add(evaluator.Name, evaluator);
-            }
-
-            object CastParameter(object input, Type target)
-            {
-                if (target == typeof(object) || target == input?.GetType())
-                    return input;
-                return Convert.ChangeType(input, target);
-            }
-
-            TCommand AddCommand<TAttr, TCommand>(MethodInfo method, object instance, TAttr attribute, Func<bool, string, Action<object>, CanExecuteEvaluator, IconEvaluator, TCommand> commandFactory)
-                where TAttr : CommandAttribute.CommandAttribute
-                where TCommand : Command
-            {
-                if (method != null)
-                {
-                    if (method.GetParameters().Length > 1)
-                    {
-                        throw new Exception($"Too many parameters for the CanExecute evaluator '{attribute.InternalName}' at {method.ReflectedType.FullName}.{method.Name}");
-                    }
-                    else if (!method.IsStatic && instance is null)
-                    {
-                        throw new Exception($"No type instance for the CanExecute evaluator '{attribute.InternalName}' at {method.ReflectedType.FullName}.{method.Name} found");
-                    }
-                }
-
-                var parameters = method?.GetParameters();
-
-                Action<object> action;
-
-                if (parameters == null || parameters.Length != 1)
-                {
-                    action = x => method.Invoke(instance, null);
-                }
-                else
-                {
-                    action = x => method.Invoke(instance, new[] { x });
-                }
-
-                string name = attribute.InternalName;
-                bool isDebug = attribute.InternalName.StartsWith("#DEBUG#");
-
-                if (attribute.InternalName.StartsWith("#DEBUG#"))
-                {
-                    name = name["#DEBUG#".Length..];
-                }
-
-                var command = commandFactory(
-                        isDebug,
-                        name,
-                        action,
-                        attribute.CanExecute != null ? CanExecuteEvaluators[attribute.CanExecute] : CanExecuteEvaluator.AlwaysTrue,
-                        attribute.IconEvaluator != null ? IconEvaluators[attribute.IconEvaluator] : IconEvaluator.Default);
-
-                Commands.Add(command);
-                AddCommandToCommandsCollection(command);
-
-                return command;
-            }
-        }
-
-        /// <summary>
-        /// Removes the old shortcut to this command and adds the new one
-        /// </summary>
-        public void UpdateShortcut(Command command, KeyCombination newShortcut)
-        {
-            Commands.RemoveShortcut(command, command.Shortcut);
-            Commands.AddShortcut(command, newShortcut);
-            command.Shortcut = newShortcut;
-            shortcutFile.SaveShortcuts();
-        }
-
-        /// <summary>
-        /// Deletes all shortcuts of <paramref name="newShortcut"/> and adds <paramref name="command"/>
-        /// </summary>
-        public void ReplaceShortcut(Command command, KeyCombination newShortcut)
-        {
-            foreach (Command other in Commands[newShortcut])
-            {
-                other.Shortcut = KeyCombination.None;
-            }
-
-            Commands.ClearShortcut(newShortcut);
-            Commands.RemoveShortcut(command, command.Shortcut);
-            Commands.AddShortcut(command, newShortcut);
-            command.Shortcut = newShortcut;
-            shortcutFile.SaveShortcuts();
-        }
-
-        public void ResetShortcuts()
-        {
-            File.Copy(ShortcutsPath, Path.ChangeExtension(ShortcutsPath, ".json.bak"), true);
-
-            Commands.ClearShortcuts();
-
-            foreach (var command in Commands)
-            {
-                Commands.RemoveShortcut(command, command.Shortcut);
-                Commands.AddShortcut(command, command.DefaultShortcut);
-                command.Shortcut = command.DefaultShortcut;
-            }
-
-            shortcutFile.SaveShortcuts();
-        }
-    }
-}

+ 0 - 55
PixiEditor/Models/Commands/CommandGroup.cs

@@ -1,55 +0,0 @@
-using PixiEditor.Models.DataHolders;
-using System.Collections;
-using System.Windows.Input;
-
-namespace PixiEditor.Models.Commands
-{
-    public class CommandGroup : IEnumerable<Command>
-    {
-        private readonly Command[] commands;
-        private readonly Command[] visibleCommands;
-
-        public string DisplayName { get; set; }
-
-        public bool HasAssignedShortcuts { get; set; }
-
-        public IEnumerable<Command> Commands => commands;
-
-        public IEnumerable<Command> VisibleCommands => visibleCommands;
-
-        public CommandGroup(string displayName, IEnumerable<Command> commands)
-        {
-            DisplayName = displayName;
-            this.commands = commands.ToArray();
-            visibleCommands = commands.Where(x => !string.IsNullOrEmpty(x.DisplayName)).ToArray();
-
-            foreach (var command in commands)
-            {
-                HasAssignedShortcuts |= command.Shortcut.Key != Key.None;
-                command.ShortcutChanged += Command_ShortcutChanged;
-            }
-        }
-
-        private void Command_ShortcutChanged(Command cmd, ShortcutChangedEventArgs args)
-        {
-            if ((args.NewShortcut != KeyCombination.None && HasAssignedShortcuts) ||
-                (args.NewShortcut == KeyCombination.None && !HasAssignedShortcuts))
-            {
-                // If a shortcut is already assigned and the new shortcut is not none nothing can change
-                // If no shortcut is already assigned and the new shortcut is none nothing can change
-                return;
-            }
-
-            HasAssignedShortcuts = false;
-
-            foreach (var command in commands)
-            {
-                HasAssignedShortcuts |= command.Shortcut.Key != Key.None;
-            }
-        }
-
-        public IEnumerator<Command> GetEnumerator() => Commands.GetEnumerator();
-
-        IEnumerator IEnumerable.GetEnumerator() => Commands.GetEnumerator();
-    }
-}

+ 0 - 16
PixiEditor/Models/Commands/Commands/BasicCommand.cs

@@ -1,16 +0,0 @@
-using PixiEditor.Models.Commands.Evaluators;
-
-namespace PixiEditor.Models.Commands
-{
-    public partial class Command
-    {
-        public class BasicCommand : Command
-        {
-            public object Parameter { get; init; }
-
-            protected override object GetParameter() => Parameter;
-
-            public BasicCommand(Action<object> onExecute, CanExecuteEvaluator canExecute) : base(onExecute, canExecute) { }
-        }
-    }
-}

+ 0 - 57
PixiEditor/Models/Commands/Commands/Command.cs

@@ -1,57 +0,0 @@
-using PixiEditor.Helpers;
-using PixiEditor.Models.Commands.Evaluators;
-using PixiEditor.Models.DataHolders;
-using System.Diagnostics;
-using System.Windows.Media;
-
-namespace PixiEditor.Models.Commands
-{
-    [DebuggerDisplay("{InternalName,nq} ('{DisplayName,nq}')")]
-    public abstract partial class Command : NotifyableObject
-    {
-        private KeyCombination _shortcut;
-
-        public bool IsDebug { get; init; }
-
-        public string InternalName { get; init; }
-
-        public string IconPath { get; init; }
-
-        public IconEvaluator IconEvaluator { get; init; }
-
-        public string DisplayName { get; init; }
-
-        public string Description { get; init; }
-
-        public CommandMethods Methods { get; init; }
-
-        public KeyCombination DefaultShortcut { get; init; }
-
-        public KeyCombination Shortcut
-        {
-            get => _shortcut;
-            set
-            {
-                if (SetProperty(ref _shortcut, value, out var oldValue))
-                {
-                    ShortcutChanged?.Invoke(this, new(oldValue, value));
-                }
-            }
-        }
-
-        public event ShortcutChangedEventHandler ShortcutChanged;
-
-        protected abstract object GetParameter();
-
-        protected Command(Action<object> onExecute, CanExecuteEvaluator canExecute) =>
-            Methods = new(this, onExecute, canExecute);
-
-        public void Execute() => Methods.Execute(GetParameter());
-
-        public bool CanExecute() => Methods.CanExecute(GetParameter());
-
-        public ImageSource GetIcon() => IconEvaluator.CallEvaluate(this, GetParameter());
-
-        public delegate void ShortcutChangedEventHandler(Command command, ShortcutChangedEventArgs args);
-    }
-}

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