mirror of
https://github.com/4sval/FModel.git
synced 2026-04-01 14:45:45 -05:00
FModel 3.0
This commit is contained in:
parent
cc1b7d029e
commit
7d74ff4c2f
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -236,7 +236,7 @@ Generated_Code/
|
|||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
#Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
|
|
|
|||
26
FModel.sln
26
FModel.sln
|
|
@ -1,37 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.202
|
||||
VisualStudioVersion = 16.0.28803.452
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FModel", "FModel\FModel.csproj", "{8FABCD3A-9D55-4B54-B237-B259D815DEB8}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FModel", "FModel\FModel.csproj", "{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|x64.Build.0 = Debug|x64
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Debug|x86.Build.0 = Debug|x86
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|x64.ActiveCfg = Release|x64
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|x64.Build.0 = Release|x64
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|x86.ActiveCfg = Release|x86
|
||||
{8FABCD3A-9D55-4B54-B237-B259D815DEB8}.Release|x86.Build.0 = Release|x86
|
||||
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3D4827DE-E5BC-4FA0-9D6B-6804C8F3BA96}
|
||||
SolutionGuid = {42CA5618-EB78-4DDF-95A4-BD589CC52791}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -6,77 +6,77 @@
|
|||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<FModel.Properties.Settings>
|
||||
<setting name="PAKsPath" serializeAs="String">
|
||||
<setting name="FPak_Path" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="ExtractOutput" serializeAs="String">
|
||||
<setting name="FOutput_Path" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="loadFeaturedImage" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="wFilename" serializeAs="String">
|
||||
<setting name="FPak_MainAES" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="wOpacity" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="wSize" serializeAs="String">
|
||||
<value>1</value>
|
||||
</setting>
|
||||
<setting name="isWatermark" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="AESKey" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UMSize" serializeAs="String">
|
||||
<value>1</value>
|
||||
</setting>
|
||||
<setting name="UMOpacity" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="UMWatermark" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="UMFeatured" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="UMFilename" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UpdateSettings" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="IconLanguage" serializeAs="String">
|
||||
<value>English</value>
|
||||
</setting>
|
||||
<setting name="challengesWatermark" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UMParameters" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="isChallengesTheme" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="challengesBannerFileName" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="challengesOpacity" serializeAs="String">
|
||||
<value>1</value>
|
||||
</setting>
|
||||
<setting name="challengesColors" serializeAs="String">
|
||||
<value>50,50,50</value>
|
||||
</setting>
|
||||
<setting name="rarityDesign" serializeAs="String">
|
||||
<setting name="FRarity_Design" serializeAs="String">
|
||||
<value>Default</value>
|
||||
</setting>
|
||||
<setting name="openSound" serializeAs="String">
|
||||
<setting name="FLanguage" serializeAs="String">
|
||||
<value>English</value>
|
||||
</setting>
|
||||
<setting name="FIsFeatured" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FUseWatermark" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FWatermarkFilePath" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="FWatermarkOpacity" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="FWatermarkScale" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="FWatermarkXPos" serializeAs="String">
|
||||
<value>3</value>
|
||||
</setting>
|
||||
<setting name="FWatermarkYPos" serializeAs="String">
|
||||
<value>3</value>
|
||||
</setting>
|
||||
<setting name="FChallengeWatermark" serializeAs="String">
|
||||
<value>{BundleName} - {Date}</value>
|
||||
</setting>
|
||||
<setting name="FUseChallengeWatermark" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FBannerFilePath" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="FBannerOpacity" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="FDiffFileSize" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="HeaderVisibility" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="ReadOnly" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="StatusBarVisibility" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="FPrimaryColor" serializeAs="String">
|
||||
<value>21:32:43</value>
|
||||
</setting>
|
||||
<setting name="FSecondaryColor" serializeAs="String">
|
||||
<value>29:161:242</value>
|
||||
</setting>
|
||||
<setting name="FUpdateSettings" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
</FModel.Properties.Settings>
|
||||
|
|
@ -84,8 +84,8 @@
|
|||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
|
||||
<assemblyIdentity name="SkiaSharp" publicKeyToken="0738eb9f132ed756" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.68.0.0" newVersion="1.68.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
|
|
|||
18
FModel/App.xaml
Normal file
18
FModel/App.xaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<Application x:Class="FModel.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:FModel"
|
||||
StartupUri="FModel_Main.xaml"
|
||||
ShutdownMode="OnMainWindowClose"
|
||||
DispatcherUnhandledException="OnDispatcherUnhandledException">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Themes\Styles.xaml" />
|
||||
<ResourceDictionary Source="Forms/HexViewer/BrushesDictionary.xaml" />
|
||||
<ResourceDictionary Source="Forms/HexViewer/MiscelanousDictionary.xaml" />
|
||||
<ResourceDictionary Source="Forms/HexViewer/ToolTipDictionary.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
18
FModel/App.xaml.cs
Normal file
18
FModel/App.xaml.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using FModel.Methods.MessageBox;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
string errorMessage = string.Format("An unhandled exception occurred: {0}", e.Exception.Message);
|
||||
DarkMessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
FModel/Commands/FModel_Commands.cs
Normal file
12
FModel/Commands/FModel_Commands.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System.Windows.Input;
|
||||
|
||||
namespace FModel.Commands
|
||||
{
|
||||
static class FModel_Commands
|
||||
{
|
||||
public static readonly RoutedUICommand OpenSettings = new RoutedUICommand("Open Settings Window", "OpenSettings", typeof(MainWindow));
|
||||
public static readonly RoutedUICommand OpenSearch = new RoutedUICommand("Open Search Window", "OpenSearch", typeof(MainWindow));
|
||||
public static readonly RoutedUICommand OpenOutput = new RoutedUICommand("Open Output Folder", "OpenOutput", typeof(MainWindow));
|
||||
public static readonly RoutedUICommand MergeImages = new RoutedUICommand("Merge Images", "MergeImages", typeof(MainWindow));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FModel
|
||||
{
|
||||
public static class JsonExtensions
|
||||
{
|
||||
public static List<JToken> FindTokens(this JToken containerToken, string name)
|
||||
{
|
||||
List<JToken> matches = new List<JToken>();
|
||||
FindTokens(containerToken, name, matches);
|
||||
return matches;
|
||||
}
|
||||
|
||||
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
|
||||
{
|
||||
if (containerToken.Type == JTokenType.Object)
|
||||
{
|
||||
foreach (JProperty child in containerToken.Children<JProperty>())
|
||||
{
|
||||
if (string.Equals(child.Name, name, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
matches.Add(child.Value);
|
||||
}
|
||||
FindTokens(child.Value, name, matches);
|
||||
}
|
||||
}
|
||||
else if (containerToken.Type == JTokenType.Array)
|
||||
{
|
||||
foreach (JToken child in containerToken.Children())
|
||||
{
|
||||
FindTokens(child, name, matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace FModel
|
||||
{
|
||||
public class TypeAssistant
|
||||
{
|
||||
public event EventHandler Idled = delegate { };
|
||||
public int WaitingMilliSeconds { get; set; }
|
||||
Timer _waitingTimer;
|
||||
|
||||
public TypeAssistant(int waitingMilliSeconds = 600)
|
||||
{
|
||||
WaitingMilliSeconds = waitingMilliSeconds;
|
||||
_waitingTimer = new Timer(p =>
|
||||
{
|
||||
Idled(this, EventArgs.Empty);
|
||||
});
|
||||
}
|
||||
public void TextChanged()
|
||||
{
|
||||
_waitingTimer.Change(WaitingMilliSeconds, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -4,16 +4,34 @@
|
|||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8FABCD3A-9D55-4B54-B237-B259D815DEB8}</ProjectGuid>
|
||||
<ProjectGuid>{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>FModel</RootNamespace>
|
||||
<AssemblyName>FModel</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
|
|
@ -24,259 +42,460 @@
|
|||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>FModel.ico</ApplicationIcon>
|
||||
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>FModel.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AutoUpdater.NET, Version=1.5.4.0, Culture=neutral, PublicKeyToken=501435c91b35f4bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Autoupdater.NET.Official.1.5.4\lib\net40\AutoUpdater.NET.dll</HintPath>
|
||||
<Reference Include="AutoUpdater.NET, Version=1.5.7.0, Culture=neutral, PublicKeyToken=501435c91b35f4bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Autoupdater.NET.Official.1.5.7\lib\net40\AutoUpdater.NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="csharp-wick, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>DLLs\csharp-wick.dll</HintPath>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.11.16.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.11.16\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Cyotek.Windows.Forms.ColorPicker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58daa28b0b2de221, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Cyotek.Windows.Forms.ColorPicker.1.7.2\lib\net35\Cyotek.Windows.Forms.ColorPicker.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.11.12.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.11.12\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
<Reference Include="ICSharpCode.AvalonEdit, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\AvalonEdit.6.0.0\lib\net45\ICSharpCode.AvalonEdit.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Ookii.Dialogs.Wpf, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66aa232afad40158, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ookii.Dialogs.Wpf.1.1.0\lib\net45\Ookii.Dialogs.Wpf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RestSharp, Version=106.6.10.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\RestSharp.106.6.10\lib\net452\RestSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScintillaNET FindReplaceDialog, Version=1.4.0.17540, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>DLLs\ScintillaNET FindReplaceDialog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScintillaNET, Version=3.6.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\jacobslusser.ScintillaNET.3.6.3\lib\net40\ScintillaNET.dll</HintPath>
|
||||
<Reference Include="SkiaSharp, Version=1.68.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SkiaSharp.1.68.0\lib\net45\SkiaSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Messaging" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WriteableBitmapEx.Wpf, Version=1.6.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\WriteableBitmapEx.1.6.3\lib\net40\WriteableBitmapEx.Wpf.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Forms\MergeImages.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\MergeImages.Designer.cs">
|
||||
<DependentUpon>MergeImages.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Methods\Converter\UnrealEngineDataToOGG.cs" />
|
||||
<Compile Include="Custom\JsonExtensions.cs" />
|
||||
<Compile Include="Custom\TypeAssistant.cs" />
|
||||
<Compile Include="Forms\AESManager.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\AESManager.Designer.cs">
|
||||
<DependentUpon>AESManager.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Methods\AESManager\DynamicKeysManager.cs" />
|
||||
<Compile Include="Methods\AESManager\DynamicKeys\AddToUI.cs" />
|
||||
<Compile Include="Methods\AESManager\DynamicKeys\Keychain.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ChallengeGenerator\BundleDesign.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ChallengeGenerator\BundleInfos.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ChallengeGenerator\ChallengeInfoEntry.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ChallengeGenerator\DrawingRewards.cs" />
|
||||
<Compile Include="Methods\DLLImport.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ItemGenerator\DrawText.cs" />
|
||||
<Compile Include="Methods\IconGenerator\SchematicGenerator\SchematicIconDesign.cs" />
|
||||
<Compile Include="Methods\IconGenerator\SchematicGenerator\SchematicInfoEntry.cs" />
|
||||
<Compile Include="Methods\IconGenerator\SchematicGenerator\SchematicItemInfos.cs" />
|
||||
<Compile Include="Methods\IconGenerator\Translations\LoadLocRes.cs" />
|
||||
<Compile Include="Methods\IconGenerator\Translations\SearchResource.cs" />
|
||||
<Compile Include="Methods\PakHelper\BackupFilesEntry.cs" />
|
||||
<Compile Include="Methods\PakHelper\CreateBackup.cs" />
|
||||
<Compile Include="Methods\PakHelper\PakHelper.cs" />
|
||||
<Compile Include="Methods\Serializer\AssetReader.cs" />
|
||||
<Compile Include="Methods\Serializer\LocRes\HotfixedStrings.cs" />
|
||||
<Compile Include="Methods\Serializer\LocRes\LocResSerializer.cs" />
|
||||
<Compile Include="Methods\Scintilla\MyScintilla.cs" />
|
||||
<Compile Include="Methods\UpdateMode\RegisterSettings.cs" />
|
||||
<Compile Include="Methods\Utilities\FontUtilities.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ItemGenerator\ItemIcon.cs" />
|
||||
<Compile Include="Methods\IconGenerator\ItemGenerator\Rarity.cs" />
|
||||
<Compile Include="Forms\About.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\About.Designer.cs">
|
||||
<DependentUpon>About.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\SearchFiles.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\SearchFiles.Designer.cs">
|
||||
<DependentUpon>SearchFiles.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Settings.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Settings.Designer.cs">
|
||||
<DependentUpon>Settings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\UpdateModeSettings.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\UpdateModeSettings.Designer.cs">
|
||||
<DependentUpon>UpdateModeSettings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.Designer.cs">
|
||||
<DependentUpon>MainWindow.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Methods\Utilities\ImageUtilities.cs" />
|
||||
<Compile Include="Methods\JohnWick\JohnWick.cs" />
|
||||
<Compile Include="Methods\Utilities\Utilities.cs" />
|
||||
<Compile Include="Methods\VarApp.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Forms\About.resx">
|
||||
<DependentUpon>About.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\AESManager.resx">
|
||||
<DependentUpon>AESManager.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\MergeImages.resx">
|
||||
<DependentUpon>MergeImages.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\SearchFiles.resx">
|
||||
<DependentUpon>SearchFiles.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\Settings.resx">
|
||||
<DependentUpon>Settings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\UpdateModeSettings.resx">
|
||||
<DependentUpon>UpdateModeSettings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="MainWindow.resx">
|
||||
<DependentUpon>MainWindow.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Commands\FModel_Commands.cs" />
|
||||
<Compile Include="Forms\AESManager.xaml.cs">
|
||||
<DependentUpon>AESManager.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ColorPicker\Code\ColorPalette.cs" />
|
||||
<Compile Include="Forms\ColorPicker\Code\ColorPickerDialogOptions.cs" />
|
||||
<Compile Include="Forms\ColorPicker\Code\ColorSwatchItem.cs" />
|
||||
<Compile Include="Forms\ColorPicker\Code\Util.cs" />
|
||||
<Compile Include="Forms\ColorPicker\ColorPickerControl.xaml.cs">
|
||||
<DependentUpon>ColorPickerControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ColorPicker\ColorPickerSettings.cs" />
|
||||
<Compile Include="Forms\ColorPicker\ColorPickerSwatch.xaml.cs">
|
||||
<DependentUpon>ColorPickerSwatch.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ColorPicker\ColorPickerWindow.xaml.cs">
|
||||
<DependentUpon>ColorPickerWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ColorPicker\ColorPickRow.xaml.cs">
|
||||
<DependentUpon>ColorPickRow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ColorPicker\SliderRow.xaml.cs">
|
||||
<DependentUpon>SliderRow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\FModel_About.xaml.cs">
|
||||
<DependentUpon>FModel_About.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\FModel_CustomMB.xaml.cs">
|
||||
<DependentUpon>FModel_CustomMB.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\FModel_ImagesMerger.xaml.cs">
|
||||
<DependentUpon>FModel_ImagesMerger.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\FModel_SearchFiles.xaml.cs">
|
||||
<DependentUpon>FModel_SearchFiles.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\FModel_Settings.xaml.cs">
|
||||
<DependentUpon>FModel_Settings.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\BaseByte.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\BookMark.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Bytes\ByteConverters.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Bytes\ByteModified.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Bytes\ByteProvider.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Caret.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\CharacterTable\DTE.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\CharacterTable\Enum.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\CharacterTable\TBLStream.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\ConstantReadOnly.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Converters\BooleanToVisibilityConverter.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Converters\BoolInverterConverter.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Converters\HexToLongStringConverter.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Converters\LongToHexStringConverter.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Converters\PathToFilenameConverter.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Enumeration.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\GenericStaticInstance.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Interfaces\IByteControl.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Interfaces\IByteModified.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\KeyValidator.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\MethodExtention\ApplicationExtention.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\MethodExtention\ByteArrayExtention.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\MethodExtention\DoubleExtension.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\MethodExtention\StringExtension.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\MethodExtention\TrackExtention.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Native\NativeMethods.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Xcbb\CustomBackgroundBlock.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Xcbb\ExeFile.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Xcbb\XcbbExpressionParser.cs" />
|
||||
<Compile Include="Forms\HexViewer\Core\Xcbb\XcbbFileParser.cs" />
|
||||
<Compile Include="Forms\HexViewer\FastTextLine.cs" />
|
||||
<Compile Include="Forms\HexViewer\FindReplaceWindow.xaml.cs">
|
||||
<DependentUpon>FindReplaceWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\FindWindow.xaml.cs">
|
||||
<DependentUpon>FindWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\GiveByteWindow.xaml.cs">
|
||||
<DependentUpon>GiveByteWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\HexBox.xaml.cs">
|
||||
<DependentUpon>HexBox.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\HexByte.cs" />
|
||||
<Compile Include="Forms\HexViewer\HexEditor.xaml.cs">
|
||||
<DependentUpon>HexEditor.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\HexViewer.xaml.cs">
|
||||
<DependentUpon>HexViewer.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\ReplaceByteWindow.xaml.cs">
|
||||
<DependentUpon>ReplaceByteWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\HexViewer\StringByte.cs" />
|
||||
<Compile Include="Methods\AESManager\DynamicKeysChecker.cs" />
|
||||
<Compile Include="Methods\AESManager\KeysManager.cs" />
|
||||
<Compile Include="Methods\Assets\AssetInformations.cs" />
|
||||
<Compile Include="Methods\Assets\AssetsLoader.cs" />
|
||||
<Compile Include="Methods\Assets\AssetTranslations.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\AthenaID\CosmeticSet.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\AthenaID\IconUserFacingFlags.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeBundleInfos.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeCompletionRewards.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeIconDesign.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeRewards.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\HeroID\HeroGameplayDefinition.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\IconCreator.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\IconImage.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\IconText.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\IconWatermark.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\Rarity.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\WeaponID\IconAmmoData.cs" />
|
||||
<Compile Include="Methods\Assets\IconCreator\WeaponID\WeaponStats.cs" />
|
||||
<Compile Include="Methods\BackupsManager\RegisterDownloadedBackups.cs" />
|
||||
<Compile Include="Methods\FindReplace\FindReplace.cs" />
|
||||
<Compile Include="Methods\FindReplace\FindReplaceDialog.xaml.cs">
|
||||
<DependentUpon>FindReplaceDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Methods\FVar.cs" />
|
||||
<Compile Include="Methods\MessageBox\DarkMessageBox.cs" />
|
||||
<Compile Include="Methods\PakReader\AESDecryptor.cs" />
|
||||
<Compile Include="Methods\PakReader\AssetReader.cs" />
|
||||
<Compile Include="Methods\PakReader\AssetRegReader.cs" />
|
||||
<Compile Include="Methods\PakReader\DDSDecoder.cs" />
|
||||
<Compile Include="Methods\PakReader\Extensions.cs" />
|
||||
<Compile Include="Methods\PakReader\ImageExporter.cs" />
|
||||
<Compile Include="Methods\PakReader\LocReader.cs" />
|
||||
<Compile Include="Methods\PakReader\MeshExporter.cs" />
|
||||
<Compile Include="Methods\PakReader\Objects.cs" />
|
||||
<Compile Include="Methods\PakReader\PakIndex.cs" />
|
||||
<Compile Include="Methods\PakReader\PakReader.cs" />
|
||||
<Compile Include="Methods\PakReader\SigReader.cs" />
|
||||
<Compile Include="Methods\PakReader\UDicReader.cs" />
|
||||
<Compile Include="Methods\PAKs\BackupPAKs.cs" />
|
||||
<Compile Include="Methods\PAKs\PAKsLoader.cs" />
|
||||
<Compile Include="Methods\PAKs\RegisterFromPath.cs" />
|
||||
<Compile Include="Methods\SyntaxHighlighter\ResourceLoader.cs" />
|
||||
<Compile Include="Methods\TreeViewModel\PropertyChangedBase.cs" />
|
||||
<Compile Include="Methods\TreeViewModel\SortedTreeViewWindowViewModel.cs" />
|
||||
<Compile Include="Methods\TreeViewModel\TreeViewItemBehavior.cs" />
|
||||
<Compile Include="Methods\TreeViewModel\TreeViewModel.cs" />
|
||||
<Compile Include="Methods\Utilities\AESUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\AssetsUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\ChallengesUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\EndpointsUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\FoldersUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\FormsUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\ImagesUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\ListBoxUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\MBoxesUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\PAKsUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\TasksUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\TextsUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\TreeViewUtility.cs" />
|
||||
<Compile Include="Methods\Utilities\UIUtility.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Themes\LeftMarginMultiplierConverter.cs" />
|
||||
<Compile Include="Themes\TreeViewItemExtensions.cs" />
|
||||
<Page Include="FModel_Main.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FModel_Main.xaml.cs">
|
||||
<DependentUpon>FModel_Main.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="Forms\AESManager.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\ColorPicker\ColorPickerControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\ColorPicker\ColorPickerSwatch.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\ColorPicker\ColorPickerWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\ColorPicker\ColorPickRow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\ColorPicker\SliderRow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\FModel_About.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\FModel_CustomMB.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\FModel_ImagesMerger.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\FModel_SearchFiles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\FModel_Settings.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\BrushesDictionary.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\FindReplaceWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\FindWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\GiveByteWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\HexBox.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\HexEditor.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\HexViewer.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\MiscelanousDictionary.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\ReplaceByteWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Forms\HexViewer\ToolTipDictionary.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Methods\FindReplace\FindReplaceDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Themes\Styles.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Methods\SyntaxHighlighter\Json.xshd" />
|
||||
<EmbeddedResource Include="Methods\SyntaxHighlighter\Ini.xshd" />
|
||||
<None Include="Forms\HexViewer\Core\Xcbb\Exefile.xcbb" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Resource Include="Resources\EBCDIC-NoSpecialChar.tbl" />
|
||||
<Resource Include="Resources\EBCDIC.tbl" />
|
||||
<Resource Include="Resources\BurbankBigCondensed-Black.ttf" />
|
||||
<Resource Include="Resources\BurbankBigCondensed-Bold.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="csharp_wick.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="DLLs\csharp-wick.dll" />
|
||||
<Content Include="DLLs\ScintillaNET FindReplaceDialog.dll" />
|
||||
<Content Include="FModel.ico" />
|
||||
<None Include="Resources\Template_M_N.png" />
|
||||
<None Include="Resources\Template_M_F.png" />
|
||||
<None Include="Resources\Template_F_N.png" />
|
||||
<None Include="Resources\Template_F_F.png" />
|
||||
<None Include="Resources\Template_D_N.png" />
|
||||
<None Include="Resources\Template_D_F.png" />
|
||||
<None Include="Resources\cTemplate.png" />
|
||||
<None Include="Resources\LBolt64.png" />
|
||||
<None Include="Resources\FModel.ico" />
|
||||
<None Include="Resources\FModel_Logo.png" />
|
||||
<None Include="Resources\twitter.ico" />
|
||||
<None Include="Resources\BurbankBigCondensed-Black-vJapanese.otf" />
|
||||
<None Include="Resources\reload64.png" />
|
||||
<None Include="Resources\clipSize64.png" />
|
||||
<None Include="Resources\dmg64.png" />
|
||||
<None Include="Resources\BurbankBigCondensed-Black.ttf" />
|
||||
<None Include="Resources\BurbankBigCondensed-Bold.ttf" />
|
||||
<None Include="Resources\T-Icon-Pets-64.png" />
|
||||
<None Include="Resources\T-Icon-Quests-64.png" />
|
||||
<None Include="Resources\unknown512.png" />
|
||||
<None Include="Resources\properties_16xLG.png" />
|
||||
<None Include="Resources\StatusAnnotations_Information_16xLG_color.png" />
|
||||
<None Include="Resources\folder_Closed_16xLG.png" />
|
||||
<None Include="Resources\folder_16x.png" />
|
||||
<Resource Include="Logo.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Logo.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 et x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Methods\Assets\IconCreator\DefenderID\" />
|
||||
<Folder Include="Methods\Assets\IconCreator\SchematicID\" />
|
||||
<Folder Include="Methods\Assets\IconCreator\VariantID\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_D_F.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_D_N.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_F_F.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_F_N.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_M_F.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_M_N.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\T-Icon-Pets-64.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\T-Icon-Quests-64.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\clipSize64.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\dmg64.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\reload64.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\unknown512.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_Challenge.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\colorpicker1.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\colorpicker2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Logo-Icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\close_file_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\folder_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\info_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\open_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\save_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\settings_16x.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="AfterResolveReferences">
|
||||
<ItemGroup>
|
||||
|
|
@ -285,8 +504,11 @@
|
|||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\SkiaSharp.1.68.0\build\net45\SkiaSharp.targets" Condition="Exists('..\packages\SkiaSharp.1.68.0\build\net45\SkiaSharp.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\SkiaSharp.1.68.0\build\net45\SkiaSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SkiaSharp.1.68.0\build\net45\SkiaSharp.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
191
FModel/FModel_Main.xaml
Normal file
191
FModel/FModel_Main.xaml
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
<Window
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel"
|
||||
xmlns:commands="clr-namespace:FModel.Commands"
|
||||
xmlns:TreeViewModel="clr-namespace:FModel.Methods.TreeViewModel"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
x:Class="FModel.MainWindow"
|
||||
mc:Ignorable="d"
|
||||
Title="FModel"
|
||||
Height="744"
|
||||
MinHeight="744"
|
||||
Width="1207"
|
||||
MinWidth="1207"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="Logo.ico"
|
||||
Loaded="Window_Loaded"
|
||||
UseLayoutRounding="True">
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenSettings}" Executed="MI_Settings_Click"/>
|
||||
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenSearch}" Executed="MI_Search_Click"/>
|
||||
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenOutput}" Executed="MI_OpenOutputFolder_Click"/>
|
||||
<CommandBinding Command="{x:Static commands:FModel_Commands.MergeImages}" Executed="MI_MergeImages_Click"/>
|
||||
</Window.CommandBindings>
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Key="F1" Command="{x:Static commands:FModel_Commands.OpenSettings}"/>
|
||||
<KeyBinding Key="F2" Command="{x:Static commands:FModel_Commands.OpenSearch}"/>
|
||||
<KeyBinding Key="F3" Command="{x:Static commands:FModel_Commands.OpenOutput}"/>
|
||||
<KeyBinding Key="F4" Command="{x:Static commands:FModel_Commands.MergeImages}"/>
|
||||
</Window.InputBindings>
|
||||
<Grid>
|
||||
<Menu Height="25" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
|
||||
<MenuItem Header="Load">
|
||||
<MenuItem x:Name="MI_LoadOnePAK" Header="Load One PAK" IsEnabled="False"/>
|
||||
<MenuItem x:Name="MI_LoadAllPAKs" Header="Load All PAKs" Padding="2,4,2,2" IsEnabled="False" Click="MI_LoadAllPAKs_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="MI_DownloadBackups" Header="Download Backups"/>
|
||||
<MenuItem x:Name="MI_BackupPAKs" Header="Backup PAKs" Click="MI_BackupPAKs_Click" IsEnabled="False"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="MI_DifferenceMode" Header="Difference Mode" IsCheckable="True" Checked="MI_Change_Header" Unchecked="MI_Change_Header"/>
|
||||
<MenuItem x:Name="MI_UpdateMode" Header="Update Mode (Coming Soon)" IsCheckable="True" Checked="MI_Change_Header" Unchecked="MI_Change_Header" IsEnabled="False"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="MI_Settings" Header="Settings" InputGestureText="F1" Command="{x:Static commands:FModel_Commands.OpenSettings}">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="Resources/settings_16x.png" Width="16" Height="16"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Files">
|
||||
<MenuItem x:Name="MI_Search" Header="Search" InputGestureText="F2" Command="{x:Static commands:FModel_Commands.OpenSearch}"/>
|
||||
<MenuItem x:Name="MI_HexViewer" Header="Hex Viewer" Click="MI_HexViewer_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/Logo-Icon.ico" Width="19"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="MI_ExportRaw" Header="Export RAW Data" Click="MI_ExportRaw_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="MI_AutoExportRaw" Header="Auto Export RAW Data" IsCheckable="True"/>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="MI_SaveJson" Header="Save JSON Data" Click="MI_SaveJson_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="MI_AutoSaveJson" Header="Auto Save JSON Data" IsCheckable="True"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Open Output Folder" InputGestureText="F3" Command="{x:Static commands:FModel_Commands.OpenOutput}">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/folder_16x.png" Width="16" Height="16"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Image">
|
||||
<MenuItem x:Name="MI_Save_Image" Header="Save Image" Click="MI_Save_Image_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="Resources/save_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="MI_Auto_Save_Images" Header="Auto Save Images" IsCheckable="True"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Images Merger" InputGestureText="F4" Command="{x:Static commands:FModel_Commands.MergeImages}"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem x:Name="MI_About" Header="About FModel" Click="MI_About_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="Resources/info_16x.png" Width="16" Height="16"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<StatusBar Height="22" Margin="0" VerticalAlignment="Bottom" Background="#FF1C2026" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Row="1">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="0">
|
||||
<TextBlock x:Name="FModelVersionLabel" Text="FModel "/>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="1" HorizontalContentAlignment="Center">
|
||||
<TextBlock x:Name="PEventTextBlock" Text="Process Events"/>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="2" HorizontalContentAlignment="Right">
|
||||
<TextBlock x:Name="StateTextBlock" Text="State" Margin="0" Padding="5,0"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
<Grid Margin="0,25,0,22">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="359*"/>
|
||||
<ColumnDefinition Width="840*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="30"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Button x:Name="Button_Extract" Content="Extract" HorizontalAlignment="Right" Margin="0,0,10,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" IsEnabled="False" Click="Button_Extract_Click"/>
|
||||
<Button x:Name="Button_Stop" Content="Stop" HorizontalAlignment="Right" Margin="0,0,95,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" IsEnabled="False" Click="Button_Stop_Click"/>
|
||||
<Button x:Name="Button_OpenImage" Content="Open Image" HorizontalAlignment="Right" Margin="0,0,180,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" Click="Button_OpenImage_Click"/>
|
||||
<Button x:Name="Button_AESManager" Content="AES Manager" HorizontalAlignment="Right" Margin="0,0,300,6" Grid.Row="2" VerticalAlignment="Bottom" Width="180" Grid.Column="1" Height="19" Click="Button_AESManager_Click"/>
|
||||
<TextBox x:Name="FilterTextBox_Main" Height="19" Margin="40,0,0,6" Grid.Row="2" TextWrapping="NoWrap" VerticalAlignment="Bottom" Foreground="#FFEFEFEF" TextChanged="FilterTextBox_Main_TextChanged"/>
|
||||
<Label Content="Filter:" HorizontalAlignment="Left" Margin="2,0,0,3" Grid.Row="2" VerticalAlignment="Bottom" Height="25" Width="38" Padding="5,7,5,5"/>
|
||||
<TreeView x:Name="TreeView_Main" TreeViewItem.Selected="NodeSelected" Margin="2,1,0,0" ItemsSource="{Binding ItemsView}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type TreeViewModel:TreeViewModel}" ItemsSource="{Binding ItemsView}">
|
||||
<TextBlock Text="{Binding Value}"/>
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
<TreeView.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="RC_ExtractFolders" Header="Extract Folder and Subfolders" Click="RC_ExtractFolders_Click"/>
|
||||
</ContextMenu>
|
||||
</TreeView.ContextMenu>
|
||||
</TreeView>
|
||||
<ListBox x:Name="ListBox_Main" Margin="2,1,0,2" Grid.Row="1" SelectionMode="Extended" SelectionChanged="ListBox_Main_SelectionChanged" MouseDoubleClick="ListBox_Main_MouseDoubleClick">
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="RC_Extract" Header="Extract Asset" Click="RC_Extract_Click"/>
|
||||
<MenuItem x:Name="RC_ExportData" Header="Export RAW Data" Click="RC_ExportData_Click"/>
|
||||
<MenuItem x:Name="RC_SaveData" Header="Save JSON Data" Click="RC_SaveData_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Copy File">
|
||||
<MenuItem x:Name="RC_Copy_FPath" Header="Copy File Path" Click="RC_Copy_FPath_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FName" Header="Copy File Name" Click="RC_Copy_FName_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FPath_NoExt" Header="Copy File Path w/o Extension" Click="RC_Copy_FPath_NoExt_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FName_NoExt" Header="Copy File Name w/o Extension" Click="RC_Copy_FName_NoExt_Click"/>
|
||||
</MenuItem>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="Resources/info_16x.png" Width="16" Height="16"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</ListBox.ContextMenu>
|
||||
</ListBox>
|
||||
<RichTextBox x:Name="ConsoleBox_Main" Grid.Column="1" Margin="1,1,1,2" Grid.Row="1" Background="#FF252D36" Foreground="#FFEFEFEF" BorderBrush="#7F748198" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" IsReadOnly="True">
|
||||
<RichTextBox.Resources>
|
||||
<Style TargetType="{x:Type Paragraph}">
|
||||
<Setter Property="Margin" Value="0" />
|
||||
</Style>
|
||||
</RichTextBox.Resources>
|
||||
</RichTextBox>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="523*"/>
|
||||
<ColumnDefinition Width="317*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border BorderBrush="#7F748198" BorderThickness="1" Grid.Column="1" Margin="1,1,1,0" Background="#FF252D36">
|
||||
<Image x:Name="ImageBox_Main" UseLayoutRounding="True"/>
|
||||
</Border>
|
||||
<Border BorderBrush="#7F748198" BorderThickness="1" Margin="1,1,0,0" Background="#FF252D36">
|
||||
<avalonedit:TextEditor x:Name="AssetPropertiesBox_Main" FontFamily="Consolas" FontSize="8pt" ShowLineNumbers="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Foreground="#FFEFEFEF"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
360
FModel/FModel_Main.xaml.cs
Normal file
360
FModel/FModel_Main.xaml.cs
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
using AutoUpdaterDotNET;
|
||||
using FModel.Forms;
|
||||
using FModel.Forms.HexViewer;
|
||||
using FModel.Methods;
|
||||
using FModel.Methods.AESManager;
|
||||
using FModel.Methods.Assets;
|
||||
using FModel.Methods.BackupsManager;
|
||||
using FModel.Methods.PAKs;
|
||||
using FModel.Methods.TreeViewModel;
|
||||
using FModel.Methods.Utilities;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
|
||||
namespace FModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public SortedTreeViewWindowViewModel ViewModel { get { return DataContext as SortedTreeViewWindowViewModel; } set { DataContext = value; } }
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
FWindow.FMain = this;
|
||||
}
|
||||
|
||||
private async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FModelVersionLabel.Text += Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5);
|
||||
|
||||
AutoUpdater.CheckForUpdateEvent += UIHelper.AutoUpdaterOnCheckForUpdateEvent;
|
||||
AutoUpdater.Start("https://dl.dropbox.com/s/3kv2pukqu6tj1r0/FModel.xml?dl=0");
|
||||
|
||||
// Copy user settings from previous application version if necessary
|
||||
/*if (FProp.Default.FUpdateSettings)
|
||||
{
|
||||
FProp.Default.Upgrade();
|
||||
FProp.Default.FUpdateSettings = false;
|
||||
FProp.Default.Save();
|
||||
}*/
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
FoldersUtility.LoadFolders();
|
||||
FoldersUtility.CheckWatermark();
|
||||
RegisterFromPath.FilterPAKs();
|
||||
DynamicKeysChecker.SetDynamicKeys();
|
||||
RegisterDownloadedBackups.LoadBackupFiles();
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
});
|
||||
|
||||
AvalonEdit.SetAEConfig();
|
||||
}
|
||||
|
||||
#region BUTTON EVENTS
|
||||
private void Button_AESManager_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("AES Manager"))
|
||||
{
|
||||
new AESManager().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("AES Manager").Focus(); }
|
||||
}
|
||||
private void Button_OpenImage_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImageBox_Main.Source != null)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>(FWindow.FCurrentAsset))
|
||||
{
|
||||
Window win = new Window();
|
||||
win.Title = FWindow.FCurrentAsset;
|
||||
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
win.Width = ImageBox_Main.Source.Width;
|
||||
win.Height = ImageBox_Main.Source.Height;
|
||||
if (ImageBox_Main.Source.Height > 1000)
|
||||
{
|
||||
win.WindowState = WindowState.Maximized;
|
||||
}
|
||||
|
||||
DockPanel dockPanel = new DockPanel
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
Image img = new Image();
|
||||
img.UseLayoutRounding = true;
|
||||
img.Source = ImageBox_Main.Source;
|
||||
dockPanel.Children.Add(img);
|
||||
|
||||
win.Content = dockPanel;
|
||||
win.Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>(FWindow.FCurrentAsset).Focus(); }
|
||||
}
|
||||
}
|
||||
private void Button_Stop_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TasksUtility.CancellableTaskTokenSource != null)
|
||||
{
|
||||
TasksUtility.CancellableTaskTokenSource.Cancel();
|
||||
if (TasksUtility.CancellableTaskTokenSource.IsCancellationRequested)
|
||||
{
|
||||
new UpdateMyProcessEvents("Canceled!", "Yikes").Update();
|
||||
}
|
||||
else { new UpdateMyProcessEvents("This is odd!\tCanceled but not requested. You should never see this tbh", "Yikes").Update(); }
|
||||
}
|
||||
}
|
||||
private async void Button_Extract_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
//FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString(); <-- already in the 'Load' loop
|
||||
await AssetsLoader.LoadSelectedAsset();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MENU ITEM EVENTS
|
||||
public async void MI_Pak_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FWindow.FCurrentPAK = (sender as MenuItem).Header.ToString();
|
||||
await PAKsLoader.LoadOnePAK();
|
||||
}
|
||||
private async void MI_LoadAllPAKs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FWindow.FCurrentPAK = string.Empty;
|
||||
|
||||
//LOAD ALL
|
||||
if (!MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
|
||||
{
|
||||
await PAKsLoader.LoadAllPAKs();
|
||||
}
|
||||
|
||||
//LOAD DIFF
|
||||
if (MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
|
||||
{
|
||||
await PAKsLoader.LoadDifference();
|
||||
}
|
||||
|
||||
//LOAD AND EXTRACT DIFF
|
||||
if (MI_DifferenceMode.IsChecked && MI_UpdateMode.IsChecked)
|
||||
{
|
||||
//not done yet
|
||||
}
|
||||
}
|
||||
private async void MI_BackupPAKs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await BackupPAKs.CreateBackupFile();
|
||||
}
|
||||
private void MI_Settings_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Settings"))
|
||||
{
|
||||
new FModel_Settings().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Settings").Focus(); }
|
||||
}
|
||||
private void MI_Search_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Search"))
|
||||
{
|
||||
new FModel_SearchFiles().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Search").Focus(); }
|
||||
}
|
||||
private void MI_HexViewer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Hex Viewer"))
|
||||
{
|
||||
new HexViewer().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Hex Viewer").Focus(); }
|
||||
}
|
||||
private void MI_ExportRaw_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
AssetsUtility.ExportAssetData();
|
||||
}
|
||||
}
|
||||
private void MI_SaveJson_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AssetsUtility.SaveAssetProperties();
|
||||
}
|
||||
private void MI_OpenOutputFolder_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FoldersUtility.OpenOutputFolder();
|
||||
}
|
||||
private void MI_Save_Image_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImageBox_Main.Source != null)
|
||||
{
|
||||
ImagesUtility.SaveImageDialog();
|
||||
}
|
||||
}
|
||||
private void MI_MergeImages_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Images Merger"))
|
||||
{
|
||||
new FModel_ImagesMerger().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Images Merger").Focus(); }
|
||||
}
|
||||
private void MI_About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("About"))
|
||||
{
|
||||
new FModel_About().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("About").Focus(); }
|
||||
}
|
||||
private void MI_Change_Header(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//DIFFERENCE MODE
|
||||
if (MI_DifferenceMode.IsChecked)
|
||||
{
|
||||
MI_LoadOnePAK.IsEnabled = false;
|
||||
MI_LoadAllPAKs.Header = "Load Difference";
|
||||
MI_UpdateMode.IsEnabled = true;
|
||||
}
|
||||
if (!MI_DifferenceMode.IsChecked)
|
||||
{
|
||||
MI_LoadOnePAK.IsEnabled = true;
|
||||
MI_UpdateMode.IsEnabled = false;
|
||||
MI_UpdateMode.IsChecked = false;
|
||||
}
|
||||
|
||||
//UPDATE MODE
|
||||
if (MI_UpdateMode.IsChecked)
|
||||
{
|
||||
MI_LoadAllPAKs.Header = "Load And Extract Difference";
|
||||
MI_UpdateMode.IsEnabled = true;
|
||||
}
|
||||
if (!MI_UpdateMode.IsChecked)
|
||||
{
|
||||
MI_LoadAllPAKs.Header = "Load Difference";
|
||||
}
|
||||
|
||||
//BOTH
|
||||
if (!MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
|
||||
{
|
||||
MI_LoadAllPAKs.Header = "Load All PAKs";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TREEVIEW EVENTS
|
||||
private async void NodeSelected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
TreeViewItem currContainer = e.OriginalSource as TreeViewItem;
|
||||
if (currContainer != null)
|
||||
{
|
||||
FWindow.TVItem = currContainer;
|
||||
await ListBoxUtility.PopulateListBox(currContainer);
|
||||
}
|
||||
|
||||
}
|
||||
private async void RC_ExtractFolders_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TreeView_Main.SelectedItem != null)
|
||||
{
|
||||
string path = TreeViewUtility.GetFullPath(FWindow.TVItem);
|
||||
await AssetsLoader.ExtractFoldersAndSub(path);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LISTBOX EVENTS
|
||||
private void ListBox_Main_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0) { ((ListBox)sender).ScrollIntoView(e.AddedItems[0]); }
|
||||
if (!AssetsLoader.isRunning) { Button_Extract.IsEnabled = ListBox_Main.SelectedIndex >= 0; }
|
||||
}
|
||||
private async void ListBox_Main_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (!AssetsLoader.isRunning && ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
//FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString(); <-- already in the 'Load' loop
|
||||
await AssetsLoader.LoadSelectedAsset();
|
||||
}
|
||||
}
|
||||
private async void FilterTextBox_Main_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
await ListBoxUtility.FilterListBox();
|
||||
}
|
||||
private async void RC_Extract_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
//FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString(); <-- already in the 'Load' loop
|
||||
await AssetsLoader.LoadSelectedAsset();
|
||||
}
|
||||
}
|
||||
private void RC_ExportData_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
AssetsUtility.ExportAssetData();
|
||||
}
|
||||
}
|
||||
private void RC_SaveData_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AssetsUtility.SaveAssetProperties();
|
||||
}
|
||||
private void RC_Copy_FPath_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy());
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FName_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(true));
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FPath_NoExt_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(false, false));
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FName_NoExt_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(true, false));
|
||||
}
|
||||
}
|
||||
private void RC_Properties_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ListBox_Main.SelectedIndex >= 0)
|
||||
{
|
||||
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
|
||||
AssetInformations.OpenAssetInfos();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
155
FModel/Forms/AESManager.Designer.cs
generated
155
FModel/Forms/AESManager.Designer.cs
generated
|
|
@ -1,155 +0,0 @@
|
|||
namespace FModel.Forms
|
||||
{
|
||||
partial class AESManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AESManager));
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.textBox2 = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.OKButton = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.groupBox3.Controls.Add(this.textBox2);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(565, 49);
|
||||
this.groupBox3.TabIndex = 14;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Static Key:";
|
||||
//
|
||||
// textBox2
|
||||
//
|
||||
this.textBox2.Location = new System.Drawing.Point(74, 19);
|
||||
this.textBox2.Name = "textBox2";
|
||||
this.textBox2.Size = new System.Drawing.Size(485, 20);
|
||||
this.textBox2.TabIndex = 2;
|
||||
this.textBox2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(6, 22);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(62, 13);
|
||||
this.label3.TabIndex = 3;
|
||||
this.label3.Text = "Main PAKs:";
|
||||
//
|
||||
// OKButton
|
||||
//
|
||||
this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OKButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.OKButton.Location = new System.Drawing.Point(480, 292);
|
||||
this.OKButton.Name = "OKButton";
|
||||
this.OKButton.Size = new System.Drawing.Size(97, 21);
|
||||
this.OKButton.TabIndex = 16;
|
||||
this.OKButton.Text = "OK";
|
||||
this.OKButton.UseVisualStyleBackColor = true;
|
||||
this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.groupBox1.Controls.Add(this.panel1);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 67);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(565, 219);
|
||||
this.groupBox1.TabIndex = 17;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Dynamic Keys:";
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.AutoScroll = true;
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel1.Location = new System.Drawing.Point(3, 16);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(559, 200);
|
||||
this.panel1.TabIndex = 0;
|
||||
//
|
||||
// linkLabel1
|
||||
//
|
||||
this.linkLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.linkLabel1.AutoSize = true;
|
||||
this.linkLabel1.Location = new System.Drawing.Point(12, 296);
|
||||
this.linkLabel1.Name = "linkLabel1";
|
||||
this.linkLabel1.Size = new System.Drawing.Size(124, 13);
|
||||
this.linkLabel1.TabIndex = 18;
|
||||
this.linkLabel1.TabStop = true;
|
||||
this.linkLabel1.Text = "Latest Fortnite AES Keys";
|
||||
this.linkLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabel1_LinkClicked);
|
||||
//
|
||||
// AESManager
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(589, 325);
|
||||
this.Controls.Add(this.linkLabel1);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.OKButton);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(605, 364);
|
||||
this.Name = "AESManager";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "AES Manager";
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox3.PerformLayout();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.TextBox textBox2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Button OKButton;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
public partial class AESManager : Form
|
||||
{
|
||||
public static bool isClosed { get; set; }
|
||||
|
||||
public AESManager()
|
||||
{
|
||||
InitializeComponent();
|
||||
isClosed = false;
|
||||
|
||||
textBox2.Text = @"0x" + Properties.Settings.Default.AESKey;
|
||||
|
||||
for (int i = 0; i < ThePak.dynamicPaksList.Count; i++)
|
||||
{
|
||||
string dCurrentUsedPak = ThePak.dynamicPaksList[i].thePak; //SET CURRENT DYNAMIC PAK
|
||||
int pFrom = dCurrentUsedPak.IndexOf("pakchunk") + "pakchunk".Length;
|
||||
int pTo = dCurrentUsedPak.LastIndexOf("WindowsClient.pak");
|
||||
|
||||
TextBox txtBox = new TextBox();
|
||||
txtBox.Location = new Point(164, 3 + (26 * i));
|
||||
txtBox.Size = new Size(372, 20);
|
||||
txtBox.Name = "txtBox_" + dCurrentUsedPak.Substring(pFrom, pTo - pFrom - 1);
|
||||
txtBox.Parent = panel1;
|
||||
|
||||
Label lbl = new Label();
|
||||
lbl.AutoSize = true;
|
||||
lbl.Location = new Point(3, 6 + (26 * i));
|
||||
lbl.Size = new Size(155, 13);
|
||||
lbl.Text = dCurrentUsedPak.Substring(0, dCurrentUsedPak.LastIndexOf("."));
|
||||
lbl.Parent = panel1;
|
||||
|
||||
if (DynamicKeysManager.AESEntries != null)
|
||||
{
|
||||
foreach (AESEntry s in DynamicKeysManager.AESEntries)
|
||||
{
|
||||
if (s.thePak == dCurrentUsedPak) { txtBox.Text = @"0x" + s.theKey; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OKButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(textBox2.Text) && textBox2.Text.StartsWith("0x"))
|
||||
{
|
||||
if (textBox2.Text.Contains(" ")) { textBox2.Text = textBox2.Text.Replace(" ", string.Empty); }
|
||||
Properties.Settings.Default.AESKey = textBox2.Text.Substring(2).ToUpper();
|
||||
}
|
||||
else { Properties.Settings.Default.AESKey = ""; }
|
||||
|
||||
DynamicKeysManager.AESEntries = new List<AESEntry>();
|
||||
for (int i = 0; i < ThePak.dynamicPaksList.Count; i++)
|
||||
{
|
||||
string dCurrentUsedPak = ThePak.dynamicPaksList[i].thePak; //SET CURRENT DYNAMIC PAK
|
||||
int pFrom = dCurrentUsedPak.IndexOf("pakchunk") + "pakchunk".Length;
|
||||
int pTo = dCurrentUsedPak.LastIndexOf("WindowsClient.pak");
|
||||
|
||||
Control[] controls = this.Controls.Find("txtBox_" + dCurrentUsedPak.Substring(pFrom, pTo - pFrom - 1), true);
|
||||
if (controls.Length > 0)
|
||||
{
|
||||
TextBox txtBox = controls[0] as TextBox;
|
||||
if (txtBox != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(txtBox.Text))
|
||||
{
|
||||
DynamicKeysManager.serialize(txtBox.Text.Substring(2).ToUpper(), dCurrentUsedPak);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
isClosed = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("http://benbotfn.tk:8080/api/aes");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
40
FModel/Forms/AESManager.xaml
Normal file
40
FModel/Forms/AESManager.xaml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<Window x:Class="FModel.Forms.AESManager"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Title="AES Manager"
|
||||
Height="370"
|
||||
MinHeight="370"
|
||||
Width="600"
|
||||
MinWidth="600"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="/FModel;component/Logo.ico" Loaded="Window_Loaded"
|
||||
>
|
||||
<Grid>
|
||||
<GroupBox Header="Static Key" Height="48" Margin="10,10,10,0" VerticalAlignment="Top" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Label Content="Main PAKs:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,0"/>
|
||||
<TextBox x:Name="MAesTextBox" Height="18" Margin="65,4,5,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Dynamic Keys" Height="232" Margin="10,63,10,0" VerticalAlignment="Top" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<ScrollViewer Background="{x:Null}">
|
||||
<Grid x:Name="Grid_DynamicKeys"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
|
||||
<Label HorizontalAlignment="Left" Margin="10,0,0,11" VerticalAlignment="Bottom" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand">
|
||||
<TextBlock>
|
||||
<Hyperlink NavigateUri="http://benbotfn.tk:8080/api/aes" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF">Latest Fortnite AES Keys</Hyperlink>
|
||||
</TextBlock>
|
||||
</Label>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
132
FModel/Forms/AESManager.xaml.cs
Normal file
132
FModel/Forms/AESManager.xaml.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
using FModel.Methods;
|
||||
using FModel.Methods.AESManager;
|
||||
using FModel.Methods.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Navigation;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour AESManager.xaml
|
||||
/// </summary>
|
||||
public partial class AESManager : Window
|
||||
{
|
||||
private static readonly string AESManager_PATH = FProp.Default.FOutput_Path + "\\FAESManager.xml";
|
||||
|
||||
public AESManager()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AddLblTxtForDynamicPAKs();
|
||||
GetUserSettings();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SetUserSettings();
|
||||
PAKsUtility.DisableNonKeyedPAKs();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
|
||||
}
|
||||
|
||||
private void AddLblTxtForDynamicPAKs()
|
||||
{
|
||||
if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any())
|
||||
{
|
||||
if (AESEntries.AESEntriesList == null) { KeysManager.Deserialize(); }
|
||||
int yPos = 4;
|
||||
|
||||
foreach (PAKInfosEntry Pak in PAKEntries.PAKEntriesList.Where(x => x.bTheDynamicPAK == true))
|
||||
{
|
||||
Label PakLabel = new Label();
|
||||
PakLabel.Content = Path.GetFileNameWithoutExtension(Pak.ThePAKPath);
|
||||
PakLabel.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
PakLabel.Margin = new Thickness(2, yPos - 2, 0, 0);
|
||||
PakLabel.VerticalAlignment = VerticalAlignment.Top;
|
||||
PakLabel.Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239));
|
||||
|
||||
TextBox PakTextBox = new TextBox();
|
||||
PakTextBox.Height = 19;
|
||||
PakTextBox.TextWrapping = TextWrapping.NoWrap;
|
||||
PakTextBox.AcceptsReturn = false;
|
||||
PakTextBox.Margin = new Thickness(160, yPos, 5, 0);
|
||||
PakTextBox.VerticalAlignment = VerticalAlignment.Top;
|
||||
PakTextBox.Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239));
|
||||
PakTextBox.Name = $"TxtBox_{Regex.Match(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), @"\d+").Value}";
|
||||
|
||||
if (AESEntries.AESEntriesList != null && AESEntries.AESEntriesList.Any())
|
||||
{
|
||||
string PAKKeyFromXML = AESEntries.AESEntriesList.Where(x => string.Equals(x.ThePAKName, Path.GetFileNameWithoutExtension(Pak.ThePAKPath))).Select(x => x.ThePAKKey).FirstOrDefault();
|
||||
PakTextBox.Text = $"0x{PAKKeyFromXML}";
|
||||
}
|
||||
|
||||
yPos += 28;
|
||||
Grid_DynamicKeys.Children.Add(PakLabel);
|
||||
Grid_DynamicKeys.Children.Add(PakTextBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUserSettings()
|
||||
{
|
||||
MAesTextBox.Text = $"0x{FProp.Default.FPak_MainAES}";
|
||||
}
|
||||
|
||||
private void SetUserSettings()
|
||||
{
|
||||
//MAIN AES
|
||||
if (!string.IsNullOrEmpty(MAesTextBox.Text))
|
||||
{
|
||||
if (MAesTextBox.Text.StartsWith("0x"))
|
||||
{
|
||||
FProp.Default.FPak_MainAES = Regex.Replace(MAesTextBox.Text.Substring(2).ToUpper(), @"\s+", string.Empty);
|
||||
}
|
||||
else { FProp.Default.FPak_MainAES = Regex.Replace(MAesTextBox.Text.ToUpper(), @"\s+", string.Empty); }
|
||||
}
|
||||
else { FProp.Default.FPak_MainAES = string.Empty; }
|
||||
|
||||
//DYNAMIC AESs
|
||||
AESEntries.AESEntriesList = new List<AESInfosEntry>();
|
||||
if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any())
|
||||
{
|
||||
foreach (PAKInfosEntry Pak in PAKEntries.PAKEntriesList.Where(x => x.bTheDynamicPAK == true))
|
||||
{
|
||||
TextBox PakTextBox = UIHelper.FindChild<TextBox>(this, $"TxtBox_{Regex.Match(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), @"\d+").Value}");
|
||||
if (!string.IsNullOrEmpty(PakTextBox.Text))
|
||||
{
|
||||
if (PakTextBox.Text.StartsWith("0x"))
|
||||
{
|
||||
KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), Regex.Replace(PakTextBox.Text.Substring(2).ToUpper(), @"\s+", string.Empty));
|
||||
}
|
||||
else { KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), Regex.Replace(PakTextBox.Text.ToUpper(), @"\s+", string.Empty)); }
|
||||
}
|
||||
else { KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), string.Empty); }
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(AESManager_PATH));
|
||||
using (var fileStream = new FileStream(AESManager_PATH, FileMode.Create))
|
||||
{
|
||||
KeysManager.serializer.Serialize(fileStream, AESEntries.AESEntriesList);
|
||||
}
|
||||
}
|
||||
|
||||
//SAVE
|
||||
FProp.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
167
FModel/Forms/About.Designer.cs
generated
167
FModel/Forms/About.Designer.cs
generated
|
|
@ -1,167 +0,0 @@
|
|||
namespace FModel.Forms
|
||||
{
|
||||
partial class About
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(About));
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
|
||||
this.linkLabel2 = new System.Windows.Forms.LinkLabel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.linkLabel3 = new System.Windows.Forms.LinkLabel();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pictureBox1
|
||||
//
|
||||
this.pictureBox1.Image = global::FModel.Properties.Resources.FModel_Logo;
|
||||
this.pictureBox1.Location = new System.Drawing.Point(12, 12);
|
||||
this.pictureBox1.Name = "pictureBox1";
|
||||
this.pictureBox1.Size = new System.Drawing.Size(90, 90);
|
||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBox1.TabIndex = 0;
|
||||
this.pictureBox1.TabStop = false;
|
||||
//
|
||||
// linkLabel1
|
||||
//
|
||||
this.linkLabel1.AutoSize = true;
|
||||
this.linkLabel1.Location = new System.Drawing.Point(138, 98);
|
||||
this.linkLabel1.Name = "linkLabel1";
|
||||
this.linkLabel1.Size = new System.Drawing.Size(69, 13);
|
||||
this.linkLabel1.TabIndex = 1;
|
||||
this.linkLabel1.TabStop = true;
|
||||
this.linkLabel1.Text = "GitHub Repo";
|
||||
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
|
||||
//
|
||||
// linkLabel2
|
||||
//
|
||||
this.linkLabel2.AutoSize = true;
|
||||
this.linkLabel2.Location = new System.Drawing.Point(381, 98);
|
||||
this.linkLabel2.Name = "linkLabel2";
|
||||
this.linkLabel2.Size = new System.Drawing.Size(43, 13);
|
||||
this.linkLabel2.TabIndex = 2;
|
||||
this.linkLabel2.TabStop = true;
|
||||
this.linkLabel2.Text = "Discord";
|
||||
this.linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel2_LinkClicked);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(108, 47);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(360, 40);
|
||||
this.label1.TabIndex = 3;
|
||||
this.label1.Text = "FModel is a Fortnite .PAK file explorer built in C#\r\nIf you find this project use" +
|
||||
"ful, feel free to give it a star on GitHub\r\n⊂(◕‿◕)つ";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label2.Location = new System.Drawing.Point(108, 8);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(360, 39);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "FModel";
|
||||
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label3.Location = new System.Drawing.Point(12, 123);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(42, 13);
|
||||
this.label3.TabIndex = 6;
|
||||
this.label3.Text = "Credits:";
|
||||
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label4.Location = new System.Drawing.Point(53, 124);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(241, 13);
|
||||
this.label4.TabIndex = 11;
|
||||
this.label4.Text = "• Waddlesworth • Maiky M • AyeTSG • FireMonkey";
|
||||
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// linkLabel3
|
||||
//
|
||||
this.linkLabel3.AutoSize = true;
|
||||
this.linkLabel3.Location = new System.Drawing.Point(260, 98);
|
||||
this.linkLabel3.Name = "linkLabel3";
|
||||
this.linkLabel3.Size = new System.Drawing.Size(67, 13);
|
||||
this.linkLabel3.TabIndex = 12;
|
||||
this.linkLabel3.TabStop = true;
|
||||
this.linkLabel3.Text = "How To Use";
|
||||
this.linkLabel3.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel3_LinkClicked);
|
||||
//
|
||||
// About
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(467, 145);
|
||||
this.Controls.Add(this.linkLabel3);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.linkLabel2);
|
||||
this.Controls.Add(this.linkLabel1);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.pictureBox1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "About";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "About FModel";
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.PictureBox pictureBox1;
|
||||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
private System.Windows.Forms.LinkLabel linkLabel2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.LinkLabel linkLabel3;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
public partial class About : Form
|
||||
{
|
||||
public About()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
label2.Text += @" " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5);
|
||||
}
|
||||
|
||||
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel");
|
||||
}
|
||||
|
||||
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://discordapp.com/invite/JmWvXKb");
|
||||
}
|
||||
|
||||
private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel/blob/master/README.md#how-to-use");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
108
FModel/Forms/ColorPicker/Code/ColorPalette.cs
Normal file
108
FModel/Forms/ColorPicker/Code/ColorPalette.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ColorPickerWPF.Code
|
||||
{
|
||||
[Serializable]
|
||||
public class ColorPalette
|
||||
{
|
||||
public List<ColorSwatchItem> BuiltInColors { get; set; }
|
||||
|
||||
public List<ColorSwatchItem> CustomColors { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
protected const int NumColorsFirstSwatch = 39;
|
||||
[XmlIgnore]
|
||||
protected const int NumColorsCustomSwatch = 44;
|
||||
[XmlIgnore]
|
||||
protected const int NumColorsSecondSwatch = 112;
|
||||
|
||||
public ColorPalette()
|
||||
{
|
||||
BuiltInColors = new List<ColorSwatchItem>();
|
||||
CustomColors = new List<ColorSwatchItem>();
|
||||
}
|
||||
|
||||
public void InitializeDefaults()
|
||||
{
|
||||
BuiltInColors.Clear();
|
||||
BuiltInColors.AddRange(
|
||||
GetColorSwatchItems(
|
||||
new List<Color>()
|
||||
{
|
||||
Colors.Black,
|
||||
Colors.Red,
|
||||
Colors.DarkOrange,
|
||||
Colors.Yellow,
|
||||
Colors.LawnGreen,
|
||||
Colors.Blue,
|
||||
Colors.Purple,
|
||||
Colors.DeepPink,
|
||||
Colors.Aqua,
|
||||
Colors.SaddleBrown,
|
||||
Colors.Wheat,
|
||||
Colors.BurlyWood,
|
||||
Colors.Teal,
|
||||
|
||||
Colors.White,
|
||||
Colors.OrangeRed,
|
||||
Colors.Orange,
|
||||
Colors.Gold,
|
||||
Colors.LimeGreen,
|
||||
Colors.DodgerBlue,
|
||||
Colors.Orchid,
|
||||
Colors.HotPink,
|
||||
Colors.Turquoise,
|
||||
Colors.SandyBrown,
|
||||
Colors.SeaGreen,
|
||||
Colors.SlateBlue,
|
||||
Colors.RoyalBlue,
|
||||
|
||||
Colors.Tan,
|
||||
Colors.Peru,
|
||||
Colors.DarkBlue,
|
||||
Colors.DarkGreen,
|
||||
Colors.DarkSlateBlue,
|
||||
Colors.Navy,
|
||||
Colors.MistyRose,
|
||||
Colors.LemonChiffon,
|
||||
Colors.ForestGreen,
|
||||
Colors.Firebrick,
|
||||
Colors.DarkViolet,
|
||||
Colors.Aquamarine,
|
||||
Colors.CornflowerBlue,
|
||||
Colors.Bisque,
|
||||
Colors.WhiteSmoke,
|
||||
Colors.AliceBlue,
|
||||
|
||||
|
||||
Color.FromArgb(255, 5, 5, 5),
|
||||
Color.FromArgb(255, 15, 15, 15),Color.FromArgb(255, 35, 35, 35),
|
||||
Color.FromArgb(255, 55, 55, 55),
|
||||
Color.FromArgb(255, 75, 75, 75),
|
||||
Color.FromArgb(255, 95, 95, 95),
|
||||
Color.FromArgb(255, 115, 115, 115),
|
||||
Color.FromArgb(255, 135, 135, 135),
|
||||
Color.FromArgb(255, 155, 155, 155),
|
||||
Color.FromArgb(255, 175, 175, 175),
|
||||
Color.FromArgb(255, 195, 195, 195),
|
||||
Color.FromArgb(255, 215, 215, 215),
|
||||
Color.FromArgb(255, 235, 235, 235),
|
||||
}));
|
||||
|
||||
CustomColors.Clear();
|
||||
CustomColors.AddRange(Enumerable.Repeat(Colors.White, NumColorsCustomSwatch)
|
||||
.Select(x => new ColorSwatchItem() { Color = x, HexString = x.ToHexString() })
|
||||
.ToList());
|
||||
}
|
||||
|
||||
|
||||
protected List<ColorSwatchItem> GetColorSwatchItems(List<Color> colors)
|
||||
{
|
||||
return colors.Select(x => new ColorSwatchItem() { Color = x, HexString = x.ToHexString() }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
FModel/Forms/ColorPicker/Code/ColorPickerDialogOptions.cs
Normal file
16
FModel/Forms/ColorPicker/Code/ColorPickerDialogOptions.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorPickerWPF.Code
|
||||
{
|
||||
[Flags]
|
||||
public enum ColorPickerDialogOptions
|
||||
{
|
||||
None,
|
||||
SimpleView,
|
||||
LoadCustomPalette
|
||||
}
|
||||
}
|
||||
15
FModel/Forms/ColorPicker/Code/ColorSwatchItem.cs
Normal file
15
FModel/Forms/ColorPicker/Code/ColorSwatchItem.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace ColorPickerWPF.Code
|
||||
{
|
||||
public class ColorSwatchItem
|
||||
{
|
||||
public Color Color { get; set; }
|
||||
public string HexString { get; set; }
|
||||
}
|
||||
}
|
||||
256
FModel/Forms/ColorPicker/Code/Util.cs
Normal file
256
FModel/Forms/ColorPicker/Code/Util.cs
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Color = System.Windows.Media.Color;
|
||||
|
||||
namespace ColorPickerWPF.Code
|
||||
{
|
||||
internal static class Util
|
||||
{
|
||||
[DllImport("shlwapi.dll")]
|
||||
public static extern int ColorHLSToRGB(int H, int L, int S);
|
||||
|
||||
public static Color ColorFromHSL(int H, int S, int L)
|
||||
{
|
||||
int colorInt = ColorHLSToRGB(H, L, S);
|
||||
byte[] bytes = BitConverter.GetBytes(colorInt);
|
||||
return Color.FromArgb(255, bytes[0], bytes[1], bytes[2]);
|
||||
}
|
||||
|
||||
|
||||
public static string ToHexString(this Color c)
|
||||
{
|
||||
return "#" + c.A.ToString("X2") + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
|
||||
}
|
||||
|
||||
public static Color ColorFromHexString(string hex)
|
||||
{
|
||||
return Color.FromRgb(
|
||||
Convert.ToByte(hex.Substring(1, 2), 16),
|
||||
Convert.ToByte(hex.Substring(3, 2), 16),
|
||||
Convert.ToByte(hex.Substring(5, 2), 16));
|
||||
}
|
||||
|
||||
public static bool IsDialogFlagSet(this ColorPickerDialogOptions flags, ColorPickerDialogOptions flag)
|
||||
{
|
||||
if ((flags & flag) == flag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static BitmapImage GetBitmapImage(BitmapSource bitmapSource)
|
||||
{
|
||||
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
BitmapImage bImg = new BitmapImage();
|
||||
|
||||
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
|
||||
encoder.Save(memoryStream);
|
||||
|
||||
memoryStream.Position = 0;
|
||||
bImg.BeginInit();
|
||||
bImg.StreamSource = memoryStream;
|
||||
bImg.EndInit();
|
||||
|
||||
memoryStream.Close();
|
||||
|
||||
return bImg;
|
||||
}
|
||||
|
||||
public static float GetHue(this System.Windows.Media.Color c)
|
||||
{
|
||||
var color = System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B);
|
||||
return color.GetHue();
|
||||
}
|
||||
|
||||
public static float GetBrightness(this System.Windows.Media.Color c)
|
||||
{
|
||||
var color = System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B);
|
||||
return color.GetBrightness();
|
||||
}
|
||||
|
||||
public static float GetSaturation(this System.Windows.Media.Color c)
|
||||
{
|
||||
var color = System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B);
|
||||
return color.GetSaturation();
|
||||
}
|
||||
|
||||
public static Color FromAhsb(int alpha, float hue, float saturation, float brightness)
|
||||
{
|
||||
|
||||
if (0 > alpha || 255 < alpha)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("alpha", alpha,
|
||||
"Value must be within a range of 0 - 255.");
|
||||
}
|
||||
if (0f > hue || 360f < hue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("hue", hue,
|
||||
"Value must be within a range of 0 - 360.");
|
||||
}
|
||||
if (0f > saturation || 1f < saturation)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("saturation", saturation,
|
||||
"Value must be within a range of 0 - 1.");
|
||||
}
|
||||
if (0f > brightness || 1f < brightness)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("brightness", brightness,
|
||||
"Value must be within a range of 0 - 1.");
|
||||
}
|
||||
|
||||
if (0 == saturation)
|
||||
{
|
||||
return Color.FromArgb((byte)alpha, Convert.ToByte(brightness * 255),
|
||||
Convert.ToByte(brightness * 255), Convert.ToByte(brightness * 255));
|
||||
}
|
||||
|
||||
float fMax, fMid, fMin;
|
||||
int iSextant;
|
||||
byte iMax, iMid, iMin;
|
||||
|
||||
if (0.5 < brightness)
|
||||
{
|
||||
fMax = brightness - (brightness * saturation) + saturation;
|
||||
fMin = brightness + (brightness * saturation) - saturation;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMax = brightness + (brightness * saturation);
|
||||
fMin = brightness - (brightness * saturation);
|
||||
}
|
||||
|
||||
iSextant = (int)Math.Floor(hue / 60f);
|
||||
if (300f <= hue)
|
||||
{
|
||||
hue -= 360f;
|
||||
}
|
||||
hue /= 60f;
|
||||
hue -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f) / 2f);
|
||||
if (0 == iSextant % 2)
|
||||
{
|
||||
fMid = hue * (fMax - fMin) + fMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMid = fMin - hue * (fMax - fMin);
|
||||
}
|
||||
|
||||
iMax = Convert.ToByte(fMax * 255);
|
||||
iMid = Convert.ToByte(fMid * 255);
|
||||
iMin = Convert.ToByte(fMin * 255);
|
||||
|
||||
switch (iSextant)
|
||||
{
|
||||
case 1:
|
||||
return Color.FromArgb((byte)alpha, iMid, iMax, iMin);
|
||||
case 2:
|
||||
return Color.FromArgb((byte)alpha, iMin, iMax, iMid);
|
||||
case 3:
|
||||
return Color.FromArgb((byte)alpha, iMin, iMid, iMax);
|
||||
case 4:
|
||||
return Color.FromArgb((byte)alpha, iMid, iMin, iMax);
|
||||
case 5:
|
||||
return Color.FromArgb((byte)alpha, iMax, iMin, iMid);
|
||||
default:
|
||||
return Color.FromArgb((byte)alpha, iMax, iMid, iMin);
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/5091455/web-color-list-in-c-sharp-application
|
||||
public static List<Color> GetWebColors()
|
||||
{
|
||||
Type colors = typeof(System.Drawing.Color);
|
||||
PropertyInfo[] colorInfo = colors.GetProperties(BindingFlags.Public |
|
||||
BindingFlags.Static);
|
||||
List<Color> list = new List<Color>();
|
||||
foreach (PropertyInfo info in colorInfo)
|
||||
{
|
||||
var c = System.Drawing.Color.FromName(info.Name);
|
||||
list.Add(Color.FromArgb(c.A, c.R, c.G, c.B));
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static void SaveToXml<T>(this T obj, string filename)
|
||||
{
|
||||
var xml = obj.GetXmlText();
|
||||
|
||||
File.WriteAllText(filename, xml);
|
||||
}
|
||||
|
||||
public static string GetXmlText<T>(this T obj)
|
||||
{
|
||||
var xmlSerializer = new XmlSerializer(typeof(T));
|
||||
|
||||
var sww = new StringWriter();
|
||||
|
||||
var settings = new XmlWriterSettings()
|
||||
{
|
||||
Indent = true,
|
||||
IndentChars = " ",
|
||||
NewLineOnAttributes = false,
|
||||
//OmitXmlDeclaration = true
|
||||
};
|
||||
var writer = XmlWriter.Create(sww, settings);
|
||||
|
||||
xmlSerializer.Serialize(writer, obj);
|
||||
var xml = sww.ToString();
|
||||
|
||||
writer.Close();
|
||||
writer.Dispose();
|
||||
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
public static T LoadFromXml<T>(this T obj, string filename)
|
||||
{
|
||||
T result = default(T);
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
var sr = new StreamReader(filename);
|
||||
var xr = new XmlTextReader(sr);
|
||||
|
||||
var xmlSerializer = new XmlSerializer(typeof(T));
|
||||
|
||||
result = (T)xmlSerializer.Deserialize(xr);
|
||||
|
||||
xr.Close();
|
||||
sr.Close();
|
||||
xr.Dispose();
|
||||
sr.Dispose();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T LoadFromXmlText<T>(this T obj, string xml)
|
||||
{
|
||||
T result = default(T);
|
||||
if (!String.IsNullOrEmpty(xml))
|
||||
{
|
||||
var xr = XmlReader.Create(new StringReader(xml));
|
||||
|
||||
var xmlSerializer = new XmlSerializer(typeof(T));
|
||||
|
||||
result = (T)xmlSerializer.Deserialize(xr);
|
||||
|
||||
xr.Close();
|
||||
xr.Dispose();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
26
FModel/Forms/ColorPicker/ColorPickRow.xaml
Normal file
26
FModel/Forms/ColorPicker/ColorPickRow.xaml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<UserControl
|
||||
x:Class="ColorPickerWPF.ColorPickRow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="28" d:DesignWidth="188" Height="28" VerticalContentAlignment="Center">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="28" />
|
||||
<ColumnDefinition Width="*" MinWidth="76" />
|
||||
<ColumnDefinition Width="84" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid>
|
||||
<Border BorderBrush="Black" BorderThickness="1">
|
||||
<Grid x:Name="ColorDisplayGrid" Background="#FFFFFFFF" />
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<TextBlock x:Name="HexLabel" Grid.Column="1" Text="#FFFFFFFF" HorizontalAlignment="Left" Margin="8,0,4,0" VerticalAlignment="Center"></TextBlock>
|
||||
<Button x:Name="PickColorButton" Content="Pick..." Grid.Column="2" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" Height="28"
|
||||
Click="PickColorButton_OnClick"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
42
FModel/Forms/ColorPicker/ColorPickRow.xaml.cs
Normal file
42
FModel/Forms/ColorPicker/ColorPickRow.xaml.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using ColorPickerWPF.Code;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ColorPickRow.xaml
|
||||
/// </summary>
|
||||
public partial class ColorPickRow : UserControl
|
||||
{
|
||||
public event EventHandler OnPick;
|
||||
|
||||
public Color Color { get; set; }
|
||||
|
||||
public ColorPickerDialogOptions Options { get; set; }
|
||||
|
||||
public ColorPickRow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void PickColorButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Color color;
|
||||
if (ColorPickerWindow.ShowDialog(out color, Options))
|
||||
{
|
||||
SetColor(color);
|
||||
OnPick?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetColor(Color color)
|
||||
{
|
||||
Color = color;
|
||||
HexLabel.Text = color.ToHexString();
|
||||
ColorDisplayGrid.Background = new SolidColorBrush(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
89
FModel/Forms/ColorPicker/ColorPickerControl.xaml
Normal file
89
FModel/Forms/ColorPicker/ColorPickerControl.xaml
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<UserControl
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:colorPickerWpf="clr-namespace:ColorPickerWPF"
|
||||
x:Class="ColorPickerWPF.ColorPickerControl"
|
||||
mc:Ignorable="d" d:DesignWidth="560" d:DesignHeight="380" MinHeight="380">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="326" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="286" />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid>
|
||||
<TabControl x:Name="TabControl" Margin="0,0,0,0"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="#7F748198">
|
||||
<TabItem Header="Picker 1" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Image x:Name="SampleImage" Source="pack://application:,,,/Resources/colorpicker1.png" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Bottom"
|
||||
Width="320" Height="240"
|
||||
MouseDown="SampleImage_OnMouseDown"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Picker 2" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Image x:Name="SampleImage2" Source="pack://application:,,,/Resources/colorpicker2.png" HorizontalAlignment="Left" Margin="2" VerticalAlignment="Top"
|
||||
Width="254" Height="254"
|
||||
MouseDown="SampleImage2_OnMouseDown"/>
|
||||
<Label x:Name="label" Content="Hue" HorizontalAlignment="Left" Margin="261,2,0,0" VerticalAlignment="Top"/>
|
||||
<Slider x:Name="PickerHueSlider" HorizontalAlignment="Left" Margin="268,33,0,0" VerticalAlignment="Top"
|
||||
Orientation="Vertical" Height="199" ValueChanged="PickerHueSlider_OnValueChanged" Maximum="360" SmallChange="1" Minimum="1" LargeChange="30"/>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Column="1" Grid.RowSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Label x:Name="rgbLabel" Content="Red, Green, Blue, Alpha" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||
<colorPickerWpf:SliderRow x:Name="RSlider" HorizontalAlignment="Stretch" Margin="0,26,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="RSlider_OnOnValueChanged" FormatString="F0" />
|
||||
<colorPickerWpf:SliderRow x:Name="GSlider" HorizontalAlignment="Stretch" Margin="0,54,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="GSlider_OnOnValueChanged" FormatString="F0"/>
|
||||
<colorPickerWpf:SliderRow x:Name="BSlider" HorizontalAlignment="Stretch" Margin="0,82,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="BSlider_OnOnValueChanged" FormatString="F0"/>
|
||||
<colorPickerWpf:SliderRow x:Name="ASlider" HorizontalAlignment="Stretch" Margin="0,110,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="ASlider_OnOnValueChanged" FormatString="F0"/>
|
||||
|
||||
<Label x:Name="hsvLabel" Content="Hue, Saturation, Value" HorizontalAlignment="Left" Margin="0,143,0,0" VerticalAlignment="Top"/>
|
||||
<colorPickerWpf:SliderRow x:Name="HSlider" HorizontalAlignment="Stretch" Margin="0,169,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="HSlider_OnOnValueChanged" FormatString="F0"/>
|
||||
<colorPickerWpf:SliderRow x:Name="SSlider" HorizontalAlignment="Stretch" Margin="0,197,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="SSlider_OnOnValueChanged"/>
|
||||
<colorPickerWpf:SliderRow x:Name="LSlider" HorizontalAlignment="Stretch" Margin="0,225,0,0" VerticalAlignment="Top"
|
||||
OnValueChanged="LSlider_OnOnValueChanged"/>
|
||||
<colorPickerWpf:ColorPickerSwatch x:Name="CustomColorSwatch" HorizontalAlignment="Left" Margin="4,289,0,0" VerticalAlignment="Stretch" Width="230"
|
||||
Editable="true" OnPickColor="Swatch_OnOnPickColor"/>
|
||||
<Label x:Name="customColorsLabel" Content="Custom Colors (Ctrl+Click to set)" HorizontalAlignment="Left" Margin="0,258,0,0" VerticalAlignment="Top"/>
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="0" Margin="3">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="60" />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Border x:Name="ColorDisplayBorder" HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
BorderBrush="Black" Background="White" BorderThickness="2" Width="58" Height="58" Margin="0,0,0,0"/>
|
||||
|
||||
<colorPickerWpf:ColorPickerSwatch x:Name="Swatch1" HorizontalAlignment="Left" Height="60" Margin="60,0,0,0" VerticalAlignment="Top" Width="260"
|
||||
OnPickColor="Swatch_OnOnPickColor"/>
|
||||
</Grid>
|
||||
<colorPickerWpf:ColorPickerSwatch x:Name="Swatch2" HorizontalAlignment="Stretch" Margin="0,0,0,0" Grid.Row="1" VerticalAlignment="Stretch"
|
||||
OnPickColor="Swatch_OnOnPickColor"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
419
FModel/Forms/ColorPicker/ColorPickerControl.xaml.cs
Normal file
419
FModel/Forms/ColorPicker/ColorPickerControl.xaml.cs
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ColorPickerWPF.Code;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ColorPickerControl.xaml
|
||||
/// </summary>
|
||||
public partial class ColorPickerControl : UserControl
|
||||
{
|
||||
public Color Color = Colors.White;
|
||||
|
||||
public delegate void ColorPickerChangeHandler(Color color);
|
||||
|
||||
public event ColorPickerChangeHandler OnPickColor;
|
||||
|
||||
internal List<ColorSwatchItem> ColorSwatch1 = new List<ColorSwatchItem>();
|
||||
internal List<ColorSwatchItem> ColorSwatch2 = new List<ColorSwatchItem>();
|
||||
|
||||
public bool IsSettingValues = false;
|
||||
|
||||
protected const int NumColorsFirstSwatch = 39;
|
||||
protected const int NumColorsSecondSwatch = 112;
|
||||
|
||||
internal static ColorPalette ColorPalette;
|
||||
|
||||
|
||||
public ColorPickerControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ColorPickerSwatch.ColorPickerControl = this;
|
||||
|
||||
// Load from file if possible
|
||||
if (ColorPickerSettings.UsingCustomPalette && File.Exists(ColorPickerSettings.CustomPaletteFilename))
|
||||
{
|
||||
try
|
||||
{
|
||||
ColorPalette = ColorPalette.LoadFromXml(ColorPickerSettings.CustomPaletteFilename);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//ok
|
||||
}
|
||||
}
|
||||
|
||||
if (ColorPalette == null)
|
||||
{
|
||||
ColorPalette = new ColorPalette();
|
||||
ColorPalette.InitializeDefaults();
|
||||
}
|
||||
|
||||
|
||||
ColorSwatch1.AddRange(ColorPalette.BuiltInColors.Take(NumColorsFirstSwatch).ToArray());
|
||||
|
||||
ColorSwatch2.AddRange(ColorPalette.BuiltInColors.Skip(NumColorsFirstSwatch).Take(NumColorsSecondSwatch).ToArray());
|
||||
|
||||
Swatch1.SwatchListBox.ItemsSource = ColorSwatch1;
|
||||
Swatch2.SwatchListBox.ItemsSource = ColorSwatch2;
|
||||
|
||||
if (ColorPickerSettings.UsingCustomPalette)
|
||||
{
|
||||
CustomColorSwatch.SwatchListBox.ItemsSource = ColorPalette.CustomColors;
|
||||
}
|
||||
else
|
||||
{
|
||||
customColorsLabel.Visibility = Visibility.Collapsed;
|
||||
CustomColorSwatch.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
|
||||
RSlider.Slider.Maximum = 255;
|
||||
GSlider.Slider.Maximum = 255;
|
||||
BSlider.Slider.Maximum = 255;
|
||||
ASlider.Slider.Maximum = 255;
|
||||
HSlider.Slider.Maximum = 360;
|
||||
SSlider.Slider.Maximum = 1;
|
||||
LSlider.Slider.Maximum = 1;
|
||||
|
||||
|
||||
RSlider.Label.Content = "R";
|
||||
RSlider.Slider.TickFrequency = 1;
|
||||
RSlider.Slider.IsSnapToTickEnabled = true;
|
||||
GSlider.Label.Content = "G";
|
||||
GSlider.Slider.TickFrequency = 1;
|
||||
GSlider.Slider.IsSnapToTickEnabled = true;
|
||||
BSlider.Label.Content = "B";
|
||||
BSlider.Slider.TickFrequency = 1;
|
||||
BSlider.Slider.IsSnapToTickEnabled = true;
|
||||
|
||||
ASlider.Label.Content = "A";
|
||||
ASlider.Slider.TickFrequency = 1;
|
||||
ASlider.Slider.IsSnapToTickEnabled = true;
|
||||
|
||||
HSlider.Label.Content = "H";
|
||||
HSlider.Slider.TickFrequency = 1;
|
||||
HSlider.Slider.IsSnapToTickEnabled = true;
|
||||
SSlider.Label.Content = "S";
|
||||
//SSlider.Slider.TickFrequency = 1;
|
||||
//SSlider.Slider.IsSnapToTickEnabled = true;
|
||||
LSlider.Label.Content = "V";
|
||||
//LSlider.Slider.TickFrequency = 1;
|
||||
//LSlider.Slider.IsSnapToTickEnabled = true;
|
||||
|
||||
|
||||
SetColor(Color);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void SetColor(Color color)
|
||||
{
|
||||
Color = color;
|
||||
|
||||
CustomColorSwatch.CurrentColor = color;
|
||||
|
||||
IsSettingValues = true;
|
||||
|
||||
RSlider.Slider.Value = Color.R;
|
||||
GSlider.Slider.Value = Color.G;
|
||||
BSlider.Slider.Value = Color.B;
|
||||
ASlider.Slider.Value = Color.A;
|
||||
|
||||
SSlider.Slider.Value = Color.GetSaturation();
|
||||
LSlider.Slider.Value = Color.GetBrightness();
|
||||
HSlider.Slider.Value = Color.GetHue();
|
||||
|
||||
ColorDisplayBorder.Background = new SolidColorBrush(Color);
|
||||
|
||||
IsSettingValues = false;
|
||||
OnPickColor?.Invoke(color);
|
||||
}
|
||||
|
||||
internal void CustomColorsChanged()
|
||||
{
|
||||
if (ColorPickerSettings.UsingCustomPalette)
|
||||
{
|
||||
SaveCustomPalette(ColorPickerSettings.CustomPaletteFilename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void SampleImageClick(BitmapSource img, Point pos)
|
||||
{
|
||||
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/82a5731e-e201-4aaf-8d4b-062b138338fe/getting-pixel-information-from-a-bitmapimage?forum=wpf
|
||||
|
||||
int stride = (int)img.Width * 4;
|
||||
int size = (int)img.Height * stride;
|
||||
byte[] pixels = new byte[(int)size];
|
||||
|
||||
img.CopyPixels(pixels, stride, 0);
|
||||
|
||||
|
||||
// Get pixel
|
||||
var x = (int)pos.X;
|
||||
var y = (int)pos.Y;
|
||||
|
||||
int index = y * stride + 4 * x;
|
||||
|
||||
byte red = pixels[index];
|
||||
byte green = pixels[index + 1];
|
||||
byte blue = pixels[index + 2];
|
||||
byte alpha = pixels[index + 3];
|
||||
|
||||
var color = Color.FromArgb(alpha, blue, green, red);
|
||||
SetColor(color);
|
||||
}
|
||||
|
||||
|
||||
private void SampleImage_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse.Capture(this);
|
||||
|
||||
this.MouseMove += ColorPickerControl_MouseMove;
|
||||
this.MouseUp += ColorPickerControl_MouseUp;
|
||||
}
|
||||
private void SampleImage2_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse.Capture(null);
|
||||
|
||||
this.MouseMove += ColorPickerControl2_MouseMove;
|
||||
this.MouseUp += ColorPickerControl2_MouseUp;
|
||||
}
|
||||
|
||||
private void ColorPickerControl_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var pos = e.GetPosition(SampleImage);
|
||||
var img = SampleImage.Source as BitmapSource;
|
||||
|
||||
if (pos.X > 0 && pos.Y > 0 && pos.X < img.PixelWidth && pos.Y < img.PixelHeight)
|
||||
SampleImageClick(img, pos);
|
||||
}
|
||||
private void ColorPickerControl2_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var pos = e.GetPosition(SampleImage2);
|
||||
var img = SampleImage2.Source as BitmapSource;
|
||||
|
||||
if (pos.X > 0 && pos.Y > 0 && pos.X < img.PixelWidth && pos.Y < img.PixelHeight)
|
||||
SampleImageClick(img, pos);
|
||||
}
|
||||
|
||||
private void ColorPickerControl_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse.Capture(null);
|
||||
this.MouseMove -= ColorPickerControl_MouseMove;
|
||||
this.MouseUp -= ColorPickerControl_MouseUp;
|
||||
}
|
||||
private void ColorPickerControl2_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Mouse.Capture(null);
|
||||
this.MouseMove -= ColorPickerControl2_MouseMove;
|
||||
this.MouseUp -= ColorPickerControl2_MouseUp;
|
||||
}
|
||||
|
||||
private void Swatch_OnOnPickColor(Color color)
|
||||
{
|
||||
SetColor(color);
|
||||
}
|
||||
|
||||
private void HSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var s = Color.GetSaturation();
|
||||
var l = Color.GetBrightness();
|
||||
var h = (float)value;
|
||||
var a = (int)ASlider.Slider.Value;
|
||||
Color = Util.FromAhsb(a, h, s, l);
|
||||
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void RSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var val = (byte)value;
|
||||
Color.R = val;
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
private void GSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var val = (byte)value;
|
||||
Color.G = val;
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
private void BSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var val = (byte)value;
|
||||
Color.B = val;
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
private void ASlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var val = (byte)value;
|
||||
Color.A = val;
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
private void SSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var s = (float)value;
|
||||
var l = Color.GetBrightness();
|
||||
var h = Color.GetHue();
|
||||
var a = (int)ASlider.Slider.Value;
|
||||
Color = Util.FromAhsb(a, h, s, l);
|
||||
|
||||
SetColor(Color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void PickerHueSlider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
UpdateImageForHSV();
|
||||
}
|
||||
|
||||
|
||||
private void UpdateImageForHSV()
|
||||
{
|
||||
|
||||
//var hueChange = (int)((PickerHueSlider.Value / 360.0) * 240);
|
||||
var sliderHue = (float)PickerHueSlider.Value;
|
||||
|
||||
|
||||
//var colorPickerImage = System.IO.Path.Combine(Environment.CurrentDirectory, @"/Resources/colorpicker1.png");
|
||||
var img =
|
||||
new BitmapImage(new Uri("pack://application:,,,/Resources/colorpicker2.png",
|
||||
UriKind.Absolute));
|
||||
|
||||
var writableImage = BitmapFactory.ConvertToPbgra32Format(img);
|
||||
|
||||
if (sliderHue <= 0f || sliderHue >= 360f)
|
||||
{
|
||||
// No hue change just return
|
||||
SampleImage2.Source = img;
|
||||
return;
|
||||
}
|
||||
|
||||
using (var context = writableImage.GetBitmapContext())
|
||||
{
|
||||
long numPixels = img.PixelWidth * img.PixelHeight;
|
||||
|
||||
for (int x = 0; x < img.PixelWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < img.PixelHeight; y++)
|
||||
{
|
||||
var pixel = writableImage.GetPixel(x, y);
|
||||
|
||||
var newHue = (float)(sliderHue + pixel.GetHue());
|
||||
if (newHue >= 360)
|
||||
newHue -= 360;
|
||||
|
||||
var color = Util.FromAhsb((int)255,
|
||||
newHue, pixel.GetSaturation(), pixel.GetBrightness());
|
||||
|
||||
writableImage.SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
SampleImage2.Source = writableImage;
|
||||
}
|
||||
|
||||
private void LSlider_OnOnValueChanged(double value)
|
||||
{
|
||||
if (!IsSettingValues)
|
||||
{
|
||||
var s = Color.GetSaturation();
|
||||
var l = (float)value;
|
||||
var h = Color.GetHue();
|
||||
var a = (int)ASlider.Slider.Value;
|
||||
Color = Util.FromAhsb(a, h, s, l);
|
||||
|
||||
SetColor(Color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SaveCustomPalette(string filename)
|
||||
{
|
||||
var colors = CustomColorSwatch.GetColors();
|
||||
ColorPalette.CustomColors = colors;
|
||||
|
||||
try
|
||||
{
|
||||
ColorPalette.SaveToXml(filename);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//ok
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadCustomPalette(string filename)
|
||||
{
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
try
|
||||
{
|
||||
ColorPalette = ColorPalette.LoadFromXml(filename);
|
||||
|
||||
CustomColorSwatch.SwatchListBox.ItemsSource = ColorPalette.CustomColors.ToList();
|
||||
|
||||
// Do regular one too
|
||||
|
||||
ColorSwatch1.Clear();
|
||||
ColorSwatch2.Clear();
|
||||
ColorSwatch1.AddRange(ColorPalette.BuiltInColors.Take(NumColorsFirstSwatch).ToArray());
|
||||
ColorSwatch2.AddRange(ColorPalette.BuiltInColors.Skip(NumColorsFirstSwatch).Take(NumColorsSecondSwatch).ToArray());
|
||||
Swatch1.SwatchListBox.ItemsSource = ColorSwatch1;
|
||||
Swatch2.SwatchListBox.ItemsSource = ColorSwatch2;
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//ok
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void LoadDefaultCustomPalette()
|
||||
{
|
||||
LoadCustomPalette(Path.Combine(ColorPickerSettings.CustomColorsDirectory, ColorPickerSettings.CustomColorsFilename));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
15
FModel/Forms/ColorPicker/ColorPickerSettings.cs
Normal file
15
FModel/Forms/ColorPicker/ColorPickerSettings.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
public static class ColorPickerSettings
|
||||
{
|
||||
internal static bool UsingCustomPalette;
|
||||
public static string CustomColorsFilename = "CustomColorPalette.xml";
|
||||
public static string CustomColorsDirectory = Environment.CurrentDirectory;
|
||||
|
||||
public static string CustomPaletteFilename { get { return Path.Combine(CustomColorsDirectory, CustomColorsFilename); } }
|
||||
|
||||
}
|
||||
}
|
||||
27
FModel/Forms/ColorPicker/ColorPickerSwatch.xaml
Normal file
27
FModel/Forms/ColorPicker/ColorPickerSwatch.xaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<UserControl x:Class="ColorPickerWPF.ColorPickerSwatch"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<ItemsControl x:Name="SwatchListBox"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="Black" Background="{Binding HexString}" BorderThickness="0" Width="20" Height="20" Margin="0,0,0,0" MouseDown="UIElement_OnMouseDown">
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
77
FModel/Forms/ColorPicker/ColorPickerSwatch.xaml.cs
Normal file
77
FModel/Forms/ColorPicker/ColorPickerSwatch.xaml.cs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using ColorPickerWPF.Code;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ColorPickerSwatch.xaml
|
||||
/// </summary>
|
||||
public partial class ColorPickerSwatch : UserControl
|
||||
{
|
||||
public delegate void ColorSwatchPickHandler(Color color);
|
||||
|
||||
public static ColorPickerControl ColorPickerControl { get; set; }
|
||||
|
||||
public event ColorSwatchPickHandler OnPickColor;
|
||||
|
||||
public bool Editable { get; set; }
|
||||
public Color CurrentColor = Colors.White;
|
||||
|
||||
public ColorPickerSwatch()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var border = (sender as Border);
|
||||
if (border == null)
|
||||
return;
|
||||
|
||||
if (Editable && Keyboard.IsKeyDown(Key.LeftCtrl))
|
||||
{
|
||||
border.Background = new SolidColorBrush(CurrentColor);
|
||||
|
||||
var data = border.DataContext as ColorSwatchItem;
|
||||
if (data != null)
|
||||
{
|
||||
data.Color = CurrentColor;
|
||||
data.HexString = CurrentColor.ToHexString();
|
||||
}
|
||||
|
||||
if (ColorPickerControl != null)
|
||||
{
|
||||
ColorPickerControl.CustomColorsChanged();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = border.Background as SolidColorBrush;
|
||||
OnPickColor?.Invoke(color.Color);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal List<ColorSwatchItem> GetColors()
|
||||
{
|
||||
var results = new List<ColorSwatchItem>();
|
||||
|
||||
var shit = SwatchListBox.Items;
|
||||
|
||||
var colors = SwatchListBox.ItemsSource as List<ColorSwatchItem>;
|
||||
if (colors != null)
|
||||
{
|
||||
return colors;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
FModel/Forms/ColorPicker/ColorPickerWindow.xaml
Normal file
23
FModel/Forms/ColorPicker/ColorPickerWindow.xaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<Window
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:colorPickerWpf="clr-namespace:ColorPickerWPF"
|
||||
x:Class="ColorPickerWPF.ColorPickerWindow"
|
||||
mc:Ignorable="d"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
Title="Color Picker" Width="574" MinWidth="342" SizeToContent="Height" MinHeight="450" Icon="/FModel;component/Logo.ico" ResizeMode="CanMinimize">
|
||||
<DockPanel LastChildFill="False">
|
||||
|
||||
<colorPickerWpf:ColorPickerControl x:Name="ColorPicker" DockPanel.Dock="Top" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" MinHeight="372"/>
|
||||
|
||||
<Grid DockPanel.Dock="Bottom" MinHeight="47">
|
||||
<Button x:Name="CloseButton" Content="Close" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="90,10,0,0" Height="27" Click="CloseButton_Click" IsCancel="True"/>
|
||||
<Button x:Name="OKButton" Content="OK" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="10,10,0,10" Height="27" Click="OKButton_Click" IsDefault="True"/>
|
||||
<Button x:Name="MinMaxViewButton" Content="<< Simple" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="243,10,0,0" Height="27" Click="MinMaxViewButton_OnClick"/>
|
||||
</Grid>
|
||||
|
||||
|
||||
</DockPanel>
|
||||
</Window>
|
||||
100
FModel/Forms/ColorPicker/ColorPickerWindow.xaml.cs
Normal file
100
FModel/Forms/ColorPicker/ColorPickerWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using ColorPickerWPF.Code;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ColorPickerWindow.xaml
|
||||
/// </summary>
|
||||
public partial class ColorPickerWindow : Window
|
||||
{
|
||||
protected readonly int WidthMax = 574;
|
||||
protected readonly int WidthMin = 342;
|
||||
protected bool SimpleMode { get; set; }
|
||||
|
||||
public ColorPickerWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static bool ShowDialog(out Color color, ColorPickerDialogOptions flags = ColorPickerDialogOptions.None, ColorPickerControl.ColorPickerChangeHandler customPreviewEventHandler = null)
|
||||
{
|
||||
if ((flags & ColorPickerDialogOptions.LoadCustomPalette) == ColorPickerDialogOptions.LoadCustomPalette)
|
||||
{
|
||||
ColorPickerSettings.UsingCustomPalette = true;
|
||||
}
|
||||
|
||||
var instance = new ColorPickerWindow();
|
||||
color = instance.ColorPicker.Color;
|
||||
|
||||
if ((flags & ColorPickerDialogOptions.SimpleView) == ColorPickerDialogOptions.SimpleView)
|
||||
{
|
||||
instance.ToggleSimpleAdvancedView();
|
||||
}
|
||||
|
||||
if (ColorPickerSettings.UsingCustomPalette)
|
||||
{
|
||||
instance.ColorPicker.LoadDefaultCustomPalette();
|
||||
}
|
||||
|
||||
if (customPreviewEventHandler != null)
|
||||
{
|
||||
instance.ColorPicker.OnPickColor += customPreviewEventHandler;
|
||||
}
|
||||
|
||||
var result = instance.ShowDialog();
|
||||
if (result.HasValue && result.Value)
|
||||
{
|
||||
color = instance.ColorPicker.Color;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OKButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = true;
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void MinMaxViewButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (SimpleMode)
|
||||
{
|
||||
SimpleMode = false;
|
||||
MinMaxViewButton.Content = "<< Simple";
|
||||
Width = WidthMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
SimpleMode = true;
|
||||
MinMaxViewButton.Content = "Advanced >>";
|
||||
Width = WidthMin;
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleSimpleAdvancedView()
|
||||
{
|
||||
if (SimpleMode)
|
||||
{
|
||||
SimpleMode = false;
|
||||
MinMaxViewButton.Content = "<< Simple";
|
||||
Width = WidthMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
SimpleMode = true;
|
||||
MinMaxViewButton.Content = "Advanced >>";
|
||||
Width = WidthMin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
FModel/Forms/ColorPicker/SliderRow.xaml
Normal file
21
FModel/Forms/ColorPicker/SliderRow.xaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<UserControl x:Class="ColorPickerWPF.SliderRow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="32" d:DesignWidth="250">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="30" />
|
||||
<ColumnDefinition Width="*" MinWidth="120" />
|
||||
<ColumnDefinition Width="60" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label x:Name="Label" Content=" " HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="0,2,0,0"/>
|
||||
<Slider x:Name="Slider" Style="{StaticResource Horizontal_Slider}" Grid.Column="1" HorizontalAlignment="Stretch" Margin="10,7,10,0" VerticalAlignment="Top"
|
||||
ValueChanged="Slider_OnValueChanged"/>
|
||||
<TextBox x:Name="TextBox" Grid.Column="2" HorizontalAlignment="Left" Height="23" Margin="0,5,0,0" TextWrapping="Wrap" Text="0.0" VerticalAlignment="Top" Width="57"
|
||||
TextChanged="TextBox_OnTextChanged" FontSize="14" Foreground="#FFEFEFEF"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
59
FModel/Forms/ColorPicker/SliderRow.xaml.cs
Normal file
59
FModel/Forms/ColorPicker/SliderRow.xaml.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ColorPickerWPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SliderRow.xaml
|
||||
/// </summary>
|
||||
public partial class SliderRow : UserControl
|
||||
{
|
||||
public delegate void SliderRowValueChangedHandler(double value);
|
||||
|
||||
public event SliderRowValueChangedHandler OnValueChanged;
|
||||
|
||||
public string FormatString { get; set; }
|
||||
|
||||
protected bool UpdatingValues = false;
|
||||
|
||||
public SliderRow()
|
||||
{
|
||||
FormatString = "F2";
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Slider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
// Set textbox
|
||||
var value = Slider.Value;
|
||||
|
||||
if (!UpdatingValues)
|
||||
{
|
||||
UpdatingValues = true;
|
||||
TextBox.Text = value.ToString(FormatString);
|
||||
OnValueChanged?.Invoke(value);
|
||||
UpdatingValues = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (!UpdatingValues)
|
||||
{
|
||||
var text = TextBox.Text;
|
||||
bool ok = false;
|
||||
double parsedValue = 0;
|
||||
|
||||
ok = double.TryParse(text, out parsedValue);
|
||||
if (ok)
|
||||
{
|
||||
UpdatingValues = true;
|
||||
Slider.Value = parsedValue;
|
||||
OnValueChanged?.Invoke(parsedValue);
|
||||
UpdatingValues = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
FModel/Forms/FModel_About.xaml
Normal file
43
FModel/Forms/FModel_About.xaml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<Window x:Class="FModel.Forms.FModel_About"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Title="About"
|
||||
Height="180"
|
||||
Width="510"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowStyle="ToolWindow"
|
||||
ShowInTaskbar="False"
|
||||
>
|
||||
<Grid>
|
||||
<Image Width="127" Height="127" Source="/FModel;component/Resources/Logo.png" Margin="10,10,0,10" HorizontalAlignment="Left"/>
|
||||
<Grid Height="127" Margin="142,10,10,10">
|
||||
<Label x:Name="AboutTitle_Lbl" Content="FModel" HorizontalAlignment="Center" VerticalAlignment="Top" FontSize="24" FontWeight="Bold" Margin="0,5,0,0"/>
|
||||
<Label Content="A powerful .PAK file explorer fully dedicated to Fortnite." HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,33,0,0"/>
|
||||
<Label Content="Big thanks to:" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,60,0,0"/>
|
||||
<Label Content="• Waddlesworth • Maiky • Asriel • FireMonkey" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,75,0,0" FontSize="11"/>
|
||||
|
||||
<Label HorizontalAlignment="Left" Margin="10,0,0,10" VerticalAlignment="Bottom" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand">
|
||||
<TextBlock>
|
||||
<Hyperlink NavigateUri="https://www.paypal.me/FModel" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF">Donate</Hyperlink>
|
||||
</TextBlock>
|
||||
</Label>
|
||||
<Label HorizontalAlignment="Center" Margin="10,0,0,10" VerticalAlignment="Bottom" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand">
|
||||
<TextBlock>
|
||||
<Hyperlink NavigateUri="https://discord.gg/fdkNYYQ" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF"><Run Text="Discord"/></Hyperlink>
|
||||
</TextBlock>
|
||||
</Label>
|
||||
<Label HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand">
|
||||
<TextBlock>
|
||||
<Hyperlink NavigateUri="https://github.com/iAmAsval/FModel/blob/master/README.md#how-to-use" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF">How To Use</Hyperlink>
|
||||
</TextBlock>
|
||||
</Label>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
25
FModel/Forms/FModel_About.xaml.cs
Normal file
25
FModel/Forms/FModel_About.xaml.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_About.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_About : Window
|
||||
{
|
||||
public FModel_About()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
|
||||
AboutTitle_Lbl.Content += " " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5);
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
FModel/Forms/FModel_CustomMB.xaml
Normal file
62
FModel/Forms/FModel_CustomMB.xaml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<Window x:Class="FModel.Forms.FModel_CustomMB"
|
||||
x:ClassModifier="internal"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
Title="" MinHeight="130" MinWidth="154"
|
||||
TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="ClearType" UseLayoutRounding="True"
|
||||
ResizeMode="NoResize" SizeToContent="WidthAndHeight"
|
||||
ShowInTaskbar="False" Topmost="True"
|
||||
WindowStyle="ToolWindow" WindowStartupLocation="CenterScreen" Height="52"
|
||||
>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" MinHeight="69">
|
||||
<DockPanel>
|
||||
<Image Name="Image_MessageBox" Width="32" Height="32" HorizontalAlignment="Left" DockPanel.Dock="Left" Margin="30,0,0,0" Visibility="Collapsed"/>
|
||||
<TextBlock Name="TextBlock_Message" TextWrapping="Wrap" Width="Auto"
|
||||
VerticalAlignment="Center" Margin="12,20,41,15" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" MinHeight="49">
|
||||
<DockPanel Margin="5,0">
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<Button Name="Button_Cancel" MinWidth="88" MaxWidth="160" Height="26" Margin="5,0" HorizontalAlignment="Right" Visibility="Collapsed" IsCancel="True"
|
||||
DockPanel.Dock="Right" Click="Button_Cancel_Click">
|
||||
<Label Name="Label_Cancel" Padding="0" Margin="10,0">_Cancel</Label>
|
||||
</Button>
|
||||
<!-- End Cancel Button -->
|
||||
|
||||
<!-- No Button -->
|
||||
<Button Name="Button_No" MinWidth="88" MaxWidth="160" Height="26" Margin="5,0" HorizontalAlignment="Right" Visibility="Collapsed"
|
||||
DockPanel.Dock="Right" Click="Button_No_Click">
|
||||
<Label Name="Label_No" Padding="0" Margin="10,0">_No</Label>
|
||||
</Button>
|
||||
<!-- End No Button -->
|
||||
|
||||
<!-- Yes Button -->
|
||||
<Button Name="Button_Yes" MinWidth="88" MaxWidth="160" Height="26" Margin="35,0,5,0" HorizontalAlignment="Right" Visibility="Collapsed"
|
||||
DockPanel.Dock="Right" Click="Button_Yes_Click">
|
||||
<Label Name="Label_Yes" Padding="0" Margin="10,0">_Yes</Label>
|
||||
</Button>
|
||||
<!-- End Yes Button -->
|
||||
|
||||
<!-- OK Button -->
|
||||
<Button Name="Button_OK" MinWidth="80" MaxWidth="160" Margin="35,10,5,0" HorizontalAlignment="Right" Height="19"
|
||||
Click="Button_OK_Click">
|
||||
<Label Name="Label_Ok" Padding="0" Margin="10,0">_OK</Label>
|
||||
</Button>
|
||||
<!-- End OK Button -->
|
||||
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
234
FModel/Forms/FModel_CustomMB.xaml.cs
Normal file
234
FModel/Forms/FModel_CustomMB.xaml.cs
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
using FModel.Methods.Utilities;
|
||||
using System.Drawing;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_CustomMB.xaml
|
||||
/// </summary>
|
||||
internal partial class FModel_CustomMB : Window
|
||||
{
|
||||
internal string Caption
|
||||
{
|
||||
get
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
set
|
||||
{
|
||||
Title = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextBlock_Message.Text;
|
||||
}
|
||||
set
|
||||
{
|
||||
TextBlock_Message.Text = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string OkButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Ok.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Ok.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
internal string CancelButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Cancel.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Cancel.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
internal string YesButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Yes.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Yes.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
internal string NoButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_No.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_No.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
public MessageBoxResult Result { get; set; }
|
||||
|
||||
internal FModel_CustomMB(string message)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
|
||||
Message = message;
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Collapsed;
|
||||
DisplayButtons(MessageBoxButton.OK);
|
||||
}
|
||||
|
||||
internal FModel_CustomMB(string message, string caption)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Message = message;
|
||||
Caption = caption;
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Collapsed;
|
||||
DisplayButtons(MessageBoxButton.OK);
|
||||
}
|
||||
|
||||
internal FModel_CustomMB(string message, string caption, MessageBoxButton button)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Message = message;
|
||||
Caption = caption;
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Collapsed;
|
||||
|
||||
DisplayButtons(button);
|
||||
}
|
||||
|
||||
internal FModel_CustomMB(string message, string caption, MessageBoxImage image)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Message = message;
|
||||
Caption = caption;
|
||||
DisplayImage(image);
|
||||
DisplayButtons(MessageBoxButton.OK);
|
||||
}
|
||||
|
||||
internal FModel_CustomMB(string message, string caption, MessageBoxButton button, MessageBoxImage image)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Message = message;
|
||||
Caption = caption;
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Collapsed;
|
||||
|
||||
DisplayButtons(button);
|
||||
DisplayImage(image);
|
||||
}
|
||||
|
||||
private void DisplayButtons(MessageBoxButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.OKCancel:
|
||||
// Hide all but OK, Cancel
|
||||
Button_OK.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_OK.Focus();
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_No.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
// Hide all but Yes, No
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Yes.Focus();
|
||||
Button_No.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_OK.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
// Hide only OK
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Yes.Focus();
|
||||
Button_No.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_OK.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
default:
|
||||
// Hide all but OK
|
||||
Button_OK.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_OK.Focus();
|
||||
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_No.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayImage(MessageBoxImage image)
|
||||
{
|
||||
Icon icon;
|
||||
|
||||
switch (image)
|
||||
{
|
||||
case MessageBoxImage.Exclamation: // Enumeration value 48 - also covers "Warning"
|
||||
icon = SystemIcons.Exclamation;
|
||||
break;
|
||||
case MessageBoxImage.Error: // Enumeration value 16, also covers "Hand" and "Stop"
|
||||
icon = SystemIcons.Hand;
|
||||
break;
|
||||
case MessageBoxImage.Information: // Enumeration value 64 - also covers "Asterisk"
|
||||
icon = SystemIcons.Information;
|
||||
break;
|
||||
case MessageBoxImage.Question:
|
||||
icon = SystemIcons.Question;
|
||||
break;
|
||||
default:
|
||||
icon = SystemIcons.Information;
|
||||
break;
|
||||
}
|
||||
|
||||
Image_MessageBox.Source = icon.ToImageSource();
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Button_OK_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.Yes;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_No_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.No;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
FModel/Forms/FModel_ImagesMerger.xaml
Normal file
32
FModel/Forms/FModel_ImagesMerger.xaml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<Window x:Class="FModel.Forms.FModel_ImagesMerger"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Title="Images Merger" Height="467.333" Width="800"
|
||||
Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Logo.ico"
|
||||
UseLayoutRounding="True" ResizeMode="CanMinimize" Loaded="Window_Loaded">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="143*"/>
|
||||
<ColumnDefinition Width="123*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<GroupBox Header="Images" Margin="10,10,0,0" BorderBrush="#7F748198" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="401" Height="409">
|
||||
<Grid>
|
||||
<ListBox x:Name="ImagesListBox" Margin="0,40,0,0" SelectionMode="Extended"/>
|
||||
<Button x:Name="AddImages_Button" Content="Add" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Width="100" Click="AddImages_Button_Click"/>
|
||||
<Button x:Name="RemoveImage_Button" Content="Remove" HorizontalAlignment="Center" Margin="0,10,0,0" VerticalAlignment="Top" Width="100" Click="RemoveImage_Button_Click"/>
|
||||
<Button x:Name="ClearImages_Button" Content="Clear" HorizontalAlignment="Right" Margin="0,10,0,0" VerticalAlignment="Top" Width="100" Click="ClearImages_Button_Click"/>
|
||||
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<Border BorderBrush="#7F748198" BorderThickness="1" Grid.Column="1" Background="#FF252D36" Margin="0,19,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="350" Width="350">
|
||||
<Image x:Name="MergerPreview_Image" UseLayoutRounding="True"/>
|
||||
</Border>
|
||||
<Slider x:Name="ImagesPerRow_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdatePreview" HorizontalAlignment="Left" VerticalAlignment="Top" Maximum="20" Minimum="1" Value="7" Width="350" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" Grid.Column="1" Margin="0,374,0,0" IsSnapToTickEnabled="True"/>
|
||||
<Button x:Name="SaveImage_Button" Content="Save Image" Grid.Column="1" HorizontalAlignment="Left" Margin="250,400,0,0" VerticalAlignment="Top" Width="100" Click="SaveImage_Button_Click"/>
|
||||
<Button x:Name="OpenImage_Button" Content="Open Image" Grid.Column="1" HorizontalAlignment="Left" Margin="0,400,0,0" VerticalAlignment="Top" Width="100" Click="OpenImage_Button_Click"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
255
FModel/Forms/FModel_ImagesMerger.xaml.cs
Normal file
255
FModel/Forms/FModel_ImagesMerger.xaml.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
using FModel.Methods.Utilities;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_ImagesMerger.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_ImagesMerger : Window
|
||||
{
|
||||
private static List<string> _imagePath { get; set; }
|
||||
|
||||
public FModel_ImagesMerger()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ImagesListBox.Items.Clear();
|
||||
}
|
||||
|
||||
private async void UpdatePreview(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MergerPreview_Image.Source != null)
|
||||
{
|
||||
await UpdateMergerPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateMergerPreview()
|
||||
{
|
||||
AddImages_Button.IsEnabled = false;
|
||||
RemoveImage_Button.IsEnabled = false;
|
||||
ClearImages_Button.IsEnabled = false;
|
||||
ImagesPerRow_Slider.IsEnabled = false;
|
||||
OpenImage_Button.IsEnabled = false;
|
||||
SaveImage_Button.IsEnabled = false;
|
||||
|
||||
if ((_imagePath != null && _imagePath.Count > 0) || ImagesListBox.Items.Count > 0)
|
||||
{
|
||||
_imagePath = new List<string>();
|
||||
for (int i = 0; i < ImagesListBox.Items.Count; ++i)
|
||||
{
|
||||
_imagePath.Add(((ListBoxItem)ImagesListBox.Items[i]).ContentStringFormat);
|
||||
}
|
||||
}
|
||||
int imageCount = _imagePath.Count;
|
||||
int numperrow = Convert.ToInt32(ImagesPerRow_Slider.Value);
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
DrawingVisual drawingVisual = new DrawingVisual();
|
||||
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
|
||||
{
|
||||
//INITIALIZATION
|
||||
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(515, 515)));
|
||||
|
||||
var w = 520 * numperrow;
|
||||
if (imageCount * 520 < 520 * numperrow)
|
||||
{
|
||||
w = imageCount * 520;
|
||||
}
|
||||
|
||||
int h = int.Parse(Math.Ceiling(double.Parse(imageCount.ToString()) / numperrow).ToString(CultureInfo.InvariantCulture)) * 520;
|
||||
|
||||
int num = 1;
|
||||
int curW = 0;
|
||||
int curH = 0;
|
||||
int maxHeight = 0;
|
||||
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
{
|
||||
int percentage = (i + 1) * 100 / imageCount;
|
||||
|
||||
BitmapImage source = new BitmapImage(new Uri(_imagePath[i]));
|
||||
source.DecodePixelWidth = 515;
|
||||
|
||||
double width = source.Width;
|
||||
double height = source.Height;
|
||||
if (height > maxHeight) { maxHeight = Convert.ToInt32(height); }
|
||||
|
||||
drawingContext.DrawImage(source, new Rect(new Point(curW, curH), new Size(width, height)));
|
||||
if (num % numperrow == 0)
|
||||
{
|
||||
curW = 0;
|
||||
curH += maxHeight + 5;
|
||||
num += 1;
|
||||
|
||||
maxHeight = 0; //reset max height for each new row
|
||||
}
|
||||
else
|
||||
{
|
||||
curW += Convert.ToInt32(width) + 5;
|
||||
num += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drawingVisual != null)
|
||||
{
|
||||
RenderTargetBitmap RTB = new RenderTargetBitmap((int)Math.Floor(drawingVisual.DescendantBounds.Width), (int)Math.Floor(drawingVisual.DescendantBounds.Height), 96, 96, PixelFormats.Pbgra32);
|
||||
RTB.Render(drawingVisual);
|
||||
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
|
||||
|
||||
this.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
MergerPreview_Image.Source = BitmapFrame.Create(RTB); //thread safe and fast af
|
||||
});
|
||||
}
|
||||
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
});
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
AddImages_Button.IsEnabled = true;
|
||||
RemoveImage_Button.IsEnabled = true;
|
||||
ClearImages_Button.IsEnabled = true;
|
||||
ImagesPerRow_Slider.IsEnabled = true;
|
||||
OpenImage_Button.IsEnabled = true;
|
||||
SaveImage_Button.IsEnabled = true;
|
||||
}
|
||||
|
||||
private async void AddImages_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenFileDialog openFiledialog = new OpenFileDialog();
|
||||
openFiledialog.Title = "Choose your images";
|
||||
openFiledialog.InitialDirectory = FProp.Default.FOutput_Path + "\\Icons\\";
|
||||
openFiledialog.Multiselect = true;
|
||||
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
|
||||
if (openFiledialog.ShowDialog() == true)
|
||||
{
|
||||
AddFiles(openFiledialog.FileNames);
|
||||
await UpdateMergerPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddFiles(string[] files)
|
||||
{
|
||||
if (files.Count() > 0)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
ListBoxItem itm = new ListBoxItem();
|
||||
itm.ContentStringFormat = file;
|
||||
itm.Content = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
ImagesListBox.Items.Add(itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void RemoveImage_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
|
||||
{
|
||||
for (int i = ImagesListBox.SelectedItems.Count - 1; i >= 0; --i)
|
||||
{
|
||||
ImagesListBox.Items.Remove(ImagesListBox.SelectedItems[i]);
|
||||
}
|
||||
|
||||
await UpdateMergerPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearImages_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ImagesListBox.Items.Clear();
|
||||
MergerPreview_Image.Source = null;
|
||||
}
|
||||
|
||||
private void OpenImage_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MergerPreview_Image.Source != null)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Merged Image"))
|
||||
{
|
||||
Window win = new Window();
|
||||
win.Title = "Merged Image";
|
||||
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
win.Width = MergerPreview_Image.Source.Width;
|
||||
win.Height = MergerPreview_Image.Source.Height;
|
||||
if (MergerPreview_Image.Source.Height > 1000)
|
||||
{
|
||||
win.WindowState = WindowState.Maximized;
|
||||
}
|
||||
|
||||
DockPanel dockPanel = new DockPanel
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
Image img = new Image();
|
||||
img.UseLayoutRounding = true;
|
||||
img.Source = MergerPreview_Image.Source;
|
||||
dockPanel.Children.Add(img);
|
||||
|
||||
win.Content = dockPanel;
|
||||
win.Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Merged Image").Focus(); }
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveImage_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MergerPreview_Image.Source != null)
|
||||
{
|
||||
SaveFileDialog saveFileDialog = new SaveFileDialog();
|
||||
saveFileDialog.Title = "Save Image";
|
||||
saveFileDialog.FileName = "Merger";
|
||||
saveFileDialog.InitialDirectory = FProp.Default.FOutput_Path;
|
||||
saveFileDialog.Filter = "PNG Files (*.png)|*.png";
|
||||
if (saveFileDialog.ShowDialog() == true)
|
||||
{
|
||||
string path = saveFileDialog.FileName;
|
||||
using (var fileStream = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
PngBitmapEncoder encoder = new PngBitmapEncoder();
|
||||
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)MergerPreview_Image.Source));
|
||||
encoder.Save(fileStream);
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
new UpdateMyConsole(System.IO.Path.GetFileNameWithoutExtension(path), CColors.Blue).Append();
|
||||
new UpdateMyConsole(" successfully saved", CColors.White, true).Append();
|
||||
}
|
||||
else //just in case
|
||||
{
|
||||
new UpdateMyConsole("Bruh moment\nCouldn't save ", CColors.White).Append();
|
||||
new UpdateMyConsole(System.IO.Path.GetFileNameWithoutExtension(path), CColors.Blue, true).Append();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
FModel/Forms/FModel_SearchFiles.xaml
Normal file
49
FModel/Forms/FModel_SearchFiles.xaml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<Window x:Class="FModel.Forms.FModel_SearchFiles"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Title="Search"
|
||||
Height="700"
|
||||
Width="1000"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="/FModel;component/Logo.ico"
|
||||
UseLayoutRounding="True" Loaded="Window_Loaded">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60*"/>
|
||||
<ColumnDefinition Width="20*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="7*"/>
|
||||
<RowDefinition Height="103*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Filter:" VerticalAlignment="Center" Height="24" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left"/>
|
||||
<TextBox x:Name="FilterTextBox_Search" Height="20" Margin="38,12,10,11" TextWrapping="NoWrap" VerticalAlignment="Center" Foreground="#FFEFEFEF" Grid.Row="0" Grid.Column="0" TextChanged="FilterTextBox_Search_TextChanged"/>
|
||||
<DataGrid x:Name="DataGrid_Search" Margin="0,0,0,0" HeadersVisibility="Column" ItemsSource="{Binding FileNames}" IsReadOnly="True" BorderBrush="#7F748198" ColumnHeaderHeight="25" AutoGenerateColumns="True" ColumnWidth="*" Grid.Row="1" Grid.ColumnSpan="2">
|
||||
<DataGrid.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="RC_GoTo" Header="Go To" Click="GoTo_Button_Click"/>
|
||||
<MenuItem x:Name="RC_ExportData" Header="Export RAW Data" Click="RC_ExportData_Click"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Copy File">
|
||||
<MenuItem x:Name="RC_Copy_FPath" Header="Copy File Path" Click="RC_Copy_FPath_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FName" Header="Copy File Name" Click="RC_Copy_FName_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FPath_NoExt" Header="Copy File Path w/o Extension" Click="RC_Copy_FPath_NoExt_Click"/>
|
||||
<MenuItem x:Name="RC_Copy_FName_NoExt" Header="Copy File Name w/o Extension" Click="RC_Copy_FName_NoExt_Click"/>
|
||||
</MenuItem>
|
||||
<Separator/>
|
||||
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/StatusAnnotations_Information_16xLG_color.png" Width="16" Height="16"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</DataGrid.ContextMenu>
|
||||
</DataGrid>
|
||||
<Button x:Name="GoTo_Button" Content="Go To Selected Asset" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Click="GoTo_Button_Click"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
269
FModel/Forms/FModel_SearchFiles.xaml.cs
Normal file
269
FModel/Forms/FModel_SearchFiles.xaml.cs
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
using FModel.Methods;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using PakReader;
|
||||
using FModel.Methods.Utilities;
|
||||
using System.IO;
|
||||
using FModel.Methods.Assets;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
using System;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_SearchFiles.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_SearchFiles : Window
|
||||
{
|
||||
private static List<FileInfo> FileNames { get; set; }
|
||||
|
||||
public class FileInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Extension { get; set; }
|
||||
public string PAK { get; set; }
|
||||
}
|
||||
|
||||
public class GridViewItem : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void OnPropertyChanged(string name)
|
||||
{
|
||||
var handler = PropertyChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FModel_SearchFiles()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PAKEntries.PAKToDisplay != null)
|
||||
{
|
||||
FilterTextBox_Search.IsReadOnly = true;
|
||||
FileNames = new List<FileInfo>();
|
||||
await PopulateDataGrid();
|
||||
DataGrid_Search.ItemsSource = FileNames;
|
||||
FilterTextBox_Search.IsReadOnly = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task PopulateDataGrid()
|
||||
{
|
||||
Dictionary<string, string> IfExistChecker = new Dictionary<string, string>();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(FWindow.FCurrentPAK))
|
||||
{
|
||||
FillList(PAKEntries.PAKToDisplay[FWindow.FCurrentPAK], IfExistChecker);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (FPakEntry[] PAKsFileInfos in PAKEntries.PAKToDisplay.Values)
|
||||
{
|
||||
FillList(PAKsFileInfos, IfExistChecker);
|
||||
}
|
||||
}
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
});
|
||||
}
|
||||
|
||||
private static void FillList(FPakEntry[] EntryArray, Dictionary<string, string> ExistChecker)
|
||||
{
|
||||
foreach (FPakEntry entry in EntryArray)
|
||||
{
|
||||
string filename = entry.Name;
|
||||
string ext = Path.GetExtension(entry.Name);
|
||||
string pak = Path.GetFileName(AssetEntries.AssetEntriesDict[entry.Name].Name);
|
||||
|
||||
if (filename.EndsWith(".uasset") || filename.EndsWith(".uexp") || filename.EndsWith(".ubulk"))
|
||||
{
|
||||
filename = filename.Substring(0, filename.LastIndexOf('.'));
|
||||
if (AssetEntries.ArraySearcher.ContainsKey(filename + ".uexp"))
|
||||
{
|
||||
ext += " .uexp";
|
||||
}
|
||||
if (AssetEntries.ArraySearcher.ContainsKey(filename + ".ubulk"))
|
||||
{
|
||||
ext += " .ubulk";
|
||||
}
|
||||
filename += ".uasset";
|
||||
}
|
||||
|
||||
if (!ExistChecker.ContainsKey(filename))
|
||||
{
|
||||
ExistChecker.Add(filename, pak);
|
||||
|
||||
FileNames.Add(new FileInfo
|
||||
{
|
||||
Name = filename,
|
||||
Extension = ext,
|
||||
PAK = pak
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void FilterTextBox_Search_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
if (PAKEntries.PAKToDisplay != null && FileNames != null)
|
||||
{
|
||||
List<FileInfo> filtered = new List<FileInfo>();
|
||||
string[] filters = FilterTextBox_Search.Text.Trim().Split(' ');
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
foreach (FileInfo fi in FileNames)
|
||||
{
|
||||
bool checkSearch = false;
|
||||
if (filters.Length > 1)
|
||||
{
|
||||
foreach (string filter in filters)
|
||||
{
|
||||
checkSearch = ListBoxUtility.CaseInsensitiveContains(fi.Name, filter);
|
||||
if (!checkSearch) { break; }
|
||||
}
|
||||
}
|
||||
else { checkSearch = ListBoxUtility.CaseInsensitiveContains(fi.Name, filters[0]); }
|
||||
|
||||
if (checkSearch)
|
||||
{
|
||||
filtered.Add(fi);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
DataGrid_Search.ItemsSource = filtered;
|
||||
}
|
||||
}
|
||||
|
||||
#region RIGHT CLICK
|
||||
private void RC_Copy_FPath_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
|
||||
Clipboard.SetText(selectedName.Substring(1));
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FName_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
|
||||
Clipboard.SetText(Path.GetFileName(selectedName));
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FPath_NoExt_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
|
||||
Clipboard.SetText(FoldersUtility.GetFullPathWithoutExtension(selectedName).Substring(1));
|
||||
}
|
||||
}
|
||||
private void RC_Copy_FName_NoExt_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
|
||||
Clipboard.SetText(Path.GetFileNameWithoutExtension(selectedName));
|
||||
}
|
||||
}
|
||||
private void RC_Properties_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
if (selectedName.EndsWith(".uasset"))
|
||||
{
|
||||
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
|
||||
}
|
||||
|
||||
FWindow.FCurrentAsset = selectedName;
|
||||
AssetInformations.OpenAssetInfos(true);
|
||||
}
|
||||
}
|
||||
private void GoTo_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
if (selectedName.EndsWith(".uasset"))
|
||||
{
|
||||
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
|
||||
}
|
||||
|
||||
FWindow.FCurrentAsset = selectedName;
|
||||
TreeViewUtility.JumpToFolder(selectedName.Substring(1, selectedName.LastIndexOf("/") - 1));
|
||||
FWindow.FMain.ListBox_Main.SelectedValue = selectedName.Substring(selectedName.LastIndexOf("/") + 1);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
private void RC_ExportData_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataGrid_Search.SelectedIndex >= 0)
|
||||
{
|
||||
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
|
||||
string selectedName = item.Name;
|
||||
if (selectedName.EndsWith(".uasset"))
|
||||
{
|
||||
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
|
||||
}
|
||||
|
||||
PakReader.PakReader reader = AssetsUtility.GetPakReader(selectedName);
|
||||
if (reader != null)
|
||||
{
|
||||
List<FPakEntry> entriesList = AssetsUtility.GetPakEntries(selectedName);
|
||||
foreach (FPakEntry entry in entriesList)
|
||||
{
|
||||
string path = FProp.Default.FOutput_Path + "\\Exports\\" + entry.Name;
|
||||
string pWExt = FoldersUtility.GetFullPathWithoutExtension(entry.Name);
|
||||
string subfolders = pWExt.Substring(0, pWExt.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
Directory.CreateDirectory(FProp.Default.FOutput_Path + "\\Exports\\" + subfolders);
|
||||
Stream stream = reader.GetPackageStream(entry);
|
||||
using (var fStream = File.OpenWrite(path))
|
||||
using (stream)
|
||||
{
|
||||
stream.CopyTo(fStream);
|
||||
}
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
new UpdateMyConsole(Path.GetFileName(path), CColors.Blue).Append();
|
||||
new UpdateMyConsole(" successfully exported", CColors.White, true).Append();
|
||||
}
|
||||
else //just in case
|
||||
{
|
||||
new UpdateMyConsole("Bruh moment\nCouldn't export ", CColors.White).Append();
|
||||
new UpdateMyConsole(Path.GetFileName(path), CColors.Blue, true).Append();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
104
FModel/Forms/FModel_Settings.xaml
Normal file
104
FModel/Forms/FModel_Settings.xaml
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<Window x:Class="FModel.Forms.FModel_Settings"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms"
|
||||
mc:Ignorable="d"
|
||||
Title="Settings"
|
||||
Height="558"
|
||||
Width="610"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Icon="/FModel;component/Logo.ico"
|
||||
ResizeMode="CanMinimize" Loaded="Window_Loaded"
|
||||
>
|
||||
<Grid>
|
||||
<GroupBox Header=".PAK Files" HorizontalAlignment="Left" Height="48" Margin="10,10,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Label Content="Input:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,1,0,0"/>
|
||||
<TextBox x:Name="InputTextBox" Height="19" Margin="41,4,121,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
<Button x:Name="BrowseInput_Button" Content="..." HorizontalAlignment="Left" Margin="446,4,0,0" VerticalAlignment="Top" Width="20" Click="BrowseInput_Button_Click"/>
|
||||
<CheckBox x:Name="bDiffFileSize" Content="Diff w/ File Size" HorizontalAlignment="Left" Margin="471,7,0,0" VerticalAlignment="Top"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Extraction" HorizontalAlignment="Left" Height="48" Margin="10,63,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Label Content="Output:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,-1"/>
|
||||
<TextBox x:Name="OutputTextBox" Height="19" Margin="50,4,35,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
<Button x:Name="BrowseOutput_Button" Content="..." HorizontalAlignment="Left" Margin="532,4,0,0" VerticalAlignment="Top" Width="20" Click="BrowseOutput_Button_Click"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Icon Creator" HorizontalAlignment="Left" Height="206" Margin="10,116,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Label Content="Language:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,0"/>
|
||||
<ComboBox x:Name="ComboBox_Language" HorizontalAlignment="Left" Margin="61,5,0,0" VerticalAlignment="Top" Width="332" BorderBrush="#7F748198" Background="#FF333C46">
|
||||
<ComboBoxItem Content="English"/>
|
||||
<ComboBoxItem Content="French"/>
|
||||
<ComboBoxItem Content="German"/>
|
||||
<ComboBoxItem Content="Italian"/>
|
||||
<ComboBoxItem Content="Spanish"/>
|
||||
<ComboBoxItem Content="Spanish (LA)"/>
|
||||
<ComboBoxItem Content="Arabic"/>
|
||||
<ComboBoxItem Content="Japanese"/>
|
||||
<ComboBoxItem Content="Korean"/>
|
||||
<ComboBoxItem Content="Polish"/>
|
||||
<ComboBoxItem Content="Portuguese (Brazil)"/>
|
||||
<ComboBoxItem Content="Russian"/>
|
||||
<ComboBoxItem Content="Turkish"/>
|
||||
<ComboBoxItem Content="Chinese (S)"/>
|
||||
<ComboBoxItem Content="Traditional Chinese"/>
|
||||
</ComboBox>
|
||||
<Label Content="Rarity Design:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,32,0,0"/>
|
||||
<ComboBox x:Name="ComboBox_Design" HorizontalAlignment="Left" Margin="78,35,0,0" VerticalAlignment="Top" Width="315" BorderBrush="#7F748198" Background="#FF333C46" IsReadOnly="True" SelectionChanged="UpdateImageBox">
|
||||
<ComboBoxItem Content="Default"/>
|
||||
<ComboBoxItem Content="Flat"/>
|
||||
<ComboBoxItem Content="Minimalist"/>
|
||||
</ComboBox>
|
||||
<Border BorderThickness="1" Background="#FF252D36" HorizontalAlignment="Right" Height="164" Margin="398,0,0,0" Width="164" VerticalAlignment="Top">
|
||||
<Image x:Name="ImageBox_RarityPreview" Source="/FModel;component/Resources/Template_D_N.png" UseLayoutRounding="True"/>
|
||||
</Border>
|
||||
|
||||
<CheckBox x:Name="bWatermarkIcon" Content="Watermark" HorizontalAlignment="Left" Margin="8,87,0,0" VerticalAlignment="Top" Checked="EnableDisableWatermark" Unchecked="EnableDisableWatermark"/>
|
||||
<Button x:Name="OpenFile_Button" Content="+" HorizontalAlignment="Right" Margin="0,0,454,82" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="OpenFile_Button_Click"/>
|
||||
<Label x:Name="Watermark_Label" Content="File Name: " MaxWidth="240" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="108,83,0,0"/>
|
||||
<Label Content="X Position:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,107,0,0"/>
|
||||
<Slider x:Name="xPos_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,110,0,0" VerticalAlignment="Top" Maximum="509" Minimum="3" Width="326" Background="#FF525A63" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
<Label Content="Y Position:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,134,0,0"/>
|
||||
<Slider x:Name="yPos_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,137,0,0" VerticalAlignment="Top" Maximum="509" Minimum="3" Width="326" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,161,0,-2"/>
|
||||
<Slider x:Name="Opacity_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,164,0,-1" VerticalAlignment="Top" Maximum="255" Width="138" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
<Label Content="Scale:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="212,161,0,-2"/>
|
||||
<Slider x:Name="Scale_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="255,164,0,-1" VerticalAlignment="Top" Maximum="515" Width="138" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
|
||||
<CheckBox x:Name="bFeaturedIcon" Content="Shop Item Icon" HorizontalAlignment="Left" Margin="305,59,0,0" VerticalAlignment="Top" Checked="UpdateImageBox" Unchecked="UpdateImageBox"/>
|
||||
<Button x:Name="OpenIconCreator_Button" Content="Open Image" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="164" Click="OpenIconCreator_Button_Click"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Challenges Theme" HorizontalAlignment="Left" Height="155" Margin="10,327,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
|
||||
<Grid>
|
||||
<Label Content="Watermark:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,-1"/>
|
||||
<TextBox x:Name="WatermarkChallenge_TextBox" Height="19" Margin="69,4,263,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF" TextChanged="UpdateChallengeCustomTheme"/>
|
||||
|
||||
<Label Content="Colors:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,82,0,0"/>
|
||||
<Button x:Name="PrimaryColor_Button" Content="Primary" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="124" Margin="0,0,393,29" IsEnabled="False" Click="PrimaryColor_Button_Click"/>
|
||||
<Button x:Name="SecondaryColor_Button" Content="Secondary" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="124" Margin="0,0,263,29" IsEnabled="False" Click="SecondaryColor_Button_Click"/>
|
||||
|
||||
<Button x:Name="AddBanner_Button" Content="+" HorizontalAlignment="Right" Margin="0,0,438,59" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="AddBanner_Button_Click"/>
|
||||
<Label x:Name="Banner_Label" Content="File Name: " MaxWidth="155" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="148,55,0,0"/>
|
||||
<Button x:Name="DeleteBanner_Button" Content="-" HorizontalAlignment="Right" Margin="0,0,414,59" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="DeleteBanner_Button_Click"/>
|
||||
|
||||
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,111,0,-3"/>
|
||||
<Slider x:Name="OpacityBanner_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateChallengeCustomTheme" HorizontalAlignment="Left" Margin="57,112,0,0" VerticalAlignment="Top" Maximum="255" Width="242" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
|
||||
<CheckBox x:Name="bCustomChallenge" Content="Custom Theme" HorizontalAlignment="Left" Margin="6,59,0,0" VerticalAlignment="Top" Checked="EnableDisableCustomTheme" Unchecked="EnableDisableCustomTheme"/>
|
||||
<Border BorderThickness="1" Background="#FF252D36" HorizontalAlignment="Right" Height="105" Width="258" VerticalAlignment="Top" Margin="0,3,0,0">
|
||||
<Image x:Name="ImageBox_ChallengePreview" Source="/FModel;component/Resources/Template_Challenge.png" UseLayoutRounding="True"/>
|
||||
</Border>
|
||||
<Button x:Name="OpenChallengeTheme_Button" Content="Open Image" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="258" Click="OpenChallengeTheme_Button_Click" Margin="0,0,0,3"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
576
FModel/Forms/FModel_Settings.xaml.cs
Normal file
576
FModel/Forms/FModel_Settings.xaml.cs
Normal file
|
|
@ -0,0 +1,576 @@
|
|||
using FModel.Methods.MessageBox;
|
||||
using System.Windows;
|
||||
using System;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
using System.Windows.Controls;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using FModel.Methods.Assets;
|
||||
using FModel.Methods;
|
||||
using System.Windows.Media.Imaging;
|
||||
using FModel.Methods.Utilities;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Ookii.Dialogs.Wpf;
|
||||
using System.Globalization;
|
||||
using FModel.Methods.Assets.IconCreator;
|
||||
using ColorPickerWPF;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_Settings.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_Settings : Window
|
||||
{
|
||||
public FModel_Settings()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
}
|
||||
|
||||
#region ENUMS
|
||||
enum LIndexes
|
||||
{
|
||||
[Description("English")]
|
||||
English = 0,
|
||||
[Description("French")]
|
||||
French = 1,
|
||||
[Description("German")]
|
||||
German = 2,
|
||||
[Description("Italian")]
|
||||
Italian = 3,
|
||||
[Description("Spanish")]
|
||||
Spanish = 4,
|
||||
[Description("Spanish (LA)")]
|
||||
Spanish_LA = 5,
|
||||
[Description("Arabic")]
|
||||
Arabic = 6,
|
||||
[Description("Japanese")]
|
||||
Japanese = 7,
|
||||
[Description("Korean")]
|
||||
Korean = 8,
|
||||
[Description("Polish")]
|
||||
Polish = 9,
|
||||
[Description("Portuguese (Brazil)")]
|
||||
Portuguese_Brazil = 10,
|
||||
[Description("Russian")]
|
||||
Russian = 11,
|
||||
[Description("Turkish")]
|
||||
Turkish = 12,
|
||||
[Description("Chinese (S)")]
|
||||
Chinese_S = 13,
|
||||
[Description("Traditional Chinese")]
|
||||
Traditional_Chinese = 14
|
||||
}
|
||||
|
||||
enum RIndexes
|
||||
{
|
||||
[Description("Default")]
|
||||
Default = 0,
|
||||
[Description("Flat")]
|
||||
Flat = 1,
|
||||
[Description("Minimalist")]
|
||||
Minimalist = 2
|
||||
}
|
||||
|
||||
public static T GetEnumValueFromDescription<T>(string description)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (!type.IsEnum) { throw new ArgumentException(); }
|
||||
FieldInfo[] fields = type.GetFields();
|
||||
var field = fields
|
||||
.SelectMany(f => f.GetCustomAttributes(
|
||||
typeof(DescriptionAttribute), false), (
|
||||
f, a) => new { Field = f, Att = a })
|
||||
.Where(a => ((DescriptionAttribute)a.Att)
|
||||
.Description == description).SingleOrDefault();
|
||||
return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FoldersUtility.CheckWatermark();
|
||||
GetUserSettings();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SetUserSettings();
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void GetUserSettings()
|
||||
{
|
||||
InputTextBox.Text = FProp.Default.FPak_Path;
|
||||
bDiffFileSize.IsChecked = FProp.Default.FDiffFileSize;
|
||||
OutputTextBox.Text = FProp.Default.FOutput_Path;
|
||||
|
||||
ComboBox_Language.SelectedIndex = (int)GetEnumValueFromDescription<LIndexes>(FProp.Default.FLanguage);
|
||||
ComboBox_Design.SelectedIndex = (int)GetEnumValueFromDescription<RIndexes>(FProp.Default.FRarity_Design);
|
||||
|
||||
bFeaturedIcon.IsChecked = FProp.Default.FIsFeatured;
|
||||
bWatermarkIcon.IsChecked = FProp.Default.FUseWatermark;
|
||||
Watermark_Label.Content += Path.GetFileName(FProp.Default.FWatermarkFilePath);
|
||||
|
||||
Opacity_Slider.Value = FProp.Default.FWatermarkOpacity;
|
||||
Scale_Slider.Value = FProp.Default.FWatermarkScale;
|
||||
xPos_Slider.Value = FProp.Default.FWatermarkXPos;
|
||||
yPos_Slider.Value = FProp.Default.FWatermarkYPos;
|
||||
|
||||
WatermarkChallenge_TextBox.Text = FProp.Default.FChallengeWatermark;
|
||||
bCustomChallenge.IsChecked = FProp.Default.FUseChallengeWatermark;
|
||||
Banner_Label.Content += Path.GetFileName(FProp.Default.FBannerFilePath);
|
||||
OpacityBanner_Slider.Value = FProp.Default.FBannerOpacity;
|
||||
|
||||
await UpdateImageWithWatermark();
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
|
||||
private void SetUserSettings()
|
||||
{
|
||||
if (!string.Equals(FProp.Default.FPak_Path, InputTextBox.Text))
|
||||
{
|
||||
FProp.Default.FPak_Path = InputTextBox.Text;
|
||||
DarkMessageBox.Show("Please, restart FModel to apply your new input path", "FModel Input Path Changed", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
FProp.Default.FDiffFileSize = (bool)bDiffFileSize.IsChecked;
|
||||
|
||||
if (!string.Equals(FProp.Default.FOutput_Path, OutputTextBox.Text))
|
||||
{
|
||||
FProp.Default.FOutput_Path = OutputTextBox.Text;
|
||||
DarkMessageBox.Show("Please, restart FModel to apply your new output path", "FModel Output Path Changed", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
if (AssetEntries.AssetEntriesDict != null && !string.Equals(FProp.Default.FLanguage, ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString()))
|
||||
{
|
||||
AssetTranslations.SetAssetTranslation(((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString());
|
||||
}
|
||||
FProp.Default.FLanguage = ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString();
|
||||
|
||||
FProp.Default.FRarity_Design = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
|
||||
FProp.Default.FIsFeatured = (bool)bFeaturedIcon.IsChecked;
|
||||
FProp.Default.FUseWatermark = (bool)bWatermarkIcon.IsChecked;
|
||||
|
||||
FProp.Default.FWatermarkOpacity = Convert.ToInt32(Opacity_Slider.Value);
|
||||
FProp.Default.FWatermarkScale = Scale_Slider.Value;
|
||||
FProp.Default.FWatermarkXPos = xPos_Slider.Value;
|
||||
FProp.Default.FWatermarkYPos = yPos_Slider.Value;
|
||||
|
||||
FProp.Default.FChallengeWatermark = WatermarkChallenge_TextBox.Text;
|
||||
FProp.Default.FUseChallengeWatermark = (bool)bCustomChallenge.IsChecked;
|
||||
FProp.Default.FBannerOpacity = Convert.ToInt32(OpacityBanner_Slider.Value);
|
||||
|
||||
FProp.Default.Save();
|
||||
}
|
||||
|
||||
private async void UpdateImageBox(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
private async void EnableDisableWatermark(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenFile_Button.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
xPos_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
yPos_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
Opacity_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
Scale_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
private void EnableDisableCustomTheme(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AddBanner_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
DeleteBanner_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
PrimaryColor_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
SecondaryColor_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
OpacityBanner_Slider.IsEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
private async void UpdateImageWithWatermark(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
private async Task UpdateImageWithWatermark()
|
||||
{
|
||||
bool watermarkEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
string rarityDesign = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
|
||||
bool isFeatured = (bool)bFeaturedIcon.IsChecked;
|
||||
int opacity = Convert.ToInt32(Opacity_Slider.Value);
|
||||
double scale = Scale_Slider.Value;
|
||||
double xPos = xPos_Slider.Value;
|
||||
double yPos = yPos_Slider.Value;
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
DrawingVisual drawingVisual = new DrawingVisual();
|
||||
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
|
||||
{
|
||||
//INITIALIZATION
|
||||
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(515, 515)));
|
||||
|
||||
BitmapImage source = null;
|
||||
switch (rarityDesign)
|
||||
{
|
||||
case "Default":
|
||||
source = new BitmapImage(new Uri(isFeatured ? "pack://application:,,,/Resources/Template_D_F.png" : "pack://application:,,,/Resources/Template_D_N.png"));
|
||||
break;
|
||||
case "Flat":
|
||||
source = new BitmapImage(new Uri(isFeatured ? "pack://application:,,,/Resources/Template_F_F.png" : "pack://application:,,,/Resources/Template_F_N.png"));
|
||||
break;
|
||||
case "Minimalist":
|
||||
source = new BitmapImage(new Uri(isFeatured ? "pack://application:,,,/Resources/Template_M_F.png" : "pack://application:,,,/Resources/Template_M_N.png"));
|
||||
break;
|
||||
}
|
||||
drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(515, 515)));
|
||||
|
||||
if (!string.IsNullOrEmpty(FProp.Default.FWatermarkFilePath) && watermarkEnabled)
|
||||
{
|
||||
using (StreamReader image = new StreamReader(FProp.Default.FWatermarkFilePath))
|
||||
{
|
||||
if (image != null)
|
||||
{
|
||||
BitmapImage bmp = new BitmapImage();
|
||||
bmp.BeginInit();
|
||||
bmp.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bmp.StreamSource = image.BaseStream;
|
||||
bmp.EndInit();
|
||||
|
||||
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(xPos, yPos, scale, scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drawingVisual != null)
|
||||
{
|
||||
RenderTargetBitmap RTB = new RenderTargetBitmap(515, 515, 96, 96, PixelFormats.Pbgra32);
|
||||
RTB.Render(drawingVisual);
|
||||
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
|
||||
|
||||
FWindow.FMain.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
ImageBox_RarityPreview.Source = BitmapFrame.Create(RTB); //thread safe and fast af
|
||||
});
|
||||
}
|
||||
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
});
|
||||
}
|
||||
private void UpdateChallengeCustomTheme(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
private void UpdateChallengeCustomTheme()
|
||||
{
|
||||
bool watermarkEnabled = (bool)bCustomChallenge.IsChecked;
|
||||
string watermark = WatermarkChallenge_TextBox.Text;
|
||||
string path = FProp.Default.FBannerFilePath;
|
||||
int opacity = Convert.ToInt32(OpacityBanner_Slider.Value);
|
||||
string[] primaryParts = FProp.Default.FPrimaryColor.Split(':');
|
||||
string[] secondaryParts = FProp.Default.FSecondaryColor.Split(':');
|
||||
SolidColorBrush PrimaryColor = new SolidColorBrush(Color.FromRgb(Convert.ToByte(primaryParts[0]), Convert.ToByte(primaryParts[1]), Convert.ToByte(primaryParts[2])));
|
||||
SolidColorBrush SecondaryColor = new SolidColorBrush(Color.FromRgb(Convert.ToByte(secondaryParts[0]), Convert.ToByte(secondaryParts[1]), Convert.ToByte(secondaryParts[2])));
|
||||
|
||||
if (watermarkEnabled)
|
||||
{
|
||||
DrawingVisual drawingVisual = new DrawingVisual();
|
||||
double PPD = VisualTreeHelper.GetDpi(drawingVisual).PixelsPerDip;
|
||||
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
|
||||
{
|
||||
//INITIALIZATION
|
||||
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(1024, 410)));
|
||||
|
||||
Point dStart = new Point(0, 256);
|
||||
LineSegment[] dSegments = new[]
|
||||
{
|
||||
new LineSegment(new Point(1024, 256), true),
|
||||
new LineSegment(new Point(1024, 241), true),
|
||||
new LineSegment(new Point(537, 236), true),
|
||||
new LineSegment(new Point(547, 249), true),
|
||||
new LineSegment(new Point(0, 241), true)
|
||||
};
|
||||
PathFigure dFigure = new PathFigure(dStart, dSegments, true);
|
||||
PathGeometry dGeo = new PathGeometry(new[] { dFigure });
|
||||
|
||||
Typeface typeface = new Typeface(TextsUtility.Burbank, FontStyles.Normal, FontWeights.Black, FontStretches.Normal);
|
||||
FormattedText formattedText =
|
||||
new FormattedText(
|
||||
"{BUNDLE DISPLAY NAME HERE}",
|
||||
CultureInfo.CurrentUICulture,
|
||||
FlowDirection.LeftToRight,
|
||||
typeface,
|
||||
55,
|
||||
Brushes.White,
|
||||
PPD
|
||||
);
|
||||
formattedText.TextAlignment = TextAlignment.Left;
|
||||
formattedText.MaxTextWidth = 768;
|
||||
formattedText.MaxLineCount = 1;
|
||||
Point textLocation = new Point(50, 165 - formattedText.Height);
|
||||
|
||||
drawingContext.DrawRectangle(PrimaryColor, null, new Rect(0, 0, 1024, 256));
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
BitmapImage bmp = new BitmapImage(new Uri(path));
|
||||
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(0, 0, 1024, 256));
|
||||
}
|
||||
drawingContext.DrawGeometry(SecondaryColor, null, dGeo);
|
||||
drawingContext.DrawText(formattedText, textLocation);
|
||||
|
||||
formattedText =
|
||||
new FormattedText(
|
||||
"{LAST FOLDER HERE}",
|
||||
CultureInfo.CurrentUICulture,
|
||||
FlowDirection.LeftToRight,
|
||||
typeface,
|
||||
30,
|
||||
SecondaryColor,
|
||||
IconCreator.PPD
|
||||
);
|
||||
formattedText.TextAlignment = TextAlignment.Left;
|
||||
formattedText.MaxTextWidth = 768;
|
||||
formattedText.MaxLineCount = 1;
|
||||
textLocation = new Point(50, 100 - formattedText.Height);
|
||||
Geometry geometry = formattedText.BuildGeometry(textLocation);
|
||||
Pen pen = new Pen(ChallengesUtility.DarkBrush(SecondaryColor, 0.3f), 1);
|
||||
pen.LineJoin = PenLineJoin.Round;
|
||||
drawingContext.DrawGeometry(SecondaryColor, pen, geometry);
|
||||
|
||||
typeface = new Typeface(TextsUtility.FBurbank, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
|
||||
formattedText =
|
||||
new FormattedText(
|
||||
watermark,
|
||||
CultureInfo.CurrentUICulture,
|
||||
FlowDirection.LeftToRight,
|
||||
typeface,
|
||||
20,
|
||||
new SolidColorBrush(Color.FromArgb(150, 255, 255, 255)),
|
||||
IconCreator.PPD
|
||||
);
|
||||
formattedText.TextAlignment = TextAlignment.Right;
|
||||
formattedText.MaxTextWidth = 1014;
|
||||
formattedText.MaxLineCount = 1;
|
||||
textLocation = new Point(0, 205);
|
||||
drawingContext.DrawText(formattedText, textLocation);
|
||||
|
||||
LinearGradientBrush linGrBrush = new LinearGradientBrush();
|
||||
linGrBrush.StartPoint = new Point(0, 0);
|
||||
linGrBrush.EndPoint = new Point(0, 1);
|
||||
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(75, SecondaryColor.Color.R, SecondaryColor.Color.G, SecondaryColor.Color.B), 0));
|
||||
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(25, PrimaryColor.Color.R, PrimaryColor.Color.G, PrimaryColor.Color.B), 0.15));
|
||||
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0, 0, 0, 0), 1));
|
||||
|
||||
drawingContext.DrawRectangle(ChallengesUtility.DarkBrush(PrimaryColor, 0.3f), null, new Rect(0, 256, 1024, 144));
|
||||
drawingContext.DrawRectangle(linGrBrush, null, new Rect(0, 256, 1024, 144));
|
||||
|
||||
typeface = new Typeface(TextsUtility.Burbank, FontStyles.Normal, FontWeights.Black, FontStretches.Normal);
|
||||
int y = 300;
|
||||
|
||||
drawingContext.DrawRectangle(ChallengesUtility.DarkBrush(PrimaryColor, 0.3f), null, new Rect(0, y, 1024, 90));
|
||||
drawingContext.DrawRectangle(PrimaryColor, null, new Rect(25, y, 1024 - 50, 70));
|
||||
|
||||
dStart = new Point(32, y + 5);
|
||||
dSegments = new[]
|
||||
{
|
||||
new LineSegment(new Point(29, y + 67), true),
|
||||
new LineSegment(new Point(1024 - 160, y + 62), true),
|
||||
new LineSegment(new Point(1024 - 150, y + 4), true)
|
||||
};
|
||||
dFigure = new PathFigure(dStart, dSegments, true);
|
||||
dGeo = new PathGeometry(new[] { dFigure });
|
||||
drawingContext.DrawGeometry(ChallengesUtility.LightBrush(PrimaryColor, 0.04f), null, dGeo);
|
||||
|
||||
drawingContext.DrawRectangle(SecondaryColor, null, new Rect(60, y + 47, 500, 7));
|
||||
|
||||
dStart = new Point(39, y + 35);
|
||||
dSegments = new[]
|
||||
{
|
||||
new LineSegment(new Point(45, y + 32), true),
|
||||
new LineSegment(new Point(48, y + 37), true),
|
||||
new LineSegment(new Point(42, y + 40), true)
|
||||
};
|
||||
dFigure = new PathFigure(dStart, dSegments, true);
|
||||
dGeo = new PathGeometry(new[] { dFigure });
|
||||
drawingContext.DrawGeometry(SecondaryColor, null, dGeo);
|
||||
}
|
||||
|
||||
if (drawingVisual != null)
|
||||
{
|
||||
RenderTargetBitmap RTB = new RenderTargetBitmap(1024, 410, 96, 96, PixelFormats.Pbgra32);
|
||||
RTB.Render(drawingVisual);
|
||||
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
|
||||
|
||||
FWindow.FMain.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
ImageBox_ChallengePreview.Source = BitmapFrame.Create(RTB); //thread safe and fast af
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BitmapImage source = new BitmapImage(new Uri("pack://application:,,,/Resources/Template_Challenge.png"));
|
||||
ImageBox_ChallengePreview.Source = source;
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenIconCreator_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImageBox_RarityPreview.Source != null)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Icon Template"))
|
||||
{
|
||||
Window win = new Window();
|
||||
win.Title = "Icon Template";
|
||||
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
win.Width = ImageBox_RarityPreview.Source.Width;
|
||||
win.Height = ImageBox_RarityPreview.Source.Height;
|
||||
|
||||
DockPanel dockPanel = new DockPanel
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
Image img = new Image();
|
||||
img.UseLayoutRounding = true;
|
||||
img.Source = ImageBox_RarityPreview.Source;
|
||||
dockPanel.Children.Add(img);
|
||||
|
||||
win.Content = dockPanel;
|
||||
win.Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Icon Template").Focus(); }
|
||||
}
|
||||
}
|
||||
|
||||
private async void OpenFile_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFiledialog = new Microsoft.Win32.OpenFileDialog();
|
||||
openFiledialog.Title = "Choose your watermark";
|
||||
openFiledialog.Multiselect = false;
|
||||
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
|
||||
if (openFiledialog.ShowDialog() == true)
|
||||
{
|
||||
Watermark_Label.Content = "File Name: " + Path.GetFileName(openFiledialog.FileName);
|
||||
FProp.Default.FWatermarkFilePath = openFiledialog.FileName;
|
||||
FProp.Default.Save();
|
||||
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
}
|
||||
|
||||
private void BrowseInput_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
|
||||
dialog.Description = "Please select a folder.";
|
||||
dialog.UseDescriptionForTitle = true; // This applies to the Vista style dialog only, not the old dialog.
|
||||
|
||||
if ((bool)dialog.ShowDialog(this))
|
||||
{
|
||||
InputTextBox.Text = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private void BrowseOutput_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
|
||||
dialog.Description = "Please select a folder.";
|
||||
dialog.UseDescriptionForTitle = true; // This applies to the Vista style dialog only, not the old dialog.
|
||||
|
||||
if ((bool)dialog.ShowDialog(this))
|
||||
{
|
||||
OutputTextBox.Text = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenChallengeTheme_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImageBox_ChallengePreview.Source != null)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Challenge Theme Template"))
|
||||
{
|
||||
Window win = new Window();
|
||||
win.Title = "Challenge Theme Template";
|
||||
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
|
||||
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
win.Width = ImageBox_ChallengePreview.Source.Width;
|
||||
win.Height = ImageBox_ChallengePreview.Source.Height;
|
||||
|
||||
DockPanel dockPanel = new DockPanel
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
|
||||
Image img = new Image();
|
||||
img.UseLayoutRounding = true;
|
||||
img.Source = ImageBox_ChallengePreview.Source;
|
||||
dockPanel.Children.Add(img);
|
||||
|
||||
win.Content = dockPanel;
|
||||
win.Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Challenge Theme Template").Focus(); }
|
||||
}
|
||||
}
|
||||
|
||||
private void PrimaryColor_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Color color;
|
||||
bool ok = ColorPickerWindow.ShowDialog(out color);
|
||||
if (ok)
|
||||
{
|
||||
FProp.Default.FPrimaryColor = color.R + ":" + color.G + ":" + color.B;
|
||||
FProp.Default.Save();
|
||||
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
}
|
||||
|
||||
private void SecondaryColor_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Color color;
|
||||
bool ok = ColorPickerWindow.ShowDialog(out color);
|
||||
if (ok)
|
||||
{
|
||||
FProp.Default.FSecondaryColor = color.R + ":" + color.G + ":" + color.B;
|
||||
FProp.Default.Save();
|
||||
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddBanner_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Microsoft.Win32.OpenFileDialog openFiledialog = new Microsoft.Win32.OpenFileDialog();
|
||||
openFiledialog.Title = "Choose your banner";
|
||||
openFiledialog.Multiselect = false;
|
||||
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
|
||||
if (openFiledialog.ShowDialog() == true)
|
||||
{
|
||||
Banner_Label.Content = "File Name: " + Path.GetFileName(openFiledialog.FileName);
|
||||
FProp.Default.FBannerFilePath = openFiledialog.FileName;
|
||||
FProp.Default.Save();
|
||||
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteBanner_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Banner_Label.Content = "File Name: ";
|
||||
FProp.Default.FBannerFilePath = string.Empty;
|
||||
FProp.Default.Save();
|
||||
|
||||
UpdateChallengeCustomTheme();
|
||||
}
|
||||
}
|
||||
}
|
||||
559
FModel/Forms/HexViewer/BaseByte.cs
Normal file
559
FModel/Forms/HexViewer/BaseByte.cs
Normal file
|
|
@ -0,0 +1,559 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Base author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
// Contributor : emes30
|
||||
// Notice : The idea to make a base class with common bytecontrol code is taken
|
||||
// from emes30 fork (https://github.com/emes30/WpfHexEditorControl)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using WpfHexaEditor.Core;
|
||||
using WpfHexaEditor.Core.Interfaces;
|
||||
|
||||
namespace WpfHexaEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for bytecontrol
|
||||
/// </summary>
|
||||
abstract class BaseByte : FrameworkElement, IByteControl
|
||||
{
|
||||
#region Global class variables
|
||||
protected readonly HexEditor _parent;
|
||||
private bool _isSelected;
|
||||
private ByteAction _action = ByteAction.Nothing;
|
||||
private byte? _byte;
|
||||
private bool _isHighLight;
|
||||
#endregion global class variables
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler ByteModified;
|
||||
public event EventHandler MouseSelection;
|
||||
public event EventHandler Click;
|
||||
public event EventHandler RightClick;
|
||||
public event EventHandler DoubleClick;
|
||||
public event EventHandler MoveNext;
|
||||
public event EventHandler MovePrevious;
|
||||
public event EventHandler MoveRight;
|
||||
public event EventHandler MoveLeft;
|
||||
public event EventHandler MoveUp;
|
||||
public event EventHandler MoveDown;
|
||||
public event EventHandler MovePageDown;
|
||||
public event EventHandler MovePageUp;
|
||||
public event EventHandler ByteDeleted;
|
||||
public event EventHandler EscapeKey;
|
||||
public event EventHandler CtrlzKey;
|
||||
public event EventHandler CtrlvKey;
|
||||
public event EventHandler CtrlcKey;
|
||||
public event EventHandler CtrlaKey;
|
||||
public event EventHandler CtrlyKey;
|
||||
|
||||
#endregion Events
|
||||
|
||||
#region Constructor
|
||||
|
||||
protected BaseByte(HexEditor parent)
|
||||
{
|
||||
//Parent hexeditor
|
||||
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
|
||||
#region Binding tooltip
|
||||
|
||||
LoadDictionary("/FModel;component/Forms/HexViewer/ToolTipDictionary.xaml");
|
||||
var txtBinding = new Binding
|
||||
{
|
||||
Source = FindResource("ByteToolTip"),
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
|
||||
Mode = BindingMode.OneWay
|
||||
};
|
||||
|
||||
// Load ressources dictionnary
|
||||
void LoadDictionary(string url)
|
||||
{
|
||||
var ttRes = new ResourceDictionary { Source = new Uri(url, UriKind.Relative) };
|
||||
Resources.MergedDictionaries.Add(ttRes);
|
||||
}
|
||||
|
||||
SetBinding(ToolTipProperty, txtBinding);
|
||||
|
||||
#endregion
|
||||
|
||||
//Default properties
|
||||
DataContext = this;
|
||||
Focusable = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Position in file
|
||||
/// </summary>
|
||||
public long BytePositionInStream { get; set; } = -1L;
|
||||
|
||||
/// <summary>
|
||||
/// Used for selection coloring
|
||||
/// </summary>
|
||||
public bool FirstSelected { protected get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to prevent ByteModified event occurc when we dont want!
|
||||
/// </summary>
|
||||
public bool InternalChange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get or set if control as in read only mode
|
||||
/// </summary>
|
||||
public bool ReadOnlyMode { protected get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the description to shown in tooltip
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return true if mouse is over... (Used with traverse methods via IByteControl)
|
||||
/// </summary>
|
||||
public bool IsMouseOverMe { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get or Set if control as selected
|
||||
/// </summary>
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set
|
||||
{
|
||||
if (value == _isSelected) return;
|
||||
|
||||
_isSelected = value;
|
||||
UpdateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get of Set if control as marked as highlighted
|
||||
/// </summary>
|
||||
public bool IsHighLight
|
||||
{
|
||||
get => _isHighLight;
|
||||
set
|
||||
{
|
||||
if (value == _isHighLight) return;
|
||||
|
||||
_isHighLight = value;
|
||||
UpdateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Byte used for this instance
|
||||
/// </summary>
|
||||
public byte? Byte
|
||||
{
|
||||
get => _byte;
|
||||
set
|
||||
{
|
||||
_byte = value;
|
||||
|
||||
if (Action != ByteAction.Nothing && InternalChange == false)
|
||||
ByteModified?.Invoke(this, new EventArgs());
|
||||
|
||||
UpdateTextRenderFromByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action with this byte
|
||||
/// </summary>
|
||||
public ByteAction Action
|
||||
{
|
||||
get => _action;
|
||||
set
|
||||
{
|
||||
_action = value != ByteAction.All ? value : ByteAction.Nothing;
|
||||
|
||||
UpdateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
protected FormattedText TextFormatted { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private base properties
|
||||
|
||||
/// <summary>
|
||||
/// Definie the foreground
|
||||
/// </summary>
|
||||
private static readonly DependencyProperty ForegroundProperty =
|
||||
TextElement.ForegroundProperty.AddOwner(
|
||||
typeof(BaseByte));
|
||||
|
||||
protected Brush Foreground
|
||||
{
|
||||
get => (Brush)GetValue(ForegroundProperty);
|
||||
set => SetValue(ForegroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty BackgroundProperty =
|
||||
TextElement.BackgroundProperty.AddOwner(typeof(BaseByte),
|
||||
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Defines the background
|
||||
/// </summary>
|
||||
protected Brush Background
|
||||
{
|
||||
get => (Brush)GetValue(BackgroundProperty);
|
||||
set => SetValue(BackgroundProperty, value);
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty TextProperty =
|
||||
DependencyProperty.Register(nameof(Text), typeof(string), typeof(BaseByte),
|
||||
new FrameworkPropertyMetadata(string.Empty,
|
||||
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Text to be displayed representation of Byte
|
||||
/// </summary>
|
||||
protected string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(typeof(BaseByte));
|
||||
|
||||
/// <summary>
|
||||
/// The FontWeight property specifies the weight of the font.
|
||||
/// </summary>
|
||||
protected FontWeight FontWeight
|
||||
{
|
||||
get => (FontWeight)GetValue(FontWeightProperty);
|
||||
set => SetValue(FontWeightProperty, value);
|
||||
}
|
||||
|
||||
#endregion Base properties
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Update Background,foreground and font property
|
||||
/// </summary>
|
||||
public virtual void UpdateVisual()
|
||||
{
|
||||
if (IsSelected)
|
||||
{
|
||||
FontWeight = _parent.FontWeight;
|
||||
Foreground = _parent.ForegroundContrast;
|
||||
|
||||
Background = FirstSelected
|
||||
? _parent.SelectionFirstColor
|
||||
: _parent.SelectionSecondColor;
|
||||
}
|
||||
else if (IsHighLight)
|
||||
{
|
||||
FontWeight = _parent.FontWeight;
|
||||
Foreground = _parent.Foreground;
|
||||
Background = _parent.HighLightColor;
|
||||
}
|
||||
else if (Action != ByteAction.Nothing)
|
||||
{
|
||||
FontWeight = FontWeights.Bold;
|
||||
Foreground = _parent.Foreground;
|
||||
|
||||
switch (Action)
|
||||
{
|
||||
case ByteAction.Modified:
|
||||
Background = _parent.ByteModifiedColor;
|
||||
break;
|
||||
case ByteAction.Deleted:
|
||||
Background = _parent.ByteDeletedColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var cbb = _parent.GetCustomBackgroundBlock(BytePositionInStream);
|
||||
|
||||
Description = cbb != null ? cbb.Description : "";
|
||||
|
||||
Background = cbb != null ? cbb.Color : Brushes.Transparent;
|
||||
Foreground = _parent.GetColumnNumber(BytePositionInStream) % 2 == 0
|
||||
? _parent.Foreground
|
||||
: _parent.ForegroundSecondColor;
|
||||
|
||||
FontWeight = _parent.FontWeight;
|
||||
}
|
||||
|
||||
UpdateAutoHighLiteSelectionByteVisual();
|
||||
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Auto highlite SelectionByte
|
||||
/// </summary>
|
||||
protected void UpdateAutoHighLiteSelectionByteVisual()
|
||||
{
|
||||
if (_parent.AllowAutoHighLightSelectionByte && _parent.SelectionByte != null &&
|
||||
Byte == _parent.SelectionByte && !IsSelected)
|
||||
Background = _parent.AutoHighLiteSelectionByteBrush;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the render of text derived bytecontrol from byte property
|
||||
/// </summary>
|
||||
public abstract void UpdateTextRenderFromByte();
|
||||
|
||||
/// <summary>
|
||||
/// Clear control
|
||||
/// </summary>
|
||||
public virtual void Clear()
|
||||
{
|
||||
InternalChange = true;
|
||||
BytePositionInStream = -1;
|
||||
Byte = null;
|
||||
Action = ByteAction.Nothing;
|
||||
IsSelected = false;
|
||||
InternalChange = false;
|
||||
Description = string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events delegate
|
||||
|
||||
/// <summary>
|
||||
/// Render the control
|
||||
/// </summary>
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
//Draw background
|
||||
if (Background != null)
|
||||
dc.DrawRectangle(Background, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
|
||||
|
||||
//Draw text
|
||||
var typeface = new Typeface(_parent.FontFamily, _parent.FontStyle, FontWeight, _parent.FontStretch);
|
||||
|
||||
var formattedText = new FormattedText(Text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
|
||||
typeface, _parent.FontSize, Foreground, VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||
|
||||
dc.DrawText(formattedText, new Point(2, 2));
|
||||
|
||||
//#if DEBUG && NET47
|
||||
// //FOR HELP TO DEBUG HIDEBYTEDELETED ONLY...
|
||||
// if (_parent.HideByteDeleted && BytePositionInStream < 10000 && Core.Bytes.ByteConverters.IsHexValue(Text).success)
|
||||
// {
|
||||
// var formattedText2 = new FormattedText(BytePositionInStream.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
|
||||
// typeface, 8, Brushes.Green, VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||
|
||||
// dc.DrawText(formattedText2, new Point(0, 10));
|
||||
// }
|
||||
//#endif
|
||||
|
||||
//Update properties
|
||||
TextFormatted = formattedText;
|
||||
}
|
||||
|
||||
protected override void OnMouseEnter(MouseEventArgs e)
|
||||
{
|
||||
if (Byte != null && !IsSelected && !IsHighLight &&
|
||||
Action != ByteAction.Modified &&
|
||||
Action != ByteAction.Deleted &&
|
||||
Action != ByteAction.Added)
|
||||
Background = _parent.MouseOverColor;
|
||||
|
||||
UpdateAutoHighLiteSelectionByteVisual();
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
MouseSelection?.Invoke(this, e);
|
||||
|
||||
IsMouseOverMe = true;
|
||||
|
||||
base.OnMouseEnter(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(MouseEventArgs e)
|
||||
{
|
||||
var cbb = _parent.GetCustomBackgroundBlock(BytePositionInStream);
|
||||
|
||||
if (Byte != null && !IsSelected && !IsHighLight &&
|
||||
Action != ByteAction.Modified &&
|
||||
Action != ByteAction.Deleted &&
|
||||
Action != ByteAction.Added)
|
||||
Background = Brushes.Transparent;
|
||||
|
||||
if (cbb != null && !IsSelected && !IsHighLight &&
|
||||
Action != ByteAction.Modified &&
|
||||
Action != ByteAction.Deleted &&
|
||||
Action != ByteAction.Added)
|
||||
Background = cbb.Color;
|
||||
|
||||
IsMouseOverMe = false;
|
||||
|
||||
UpdateAutoHighLiteSelectionByteVisual();
|
||||
|
||||
base.OnMouseLeave(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
if (!IsFocused)
|
||||
Focus();
|
||||
|
||||
switch (e.ClickCount)
|
||||
{
|
||||
case 1:
|
||||
Click?.Invoke(this, e);
|
||||
break;
|
||||
case 2:
|
||||
DoubleClick?.Invoke(this, e);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (e.RightButton == MouseButtonState.Pressed)
|
||||
RightClick?.Invoke(this, e);
|
||||
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnToolTipOpening(ToolTipEventArgs e)
|
||||
{
|
||||
if (Byte == null || !_parent.ShowByteToolTip)
|
||||
e.Handled = true;
|
||||
|
||||
base.OnToolTipOpening(e);
|
||||
}
|
||||
|
||||
protected override void OnLostFocus(RoutedEventArgs e)
|
||||
{
|
||||
_parent.HideCaret();
|
||||
base.OnLostFocus(e);
|
||||
}
|
||||
|
||||
protected void OnMoveNext(EventArgs e) => MoveNext?.Invoke(this, e);
|
||||
|
||||
protected bool KeyValidation(KeyEventArgs e)
|
||||
{
|
||||
#region Key validation and launch event if needed
|
||||
|
||||
if (KeyValidator.IsUpKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MoveUp?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsDownKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MoveDown?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsLeftKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MoveLeft?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsRightKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MoveRight?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsPageDownKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MovePageDown?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsPageUpKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
MovePageUp?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (KeyValidator.IsDeleteKey(e.Key))
|
||||
{
|
||||
if (!ReadOnlyMode)
|
||||
{
|
||||
e.Handled = true;
|
||||
ByteDeleted?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (KeyValidator.IsBackspaceKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
ByteDeleted?.Invoke(this, new EventArgs());
|
||||
|
||||
MovePrevious?.Invoke(this, new EventArgs());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsEscapeKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
EscapeKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsCtrlZKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
CtrlzKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsCtrlYKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
CtrlyKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsCtrlVKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
CtrlvKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsCtrlCKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
CtrlcKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
else if (KeyValidator.IsCtrlAKey(e.Key))
|
||||
{
|
||||
e.Handled = true;
|
||||
CtrlaKey?.Invoke(this, new EventArgs());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
15
FModel/Forms/HexViewer/BrushesDictionary.xaml
Normal file
15
FModel/Forms/HexViewer/BrushesDictionary.xaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!--
|
||||
Apache 2.0 - 2016-2018
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!-- THIS DICTIONARY IS USED FOR PUT CUSTOM BRUSH -->
|
||||
|
||||
<SolidColorBrush x:Key="BookMarkColor" Color="#B20000FF" />
|
||||
<SolidColorBrush x:Key="SearchBookMarkColor" Color="#FFFF8B00" />
|
||||
<SolidColorBrush x:Key="SelectionStartBookMarkColor" Color="Blue" />
|
||||
<SolidColorBrush x:Key="ByteModifiedMarkColor" Color="#CC68717C" />
|
||||
<SolidColorBrush x:Key="ByteDeletedMarkColor" Color="#B2FF0000" />
|
||||
</ResourceDictionary>
|
||||
40
FModel/Forms/HexViewer/Core/BookMark.cs
Normal file
40
FModel/Forms/HexViewer/Core/BookMark.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// BookMark class
|
||||
/// </summary>
|
||||
public sealed class BookMark
|
||||
{
|
||||
public ScrollMarker Marker { get; set; } = ScrollMarker.Nothing;
|
||||
public long BytePositionInStream { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public BookMark() { }
|
||||
|
||||
public BookMark(string description, long position)
|
||||
{
|
||||
BytePositionInStream = position;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public BookMark(string description, long position, ScrollMarker marker)
|
||||
{
|
||||
BytePositionInStream = position;
|
||||
Description = description;
|
||||
Marker = marker;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representation
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString() => $"({ByteConverters.LongToHex(BytePositionInStream)}h){Description}";
|
||||
}
|
||||
}
|
||||
255
FModel/Forms/HexViewer/Core/Bytes/ByteConverters.cs
Normal file
255
FModel/Forms/HexViewer/Core/Bytes/ByteConverters.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WpfHexaEditor.Core.Bytes
|
||||
{
|
||||
/// <summary>
|
||||
/// ByteCharConverter for convert data
|
||||
/// </summary>
|
||||
public static class ByteConverters
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert long to hex value
|
||||
/// </summary>
|
||||
public static string LongToHex(long val, OffSetPanelFixedWidth offsetwight = OffSetPanelFixedWidth.Dynamic) =>
|
||||
val.ToString(offsetwight == OffSetPanelFixedWidth.Dynamic
|
||||
? ConstantReadOnly.HexStringFormat
|
||||
: ConstantReadOnly.HexLineInfoStringFormat
|
||||
, CultureInfo.InvariantCulture);
|
||||
|
||||
public static string LongToString(long val, int saveBits = -1)
|
||||
{
|
||||
if (saveBits == -1) return val.ToString();
|
||||
|
||||
//Char[] with fixed size is always
|
||||
var chs = new char[saveBits];
|
||||
for (int i = 1; i <= saveBits; i++)
|
||||
{
|
||||
chs[saveBits - i] = (char)(val % 10 + 48);
|
||||
val /= 10;
|
||||
}
|
||||
return new string(chs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert Byte to Char (can be used as visible text)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Code from : https://github.com/pleonex/tinke/blob/master/Be.Windows.Forms.HexBox/ByteCharConverters.cs
|
||||
/// </remarks>
|
||||
public static char ByteToChar(byte val) => val > 0x1F && !(val > 0x7E && val < 0xA0) ? (char)val : '.';
|
||||
|
||||
/// <summary>
|
||||
/// Convert Char to Byte
|
||||
/// </summary>
|
||||
public static byte CharToByte(char val) => (byte)val;
|
||||
|
||||
/// <summary>
|
||||
/// Converts a byte array to a hex string. For example: {10,11} = "0A 0B"
|
||||
/// </summary>
|
||||
public static string ByteToHex(byte[] data)
|
||||
{
|
||||
if (data == null) return string.Empty;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var b in data)
|
||||
{
|
||||
var hex = ByteToHex(b);
|
||||
sb.Append(hex);
|
||||
sb.Append(" ");
|
||||
}
|
||||
|
||||
if (sb.Length > 0)
|
||||
sb.Remove(sb.Length - 1, 1);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a byte to char[2].
|
||||
/// </summary>
|
||||
public static char[] ByteToHexCharArray(byte val)
|
||||
{
|
||||
var hexbyteArray = new char[2];
|
||||
ByteToHexCharArray(val, hexbyteArray);
|
||||
return hexbyteArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill the <paramref name="charArr"/> with hex char;
|
||||
/// </summary>
|
||||
/// <param name="charArr">The length of this value should be 2.</param>
|
||||
public static void ByteToHexCharArray(byte val, char[] charArr)
|
||||
{
|
||||
if (charArr == null)
|
||||
throw new ArgumentNullException(nameof(charArr));
|
||||
|
||||
if (charArr.Length != 2)
|
||||
throw new ArgumentException($"The length of {charArr} should be 2.");
|
||||
|
||||
charArr[0] = ByteToHexChar(val >> 4);
|
||||
charArr[1] = ByteToHexChar(val - ((val >> 4) << 4));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a byte to Hex char,i.e,10 = 'A'
|
||||
/// </summary>
|
||||
public static char ByteToHexChar(int val)
|
||||
{
|
||||
if (val < 10)
|
||||
{
|
||||
return (char)(48 + val);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (val)
|
||||
{
|
||||
case 10:
|
||||
return 'A';
|
||||
case 11:
|
||||
return 'B';
|
||||
case 12:
|
||||
return 'C';
|
||||
case 13:
|
||||
return 'D';
|
||||
case 14:
|
||||
return 'E';
|
||||
case 15:
|
||||
return 'F';
|
||||
default:
|
||||
return 's';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the byte to a hex string. For example: "10" = "0A";
|
||||
/// </summary>
|
||||
public static string ByteToHex(byte val) => new string(ByteToHexCharArray(val));
|
||||
|
||||
/// <summary>
|
||||
/// Convert byte to ASCII string
|
||||
/// </summary>
|
||||
public static string BytesToString(byte[] buffer, ByteToString converter = ByteToString.ByteToCharProcess)
|
||||
{
|
||||
if (buffer == null) return string.Empty;
|
||||
|
||||
switch (converter)
|
||||
{
|
||||
case ByteToString.AsciiEncoding:
|
||||
return Encoding.ASCII.GetString(buffer, 0, buffer.Length);
|
||||
|
||||
case ByteToString.ByteToCharProcess:
|
||||
var builder = new StringBuilder();
|
||||
|
||||
foreach (var @byte in buffer)
|
||||
builder.Append(ByteToChar(@byte));
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the hex string to an byte array. The hex string must be separated by a space char ' '. If there is any invalid hex information in the string the result will be null.
|
||||
/// </summary>
|
||||
public static byte[] HexToByte(string hex)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hex)) return null;
|
||||
|
||||
hex = hex.Trim();
|
||||
var hexArray = hex.Split(' ');
|
||||
var byteArray = new byte[hexArray.Length];
|
||||
|
||||
for (var i = 0; i < hexArray.Length; i++)
|
||||
{
|
||||
var hexValue = hexArray[i];
|
||||
var (isByte, val) = HexToUniqueByte(hexValue);
|
||||
|
||||
if (!isByte) return null;
|
||||
|
||||
byteArray[i] = val;
|
||||
}
|
||||
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return Tuple (bool, byte) that bool represent if is a byte
|
||||
/// </summary>
|
||||
public static (bool success, byte val) HexToUniqueByte(string hex) =>
|
||||
(byte.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var val), val);
|
||||
|
||||
/// <summary>
|
||||
/// Convert a hex string to long.
|
||||
/// </summary>
|
||||
/// <return>
|
||||
/// Return (true, [position])
|
||||
/// Return (false, -1) on error
|
||||
/// </return>
|
||||
public static (bool success, long position) HexLiteralToLong(string hex)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hex)) return (false, -1);
|
||||
|
||||
var i = hex.Length > 1 && hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')
|
||||
? 2
|
||||
: 0;
|
||||
|
||||
long value = 0;
|
||||
|
||||
while (i < hex.Length)
|
||||
{
|
||||
#region convert
|
||||
|
||||
int x = hex[i++];
|
||||
|
||||
if
|
||||
(x >= '0' && x <= '9') x -= '0';
|
||||
else if
|
||||
(x >= 'A' && x <= 'F') x -= 'A' + 10;
|
||||
else if
|
||||
(x >= 'a' && x <= 'f') x -= 'a' + 10;
|
||||
else
|
||||
return (false, -1);
|
||||
|
||||
value = 16 * value + x;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
return (true, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if is an hexa string
|
||||
/// </summary>
|
||||
public static (bool success, long value) IsHexValue(string hexastring) => HexLiteralToLong(hexastring);
|
||||
|
||||
/// <summary>
|
||||
/// Check if is an hexa byte string
|
||||
/// </summary>
|
||||
public static (bool success, byte[] value) IsHexaByteStringValue(string hexastring) =>
|
||||
HexToByte(hexastring) == null
|
||||
? (false, null)
|
||||
: (true, byteArray: HexToByte(hexastring));
|
||||
|
||||
/// <summary>
|
||||
/// Convert string to byte array
|
||||
/// </summary>
|
||||
public static byte[] StringToByte(string str) => str.Select(CharToByte).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Convert String to hex string For example: "barn" = "62 61 72 6e"
|
||||
/// </summary>
|
||||
public static string StringToHex(string str) => ByteToHex(StringToByte(str));
|
||||
}
|
||||
}
|
||||
100
FModel/Forms/HexViewer/Core/Bytes/ByteModified.cs
Normal file
100
FModel/Forms/HexViewer/Core/Bytes/ByteModified.cs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using WpfHexaEditor.Core.Interfaces;
|
||||
|
||||
namespace WpfHexaEditor.Core.Bytes
|
||||
{
|
||||
public class ByteModified : IByteModified
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Default contructor
|
||||
/// </summary>
|
||||
public ByteModified() { }
|
||||
|
||||
/// <summary>
|
||||
/// complete contructor
|
||||
/// </summary>
|
||||
public ByteModified(byte? val, ByteAction action, long bytePositionInStream, long undoLength)
|
||||
{
|
||||
Byte = val;
|
||||
Action = action;
|
||||
BytePositionInStream = bytePositionInStream;
|
||||
Length = undoLength;
|
||||
}
|
||||
|
||||
#endregion constructor
|
||||
|
||||
#region properties
|
||||
|
||||
/// <summary>
|
||||
/// Byte mofidied
|
||||
/// </summary>
|
||||
public byte? Byte { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action have made in this byte
|
||||
/// </summary>
|
||||
public ByteAction Action { get; set; } = ByteAction.Nothing;
|
||||
|
||||
/// <summary>
|
||||
/// Get of Set te position in file
|
||||
/// </summary>
|
||||
public long BytePositionInStream { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Number of byte to undo when this byte is reach
|
||||
/// </summary>
|
||||
public long Length { get; set; } = 1;
|
||||
|
||||
#endregion properties
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Check if the object is valid and data can be used for action
|
||||
/// </summary>
|
||||
public bool IsValid => BytePositionInStream > -1 && Action != ByteAction.Nothing && Byte != null;
|
||||
|
||||
/// <summary>
|
||||
/// String representation of byte
|
||||
/// </summary>
|
||||
public override string ToString() =>
|
||||
$"ByteModified - Action:{Action} Position:{BytePositionInStream} Byte:{Byte}";
|
||||
|
||||
/// <summary>
|
||||
/// Clear object
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
Byte = null;
|
||||
Action = ByteAction.Nothing;
|
||||
BytePositionInStream = -1;
|
||||
Length = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy Current instance to another
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ByteModified GetCopy() => new ByteModified
|
||||
{
|
||||
Action = Action,
|
||||
Byte = Byte,
|
||||
Length = Length,
|
||||
BytePositionInStream = BytePositionInStream
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get if bytemodified is valid
|
||||
/// </summary>
|
||||
public static bool CheckIsValid(ByteModified byteModified) => byteModified != null && byteModified.IsValid;
|
||||
|
||||
#endregion Methods
|
||||
|
||||
}
|
||||
}
|
||||
1725
FModel/Forms/HexViewer/Core/Bytes/ByteProvider.cs
Normal file
1725
FModel/Forms/HexViewer/Core/Bytes/ByteProvider.cs
Normal file
File diff suppressed because it is too large
Load Diff
277
FModel/Forms/HexViewer/Core/Caret.cs
Normal file
277
FModel/Forms/HexViewer/Core/Caret.cs
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
//////////////////////////////////////////////
|
||||
// Fork 2017 : Derek Tremblay (derektremblay666@gmail.com)
|
||||
// Part of Wpf HexEditor control : https://github.com/abbaye/WPFHexEditorControl
|
||||
// Reference : https://www.codeproject.com/Tips/431000/Caret-for-WPF-User-Controls
|
||||
// Reference license : The Code Project Open License (CPOL) 1.02
|
||||
// Contributor : emes30
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Threading;
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represent a visual caret on editor
|
||||
/// </summary>
|
||||
public sealed class Caret : FrameworkElement, INotifyPropertyChanged
|
||||
{
|
||||
#region Global class variables
|
||||
private Timer _timer;
|
||||
private Point _position;
|
||||
private readonly Pen _pen = new Pen(Brushes.Black, 1);
|
||||
private readonly Brush _brush = new SolidColorBrush(Colors.Black);
|
||||
private int _blinkPeriod = 500;
|
||||
private double _caretHeight = 18;
|
||||
private double _caretWidth = 9;
|
||||
private bool _hide;
|
||||
private CaretMode _caretMode = CaretMode.Overwrite;
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public Caret()
|
||||
{
|
||||
if (!DesignerProperties.GetIsInDesignMode(this))
|
||||
{
|
||||
_pen.Freeze();
|
||||
_brush.Opacity = .5;
|
||||
IsHitTestVisible = false;
|
||||
InitializeTimer();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public Caret(Brush brush)
|
||||
{
|
||||
if (!DesignerProperties.GetIsInDesignMode(this))
|
||||
{
|
||||
_pen.Brush = brush;
|
||||
_pen.Freeze();
|
||||
_brush.Opacity = .5;
|
||||
IsHitTestVisible = false;
|
||||
InitializeTimer();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
private static readonly DependencyProperty VisibleProperty =
|
||||
DependencyProperty.Register(nameof(Visible), typeof(bool),
|
||||
typeof(Caret), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Get is caret is running
|
||||
/// </summary>
|
||||
public bool IsEnable => _timer != null;
|
||||
|
||||
/// <summary>
|
||||
/// Propertie used when caret is blinking
|
||||
/// </summary>
|
||||
private bool Visible
|
||||
{
|
||||
get => (bool)GetValue(VisibleProperty);
|
||||
set => SetValue(VisibleProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Height of the caret
|
||||
/// </summary>
|
||||
public double CaretHeight
|
||||
{
|
||||
get => _caretHeight;
|
||||
set
|
||||
{
|
||||
if (_caretHeight == value) return;
|
||||
|
||||
_caretHeight = value;
|
||||
|
||||
//InitializeTimer();
|
||||
|
||||
OnPropertyChanged(nameof(CaretHeight));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Width of the caret
|
||||
/// </summary>
|
||||
public double CaretWidth
|
||||
{
|
||||
get => _caretWidth;
|
||||
set
|
||||
{
|
||||
if (_caretWidth == value) return;
|
||||
|
||||
_caretWidth = value;
|
||||
|
||||
OnPropertyChanged(nameof(CaretWidth));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the relative position of the caret
|
||||
/// </summary>
|
||||
public Point Position => _position;
|
||||
|
||||
/// <summary>
|
||||
/// Left position of the caret
|
||||
/// </summary>
|
||||
public double Left
|
||||
{
|
||||
get => _position.X;
|
||||
private set
|
||||
{
|
||||
if (_position.X == value) return;
|
||||
|
||||
_position.X = Math.Floor(value);
|
||||
if (Visible) Visible = false;
|
||||
|
||||
OnPropertyChanged(nameof(Position));
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Top position of the caret
|
||||
/// </summary>
|
||||
public double Top
|
||||
{
|
||||
get => _position.Y;
|
||||
private set
|
||||
{
|
||||
if (_position.Y == value) return;
|
||||
|
||||
_position.Y = Math.Floor(value);
|
||||
if (Visible) Visible = false;
|
||||
|
||||
OnPropertyChanged(nameof(Position));
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Properties return true if caret is visible
|
||||
/// </summary>
|
||||
public bool IsVisibleCaret => Left >= 0 && Top > 0 && _hide == false;
|
||||
|
||||
/// <summary>
|
||||
/// Blick period in millisecond
|
||||
/// </summary>
|
||||
public int BlinkPeriod
|
||||
{
|
||||
get => _blinkPeriod;
|
||||
set
|
||||
{
|
||||
_blinkPeriod = value;
|
||||
InitializeTimer();
|
||||
|
||||
OnPropertyChanged(nameof(BlinkPeriod));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caret display mode. Line for Insert, Block for Overwrite
|
||||
/// </summary>
|
||||
public CaretMode CaretMode
|
||||
{
|
||||
get => _caretMode;
|
||||
set
|
||||
{
|
||||
if (_caretMode == value) return;
|
||||
|
||||
_caretMode = value;
|
||||
|
||||
OnPropertyChanged(nameof(CaretMode));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Hide the caret
|
||||
/// </summary>
|
||||
public void Hide() => _hide = true;
|
||||
|
||||
/// <summary>
|
||||
/// Method delegate for blink the caret
|
||||
/// </summary>
|
||||
private void BlinkCaret(Object state) => Dispatcher?.Invoke(() =>
|
||||
{
|
||||
Visible = !Visible && !_hide;
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Initialise the timer
|
||||
/// </summary>
|
||||
private void InitializeTimer() => _timer = new Timer(BlinkCaret, null, 0, BlinkPeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Move the caret over the position defined by point parameter
|
||||
/// </summary>
|
||||
public void MoveCaret(Point point) => MoveCaret(point.X, point.Y);
|
||||
|
||||
/// <summary>
|
||||
/// Move the caret over the position defined by point parameter
|
||||
/// </summary>
|
||||
public void MoveCaret(double x, double y)
|
||||
{
|
||||
_hide = false;
|
||||
Left = x;
|
||||
Top = y;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start the caret
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
InitializeTimer();
|
||||
|
||||
_hide = false;
|
||||
|
||||
OnPropertyChanged(nameof(IsEnable));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the carret
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
Hide();
|
||||
_timer = null;
|
||||
|
||||
OnPropertyChanged(nameof(IsEnable));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render the caret
|
||||
/// </summary>
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
if (Visible)
|
||||
switch (_caretMode)
|
||||
{
|
||||
case CaretMode.Insert:
|
||||
dc.DrawLine(_pen, _position, new Point(Left, _position.Y + CaretHeight));
|
||||
break;
|
||||
case CaretMode.Overwrite:
|
||||
dc.DrawRectangle(_brush, _pen, new Rect(Left, _position.Y, _caretWidth, CaretHeight));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
164
FModel/Forms/HexViewer/Core/CharacterTable/DTE.cs
Normal file
164
FModel/Forms/HexViewer/Core/CharacterTable/DTE.cs
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2003-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
|
||||
namespace WpfHexaEditor.Core.CharacterTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Objet représentant un DTE.
|
||||
/// </summary>
|
||||
public sealed class Dte
|
||||
{
|
||||
/// <summary>Nom du DTE</summary>
|
||||
private string _entry;
|
||||
|
||||
#region Constructeurs
|
||||
|
||||
/// <summary>
|
||||
/// Constructeur principal
|
||||
/// </summary>
|
||||
public Dte()
|
||||
{
|
||||
_entry = string.Empty;
|
||||
Type = DteType.Invalid;
|
||||
Value = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contructeur permetant d'ajouter une entrée et une valeur
|
||||
/// </summary>
|
||||
/// <param name="entry">Nom du DTE</param>
|
||||
/// <param name="value">Valeur du DTE</param>
|
||||
public Dte(string entry, string value)
|
||||
{
|
||||
_entry = entry;
|
||||
Value = value;
|
||||
Type = DteType.DualTitleEncoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contructeur permetant d'ajouter une entrée, une valeur et une description
|
||||
/// </summary>
|
||||
/// <param name="entry">Nom du DTE</param>
|
||||
/// <param name="value">Valeur du DTE</param>
|
||||
/// <param name="type">Type de DTE</param>
|
||||
public Dte(string entry, string value, DteType type)
|
||||
{
|
||||
_entry = entry;
|
||||
Value = value;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
#endregion Constructeurs
|
||||
|
||||
#region Propriétés
|
||||
|
||||
/// <summary>
|
||||
/// Nom du DTE
|
||||
/// </summary>
|
||||
public string Entry
|
||||
{
|
||||
set => _entry = value != null ? value.ToUpper(): string.Empty;
|
||||
get => _entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Valeur du DTE
|
||||
/// </summary>
|
||||
public string Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Type de DTE
|
||||
/// </summary>
|
||||
public DteType Type { get; }
|
||||
|
||||
#endregion Propriétés
|
||||
|
||||
#region Méthodes
|
||||
|
||||
/// <summary>
|
||||
/// Cette fonction permet de retourner le DTE sous forme : [Entry]=[Valeur]
|
||||
/// </summary>
|
||||
/// <returns>Retourne le DTE sous forme : [Entry]=[Valeur]</returns>
|
||||
public override string ToString() => Type != DteType.EndBlock && Type != DteType.EndLine
|
||||
? _entry + "=" + Value
|
||||
: _entry;
|
||||
|
||||
#endregion Méthodes
|
||||
|
||||
#region Methodes Static
|
||||
|
||||
public static DteType TypeDte(Dte dteValue)
|
||||
{
|
||||
if (dteValue == null) return DteType.Invalid;
|
||||
|
||||
try
|
||||
{
|
||||
switch (dteValue._entry.Length)
|
||||
{
|
||||
case 2:
|
||||
return dteValue.Value.Length == 2 ? DteType.Ascii : DteType.DualTitleEncoding;
|
||||
case 4: // >2
|
||||
return DteType.MultipleTitleEncoding;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
switch (dteValue._entry)
|
||||
{
|
||||
case @"/":
|
||||
return DteType.EndBlock;
|
||||
|
||||
case @"*":
|
||||
return DteType.EndLine;
|
||||
//case @"\":
|
||||
}
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
//Du a une entre qui a 2 = de suite... EX: XX==
|
||||
return DteType.DualTitleEncoding;
|
||||
}
|
||||
|
||||
return DteType.Invalid;
|
||||
}
|
||||
|
||||
public static DteType TypeDte(string dteValue)
|
||||
{
|
||||
if (dteValue == null) return DteType.Invalid;
|
||||
|
||||
try
|
||||
{
|
||||
if (dteValue == FModel.Properties.Resources.EndTagString)
|
||||
return DteType.EndBlock; //<end>
|
||||
|
||||
if (dteValue == FModel.Properties.Resources.LineTagString)
|
||||
return DteType.EndLine; //<ln>
|
||||
|
||||
switch (dteValue.Length)
|
||||
{
|
||||
case 1:
|
||||
return DteType.Ascii;
|
||||
case 2:
|
||||
return DteType.DualTitleEncoding;
|
||||
}
|
||||
|
||||
if (dteValue.Length > 2)
|
||||
return DteType.MultipleTitleEncoding;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
//Du a une entre qui a 2 = de suite... EX: XX==
|
||||
return DteType.DualTitleEncoding;
|
||||
}
|
||||
|
||||
return DteType.Invalid;
|
||||
}
|
||||
|
||||
#endregion Methodes Static
|
||||
|
||||
}
|
||||
}
|
||||
30
FModel/Forms/HexViewer/Core/CharacterTable/Enum.cs
Normal file
30
FModel/Forms/HexViewer/Core/CharacterTable/Enum.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2003-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
namespace WpfHexaEditor.Core.CharacterTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of DTE used in TBL
|
||||
/// </summary>
|
||||
public enum DteType
|
||||
{
|
||||
Invalid = -1,
|
||||
Ascii = 0,
|
||||
Japonais,
|
||||
DualTitleEncoding,
|
||||
MultipleTitleEncoding,
|
||||
EndLine,
|
||||
EndBlock
|
||||
}
|
||||
|
||||
public enum DefaultCharacterTableType
|
||||
{
|
||||
Ascii,
|
||||
EbcdicWithSpecialChar,
|
||||
EbcdicNoSpecialChar
|
||||
//MACINTOSH
|
||||
//DOS/IBM-ASCII
|
||||
}
|
||||
}
|
||||
406
FModel/Forms/HexViewer/Core/CharacterTable/TBLStream.cs
Normal file
406
FModel/Forms/HexViewer/Core/CharacterTable/TBLStream.cs
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2003-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core.CharacterTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to manage Thingy TBL file (entry=value)
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "<En attente>")]
|
||||
public sealed class TblStream : IDisposable
|
||||
{
|
||||
#region Global class variables
|
||||
/// <summary>
|
||||
/// TBL file path
|
||||
/// </summary>
|
||||
private string _fileName = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represente the whole TBL file
|
||||
/// </summary>
|
||||
private Dictionary<string, Dte> _dteList = new Dictionary<string, Dte>();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Constructeur permétant de charg?le fichier DTE
|
||||
/// </summary>
|
||||
public TblStream(string fileName) => FileName = fileName;
|
||||
|
||||
/// <summary>
|
||||
/// Constructeur permétant de chargéle fichier DTE
|
||||
/// </summary>
|
||||
public TblStream() { }
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
|
||||
/// <summary>
|
||||
/// Indexer to work on the DTE contained in TBL in the manner of a table.
|
||||
/// </summary>
|
||||
public Dte this[string index]
|
||||
{
|
||||
get => _dteList[index];
|
||||
set => _dteList[index] = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Find entry in TBL file
|
||||
/// </summary>
|
||||
/// <param name="hex">Hex value to find match</param>
|
||||
/// <param name="showSpecialValue">Fin the Endblock and EndLine</param>
|
||||
public string FindMatch(string hex, bool showSpecialValue)
|
||||
{
|
||||
if (showSpecialValue)
|
||||
{
|
||||
if (_dteList.ContainsKey($"/{hex}")) return FModel.Properties.Resources.EndTagString; //"<end>";
|
||||
if (_dteList.ContainsKey($"*{hex}")) return FModel.Properties.Resources.LineTagString; //"<ln>";
|
||||
}
|
||||
|
||||
return _dteList.ContainsKey(hex)
|
||||
? _dteList[hex].Value
|
||||
: "#";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert data to TBL string.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Return string converted to TBL string representation.
|
||||
/// Return null on error
|
||||
/// </returns>
|
||||
public string ToTblString(byte[] data)
|
||||
{
|
||||
if (data == null) return null;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i < data.Length - 1)
|
||||
{
|
||||
var mte = FindMatch(ByteConverters.ByteToHex(data[i]) + ByteConverters.ByteToHex(data[i + 1]), true);
|
||||
|
||||
if (mte != "#")
|
||||
{
|
||||
sb.Append(mte);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(FindMatch(ByteConverters.ByteToHex(data[i]), true));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the TBL and clear object
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
_fileName = string.Empty;
|
||||
_dteList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the TBL file
|
||||
/// </summary>
|
||||
private void Load(string tblString)
|
||||
{
|
||||
//Variables
|
||||
char[] sepEndLine = {'\n'}; //end line char
|
||||
char[] sepEqual = {'='}; //equal separator char
|
||||
|
||||
//build strings line
|
||||
var textFromString = new StringBuilder(tblString);
|
||||
textFromString.Insert(textFromString.Length, new[] { '\r', '\n' });
|
||||
var lines = textFromString.ToString().Split(sepEndLine);
|
||||
|
||||
//Clear before loading
|
||||
_dteList.Clear();
|
||||
|
||||
#region Fill dtelist dictionary
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var info = line.Split(sepEqual);
|
||||
|
||||
Dte dte;
|
||||
try
|
||||
{
|
||||
switch (info[0].Length)
|
||||
{
|
||||
case 2:
|
||||
dte = info[1].Length == 2
|
||||
? new Dte(info[0], info[1].Substring(0, info[1].Length - 1), DteType.Ascii)
|
||||
: new Dte(info[0], info[1].Substring(0, info[1].Length - 1),
|
||||
DteType.DualTitleEncoding);
|
||||
break;
|
||||
case 4: // >2
|
||||
dte = new Dte(info[0], info[1].Substring(0, info[1].Length - 1),
|
||||
DteType.MultipleTitleEncoding);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
switch (info[0].Substring(0, 1))
|
||||
{
|
||||
case @"/":
|
||||
dte = new Dte(info[0].Substring(0, info[0].Length - 1), string.Empty, DteType.EndBlock);
|
||||
break;
|
||||
case @"*":
|
||||
dte = new Dte(info[0].Substring(0, info[0].Length - 1), string.Empty, DteType.EndLine);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
//Occurs when two == are in the same line
|
||||
dte = new Dte(info[0], "=", DteType.DualTitleEncoding);
|
||||
}
|
||||
|
||||
_dteList.Add(dte.Entry, dte);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Load bookmark
|
||||
BookMarks.Clear();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (line.Substring(0, 1) == "(")
|
||||
{
|
||||
var fav = new BookMark();
|
||||
var lineSplited = line.Split(')');
|
||||
fav.Description = lineSplited[1].Substring(0, lineSplited[1].Length - 1);
|
||||
|
||||
lineSplited = line.Split('h');
|
||||
fav.BytePositionInStream =
|
||||
ByteConverters.HexLiteralToLong(lineSplited[0].Substring(1, lineSplited[0].Length - 1)).position;
|
||||
fav.Marker = ScrollMarker.TblBookmark;
|
||||
BookMarks.Add(fav);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Nothing to add if error
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load TBL file
|
||||
/// </summary>
|
||||
private void Load()
|
||||
{
|
||||
//ouverture du fichier
|
||||
if (!File.Exists(_fileName))
|
||||
{
|
||||
var fs = File.Create(_fileName);
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
StreamReader tblFile;
|
||||
try
|
||||
{
|
||||
tblFile = new StreamReader(_fileName, Encoding.ASCII);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (tblFile.BaseStream.CanRead)
|
||||
Load(tblFile.ReadToEnd());
|
||||
|
||||
tblFile.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save tbl file
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
var myFile = new FileStream(_fileName, FileMode.Create, FileAccess.Write);
|
||||
var tblFile = new StreamWriter(myFile, Encoding.Unicode); //ASCII
|
||||
|
||||
if (tblFile.BaseStream.CanWrite)
|
||||
{
|
||||
//Save tbl set
|
||||
foreach (var dte in _dteList)
|
||||
if (dte.Value.Type != DteType.EndBlock &&
|
||||
dte.Value.Type != DteType.EndLine)
|
||||
tblFile.WriteLine(dte.Value.Entry + "=" + dte.Value);
|
||||
else
|
||||
tblFile.WriteLine(dte.Value.Entry);
|
||||
|
||||
//Save bookmark
|
||||
tblFile.WriteLine();
|
||||
foreach (var mark in BookMarks)
|
||||
tblFile.WriteLine(mark.ToString());
|
||||
|
||||
//Add to line at end of file. Needed for some apps that using tbl file
|
||||
tblFile.WriteLine();
|
||||
tblFile.WriteLine();
|
||||
}
|
||||
|
||||
//close file
|
||||
tblFile.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a DTE/MTE in TBL
|
||||
/// </summary>
|
||||
public void Add(Dte dte) => _dteList.Add(dte.Entry, dte);
|
||||
|
||||
/// <summary>
|
||||
/// Remove TBL entry
|
||||
/// </summary>
|
||||
/// <param name="dte"></param>
|
||||
public void Remove(Dte dte) => _dteList.Remove(dte.Entry);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Property
|
||||
/// <summary>
|
||||
/// Get or set the File path to TBL
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get => _fileName;
|
||||
internal set
|
||||
{
|
||||
if (File.Exists(value))
|
||||
{
|
||||
_fileName = value;
|
||||
Load();
|
||||
}
|
||||
else
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the count of DTE/MTE in the TBL
|
||||
/// </summary>
|
||||
public int Length => _dteList.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Get of set bookmarks
|
||||
/// </summary>
|
||||
public List<BookMark> BookMarks { get; set; } = new List<BookMark>();
|
||||
|
||||
public int TotalDte => _dteList.Count(l => l.Value.Type == DteType.DualTitleEncoding);
|
||||
public int TotalMte => _dteList.Count(l => l.Value.Type == DteType.MultipleTitleEncoding);
|
||||
public int TotalAscii => _dteList.Count(l => l.Value.Type == DteType.Ascii);
|
||||
public int TotalInvalid => _dteList.Count(l => l.Value.Type == DteType.Invalid);
|
||||
public int TotalJaponais => _dteList.Count(l => l.Value.Type == DteType.Japonais);
|
||||
public int TotalEndLine => _dteList.Count(l => l.Value.Type == DteType.EndLine);
|
||||
public int TotalEndBlock => _dteList.Count(l => l.Value.Type == DteType.EndBlock);
|
||||
|
||||
/// <summary>
|
||||
/// Get the end block char
|
||||
/// </summary>
|
||||
public string EndBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var dte in _dteList)
|
||||
if (dte.Value.Type == DteType.EndBlock)
|
||||
return dte.Value.Entry;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the end line char
|
||||
/// </summary>
|
||||
public string EndLine
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var dte in _dteList)
|
||||
if (dte.Value.Type == DteType.EndLine)
|
||||
return dte.Value.Entry;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable/Disable Readonly on control.
|
||||
/// </summary>
|
||||
public bool AllowEdit { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Build default TBL
|
||||
|
||||
public static TblStream CreateDefaultTbl(DefaultCharacterTableType type = DefaultCharacterTableType.Ascii)
|
||||
{
|
||||
var tbl = new TblStream();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DefaultCharacterTableType.Ascii:
|
||||
for (byte i = 0; i < 255; i++)
|
||||
tbl.Add(new Dte(ByteConverters.ByteToHex(i).ToUpper(), $"{ByteConverters.ByteToChar(i)}"));
|
||||
break;
|
||||
case DefaultCharacterTableType.EbcdicWithSpecialChar:
|
||||
tbl.Load(FModel.Properties.Resources.EBCDIC);
|
||||
break;
|
||||
case DefaultCharacterTableType.EbcdicNoSpecialChar:
|
||||
tbl.Load(FModel.Properties.Resources.EBCDIC_NoSpecialChar);
|
||||
break;
|
||||
}
|
||||
|
||||
tbl.AllowEdit = true;
|
||||
return tbl;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Support
|
||||
|
||||
private bool _disposedValue; // To detect redundant calls
|
||||
|
||||
void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_dteList = null;
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() => Dispose(true);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
23
FModel/Forms/HexViewer/Core/ConstantReadOnly.cs
Normal file
23
FModel/Forms/HexViewer/Core/ConstantReadOnly.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
public static class ConstantReadOnly
|
||||
{
|
||||
public static readonly string HexLineInfoStringFormat = "x8";
|
||||
public static readonly string HexStringFormat = "x";
|
||||
public static readonly string DefaultHex8String = "0x00000000";
|
||||
|
||||
public const long Largefilelength = 52_428_800L; //50 MB
|
||||
public const int Copyblocksize = 131_072; //128 KB
|
||||
public const int Findblocksize = 1_048_576; //1 MB
|
||||
|
||||
/// <summary>
|
||||
/// "D" may have the "widest" size
|
||||
/// </summary>
|
||||
public const char WidestChar = 'D';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WpfHexaEditor.Core.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Permet d'inverser des bool
|
||||
/// </summary>
|
||||
public sealed class BoolInverterConverter : GenericStaticInstance<BoolInverterConverter>,IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool? val = null;
|
||||
|
||||
try
|
||||
{
|
||||
val = value != null && (bool) value;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return !val;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WpfHexaEditor.Core.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// CODE FROM NUGET PACKAGE EXPLORER : https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
|
||||
///
|
||||
/// This BooleanToVisibility converter allows us to override the converted value when
|
||||
/// the bound value is false.
|
||||
///
|
||||
/// The built-in converter in WPF restricts us to always use Collapsed when the bound
|
||||
/// value is false.
|
||||
/// </summary>
|
||||
public sealed class BooleanToVisibilityConverter : GenericStaticInstance<BooleanToVisibilityConverter>,IValueConverter
|
||||
{
|
||||
public bool Inverted { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var boolValue = (bool) value;
|
||||
|
||||
if (Inverted)
|
||||
boolValue = !boolValue;
|
||||
|
||||
return (string) parameter == "hidden"
|
||||
? (boolValue ? Visibility.Visible : Visibility.Hidden)
|
||||
: (boolValue ? Visibility.Visible : Visibility.Collapsed);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to convert hexadecimal to Long value.
|
||||
/// </summary>
|
||||
public sealed class HexToLongStringConverter : GenericStaticInstance<HexToLongStringConverter> ,IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var (success, val) = ByteConverters.IsHexValue(value.ToString());
|
||||
|
||||
return success
|
||||
? (object) val
|
||||
: string.Empty;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WpfHexaEditor.Core.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to convert long value to hexadecimal string like this 0xFFFFFFFF.
|
||||
/// </summary>
|
||||
public sealed class LongToHexStringConverter : GenericStaticInstance<LongToHexStringConverter>,IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
value != null
|
||||
? (long.TryParse(value.ToString(), out var longValue)
|
||||
? (longValue > -1
|
||||
? "0x" + longValue
|
||||
.ToString(ConstantReadOnly.HexLineInfoStringFormat, CultureInfo.InvariantCulture)
|
||||
.ToUpper()
|
||||
: ConstantReadOnly.DefaultHex8String)
|
||||
: ConstantReadOnly.DefaultHex8String)
|
||||
: ConstantReadOnly.DefaultHex8String;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.IO;
|
||||
|
||||
namespace WpfHexaEditor.Core.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to get the filename with extention.
|
||||
/// </summary>
|
||||
public sealed class PathToFilenameConverter : GenericStaticInstance<PathToFilenameConverter> ,IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
(value is string filename)
|
||||
? Path.GetFileName(filename)
|
||||
: string.Empty;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
|
||||
}
|
||||
}
|
||||
209
FModel/Forms/HexViewer/Core/Enumeration.cs
Normal file
209
FModel/Forms/HexViewer/Core/Enumeration.cs
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// ByteAction used for ByteModified class
|
||||
/// </summary>
|
||||
public enum ByteAction
|
||||
{
|
||||
Nothing,
|
||||
Added,
|
||||
Deleted,
|
||||
Modified,
|
||||
|
||||
/// <summary>
|
||||
/// Used in ByteProvider for get list
|
||||
/// </summary>
|
||||
All
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for coloring mode of selection
|
||||
/// </summary>
|
||||
public enum FirstColor
|
||||
{
|
||||
HexByteData,
|
||||
StringByteData
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mode of Copy/Paste
|
||||
/// </summary>
|
||||
public enum CopyPasteMode
|
||||
{
|
||||
Byte,
|
||||
HexaString,
|
||||
AsciiString,
|
||||
TblString,
|
||||
CSharpCode,
|
||||
VbNetCode,
|
||||
JavaCode,
|
||||
CCode,
|
||||
FSharpCode,
|
||||
PascalCode
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used with Copy to code fonction for language are similar to C.
|
||||
/// </summary>
|
||||
internal enum CodeLanguage
|
||||
{
|
||||
C,
|
||||
CSharp,
|
||||
Java,
|
||||
FSharp,
|
||||
Vbnet,
|
||||
Pascal
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for check label are selected et next label to select...
|
||||
/// </summary>
|
||||
public enum KeyDownLabel
|
||||
{
|
||||
FirstChar,
|
||||
SecondChar,
|
||||
|
||||
//ThirdChar,
|
||||
NextPosition
|
||||
}
|
||||
|
||||
public enum ByteToString
|
||||
{
|
||||
/// <summary>
|
||||
/// Build-in convertion mode. (recommended)
|
||||
/// </summary>
|
||||
ByteToCharProcess,
|
||||
|
||||
/// <summary>
|
||||
/// System.Text.Encoding.ASCII string encoder
|
||||
/// </summary>
|
||||
AsciiEncoding
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrollbar marker
|
||||
/// </summary>
|
||||
public enum ScrollMarker
|
||||
{
|
||||
Nothing,
|
||||
SearchHighLight,
|
||||
Bookmark,
|
||||
SelectionStart,
|
||||
ByteModified,
|
||||
ByteDeleted,
|
||||
TblBookmark
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type are opened in byteprovider
|
||||
/// </summary>
|
||||
///[Obsolete("The ByteProviderStreamType is low extensible for variety of stream source,and will be removed in next release.")]
|
||||
public enum ByteProviderStreamType
|
||||
{
|
||||
File,
|
||||
MemoryStream,
|
||||
Nothing
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of character are used
|
||||
/// </summary>
|
||||
public enum CharacterTableType
|
||||
{
|
||||
Ascii,
|
||||
TblFile
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for control the speed of mouse wheel
|
||||
/// </summary>
|
||||
public enum MouseWheelSpeed
|
||||
{
|
||||
VerySlow = 1,
|
||||
Slow = 3,
|
||||
Normal = 5,
|
||||
Fast = 7,
|
||||
VeryFast = 9,
|
||||
System
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IByteControl spacer width
|
||||
/// </summary>
|
||||
public enum ByteSpacerWidth
|
||||
{
|
||||
VerySmall = 1,
|
||||
Small = 3,
|
||||
Normal = 6,
|
||||
Large = 9,
|
||||
VeryLarge = 12
|
||||
}
|
||||
|
||||
public enum ByteSpacerGroup
|
||||
{
|
||||
TwoByte = 2,
|
||||
FourByte = 4,
|
||||
SixByte = 6,
|
||||
EightByte = 8
|
||||
}
|
||||
|
||||
public enum ByteSpacerPosition
|
||||
{
|
||||
HexBytePanel,
|
||||
StringBytePanel,
|
||||
Both,
|
||||
Nothing
|
||||
}
|
||||
|
||||
public enum ByteSpacerVisual
|
||||
{
|
||||
Empty,
|
||||
Line,
|
||||
Dash
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used with the view mode of HexByte, header or position.
|
||||
/// </summary>
|
||||
public enum DataVisualType
|
||||
{
|
||||
Hexadecimal, //Editable
|
||||
Decimal //Not editable
|
||||
//Binary //Editable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to select the visual of the offset panel
|
||||
/// </summary>
|
||||
public enum OffSetPanelType
|
||||
{
|
||||
OffsetOnly,
|
||||
LineOnly,
|
||||
Both
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to fix the wigth of the offset panel
|
||||
/// </summary>
|
||||
public enum OffSetPanelFixedWidth
|
||||
{
|
||||
Dynamic,
|
||||
Fixed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use mode of the caret
|
||||
/// </summary>
|
||||
public enum CaretMode
|
||||
{
|
||||
Insert,
|
||||
Overwrite
|
||||
}
|
||||
}
|
||||
17
FModel/Forms/HexViewer/Core/GenericStaticInstance.cs
Normal file
17
FModel/Forms/HexViewer/Core/GenericStaticInstance.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2018
|
||||
// Author : Janus Tida
|
||||
//////////////////////////////////////////////
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is designed to simplify getting the instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class GenericStaticInstance<T> where T : class, new()
|
||||
{
|
||||
private static T _staticInstance;
|
||||
public static T StaticInstance => _staticInstance ?? (_staticInstance = new T());
|
||||
}
|
||||
}
|
||||
52
FModel/Forms/HexViewer/Core/Interfaces/IByteControl.cs
Normal file
52
FModel/Forms/HexViewer/Core/Interfaces/IByteControl.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2017-2019
|
||||
// Author : Janus Tida
|
||||
// Contributor : Derek Tremblay
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
|
||||
namespace WpfHexaEditor.Core.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// All byte control inherit from this interface.
|
||||
/// This interface is used to reduce the code when manipulate byte control
|
||||
/// </summary>
|
||||
internal interface IByteControl
|
||||
{
|
||||
//Properties
|
||||
long BytePositionInStream { get; set; }
|
||||
ByteAction Action { get; set; }
|
||||
byte? Byte { get; set; }
|
||||
bool IsHighLight { get; set; }
|
||||
bool IsSelected { get; set; }
|
||||
bool InternalChange { get; set; }
|
||||
bool IsMouseOverMe { get; }
|
||||
|
||||
//Methods
|
||||
void UpdateVisual();
|
||||
void Clear();
|
||||
|
||||
//Events
|
||||
event EventHandler ByteModified;
|
||||
event EventHandler MouseSelection;
|
||||
event EventHandler Click;
|
||||
event EventHandler DoubleClick;
|
||||
event EventHandler RightClick;
|
||||
event EventHandler MoveNext;
|
||||
event EventHandler MovePrevious;
|
||||
event EventHandler MoveRight;
|
||||
event EventHandler MoveLeft;
|
||||
event EventHandler MoveUp;
|
||||
event EventHandler MoveDown;
|
||||
event EventHandler MovePageDown;
|
||||
event EventHandler MovePageUp;
|
||||
event EventHandler ByteDeleted;
|
||||
event EventHandler EscapeKey;
|
||||
event EventHandler CtrlzKey;
|
||||
event EventHandler CtrlvKey;
|
||||
event EventHandler CtrlcKey;
|
||||
event EventHandler CtrlaKey;
|
||||
event EventHandler CtrlyKey;
|
||||
}
|
||||
}
|
||||
26
FModel/Forms/HexViewer/Core/Interfaces/IByteModified.cs
Normal file
26
FModel/Forms/HexViewer/Core/Interfaces/IByteModified.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2017
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core.Interfaces
|
||||
{
|
||||
public interface IByteModified
|
||||
{
|
||||
//Properties
|
||||
ByteAction Action { get; set; }
|
||||
|
||||
byte? Byte { get; set; }
|
||||
long BytePositionInStream { get; set; }
|
||||
bool IsValid { get; }
|
||||
long Length { get; set; }
|
||||
|
||||
//Methods
|
||||
void Clear();
|
||||
|
||||
ByteModified GetCopy();
|
||||
string ToString();
|
||||
}
|
||||
}
|
||||
179
FModel/Forms/HexViewer/Core/KeyValidator.cs
Normal file
179
FModel/Forms/HexViewer/Core/KeyValidator.cs
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using WpfHexaEditor.Core.Native;
|
||||
|
||||
namespace WpfHexaEditor.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class for valid keyboard key.
|
||||
/// </summary>
|
||||
public static class KeyValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Check if is a numeric key as pressed
|
||||
/// </summary>
|
||||
public static bool IsNumericKey(Key key)
|
||||
{
|
||||
return key == Key.D0 || key == Key.D1 || key == Key.D2 || key == Key.D3 || key == Key.D4 || key == Key.D5 ||
|
||||
key == Key.D6 || key == Key.D7 || key == Key.D8 || key == Key.D9 ||
|
||||
key == Key.NumPad0 || key == Key.NumPad1 || key == Key.NumPad2 || key == Key.NumPad3 ||
|
||||
key == Key.NumPad4 || key == Key.NumPad5 || key == Key.NumPad6 || key == Key.NumPad7 ||
|
||||
key == Key.NumPad8 || key == Key.NumPad9;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get if key is a Hexakey (alpha)
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsHexKey(Key key)
|
||||
{
|
||||
return key == Key.A || key == Key.B || key == Key.C || key == Key.D || key == Key.E || key == Key.F ||
|
||||
IsNumericKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the digit from key
|
||||
/// </summary>
|
||||
public static int GetDigitFromKey(Key key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Key.D0:
|
||||
case Key.NumPad0: return 0;
|
||||
case Key.D1:
|
||||
case Key.NumPad1: return 1;
|
||||
case Key.D2:
|
||||
case Key.NumPad2: return 2;
|
||||
case Key.D3:
|
||||
case Key.NumPad3: return 3;
|
||||
case Key.D4:
|
||||
case Key.NumPad4: return 4;
|
||||
case Key.D5:
|
||||
case Key.NumPad5: return 5;
|
||||
case Key.D6:
|
||||
case Key.NumPad6: return 6;
|
||||
case Key.D7:
|
||||
case Key.NumPad7: return 7;
|
||||
case Key.D8:
|
||||
case Key.NumPad8: return 8;
|
||||
case Key.D9:
|
||||
case Key.NumPad9: return 9;
|
||||
default: throw new ArgumentOutOfRangeException("Invalid key: " + key);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsIgnoredKey(Key key)
|
||||
{
|
||||
//ADD SOMES OTHER KEY FOR VALIDATED IN IBYTECONTROL
|
||||
|
||||
//DELETE KEY FOR ADD OTHER FUNCTIONALITY...
|
||||
|
||||
return key == Key.Tab ||
|
||||
key == Key.Enter ||
|
||||
key == Key.Return ||
|
||||
key == Key.LWin ||
|
||||
key == Key.RWin ||
|
||||
key == Key.CapsLock ||
|
||||
key == Key.LeftAlt ||
|
||||
key == Key.RightAlt ||
|
||||
key == Key.System ||
|
||||
key == Key.LeftCtrl ||
|
||||
key == Key.F1 || key == Key.F2 || key == Key.F3 || key == Key.F4 || key == Key.F5 || key == Key.F6 ||
|
||||
key == Key.F7 || key == Key.F8 || key == Key.F9 || key == Key.F10 || key == Key.F11 ||
|
||||
key == Key.F12 ||
|
||||
key == Key.Home ||
|
||||
key == Key.Insert ||
|
||||
key == Key.End;
|
||||
}
|
||||
|
||||
public static bool IsArrowKey(Key key) =>
|
||||
key == Key.Up || key == Key.Down || key == Key.Left || key == Key.Right;
|
||||
|
||||
public static bool IsBackspaceKey(Key key) => key == Key.Back;
|
||||
|
||||
public static bool IsSubstractKey(Key key) => key == Key.Subtract || key == Key.OemMinus;
|
||||
|
||||
public static bool IsDeleteKey(Key key) => key == Key.Delete;
|
||||
|
||||
public static bool IsCapsLock(Key key) => key == Key.CapsLock;
|
||||
|
||||
public static bool IsEscapeKey(Key key) => key == Key.Escape;
|
||||
|
||||
public static bool IsUpKey(Key key) => key == Key.Up;
|
||||
|
||||
public static bool IsWindowsKey(Key key) => key == Key.LWin || key == Key.RWin;
|
||||
|
||||
public static bool IsDownKey(Key key) => key == Key.Down;
|
||||
|
||||
public static bool IsRightKey(Key key) => key == Key.Right;
|
||||
|
||||
public static bool IsLeftKey(Key key) => key == Key.Left;
|
||||
|
||||
public static bool IsPageDownKey(Key key) => key == Key.PageDown;
|
||||
|
||||
public static bool IsPageUpKey(Key key) => key == Key.PageUp;
|
||||
|
||||
public static bool IsEnterKey(Key key) => key == Key.Enter;
|
||||
|
||||
public static bool IsTabKey(Key key) => key == Key.Tab;
|
||||
|
||||
public static bool IsCtrlCKey(Key key) => key == Key.C && Keyboard.Modifiers == ModifierKeys.Control;
|
||||
|
||||
public static bool IsCtrlZKey(Key key) => key == Key.Z && Keyboard.Modifiers == ModifierKeys.Control;
|
||||
|
||||
public static bool IsCtrlYKey(Key key) => key == Key.Y && Keyboard.Modifiers == ModifierKeys.Control;
|
||||
|
||||
public static bool IsCtrlVKey(Key key) => key == Key.V && Keyboard.Modifiers == ModifierKeys.Control;
|
||||
|
||||
public static bool IsCtrlAKey(Key key) => key == Key.A && Keyboard.Modifiers == ModifierKeys.Control;
|
||||
|
||||
#region DllImport/methods for key detection (Thank to : Inbar Barkai for help)
|
||||
|
||||
/// <summary>
|
||||
/// Capture character on different locale keyboards in WPF. Convert key to appropiate char?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Code from
|
||||
/// http://stackoverflow.com/questions/5825820/how-to-capture-the-character-on-different-locale-keyboards-in-wpf-c
|
||||
/// </remarks>
|
||||
/// <returns>return a char represent the key passed in parameter</returns>
|
||||
public static char GetCharFromKey(Key key)
|
||||
{
|
||||
var ch = ' ';
|
||||
|
||||
var virtualKey = KeyInterop.VirtualKeyFromKey(key);
|
||||
var keyboardState = new byte[256];
|
||||
NativeMethods.GetKeyboardState(keyboardState);
|
||||
|
||||
var scanCode = NativeMethods.MapVirtualKey((uint) virtualKey, NativeMethods.MapType.MapvkVkToVsc);
|
||||
var stringBuilder = new StringBuilder(2);
|
||||
|
||||
var result = NativeMethods.ToUnicode((uint) virtualKey, scanCode, keyboardState, stringBuilder,
|
||||
stringBuilder.Capacity, 0);
|
||||
switch (result)
|
||||
{
|
||||
case -1:
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ch = stringBuilder[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
ch = stringBuilder[0];
|
||||
break;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
#endregion DllImport for key detection (Thank to : Inbar Barkai for help)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace WpfHexaEditor.Core.MethodExtention
|
||||
{
|
||||
/// <summary>
|
||||
/// DoEvents when control is in long task. Control do not freeze the dispatcher.
|
||||
/// </summary>
|
||||
public static class ApplicationExtention
|
||||
{
|
||||
private static readonly DispatcherOperationCallback ExitFrameCallback = ExitFrame;
|
||||
|
||||
public static void DoEvents(this Application app, DispatcherPriority priority = DispatcherPriority.Background)
|
||||
{
|
||||
var nestedFrame = new DispatcherFrame();
|
||||
var exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(priority, ExitFrameCallback, nestedFrame);
|
||||
|
||||
try
|
||||
{
|
||||
//execute all next message
|
||||
Dispatcher.PushFrame(nestedFrame);
|
||||
|
||||
//If not completed, will stop it
|
||||
if (exitOperation.Status != DispatcherOperationStatus.Completed)
|
||||
exitOperation.Abort();
|
||||
}
|
||||
catch
|
||||
{
|
||||
exitOperation.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
private static object ExitFrame(object f)
|
||||
{
|
||||
(f as DispatcherFrame).Continue = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace WpfHexaEditor.Core.MethodExtention
|
||||
{
|
||||
/// <summary>
|
||||
/// Extention methodes for find match in byte[]
|
||||
/// </summary>
|
||||
public static class ByteArrayExtention
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds all index of byte find
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "<En attente>")]
|
||||
public static IEnumerable<long> FindIndexOf(this byte[] self, byte[] candidate)
|
||||
{
|
||||
if (!IsEmptyLocate(self, candidate))
|
||||
for (var i = 0; i < self.Length; i++)
|
||||
{
|
||||
if (!IsMatch(self, i, candidate))
|
||||
continue;
|
||||
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if match is finded
|
||||
/// </summary>
|
||||
private static bool IsMatch(byte[] array, long position, byte[] candidate) =>
|
||||
candidate.Length <= array.Length - position && !candidate.Where((t, i) => array[position + i] != t).Any();
|
||||
|
||||
/// <summary>
|
||||
/// Check if can find
|
||||
/// </summary>
|
||||
private static bool IsEmptyLocate(byte[] array, byte[] candidate) => array == null
|
||||
|| candidate == null
|
||||
|| array.Length == 0
|
||||
|| candidate.Length == 0
|
||||
|| candidate.Length > array.Length;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
|
||||
namespace WpfHexaEditor.Core.MethodExtention
|
||||
{
|
||||
public static class DoubleExtension
|
||||
{
|
||||
public static double Round(this double s, int digit = 2) => Math.Round(s, digit);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WpfHexaEditor.Core.MethodExtention
|
||||
{
|
||||
public static class StringExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// The screen size of a string
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Code from :
|
||||
/// https://stackoverflow.com/questions/11447019/is-there-any-way-to-find-the-width-of-a-character-in-a-fixed-width-font-given-t
|
||||
///
|
||||
/// Modified/adapted by Derek Tremblay
|
||||
/// </remarks>
|
||||
public static Size GetScreenSize(this string text, FontFamily fontFamily, double fontSize, FontStyle fontStyle,
|
||||
FontWeight fontWeight, FontStretch fontStretch, Brush foreGround)
|
||||
{
|
||||
fontFamily = new TextBlock().FontFamily;
|
||||
fontSize = fontSize > 0 ? fontSize : new TextBlock().FontSize;
|
||||
|
||||
var typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
|
||||
|
||||
var ft = new FormattedText(text ?? string.Empty, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
|
||||
typeface, fontSize, foreGround, VisualTreeHelper.GetDpi(Application.Current.MainWindow).PixelsPerDip);
|
||||
|
||||
|
||||
return new Size(ft.Width, ft.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace WpfHexaEditor.Core.MethodExtention
|
||||
{
|
||||
public static class TrackExtention
|
||||
{
|
||||
/// <summary>
|
||||
/// Get actual top position of track
|
||||
/// </summary>
|
||||
public static double Top(this Track track)
|
||||
{
|
||||
if (track.Parent is Grid parent)
|
||||
{
|
||||
var topRepeatButton = parent.Children[1] as RepeatButton;
|
||||
|
||||
return topRepeatButton.ActualHeight + parent.Margin.Top + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get actual bottom position of track
|
||||
/// </summary>
|
||||
public static double Bottom(this Track track)
|
||||
{
|
||||
if (track.Parent is Grid parent)
|
||||
{
|
||||
var trackControl = parent.Children[2] as Track;
|
||||
|
||||
return trackControl.Top() +
|
||||
trackControl.ActualHeight +
|
||||
parent.Margin.Top + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get actual bottom position of track
|
||||
/// </summary>
|
||||
public static double ButtonHeight(this Track track) => track.Top() - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Get actual Tick Height
|
||||
/// </summary>
|
||||
public static double TickHeight(this Track track) => track.ActualHeight / track.Maximum;
|
||||
|
||||
/// <summary>
|
||||
/// Get actual Tick Height with another maximum value
|
||||
/// </summary>
|
||||
public static double TickHeight(this Track track, long maximum) => track.ActualHeight / maximum;
|
||||
}
|
||||
}
|
||||
33
FModel/Forms/HexViewer/Core/Native/NativeMethods.cs
Normal file
33
FModel/Forms/HexViewer/Core/Native/NativeMethods.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace WpfHexaEditor.Core.Native
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for key detection
|
||||
/// </summary>
|
||||
internal static class NativeMethods
|
||||
{
|
||||
internal enum MapType : uint
|
||||
{
|
||||
MapvkVkToVsc = 0x0,
|
||||
MapvkVscToVk = 0x1,
|
||||
MapvkVkToChar = 0x2,
|
||||
MapvkVscToVkEx = 0x3,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal 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")]
|
||||
internal static extern bool GetKeyboardState(byte[] lpKeyState);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint MapVirtualKey(uint uCode, MapType uMapType);
|
||||
}
|
||||
}
|
||||
83
FModel/Forms/HexViewer/Core/Xcbb/CustomBackgroundBlock.cs
Normal file
83
FModel/Forms/HexViewer/Core/Xcbb/CustomBackgroundBlock.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Windows.Media;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core.Xcbb
|
||||
{
|
||||
/// <summary>
|
||||
/// IMPLEMENTATION NOT COMPLETED
|
||||
/// Used to create block of custom colors background
|
||||
/// </summary>
|
||||
/// TODO : Add programated positon..
|
||||
public class CustomBackgroundBlock
|
||||
{
|
||||
private long _length;
|
||||
|
||||
public CustomBackgroundBlock() { }
|
||||
|
||||
public CustomBackgroundBlock(long start, long length, SolidColorBrush color, string description)
|
||||
{
|
||||
StartOffset = start;
|
||||
Length = length;
|
||||
Color = color;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public CustomBackgroundBlock(long start, long length, SolidColorBrush color)
|
||||
{
|
||||
StartOffset = start;
|
||||
Length = length;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public CustomBackgroundBlock(string start, long length, SolidColorBrush color)
|
||||
{
|
||||
var srt = ByteConverters.HexLiteralToLong(start);
|
||||
|
||||
StartOffset = srt.success ? srt.position : throw new Exception("Can't convert this string to long");
|
||||
Length = length;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public CustomBackgroundBlock(string start, long length, SolidColorBrush color, string description)
|
||||
{
|
||||
var srt = ByteConverters.HexLiteralToLong(start);
|
||||
|
||||
StartOffset = srt.success ? srt.position : throw new Exception("Can't convert this string to long");
|
||||
Length = length;
|
||||
Color = color;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the start offset
|
||||
/// </summary>
|
||||
public long StartOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the stop offset
|
||||
/// </summary>
|
||||
public long StopOffset => StartOffset + Length - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the lenght of background block
|
||||
/// </summary>
|
||||
public long Length
|
||||
{
|
||||
get => _length;
|
||||
set => _length = value > 0 ? value : 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Description of background block
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
public SolidColorBrush Color { get; set; } = Brushes.Transparent;
|
||||
}
|
||||
}
|
||||
61
FModel/Forms/HexViewer/Core/Xcbb/ExeFile.cs
Normal file
61
FModel/Forms/HexViewer/Core/Xcbb/ExeFile.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Windows.Media;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
using static FModel.Properties.Resources;
|
||||
|
||||
namespace WpfHexaEditor.Core.Xcbb
|
||||
{
|
||||
/// <summary>
|
||||
/// IMPLEMENTATON NOT COMPLETED - FOR TESTING CONCEPT ONLY
|
||||
/// Window executable file custom background block.
|
||||
/// Will be implemented in XML file (XCBB)...
|
||||
/// Will de deleted soon in futher commit
|
||||
/// </summary>
|
||||
/// TODO : Localize string
|
||||
public class ExeFile
|
||||
{
|
||||
public List<CustomBackgroundBlock> GetCustomBackgroundBlock() =>
|
||||
new List<CustomBackgroundBlock>
|
||||
{
|
||||
new CustomBackgroundBlock(0, 2, Brushes.BlueViolet, CBB_EXEFile_MagicNumberString),
|
||||
new CustomBackgroundBlock(2, 2, Brushes.Brown, CBB_EXEFile_BytesInLastBlockString),
|
||||
new CustomBackgroundBlock(4, 2, Brushes.SeaGreen, CBB_EXEFile_NumberOfBlockInFileBlockString),
|
||||
new CustomBackgroundBlock(6, 2, Brushes.CadetBlue, CBB_EXEFile_NumberOfRelocationEntriesString),
|
||||
new CustomBackgroundBlock(8, 2, Brushes.DarkGoldenrod, CBB_EXEFile_NumberOfRelocationEntriesString),
|
||||
new CustomBackgroundBlock("0x0A", 2, Brushes.Coral, CBB_EXEFile_NumberOfHeaderParagraphAdditionalMemoryString),
|
||||
new CustomBackgroundBlock("0x0C", 2, Brushes.HotPink, CBB_EXEFile_MaxNumberOfHeaderParagraphAdditionalMemoryString),
|
||||
new CustomBackgroundBlock("0x0E", 2, Brushes.Cyan, CBB_EXEFile_RelativeValueOfStackSegmentString),
|
||||
new CustomBackgroundBlock("0x10", 2, Brushes.IndianRed, CBB_EXEFile_InitialValueOfSPRegisterString),
|
||||
new CustomBackgroundBlock("0x12", 2, Brushes.LimeGreen, CBB_EXEFile_WordChecksumString),
|
||||
new CustomBackgroundBlock("0x14", 2, Brushes.PaleTurquoise, CBB_EXEFile_InitialValueOfIPRegisterString),
|
||||
new CustomBackgroundBlock("0x16", 2, Brushes.DarkOrange, CBB_EXEFile_InitialValueOfCSRegisterString),
|
||||
new CustomBackgroundBlock("0x18", 2, Brushes.Chartreuse, CBB_EXEFile_OffsetOfTheFirstRelocationItemString),
|
||||
new CustomBackgroundBlock("0x1A", 2, Brushes.DarkSeaGreen, CBB_EXEFile_OverlayNumberString),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Detect if is a PE file and create the backgroung based on file data
|
||||
/// </summary>
|
||||
/// TODO : complete with other various custombackground based on file
|
||||
public List<CustomBackgroundBlock> GetCustomBackgroundBlock(ByteProvider provider)
|
||||
{
|
||||
if (ByteProvider.CheckIsOpen(provider))
|
||||
{
|
||||
//Added only if is a PE file...
|
||||
if (ByteConverters.ByteToHex(provider.GetCopyData(0, 1, true)) == "4D 5A")
|
||||
{
|
||||
//Load default
|
||||
var list = GetCustomBackgroundBlock();
|
||||
|
||||
//Add CBB : This program cannot be run in DOS mode
|
||||
list.Add(new CustomBackgroundBlock("0x4E", 38, Brushes.PaleVioletRed, CBB_EXEFile_NotDOSProgramString));
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
return new List<CustomBackgroundBlock>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
95
FModel/Forms/HexViewer/Core/Xcbb/Exefile.xcbb
Normal file
95
FModel/Forms/HexViewer/Core/Xcbb/Exefile.xcbb
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<!--DEV TEST - wpf hexeditor control - Custom Backgroung Block definition file-->
|
||||
|
||||
<XcbbFileDefinition FileType="exe" ValidIf="[0x00-0x01]=$'4D 5A'">
|
||||
<CustomBackgroundBlock PositionStart="0x00" Lenght="2" BackColor="BlueViolet">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="This is the 'magic number' of an EXE file."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="C'est le 'nombre magique' d'un fichier EXE."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x02" Lenght="2" BackColor="Brown">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="The number of bytes in the last block of the program that are actually used.
|
||||
If this value is zero, that means the entire last block is used"/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre d'octets réellement utilisés dans le dernier bloc du programme.
|
||||
Si cette valeur est zéro, cela signifie que le dernier bloc entier est utilisé"/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x04" Lenght="2" BackColor="SeaGreen">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of blocks in the file that are part of the EXE file.
|
||||
If [02-03] is non-zero, only that much of the last block is used."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre de blocs dans le fichier qui font partie du fichier EXE.
|
||||
Si [02-03] est non nul, seule la plus grande partie du dernier bloc est utilisée."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x06" Lenght="2" BackColor="BlueViolet">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of relocation entries stored after the header. May be zero."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre d'entrées de relocalisation stockées après l'en-tête. Peut être zéro"/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x08" Lenght="2" BackColor="DarkGoldenrod">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of paragraphs in the header. The program's data begins just after the header, and this field can be used to calculate the appropriate file offset.
|
||||
The header includes the relocation entries. Note that some OSs and/or programs may fail if the header is not a multiple of 512 bytes."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre de paragraphes dans l'en-tête. Les données du programme commencent juste après l'en-tête et ce champ peut être utilisé pour calculer le décalage de fichier approprié.
|
||||
L'en-tête comprend les entrées de relocalisation. Notez que certains systèmes d'exploitation et / ou programmes peuvent échouer si l'en-tête n'est pas un multiple de 512 octets."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x0A" Lenght="2" BackColor="Coral">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of paragraphs of additional memory that the program will need.
|
||||
This is the equivalent of the BSS size in a Unix program.
|
||||
The program can't be loaded if there isn't at least this much memory available to it."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre de paragraphes de mémoire supplémentaire dont le programme aura besoin.
|
||||
C'est l'équivalent de la taille BSS dans un programme Unix.
|
||||
Le programme ne peut pas être chargé s'il n'y a pas au moins autant de mémoire disponible."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x0C" Lenght="2" BackColor="HotPink">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Maximum number of paragraphs of additional memory.
|
||||
Normally, the OS reserves all the remaining conventional memory for your program, but you can limit it with this field."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Nombre maximum de paragraphes de mémoire supplémentaire.
|
||||
Normalement, le système d'exploitation réserve toute la mémoire conventionnelle restante pour votre programme, mais vous pouvez le limiter avec ce champ."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x0E" Lenght="2" BackColor="Cyan">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Relative value of the stack segment.
|
||||
This value is added to the segment the program was loaded at, and the result is used to initialize the SS register."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Valeur relative du segment de pile.
|
||||
Cette valeur est ajoutée au segment dans lequel le programme a été chargé et le résultat est utilisé pour initialiser le registre SS."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x10" Lenght="2" BackColor="IndianRed">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the SP register."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre SP."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x12" Lenght="2" BackColor="LimeGreen">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Word checksum.
|
||||
If set properly, the 16-bit sum of all words in the file should be zero.
|
||||
Usually, this isn't filled in."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Word checksum.
|
||||
Si défini correctement, la somme de 16 bits de tous les mots du fichier doit être zéro.
|
||||
Habituellement, ce n'est pas renseigné."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x14" Lenght="2" BackColor="PaleTurquoise">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the IP register."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre IP."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x16" Lenght="2" BackColor="DarkOrange">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the CS register, relative to the segment the program was loaded at."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre CS, relative au segment dans lequel le programme a été chargé."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x18" Lenght="2" BackColor="Chartreuse">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Offset of the first relocation item in the file."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Décalage du premier élément de déplacement dans le fichier."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
<CustomBackgroundBlock PositionStart="0x1A" Lenght="2" BackColor="DarkSeaGreen">
|
||||
<LocalizedDescription Language="en-US" IsDefault="True" Description="Overlay number. Normally zero, meaning that it's the main program."/>
|
||||
<LocalizedDescription Language="fr-CA" Description="Numéro de superposition. Normalement zéro, ce qui signifie que c'est le programme principal."/>
|
||||
</CustomBackgroundBlock>
|
||||
|
||||
</XcbbFileDefinition>
|
||||
|
||||
46
FModel/Forms/HexViewer/Core/Xcbb/XcbbExpressionParser.cs
Normal file
46
FModel/Forms/HexViewer/Core/Xcbb/XcbbExpressionParser.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor.Core.Xcbb
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to parse expression used in Xccb file for validate byte data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Expression parser need to be linked to a ByteProvided for validating data.
|
||||
/// </remarks>
|
||||
public class XcbbExpressionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// This ByteProvider is used for get data from file/stream and validate them in expression
|
||||
/// </summary>
|
||||
private readonly ByteProvider _provider;
|
||||
|
||||
/// <summary>
|
||||
/// Unique constructor
|
||||
/// </summary>
|
||||
XcbbExpressionParser(ByteProvider provider) => _provider = provider;
|
||||
|
||||
/// <summary>
|
||||
/// Use for valid expresion "valid if data are equal to..."
|
||||
/// </summary>
|
||||
/// <param name="expression">expression like: [0x00-0x01]=$'4D 5A'</param>
|
||||
/// <returns>
|
||||
/// True = expression is valid
|
||||
/// False = expression not valid
|
||||
/// Null = unable to valid expression</returns>
|
||||
public bool? ValidIf(string expression)
|
||||
{
|
||||
if (ByteProvider.CheckIsOpen(_provider))
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
24
FModel/Forms/HexViewer/Core/Xcbb/XcbbFileParser.cs
Normal file
24
FModel/Forms/HexViewer/Core/Xcbb/XcbbFileParser.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace WpfHexaEditor.Core.Xcbb
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for read and parse xcbb file (xml custom backgroung block definition)
|
||||
/// </summary>
|
||||
public class XcbbFileParser
|
||||
{
|
||||
|
||||
|
||||
protected XcbbFileParser(string path)
|
||||
{
|
||||
LoadFile(path);
|
||||
}
|
||||
|
||||
private void LoadFile(string path)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
127
FModel/Forms/HexViewer/FastTextLine.cs
Normal file
127
FModel/Forms/HexViewer/FastTextLine.cs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2018
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WpfHexaEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Light Label like control
|
||||
/// </summary>
|
||||
internal class FastTextLine: FrameworkElement
|
||||
{
|
||||
private readonly HexEditor _parent;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public FastTextLine(HexEditor parent)
|
||||
{
|
||||
//Parent hexeditor
|
||||
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
|
||||
|
||||
//Default properties
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
#endregion Contructor
|
||||
|
||||
#region Base properties
|
||||
|
||||
/// <summary>
|
||||
/// Definie the foreground
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ForegroundProperty =
|
||||
TextElement.ForegroundProperty.AddOwner(
|
||||
typeof(FastTextLine));
|
||||
|
||||
public Brush Foreground
|
||||
{
|
||||
get => (Brush)GetValue(ForegroundProperty);
|
||||
set => SetValue(ForegroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty BackgroundProperty =
|
||||
TextElement.BackgroundProperty.AddOwner(typeof(FastTextLine),
|
||||
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Defines the background
|
||||
/// </summary>
|
||||
public Brush Background
|
||||
{
|
||||
get => (Brush)GetValue(BackgroundProperty);
|
||||
set => SetValue(BackgroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TextProperty =
|
||||
DependencyProperty.Register(nameof(Text), typeof(string), typeof(FastTextLine),
|
||||
new FrameworkPropertyMetadata(string.Empty,
|
||||
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
/// <summary>
|
||||
/// Text to be displayed representation of Byte
|
||||
/// </summary>
|
||||
public string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(typeof(FastTextLine));
|
||||
|
||||
/// <summary>
|
||||
/// The FontWeight property specifies the weight of the font.
|
||||
/// </summary>
|
||||
public FontWeight FontWeight
|
||||
{
|
||||
get => (FontWeight)GetValue(FontWeightProperty);
|
||||
set => SetValue(FontWeightProperty, value);
|
||||
}
|
||||
|
||||
#endregion Base properties
|
||||
|
||||
#region Properties
|
||||
|
||||
public bool AutoWidth { get; set; } = true;
|
||||
|
||||
public Point RenderPoint
|
||||
{
|
||||
get => (Point)GetValue(RenderPointProperty);
|
||||
set => SetValue(RenderPointProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for RenderPoint. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty RenderPointProperty =
|
||||
DependencyProperty.Register(nameof(RenderPoint), typeof(Point), typeof(FastTextLine),
|
||||
new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Render the control
|
||||
/// </summary>
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
//Draw background
|
||||
if (Background != null)
|
||||
dc.DrawRectangle(Background, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
|
||||
|
||||
//Draw text
|
||||
var formatedText = new FormattedText(Text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
|
||||
new Typeface(_parent.FontFamily, _parent.FontStyle, FontWeight, _parent.FontStretch),
|
||||
_parent.FontSize, Foreground, VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||
|
||||
dc.DrawText(formatedText, new Point(RenderPoint.X, RenderPoint.Y));
|
||||
|
||||
if (AutoWidth)
|
||||
Width = formatedText.Width + RenderPoint.X;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
229
FModel/Forms/HexViewer/FindReplaceWindow.xaml
Normal file
229
FModel/Forms/HexViewer/FindReplaceWindow.xaml
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
<!--
|
||||
Apache 2.0 - 2019
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<Window
|
||||
x:Class="WpfHexaEditor.Dialog.FindReplaceWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
xmlns:wpfHexaEditor="clr-namespace:WpfHexaEditor"
|
||||
Title="Find and Replace"
|
||||
Width="193"
|
||||
Height="340"
|
||||
MinWidth="550"
|
||||
MinHeight="360"
|
||||
MaxWidth="700"
|
||||
MaxHeight="500"
|
||||
Icon="/FModel;component/Resources/Logo-Icon.ico"
|
||||
ResizeMode="CanResizeWithGrip"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
|
||||
<Popup
|
||||
x:Name="SettingPopup"
|
||||
OpacityMask="WhiteSmoke"
|
||||
PlacementTarget="{Binding ElementName=SettingButton}"
|
||||
StaysOpen="False">
|
||||
|
||||
<StackPanel Margin="1,0.5,0.5,0.8" Background="{x:Static SystemColors.MenuBarBrush}">
|
||||
<MenuItem
|
||||
x:Name="HighlightMenuItem"
|
||||
Click="SettingMenuItem_Click"
|
||||
Header="Trim the data on the find length when replace"
|
||||
IsCheckable="True"
|
||||
IsChecked="True" />
|
||||
<MenuItem
|
||||
x:Name="TrimMenuItem"
|
||||
Click="SettingMenuItem_Click"
|
||||
Header="Highlight all data find"
|
||||
IsCheckable="True"
|
||||
IsChecked="True" />
|
||||
</StackPanel>
|
||||
|
||||
</Popup>
|
||||
|
||||
<Button
|
||||
x:Name="FindNextButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,73,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindNextButton_Click"
|
||||
Content="Find Next"
|
||||
TabIndex="3" />
|
||||
|
||||
<Button
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,0,14,10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="CloseButton_Click"
|
||||
Content="Close"
|
||||
IsCancel="True"
|
||||
TabIndex="10" />
|
||||
|
||||
<wpfHexaEditor:HexEditor
|
||||
x:Name="FindHexEdit"
|
||||
Height="110"
|
||||
Margin="10,41,129,0"
|
||||
VerticalAlignment="Top"
|
||||
AllowAutoHighLightSelectionByte="False"
|
||||
AllowContextMenu="False"
|
||||
AllowDeleteByte="True"
|
||||
AllowDrop="True"
|
||||
AllowExtend="True"
|
||||
AllowFileDrop="False"
|
||||
AllowZoom="False"
|
||||
AppendNeedConfirmation="False"
|
||||
ByteModifiedColor="White"
|
||||
BytePerLine="8"
|
||||
ByteSpacerPositioning="Nothing"
|
||||
BytesDeleted="FindHexEdit_BytesDeleted"
|
||||
HideByteDeleted="False"
|
||||
StatusBarVisibility="Collapsed" />
|
||||
|
||||
<Label
|
||||
Margin="10,10,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Find what:" />
|
||||
|
||||
<Button
|
||||
x:Name="ReplaceButton"
|
||||
Width="100"
|
||||
Height="28"
|
||||
Margin="0,169,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ReplaceButton_Click"
|
||||
Content="Replace"
|
||||
TabIndex="6" />
|
||||
|
||||
<Button
|
||||
x:Name="ReplaceAllButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,234,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ReplaceAllButton_Click"
|
||||
Content="Replace All"
|
||||
TabIndex="9" />
|
||||
|
||||
<wpfHexaEditor:HexEditor
|
||||
x:Name="ReplaceHexEdit"
|
||||
Margin="10,187,129,10"
|
||||
AllowAutoHighLightSelectionByte="False"
|
||||
AllowContextMenu="False"
|
||||
AllowDeleteByte="True"
|
||||
AllowDrop="True"
|
||||
AllowExtend="True"
|
||||
AllowFileDrop="False"
|
||||
AllowZoom="False"
|
||||
AppendNeedConfirmation="False"
|
||||
ByteModifiedColor="White"
|
||||
BytePerLine="8"
|
||||
ByteSpacerPositioning="Nothing"
|
||||
BytesDeleted="ReplaceHexEdit_BytesDeleted"
|
||||
HideByteDeleted="False"
|
||||
StatusBarVisibility="Collapsed" />
|
||||
|
||||
<Label
|
||||
Height="26"
|
||||
Margin="10,156,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Replace with:" />
|
||||
|
||||
<Button
|
||||
x:Name="FindAllButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,137,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindAllButton_Click"
|
||||
Content="Find All"
|
||||
TabIndex="5" />
|
||||
|
||||
<Button
|
||||
x:Name="FindFirstButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,41,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindFirstButton_Click"
|
||||
Content="Find First"
|
||||
TabIndex="2" />
|
||||
|
||||
<Button
|
||||
x:Name="FindLastButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,105,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindLastButton_Click"
|
||||
Content="Find Last"
|
||||
TabIndex="4" />
|
||||
|
||||
<Button
|
||||
Width="61"
|
||||
Height="26"
|
||||
Margin="0,10,129,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ClearButton_Click"
|
||||
Content="Clear"
|
||||
TabIndex="1" />
|
||||
|
||||
<Button
|
||||
Width="61"
|
||||
Height="26"
|
||||
Margin="0,156,129,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ClearReplaceButton_Click"
|
||||
Content="Clear"
|
||||
TabIndex="11" />
|
||||
|
||||
<Button
|
||||
x:Name="ReplaceNextButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,202,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ReplaceNextButton_Click"
|
||||
Content="Replace Next"
|
||||
TabIndex="7" />
|
||||
|
||||
<Button
|
||||
x:Name="SettingButton"
|
||||
Width="100"
|
||||
Height="26"
|
||||
Margin="0,10,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="SettingButton_Click">
|
||||
|
||||
<Image
|
||||
Width="31"
|
||||
Height="23"
|
||||
Source="/WPFHexaEditor;component/Resources/Icon/Settings-Icon.ico" />
|
||||
</Button>
|
||||
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
84
FModel/Forms/HexViewer/FindReplaceWindow.xaml.cs
Normal file
84
FModel/Forms/HexViewer/FindReplaceWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfHexaEditor.Dialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FindReplaceWindow.xaml
|
||||
/// </summary>
|
||||
public partial class FindReplaceWindow
|
||||
{
|
||||
private readonly HexEditor _parent;
|
||||
|
||||
public FindReplaceWindow(HexEditor parent, byte[] findData = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//Parent hexeditor for "binding" search
|
||||
_parent = parent;
|
||||
|
||||
InitializeMStream(FindHexEdit, findData);
|
||||
InitializeMStream(ReplaceHexEdit);
|
||||
}
|
||||
|
||||
#region Events
|
||||
private void ClearButton_Click(object sender, RoutedEventArgs e) => InitializeMStream(FindHexEdit);
|
||||
private void ClearReplaceButton_Click(object sender, RoutedEventArgs e) => InitializeMStream(ReplaceHexEdit);
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
private void FindAllButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindAll(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
|
||||
|
||||
private void FindFirstButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindFirst(FindHexEdit.GetAllBytes(), 0, HighlightMenuItem.IsChecked);
|
||||
|
||||
private void FindNextButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindNext(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
|
||||
|
||||
private void FindLastButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindLast(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
|
||||
|
||||
private void ReplaceButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.ReplaceFirst(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
|
||||
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
|
||||
|
||||
private void ReplaceNextButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.ReplaceNext(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
|
||||
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
|
||||
|
||||
private void ReplaceAllButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.ReplaceAll(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
|
||||
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
|
||||
|
||||
private void ReplaceHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
|
||||
InitializeMStream(ReplaceHexEdit, ReplaceHexEdit.GetAllBytes());
|
||||
|
||||
private void FindHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
|
||||
InitializeMStream(FindHexEdit, FindHexEdit.GetAllBytes());
|
||||
|
||||
private void SettingButton_Click(object sender, RoutedEventArgs e) => SettingPopup.IsOpen = true;
|
||||
|
||||
private void SettingMenuItem_Click(object sender, RoutedEventArgs e) => SettingPopup.IsOpen = false;
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Initialize stream and hexeditor
|
||||
/// </summary>
|
||||
private void InitializeMStream(HexEditor hexeditor, byte[] findData = null)
|
||||
{
|
||||
hexeditor.CloseProvider();
|
||||
|
||||
var ms = new MemoryStream(1);
|
||||
|
||||
if (findData != null && findData.Length > 0)
|
||||
foreach (byte b in findData)
|
||||
ms.WriteByte(b);
|
||||
else
|
||||
ms.WriteByte(0);
|
||||
|
||||
hexeditor.Stream = ms;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
119
FModel/Forms/HexViewer/FindWindow.xaml
Normal file
119
FModel/Forms/HexViewer/FindWindow.xaml
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<!--
|
||||
Apache 2.0 2018 - 2019
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<Window
|
||||
x:Class="WpfHexaEditor.Dialog.FindWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
xmlns:wpfHexaEditor="clr-namespace:WpfHexaEditor"
|
||||
Title="Find"
|
||||
Width="193"
|
||||
Height="190"
|
||||
MinWidth="550"
|
||||
MinHeight="275"
|
||||
MaxWidth="700"
|
||||
MaxHeight="500"
|
||||
Icon="/FModel;component/Resources/Logo-Icon.ico"
|
||||
ResizeMode="CanResizeWithGrip"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
|
||||
<Button
|
||||
x:Name="FindNextButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,73,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindNextButton_Click"
|
||||
Content="Find Next"
|
||||
TabIndex="3" />
|
||||
|
||||
<Button
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,0,14,16"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="CloseButton_Click"
|
||||
Content="Close"
|
||||
IsCancel="True"
|
||||
TabIndex="6" />
|
||||
|
||||
<wpfHexaEditor:HexEditor
|
||||
x:Name="FindHexEdit"
|
||||
Margin="10,41,129,21"
|
||||
AllowAutoHighLightSelectionByte="False"
|
||||
AllowContextMenu="False"
|
||||
AllowDeleteByte="True"
|
||||
AllowDrop="True"
|
||||
AllowExtend="True"
|
||||
AllowFileDrop="False"
|
||||
AllowZoom="False"
|
||||
AppendNeedConfirmation="False"
|
||||
ByteModifiedColor="White"
|
||||
BytePerLine="8"
|
||||
ByteSpacerPositioning="Nothing"
|
||||
BytesDeleted="FindHexEdit_BytesDeleted"
|
||||
HideByteDeleted="False"
|
||||
StatusBarVisibility="Collapsed" />
|
||||
|
||||
<Label
|
||||
Margin="10,10,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Find what:" />
|
||||
|
||||
<Button
|
||||
x:Name="FindAllButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,137,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindAllButton_Click"
|
||||
Content="Find All"
|
||||
TabIndex="5" />
|
||||
|
||||
<Button
|
||||
x:Name="FindFirstButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,41,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindFirstButton_Click"
|
||||
Content="Find First"
|
||||
TabIndex="2" />
|
||||
|
||||
<Button
|
||||
x:Name="FindLastButton"
|
||||
Width="100"
|
||||
Height="27"
|
||||
Margin="0,105,14,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="FindLastButton_Click"
|
||||
Content="Find Last"
|
||||
TabIndex="4" />
|
||||
|
||||
<Button
|
||||
Width="61"
|
||||
Height="26"
|
||||
Margin="0,10,129,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="ClearButton_Click"
|
||||
Content="Clear"
|
||||
TabIndex="1" />
|
||||
</Grid>
|
||||
</Window>
|
||||
60
FModel/Forms/HexViewer/FindWindow.xaml.cs
Normal file
60
FModel/Forms/HexViewer/FindWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfHexaEditor.Dialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FindWindow.xaml
|
||||
/// </summary>
|
||||
public partial class FindWindow
|
||||
{
|
||||
private MemoryStream _findMs = new MemoryStream(1);
|
||||
private readonly HexEditor _parent;
|
||||
|
||||
public FindWindow(HexEditor parent, byte[] findData = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//Parent hexeditor for "binding" search
|
||||
_parent = parent;
|
||||
|
||||
InitializeMStream(findData);
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e) => Close();
|
||||
private void ClearButton_Click(object sender, RoutedEventArgs e) => InitializeMStream();
|
||||
|
||||
private void FindHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
|
||||
InitializeMStream(FindHexEdit.GetAllBytes());
|
||||
|
||||
private void FindAllButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindAll(FindHexEdit.GetAllBytes(), true);
|
||||
|
||||
private void FindFirstButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindFirst(FindHexEdit.GetAllBytes());
|
||||
|
||||
private void FindNextButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindNext(FindHexEdit.GetAllBytes());
|
||||
|
||||
private void FindLastButton_Click(object sender, RoutedEventArgs e) =>
|
||||
_parent?.FindLast(FindHexEdit.GetAllBytes());
|
||||
|
||||
/// <summary>
|
||||
/// Initialize stream and hexeditor
|
||||
/// </summary>
|
||||
private void InitializeMStream(byte[] findData = null)
|
||||
{
|
||||
FindHexEdit.CloseProvider();
|
||||
|
||||
_findMs = new MemoryStream(1);
|
||||
|
||||
if (findData != null && findData.Length > 0)
|
||||
foreach (byte b in findData)
|
||||
_findMs.WriteByte(b);
|
||||
else
|
||||
_findMs.WriteByte(0);
|
||||
|
||||
FindHexEdit.Stream = _findMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
FModel/Forms/HexViewer/GiveByteWindow.xaml
Normal file
56
FModel/Forms/HexViewer/GiveByteWindow.xaml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<Window
|
||||
x:Class="WpfHexaEditor.Dialog.GiveByteWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:control="clr-namespace:WpfHexaEditor"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
Title="Enter hexadecimal value ..."
|
||||
Width="359"
|
||||
Height="121"
|
||||
x:ClassModifier="internal"
|
||||
Icon="/FModel;component/Resources/Logo-Icon.ico"
|
||||
ResizeMode="NoResize"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
WindowStyle="SingleBorderWindow"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Button
|
||||
x:Name="OkButton"
|
||||
Width="75"
|
||||
Margin="0,0,92,10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="OKButton_Click"
|
||||
Content="Ok"
|
||||
IsDefault="True"
|
||||
TabIndex="2" />
|
||||
|
||||
<Button
|
||||
Width="75"
|
||||
Height="20"
|
||||
Margin="0,0,10,10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Content="Cancel"
|
||||
IsCancel="True"
|
||||
TabIndex="3" />
|
||||
|
||||
<Label
|
||||
Margin="10,18,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Byte to search" />
|
||||
|
||||
<control:HexBox
|
||||
x:Name="HexTextBox"
|
||||
Width="Auto"
|
||||
Height="23"
|
||||
Margin="143,20,10,0"
|
||||
VerticalAlignment="Top"
|
||||
MaximumValue="255" />
|
||||
</Grid>
|
||||
</Window>
|
||||
14
FModel/Forms/HexViewer/GiveByteWindow.xaml.cs
Normal file
14
FModel/Forms/HexViewer/GiveByteWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System.Windows;
|
||||
|
||||
namespace WpfHexaEditor.Dialog
|
||||
{
|
||||
/// <summary>
|
||||
/// This Window is used to give a hex value for fill the selection with.
|
||||
/// </summary>
|
||||
internal partial class GiveByteWindow
|
||||
{
|
||||
public GiveByteWindow() => InitializeComponent();
|
||||
|
||||
private void OKButton_Click(object sender, RoutedEventArgs e) => DialogResult = true;
|
||||
}
|
||||
}
|
||||
87
FModel/Forms/HexViewer/HexBox.xaml
Normal file
87
FModel/Forms/HexViewer/HexBox.xaml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<!--
|
||||
Apache 2.0 - 2016-2018
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<UserControl
|
||||
x:Class="WpfHexaEditor.HexBox"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
Width="100"
|
||||
Height="24"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="13" />
|
||||
<ColumnDefinition Width="65*" />
|
||||
<ColumnDefinition Width="22" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RepeatButton
|
||||
Grid.Column="2"
|
||||
Padding="0"
|
||||
BorderBrush="#FFCDCBCB"
|
||||
Click="UpButton_Click">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Margin="0,-1,0,0"
|
||||
FontSize="8"
|
||||
Text="▲" />
|
||||
</Grid>
|
||||
</RepeatButton>
|
||||
|
||||
<RepeatButton
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Padding="0"
|
||||
BorderBrush="#FFCDCBCB"
|
||||
Click="DownButton_Click">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Margin="0,-1,0,0"
|
||||
FontSize="8"
|
||||
Text="▼" />
|
||||
</Grid>
|
||||
</RepeatButton>
|
||||
|
||||
<TextBox
|
||||
x:Name="HexTextBox"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
VerticalContentAlignment="Center"
|
||||
BorderBrush="{x:Null}"
|
||||
Focusable="True"
|
||||
IsUndoEnabled="False"
|
||||
KeyDown="HexTextBox_KeyDown"
|
||||
MaxLength="15"
|
||||
MaxLines="1"
|
||||
PreviewKeyDown="HexTextBox_PreviewKeyDown"
|
||||
TabIndex="1"
|
||||
Text="0"
|
||||
TextChanged="HexTextBox_TextChanged" Padding="0" Foreground="White">
|
||||
<TextBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Click="CopyHexaMenuItem_Click" Header="Copy as hexadecimal" />
|
||||
<MenuItem Click="CopyLongMenuItem_Click" Header="Copy as decimal" />
|
||||
</ContextMenu>
|
||||
</TextBox.ContextMenu>
|
||||
</TextBox>
|
||||
|
||||
<Label
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Padding="0"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="0x" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
174
FModel/Forms/HexViewer/HexBox.xaml.cs
Normal file
174
FModel/Forms/HexViewer/HexBox.xaml.cs
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2017-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using WpfHexaEditor.Core;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
|
||||
namespace WpfHexaEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Control for enter hex value and deal with.
|
||||
/// </summary>
|
||||
public partial class HexBox
|
||||
{
|
||||
public HexBox() => InitializeComponent();
|
||||
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Occurs when value are changed.
|
||||
/// </summary>
|
||||
public event EventHandler ValueChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Get hexadecimal value of LongValue
|
||||
/// </summary>
|
||||
public string HexValue => ByteConverters.LongToHex(LongValue);
|
||||
|
||||
/// <summary>
|
||||
/// Set maximum value
|
||||
/// </summary>
|
||||
public long MaximumValue
|
||||
{
|
||||
get => (long)GetValue(MaximumValueProperty);
|
||||
set => SetValue(MaximumValueProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for MaximumValue. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty MaximumValueProperty =
|
||||
DependencyProperty.Register(nameof(MaximumValue), typeof(long), typeof(HexBox),
|
||||
new FrameworkPropertyMetadata(long.MaxValue, MaximumValue_Changed));
|
||||
|
||||
private static void MaximumValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is HexBox ctrl)
|
||||
if (e.NewValue != e.OldValue)
|
||||
if (ctrl.LongValue > (long)e.NewValue)
|
||||
ctrl.UpdateValueFrom((long)e.NewValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the hex value show in control
|
||||
/// </summary>
|
||||
public long LongValue
|
||||
{
|
||||
get => (long)GetValue(LongValueProperty);
|
||||
set => SetValue(LongValueProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for LongValue. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty LongValueProperty =
|
||||
DependencyProperty.Register(nameof(LongValue), typeof(long), typeof(HexBox),
|
||||
new FrameworkPropertyMetadata(0L,
|
||||
LongValue_Changed,
|
||||
LongValue_CoerceValue));
|
||||
|
||||
private static object LongValue_CoerceValue(DependencyObject d, object baseValue)
|
||||
{
|
||||
var ctrl = d as HexBox;
|
||||
|
||||
var newValue = (long)baseValue;
|
||||
|
||||
if (newValue > ctrl.MaximumValue) newValue = ctrl.MaximumValue;
|
||||
if (newValue < 0) newValue = 0;
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private static void LongValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is HexBox ctrl)
|
||||
if (e.NewValue != e.OldValue)
|
||||
{
|
||||
var val = ByteConverters.LongToHex((long)e.NewValue);
|
||||
|
||||
if (val == "00000000")
|
||||
val = "0";
|
||||
else if (val.Length >= 3)
|
||||
val = val.TrimStart('0');
|
||||
|
||||
ctrl.HexTextBox.Text = val.ToUpper();
|
||||
ctrl.HexTextBox.CaretIndex = ctrl.HexTextBox.Text.Length;
|
||||
ctrl.ToolTip = e.NewValue;
|
||||
|
||||
ctrl.ValueChanged?.Invoke(ctrl, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Substract one to the LongValue
|
||||
/// </summary>
|
||||
private void SubstractOne() => LongValue--;
|
||||
|
||||
/// <summary>
|
||||
/// Add one to the LongValue
|
||||
/// </summary>
|
||||
private void AddOne() => LongValue++;
|
||||
|
||||
/// <summary>
|
||||
/// Update value from decimal long
|
||||
/// </summary>
|
||||
private void UpdateValueFrom(long value) => LongValue = value;
|
||||
|
||||
/// <summary>
|
||||
/// Update value from hex string
|
||||
/// </summary>
|
||||
private void UpdateValueFrom(string value)
|
||||
{
|
||||
var (success, val) = ByteConverters.HexLiteralToLong(value);
|
||||
|
||||
LongValue = success ? val : 0;
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
||||
#region Controls events
|
||||
|
||||
private void HexTextBox_PreviewKeyDown(object sender, KeyEventArgs e) =>
|
||||
e.Handled = !KeyValidator.IsHexKey(e.Key) &&
|
||||
!KeyValidator.IsBackspaceKey(e.Key) &&
|
||||
!KeyValidator.IsDeleteKey(e.Key) &&
|
||||
!KeyValidator.IsArrowKey(e.Key) &&
|
||||
!KeyValidator.IsTabKey(e.Key) &&
|
||||
!KeyValidator.IsEnterKey(e.Key);
|
||||
|
||||
private void HexTextBox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Up)
|
||||
AddOne();
|
||||
|
||||
if (e.Key == Key.Down)
|
||||
SubstractOne();
|
||||
|
||||
HexTextBox.Focus();
|
||||
}
|
||||
|
||||
private void UpButton_Click(object sender, RoutedEventArgs e) => AddOne();
|
||||
|
||||
private void DownButton_Click(object sender, RoutedEventArgs e) => SubstractOne();
|
||||
|
||||
private void HexTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
|
||||
UpdateValueFrom(HexTextBox.Text);
|
||||
|
||||
private void CopyHexaMenuItem_Click(object sender, RoutedEventArgs e) =>
|
||||
Clipboard.SetText($"0x{HexTextBox.Text}");
|
||||
|
||||
private void CopyLongMenuItem_Click(object sender, RoutedEventArgs e) =>
|
||||
Clipboard.SetText(LongValue.ToString());
|
||||
|
||||
#endregion Controls events
|
||||
}
|
||||
}
|
||||
218
FModel/Forms/HexViewer/HexByte.cs
Normal file
218
FModel/Forms/HexViewer/HexByte.cs
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
// Contributor: Janus Tida
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using WpfHexaEditor.Core;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
using WpfHexaEditor.Core.MethodExtention;
|
||||
|
||||
namespace WpfHexaEditor
|
||||
{
|
||||
internal class HexByte : BaseByte
|
||||
{
|
||||
#region Global class variables
|
||||
|
||||
private KeyDownLabel _keyDownLabel = KeyDownLabel.FirstChar;
|
||||
|
||||
#endregion global class variables
|
||||
|
||||
#region Constructor
|
||||
|
||||
public HexByte(HexEditor parent) : base(parent)
|
||||
{
|
||||
//Update width
|
||||
UpdateDataVisualWidth();
|
||||
}
|
||||
|
||||
#endregion Contructor
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Update the render of text derived bytecontrol from byte property
|
||||
/// </summary>
|
||||
public override void UpdateTextRenderFromByte()
|
||||
{
|
||||
if (Byte != null)
|
||||
{
|
||||
switch (_parent.DataStringVisual)
|
||||
{
|
||||
case DataVisualType.Hexadecimal:
|
||||
var chArr = ByteConverters.ByteToHexCharArray(Byte.Value);
|
||||
Text = new string(chArr);
|
||||
break;
|
||||
case DataVisualType.Decimal:
|
||||
Text = Byte.Value.ToString("d3");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Text = string.Empty;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_keyDownLabel = KeyDownLabel.FirstChar;
|
||||
}
|
||||
|
||||
public void UpdateDataVisualWidth()
|
||||
{
|
||||
switch (_parent.DataStringVisual)
|
||||
{
|
||||
case DataVisualType.Decimal:
|
||||
Width = 25;
|
||||
break;
|
||||
case DataVisualType.Hexadecimal:
|
||||
Width = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
||||
#region Events delegate
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
if (IsFocused)
|
||||
{
|
||||
//Is focused set editing to second char.
|
||||
_keyDownLabel = KeyDownLabel.SecondChar;
|
||||
UpdateCaret();
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if (Byte == null) return;
|
||||
|
||||
if (KeyValidation(e)) return;
|
||||
|
||||
//MODIFY BYTE
|
||||
if (!ReadOnlyMode && KeyValidator.IsHexKey(e.Key))
|
||||
switch (_parent.DataStringVisual)
|
||||
{
|
||||
case DataVisualType.Hexadecimal:
|
||||
|
||||
#region Edit hexadecimal value
|
||||
|
||||
string key;
|
||||
key = KeyValidator.IsNumericKey(e.Key)
|
||||
? KeyValidator.GetDigitFromKey(e.Key).ToString()
|
||||
: e.Key.ToString().ToLower();
|
||||
|
||||
//Update byte
|
||||
var byteValueCharArray = ByteConverters.ByteToHexCharArray(Byte.Value);
|
||||
switch (_keyDownLabel)
|
||||
{
|
||||
case KeyDownLabel.FirstChar:
|
||||
byteValueCharArray[0] = key.ToCharArray()[0];
|
||||
_keyDownLabel = KeyDownLabel.SecondChar;
|
||||
Action = ByteAction.Modified;
|
||||
Byte = ByteConverters.HexToByte(
|
||||
byteValueCharArray[0] + byteValueCharArray[1].ToString())[0];
|
||||
break;
|
||||
case KeyDownLabel.SecondChar:
|
||||
byteValueCharArray[1] = key.ToCharArray()[0];
|
||||
_keyDownLabel = KeyDownLabel.NextPosition;
|
||||
|
||||
Action = ByteAction.Modified;
|
||||
Byte = ByteConverters.HexToByte(
|
||||
byteValueCharArray[0] + byteValueCharArray[1].ToString())[0];
|
||||
|
||||
//Insert byte at end of file
|
||||
if (_parent.Length != BytePositionInStream + 1)
|
||||
{
|
||||
_keyDownLabel = KeyDownLabel.NextPosition;
|
||||
OnMoveNext(new EventArgs());
|
||||
}
|
||||
break;
|
||||
case KeyDownLabel.NextPosition:
|
||||
|
||||
//byte[] byteToAppend = { (byte)key.ToCharArray()[0] };
|
||||
_parent.AppendByte(new byte[] { 0 });
|
||||
|
||||
OnMoveNext(new EventArgs());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
break;
|
||||
case DataVisualType.Decimal:
|
||||
|
||||
//Not editable at this moment, maybe in future
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateCaret();
|
||||
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
#endregion Events delegate
|
||||
|
||||
#region Caret events/methods
|
||||
|
||||
protected override void OnGotFocus(RoutedEventArgs e)
|
||||
{
|
||||
_keyDownLabel = KeyDownLabel.FirstChar;
|
||||
UpdateCaret();
|
||||
|
||||
base.OnGotFocus(e);
|
||||
}
|
||||
|
||||
private void UpdateCaret()
|
||||
{
|
||||
if (ReadOnlyMode || Byte == null)
|
||||
_parent.HideCaret();
|
||||
else
|
||||
{
|
||||
//TODO: clear size and use BaseByte.TextFormatted property...
|
||||
var size = Text[1].ToString()
|
||||
.GetScreenSize(_parent.FontFamily, _parent.FontSize, _parent.FontStyle, FontWeight,
|
||||
_parent.FontStretch, _parent.Foreground);
|
||||
|
||||
_parent.SetCaretSize(Width / 2, size.Height);
|
||||
_parent.SetCaretMode(CaretMode.Overwrite);
|
||||
|
||||
switch (_keyDownLabel)
|
||||
{
|
||||
case KeyDownLabel.FirstChar:
|
||||
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(0, 0)));
|
||||
break;
|
||||
case KeyDownLabel.SecondChar:
|
||||
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(size.Width + 1, 0)));
|
||||
break;
|
||||
case KeyDownLabel.NextPosition:
|
||||
if (_parent.Length == BytePositionInStream + 1)
|
||||
if (_parent.AllowExtend)
|
||||
{
|
||||
_parent.SetCaretMode(CaretMode.Insert);
|
||||
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(size.Width * 2, 0)));
|
||||
}
|
||||
else
|
||||
_parent.HideCaret();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
425
FModel/Forms/HexViewer/HexEditor.xaml
Normal file
425
FModel/Forms/HexViewer/HexEditor.xaml
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
<!--
|
||||
Apache 2.0 - 2016-2019
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<UserControl
|
||||
x:Class="WpfHexaEditor.HexEditor"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:WpfHexaEditor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
d:DesignHeight="350"
|
||||
d:DesignWidth="804"
|
||||
BorderBrush="#FF443E3E"
|
||||
BorderThickness="1"
|
||||
Drop="Control_Drop"
|
||||
Focusable="True"
|
||||
FontSize="11"
|
||||
KeyDown="Control_KeyDown"
|
||||
Loaded="Control_Loaded"
|
||||
MouseWheel="Control_MouseWheel"
|
||||
Unloaded="Control_Unloaded"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<!--#region Ressources-->
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="BrushesDictionary.xaml" />
|
||||
<ResourceDictionary Source="ToolTipDictionary.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<!--#endregion-->
|
||||
|
||||
<!--#region Build-in Context Menu-->
|
||||
<UserControl.ContextMenu>
|
||||
<ContextMenu x:Name="CMenu" Visibility="Collapsed">
|
||||
<MenuItem
|
||||
x:Name="UndoCMenu"
|
||||
Click="UndoCMenu_Click"
|
||||
Header="Undo">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Undo-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Bookmarks">
|
||||
<MenuItem
|
||||
x:Name="BookMarkCMenu"
|
||||
Width="Auto"
|
||||
Click="BookMarkCMenu_Click"
|
||||
Header="Set bookmark">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Add-Bookmark-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="ClearBookMarkCMenu"
|
||||
Width="Auto"
|
||||
Click="ClearBookMarkCMenu_Click"
|
||||
Header="Clear bookmark">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Clear-Bookmark-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="CopyHexaCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="Copy as hexadecimal">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Copy-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
x:Name="CopyAsciicMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="Copy as ASCII">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Copy-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="CopyAsCMenu" Header="Copy selection as ...">
|
||||
<MenuItem
|
||||
x:Name="CopyCcMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="C" />
|
||||
<MenuItem
|
||||
x:Name="CopyCSharpCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="C#" />
|
||||
<MenuItem
|
||||
x:Name="CopyFSharpCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="F#" />
|
||||
<MenuItem
|
||||
x:Name="CopyJavaCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="Java" />
|
||||
<MenuItem
|
||||
x:Name="CopyVbNetCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="Visual Basic.Net" />
|
||||
<MenuItem
|
||||
x:Name="CopyPascalCMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="Pascal" />
|
||||
<MenuItem
|
||||
x:Name="CopyTblcMenu"
|
||||
Click="CopyToClipBoardCMenu_Click"
|
||||
Header="TBL string (character file loaded)" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="PasteMenu"
|
||||
Click="PasteMenu_Click"
|
||||
Header="Paste without inserting">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Paste-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="FillByteCMenu"
|
||||
Click="FillByteCMenu_Click"
|
||||
Header="Fill selection with byte...">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/0x-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
x:Name="ReplaceByteCMenu"
|
||||
Click="ReplaceByteCMenu_Click"
|
||||
Header="Replace byte in selection...">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/0x-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="DeleteCMenu"
|
||||
Click="DeleteCMenu_Click"
|
||||
Header="Delete">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Delete-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="FindAllCMenu"
|
||||
Click="FindAllCMenu_Click"
|
||||
Header="Find all occurence of selection">
|
||||
<!-- <MenuItem.Icon>
|
||||
<Image Source="/WPFHexaEditor;component/Resources/Icon/Find-Icon.ico" />
|
||||
</MenuItem.Icon> -->
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="SelectAllCMenu"
|
||||
Click="SelectAllCMenu_Click"
|
||||
Header="Select all" />
|
||||
</ContextMenu>
|
||||
</UserControl.ContextMenu>
|
||||
<!--#endregion-->
|
||||
|
||||
<Grid
|
||||
x:Name="BaseGrid"
|
||||
SizeChanged="Grid_SizeChanged" Background="White">
|
||||
|
||||
<!--#region Grid/Column Definitions-->
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="207*" />
|
||||
<ColumnDefinition Width="10*" />
|
||||
<ColumnDefinition Width="20" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="287*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<!--#endregion-->
|
||||
|
||||
<!--#region Data/Infos StackPanel-->
|
||||
<StackPanel
|
||||
x:Name="LinesInfoStackPanel"
|
||||
Grid.Row="1"
|
||||
Margin="2,0,0,0"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<StackPanel
|
||||
x:Name="HexDataStackPanel"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="5,0" />
|
||||
|
||||
<StackPanel
|
||||
x:Name="HexHeaderStackPanel"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="5,0"
|
||||
Orientation="Horizontal" />
|
||||
|
||||
<StackPanel
|
||||
x:Name="StringDataStackPanel"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="5,0,0,0"/>
|
||||
<!--#endregion-->
|
||||
|
||||
<!--#region Statusbar definition-->
|
||||
<Grid
|
||||
x:Name="StatusBarGrid"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="5"
|
||||
VerticalAlignment="Top"
|
||||
Background="#FF252D36"
|
||||
Visibility="Visible">
|
||||
|
||||
<Separator
|
||||
Height="1"
|
||||
Margin="0,0,0,27"
|
||||
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:HexEditor}}, Path=BorderBrush}" />
|
||||
|
||||
<StatusBar Height="27" BorderBrush="#7F748198" Margin="0">
|
||||
<StatusBarItem Padding="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!--<Label
|
||||
Padding="5,5,0,5"
|
||||
Content="{x:Static p:Resources.ZoomString}"
|
||||
FontWeight="Bold" />-->
|
||||
<Label
|
||||
Width="40"
|
||||
Content="{Binding Path=ZoomScale, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}"
|
||||
ContentStringFormat="P0"
|
||||
ToolTip="Zoom" />
|
||||
<Button
|
||||
BorderThickness="0"
|
||||
Click="ZoomResetButton_Click"
|
||||
Content="X"
|
||||
FontWeight="Bold"
|
||||
ToolTip="Reset zoom to 100%" />
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator Background="#7F748198" />
|
||||
<StatusBarItem Width="110" Padding="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Padding="5,5,0,5"
|
||||
Content="Ln"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}">
|
||||
<Label.ToolTip>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="Line :" FontWeight="Bold" />
|
||||
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}" />
|
||||
</StackPanel>
|
||||
</Label.ToolTip>
|
||||
</Label>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator Background="#7F748198" />
|
||||
<StatusBarItem Width="125" Padding="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Padding="5,5,0,5"
|
||||
Content="Position"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}">
|
||||
<Label.ToolTip>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="Position" FontWeight="Bold" />
|
||||
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}" />
|
||||
</StackPanel>
|
||||
</Label.ToolTip>
|
||||
</Label>
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator Background="#7F748198" />
|
||||
<StatusBarItem Width="125" Padding="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Padding="5,5,0,5"
|
||||
Content="Length"
|
||||
FontWeight="Bold" />
|
||||
<Label x:Name="FileLengthKbLabel" ContentStringFormat="N0" />
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
<Separator Background="#7F748198" />
|
||||
<StatusBarItem
|
||||
x:Name="ByteCountPanel"
|
||||
Padding="0"
|
||||
Visibility="Collapsed">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Padding="5,5,0,5"
|
||||
Content="Count of"
|
||||
FontWeight="Bold" />
|
||||
<Label x:Name="CountOfByteLabel" ToolTip="Byte at position start" />
|
||||
<Label Padding="0,5" Content=":" />
|
||||
<Label
|
||||
x:Name="CountOfByteSumLabel"
|
||||
ContentStringFormat="N0"
|
||||
ToolTip="Count of Byte at position start" />
|
||||
</StackPanel>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
|
||||
<Label
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
Width="64"
|
||||
Margin="0,0,5,0"
|
||||
HorizontalAlignment="Right"
|
||||
Content="ReadOnly"
|
||||
FontWeight="Bold"
|
||||
Visibility="{Binding Path=ReadOnlyMode, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" Padding="0,0,0,1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
|
||||
<!--#endregion-->
|
||||
|
||||
<!--#region Scrollbar, marker, and move rectangle-->
|
||||
<ScrollBar
|
||||
x:Name="VerticalScrollBar"
|
||||
Style="{StaticResource VerticalScrollBarStyle}"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="4"
|
||||
Width="20"
|
||||
HorizontalAlignment="Right"
|
||||
LargeChange="100"
|
||||
SmallChange="1"
|
||||
ValueChanged="VerticalScrollBar_ValueChanged" />
|
||||
|
||||
<Grid
|
||||
x:Name="MarkerGrid"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="4"
|
||||
Margin="0,17" />
|
||||
|
||||
<Rectangle
|
||||
x:Name="BottomRectangle"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="4"
|
||||
Height="10"
|
||||
VerticalAlignment="Bottom"
|
||||
Fill="#FF252D36"
|
||||
MouseDown="BottomRectangle_MouseDown"
|
||||
MouseEnter="BottomRectangle_MouseEnter"
|
||||
MouseLeave="BottomRectangle_MouseLeave"
|
||||
Opacity="0" />
|
||||
|
||||
<Rectangle
|
||||
x:Name="TopRectangle"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="4"
|
||||
Height="10"
|
||||
VerticalAlignment="Top"
|
||||
Fill="#FF252D36"
|
||||
MouseDown="TopRectangle_MouseDown"
|
||||
MouseEnter="TopRectangle_MouseEnter"
|
||||
MouseLeave="TopRectangle_MouseLeave"
|
||||
Opacity="0" />
|
||||
<!--#endregion-->
|
||||
|
||||
<!--#region Long process-->
|
||||
<ProgressBar
|
||||
x:Name="LongProgressProgressBar"
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="5"
|
||||
Height="3"
|
||||
BorderThickness="0"
|
||||
Maximum="1"
|
||||
Minimum="0" Background="#FF252D36" BorderBrush="#7F748198" />
|
||||
|
||||
<!-- TODO: ADD TEXTBLOCK FOR DETAIL -->
|
||||
<Border
|
||||
x:Name="CancelLongProcessButton"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="4"
|
||||
Width="120"
|
||||
Height="50"
|
||||
BorderBrush="Gray"
|
||||
BorderThickness="2"
|
||||
CornerRadius="4">
|
||||
<Button
|
||||
VerticalContentAlignment="Center"
|
||||
BorderThickness="0"
|
||||
Click="CancelLongProcessButton_Click"
|
||||
Content="Cancel long process"
|
||||
FontWeight="Bold"
|
||||
Opacity="0.9"
|
||||
ToolTip="Click to cancel long process." />
|
||||
</Border>
|
||||
|
||||
<Label
|
||||
x:Name="TblLabel"
|
||||
Grid.Row="2"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="2"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,1,05,1"
|
||||
HorizontalAlignment="Right"
|
||||
Content="TBL string (character file loaded)"
|
||||
FontWeight="Bold"
|
||||
Visibility="Collapsed" />
|
||||
<!--#endregion-->
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
4892
FModel/Forms/HexViewer/HexEditor.xaml.cs
Normal file
4892
FModel/Forms/HexViewer/HexEditor.xaml.cs
Normal file
File diff suppressed because it is too large
Load Diff
286
FModel/Forms/HexViewer/HexViewer.xaml
Normal file
286
FModel/Forms/HexViewer/HexViewer.xaml
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
<Window x:Class="FModel.Forms.HexViewer.HexViewer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:FModel.Forms.HexViewer"
|
||||
xmlns:control="clr-namespace:WpfHexaEditor"
|
||||
xmlns:properties="clr-namespace:FModel.Properties"
|
||||
mc:Ignorable="d"
|
||||
Title="Hex Viewer" Height="700" Width="1000" Closing="Window_Closing" Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Resources/Logo-Icon.ico" >
|
||||
<Grid>
|
||||
<DockPanel>
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem
|
||||
Height="26"
|
||||
Header="File"
|
||||
RenderTransformOrigin="0.656,0.769">
|
||||
<MenuItem
|
||||
x:Name="OpenMenu"
|
||||
Click="OpenMenu_Click"
|
||||
Header="Open...">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/open_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="SaveMenu"
|
||||
Click="SaveMenu_Click"
|
||||
Header="Save">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
Click="SaveAsMenu_Click"
|
||||
Header="Save as..."
|
||||
IsEnabled="True" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="CloseFileMenu"
|
||||
Click="CloseFileMenu_Click"
|
||||
Header="Close file">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FModel;component/Resources/close_file_16x.png" Height="15" Width="15"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="ExitMenu"
|
||||
Click="ExitMenu_Click"
|
||||
Header="Exit" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="Edit">
|
||||
<MenuItem
|
||||
x:Name="UndoMenu"
|
||||
Click="UndoMenu_Click"
|
||||
Header="Undo" />
|
||||
<MenuItem
|
||||
x:Name="RedoMenu"
|
||||
Click="RedoMenu_Click"
|
||||
Header="Redo" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="FindMenu"
|
||||
Click="FindMenu_Click"
|
||||
Header="Find..." />
|
||||
<MenuItem
|
||||
x:Name="ReplaceMenu"
|
||||
Click="ReplaceMenu_Click"
|
||||
Header="Find and replace..." />
|
||||
<MenuItem
|
||||
x:Name="FindAllSelection"
|
||||
Click="FindAllSelection_Click"
|
||||
Header="Find all occurence of selection" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="SetReadOnlyMenu"
|
||||
Click="SetReadOnlyMenu_Click"
|
||||
Header="Read only"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=ReadOnly, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="CopyHexaMenu"
|
||||
Click="CopyHexaMenu_Click"
|
||||
Header="Copy hexadecimal string" />
|
||||
<MenuItem
|
||||
x:Name="CopyStringMenu"
|
||||
Click="CopyStringMenu_Click"
|
||||
Header="Copy ASCII string" />
|
||||
<MenuItem
|
||||
x:Name="DeleteSelectionMenu"
|
||||
Click="DeleteSelectionMenu_Click"
|
||||
Header="Delete selection" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
x:Name="SelectAllButton"
|
||||
Click="SelectAllButton_Click"
|
||||
Header="Select all" />
|
||||
<Separator />
|
||||
<MenuItem Header="Bookmarks">
|
||||
<MenuItem
|
||||
x:Name="SetBookMarkButton"
|
||||
Click="SetBookMarkButton_Click"
|
||||
Header="Set position as bookmark" />
|
||||
<MenuItem
|
||||
x:Name="DeleteBookmark"
|
||||
Click="DeleteBookmark_Click"
|
||||
Header="Remove all bookmarks" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Character table">
|
||||
<MenuItem
|
||||
x:Name="CTableAsciiButton"
|
||||
Click="CTableASCIIButton_Click"
|
||||
Header="ASCII"
|
||||
IsCheckable="True" />
|
||||
<MenuItem
|
||||
x:Name="CTableTblButton"
|
||||
Click="CTableTBLButton_Click"
|
||||
Header="Load TBL file" />
|
||||
<MenuItem
|
||||
x:Name="CTableTblDefaultEbcdicButton"
|
||||
Click="CTableTblDefaultEBCDICButton_Click"
|
||||
Header="Load Build-in TBL : EBCDIC with special character" />
|
||||
<MenuItem
|
||||
x:Name="CTableTblDefaultEbcdicnoSpButton"
|
||||
Click="CTableTblDefaultEBCDICNoSPButton_Click"
|
||||
Header="Load Build-in TBL : EBCDIC no special character" />
|
||||
<MenuItem
|
||||
x:Name="CTableTblDefaultAsciiButton"
|
||||
Click="CTableTBLDefaultASCIIButton_Click"
|
||||
Header="Load Build-in TBL : ASCII" />
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="PositionMenu" Header="Position">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Width="100" Content="Byte per line" Padding="0" />
|
||||
<TextBox
|
||||
Width="96"
|
||||
VerticalContentAlignment="Center"
|
||||
Text="{Binding BytePerLine, ElementName=HexEdit, UpdateSourceTrigger=LostFocus}"
|
||||
TextWrapping="Wrap" Foreground="White" Padding="0,0,0,0" />
|
||||
<Label Content="(Lost Focus)" Padding="10,0,0,0" />
|
||||
</StackPanel>
|
||||
<Separator />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Width="100" Content="Byte shit left" Padding="0" />
|
||||
<control:HexBox
|
||||
x:Name="HbBsl"
|
||||
Width="96"
|
||||
ToolTip="ByteShiftLeft test" Height="15" />
|
||||
<Separator />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Width="100" Content="Set position" Padding="0" />
|
||||
<TextBox
|
||||
x:Name="PositionText"
|
||||
Width="75"
|
||||
VerticalContentAlignment="Center"
|
||||
TextChanged="PositionText_TextChanged" Padding="0" Foreground="White" />
|
||||
<Button
|
||||
x:Name="GoPositionButton"
|
||||
Click="GOPosition_Click"
|
||||
Content="GO"
|
||||
IsEnabled="False" Padding="0,-2,0,0" Width="28" Foreground="White" Background="#FF333C46" Margin="5,0,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Width="100" Content="Set position" Padding="0" />
|
||||
<control:HexBox
|
||||
x:Name="HbSetPosition"
|
||||
Width="96"
|
||||
Height="15" />
|
||||
</StackPanel>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem x:Name="ViewMenu" Header="View">
|
||||
<MenuItem
|
||||
x:Name="ShowHeaderMenu"
|
||||
Click="ShowHeaderMenu_Click"
|
||||
Header="Header visibility"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=HeaderVisibility, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
|
||||
<MenuItem
|
||||
Click="StatusBarVisibility_Click"
|
||||
Header="Statusbar visibility"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=StatusBarVisibility, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="OptionMenu" Header="Options">
|
||||
<MenuItem
|
||||
Header="Allow context menu"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowContextMenu, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Show byte ToolTip"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=ShowByteToolTip, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Auto highlight bytes same as the selected byte"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowAutoHighLightSelectionByte, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Auto select all same byte of SelectionStart in rage at double click"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowAutoSelectSameByteAtDoubleClick, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Count the number of the selected byte"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowByteCount, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Header="Hide byte are deleted"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=HideByteDeleted, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Allow the possibility to delete byte"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowDeleteByte, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Allow expend at end of file"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowExtend, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Header="Allow drop over control"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowDrop, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Allow file drop"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowFileDrop, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuItem
|
||||
Header="Allow text drop"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowTextDrop, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Header="Allow zoom"
|
||||
IsCheckable="True"
|
||||
IsChecked="{Binding ElementName=HexEdit, Path=AllowZoom, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Slider
|
||||
x:Name="ZoomSlider"
|
||||
Style="{StaticResource Horizontal_Slider}"
|
||||
Width="225"
|
||||
LargeChange="0.1"
|
||||
Maximum="2"
|
||||
Minimum="0.5"
|
||||
ToolTip="Zoom editor (50% to 200%)"
|
||||
Value="{Binding ElementName=HexEdit, Path=ZoomScale}" MinHeight="19" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<TabControl>
|
||||
<TabItem x:Name="TabHexEditor"
|
||||
Height="20"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Header="{Binding ElementName=HexEdit, Path=FileName, Converter={StaticResource FilenameConverter}}">
|
||||
<control:HexEditor
|
||||
x:Name="HexEdit"
|
||||
Width="Auto"
|
||||
Height="Auto"
|
||||
AllowByteCount="False"
|
||||
AllowDrop="True"
|
||||
AllowExtend="False"
|
||||
AppendNeedConfirmation="True"
|
||||
ApplicationName="Hex Viewer"
|
||||
BorderThickness="1"
|
||||
ByteGrouping="FourByte"
|
||||
ByteShiftLeft="{Binding LongValue, ElementName=HbBsl, UpdateSourceTrigger=PropertyChanged}"
|
||||
ByteSpacerPositioning="HexBytePanel"
|
||||
ByteSpacerVisualStyle="Dash"
|
||||
ByteSpacerWidthTickness="Normal"
|
||||
DataStringVisual="Hexadecimal"
|
||||
DefaultCopyToClipboardMode="HexaString"
|
||||
ForegroundSecondColor="Blue"
|
||||
OffSetStringVisual="Hexadecimal"
|
||||
UseCustomBackGroudBlock="True" BorderBrush="#7F748198" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
217
FModel/Forms/HexViewer/HexViewer.xaml.cs
Normal file
217
FModel/Forms/HexViewer/HexViewer.xaml.cs
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using WpfHexaEditor.Core;
|
||||
using WpfHexaEditor.Core.CharacterTable;
|
||||
using WpfHexaEditor.Dialog;
|
||||
using FModel.Properties;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
|
||||
namespace FModel.Forms.HexViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour HexViewer.xaml
|
||||
/// </summary>
|
||||
public partial class HexViewer : Window
|
||||
{
|
||||
private enum SettingEnum
|
||||
{
|
||||
HeaderVisibility,
|
||||
ReadOnly,
|
||||
ScrollVisibility,
|
||||
StatusBarVisibility
|
||||
}
|
||||
|
||||
public HexViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
UpdateAllSettings();
|
||||
}
|
||||
|
||||
private void OpenMenu_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var fileDialog = new OpenFileDialog();
|
||||
//fileDialog.InitialDirectory = FProp.Default.FOutput_Path + "\\Exports\\";
|
||||
|
||||
if (fileDialog.ShowDialog() != null && File.Exists(fileDialog.FileName))
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
|
||||
HexEdit.FileName = fileDialog.FileName;
|
||||
TabHexEditor.Header = Path.GetFileName(fileDialog.FileName);
|
||||
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveMenu_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
//HexEdit.SaveTBLFile();
|
||||
HexEdit.SubmitChanges();
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
|
||||
private void CloseFileMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CloseProvider();
|
||||
|
||||
private void SetReadOnlyMenu_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.ReadOnly);
|
||||
|
||||
private void ShowHeaderMenu_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.HeaderVisibility);
|
||||
|
||||
private void StatusBarVisibility_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.StatusBarVisibility);
|
||||
|
||||
private void UpdateSetting(SettingEnum setting)
|
||||
{
|
||||
switch (setting)
|
||||
{
|
||||
case SettingEnum.HeaderVisibility:
|
||||
HexEdit.HeaderVisibility = !Settings.Default.HeaderVisibility
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
Settings.Default.HeaderVisibility = HexEdit.HeaderVisibility == Visibility.Visible;
|
||||
break;
|
||||
case SettingEnum.ReadOnly:
|
||||
HexEdit.ReadOnlyMode = Settings.Default.ReadOnly;
|
||||
|
||||
HexEdit.ClearAllChange();
|
||||
HexEdit.RefreshView();
|
||||
break;
|
||||
case SettingEnum.StatusBarVisibility:
|
||||
HexEdit.StatusBarVisibility = !Settings.Default.StatusBarVisibility
|
||||
? Visibility.Collapsed
|
||||
: Visibility.Visible;
|
||||
|
||||
Settings.Default.StatusBarVisibility = HexEdit.StatusBarVisibility == Visibility.Visible;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAllSettings()
|
||||
{
|
||||
UpdateSetting(SettingEnum.HeaderVisibility);
|
||||
UpdateSetting(SettingEnum.ReadOnly);
|
||||
UpdateSetting(SettingEnum.ScrollVisibility);
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
HexEdit.CloseProvider();
|
||||
Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void ExitMenu_Click(object sender, RoutedEventArgs e) => Close();
|
||||
|
||||
private void CopyHexaMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CopyToClipboard(CopyPasteMode.HexaString);
|
||||
|
||||
private void CopyStringMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CopyToClipboard();
|
||||
|
||||
private void DeleteSelectionMenu_Click(object sender, RoutedEventArgs e) => HexEdit.DeleteSelection();
|
||||
|
||||
private void GOPosition_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (long.TryParse(PositionText.Text, out var position))
|
||||
HexEdit.SetPosition(position, 1);
|
||||
else
|
||||
MessageBox.Show("Enter long value.");
|
||||
|
||||
ViewMenu.IsSubmenuOpen = false;
|
||||
}
|
||||
|
||||
private void PositionText_TextChanged(object sender, TextChangedEventArgs e) =>
|
||||
GoPositionButton.IsEnabled = long.TryParse(PositionText.Text, out var _);
|
||||
|
||||
private void UndoMenu_Click(object sender, RoutedEventArgs e) => HexEdit.Undo();
|
||||
|
||||
private void RedoMenu_Click(object sender, RoutedEventArgs e) => HexEdit.Redo();
|
||||
|
||||
private void SetBookMarkButton_Click(object sender, RoutedEventArgs e) => HexEdit.SetBookMark();
|
||||
|
||||
private void DeleteBookmark_Click(object sender, RoutedEventArgs e) => HexEdit.ClearScrollMarker(ScrollMarker.Bookmark);
|
||||
|
||||
private void FindAllSelection_Click(object sender, RoutedEventArgs e) => HexEdit.FindAllSelection(true);
|
||||
|
||||
private void SelectAllButton_Click(object sender, RoutedEventArgs e) => HexEdit.SelectAll();
|
||||
|
||||
private void CTableASCIIButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HexEdit.TypeOfCharacterTable = CharacterTableType.Ascii;
|
||||
CTableAsciiButton.IsChecked = true;
|
||||
CTableTblButton.IsChecked = false;
|
||||
CTableTblDefaultAsciiButton.IsChecked = false;
|
||||
}
|
||||
|
||||
private void CTableTBLButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var fileDialog = new OpenFileDialog();
|
||||
|
||||
if (fileDialog.ShowDialog() != null)
|
||||
{
|
||||
if (File.Exists(fileDialog.FileName))
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
|
||||
HexEdit.LoadTblFile(fileDialog.FileName);
|
||||
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
|
||||
CTableAsciiButton.IsChecked = false;
|
||||
CTableTblButton.IsChecked = true;
|
||||
CTableTblDefaultAsciiButton.IsChecked = false;
|
||||
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CTableTBLDefaultASCIIButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
|
||||
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
|
||||
HexEdit.LoadDefaultTbl();
|
||||
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
|
||||
private void SaveAsMenu_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var fileDialog = new SaveFileDialog();
|
||||
|
||||
if (fileDialog.ShowDialog() != null)
|
||||
HexEdit.SubmitChanges(fileDialog.FileName, true);
|
||||
}
|
||||
|
||||
private void CTableTblDefaultEBCDICButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
|
||||
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
|
||||
HexEdit.LoadDefaultTbl(DefaultCharacterTableType.EbcdicWithSpecialChar);
|
||||
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
|
||||
private void CTableTblDefaultEBCDICNoSPButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.MainWindow.Cursor = Cursors.Wait;
|
||||
|
||||
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
|
||||
HexEdit.LoadDefaultTbl(DefaultCharacterTableType.EbcdicNoSpecialChar);
|
||||
|
||||
Application.Current.MainWindow.Cursor = null;
|
||||
}
|
||||
|
||||
private void FindMenu_Click(object sender, RoutedEventArgs e) =>
|
||||
new FindWindow(HexEdit, HexEdit.SelectionByteArray)
|
||||
{
|
||||
Owner = this
|
||||
}.Show();
|
||||
|
||||
private void ReplaceMenu_Click(object sender, RoutedEventArgs e) =>
|
||||
new FindReplaceWindow(HexEdit, HexEdit.SelectionByteArray)
|
||||
{
|
||||
Owner = this
|
||||
}.Show();
|
||||
}
|
||||
}
|
||||
18
FModel/Forms/HexViewer/MiscelanousDictionary.xaml
Normal file
18
FModel/Forms/HexViewer/MiscelanousDictionary.xaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<!--
|
||||
Apache 2.0 - 2016-2018
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:conv="clr-namespace:WpfHexaEditor.Core.Converters">
|
||||
|
||||
<!-- THIS DICTIONNARY IS USED TO PUT VARIOUS RESSOURCES TYPE -->
|
||||
|
||||
<!-- VALUE CONVERTER -->
|
||||
<conv:LongToHexStringConverter x:Key="LongHexConverter" />
|
||||
<conv:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<conv:HexToLongStringConverter x:Key="HexToLongConverter" />
|
||||
<conv:PathToFilenameConverter x:Key="FilenameConverter"/>
|
||||
</ResourceDictionary>
|
||||
70
FModel/Forms/HexViewer/ReplaceByteWindow.xaml
Normal file
70
FModel/Forms/HexViewer/ReplaceByteWindow.xaml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<Window
|
||||
x:Class="WpfHexaEditor.Dialog.ReplaceByteWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:control="clr-namespace:WpfHexaEditor"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
Title="Enter hexadecimal value ..."
|
||||
Width="417.297"
|
||||
Height="168"
|
||||
x:ClassModifier="internal"
|
||||
Icon="/FModel;component/Logo.ico"
|
||||
ResizeMode="NoResize"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
WindowStyle="SingleBorderWindow"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Button
|
||||
x:Name="OkButton"
|
||||
Width="75"
|
||||
Margin="0,0,90,10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="OKButton_Click"
|
||||
Content="Ok"
|
||||
IsDefault="True"
|
||||
TabIndex="2" />
|
||||
|
||||
<Button
|
||||
Width="75"
|
||||
Height="20"
|
||||
Margin="0,0,10,10"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Content="Cancel"
|
||||
IsCancel="True"
|
||||
TabIndex="3" />
|
||||
|
||||
<Label
|
||||
Margin="10,18,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Byte to search" />
|
||||
|
||||
<control:HexBox
|
||||
x:Name="HexTextBox"
|
||||
Width="Auto"
|
||||
Height="23"
|
||||
Margin="201,19,10,0"
|
||||
VerticalAlignment="Top"
|
||||
MaximumValue="255" />
|
||||
|
||||
<Label
|
||||
Margin="10,60,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Content="Replace by byte" />
|
||||
|
||||
<control:HexBox
|
||||
x:Name="ReplaceHexTextBox"
|
||||
Width="Auto"
|
||||
Height="23"
|
||||
Margin="201,61,10,0"
|
||||
VerticalAlignment="Top"
|
||||
MaximumValue="255" />
|
||||
</Grid>
|
||||
</Window>
|
||||
14
FModel/Forms/HexViewer/ReplaceByteWindow.xaml.cs
Normal file
14
FModel/Forms/HexViewer/ReplaceByteWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System.Windows;
|
||||
|
||||
namespace WpfHexaEditor.Dialog
|
||||
{
|
||||
/// <summary>
|
||||
/// This Window is used to give tow hex value for deal with.
|
||||
/// </summary>
|
||||
internal partial class ReplaceByteWindow
|
||||
{
|
||||
public ReplaceByteWindow() => InitializeComponent();
|
||||
|
||||
private void OKButton_Click(object sender, RoutedEventArgs e) => DialogResult = true;
|
||||
}
|
||||
}
|
||||
299
FModel/Forms/HexViewer/StringByte.cs
Normal file
299
FModel/Forms/HexViewer/StringByte.cs
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
//////////////////////////////////////////////
|
||||
// Apache 2.0 - 2016-2019
|
||||
// Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
// Contributor: Janus Tida
|
||||
//////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using WpfHexaEditor.Core;
|
||||
using WpfHexaEditor.Core.Bytes;
|
||||
using WpfHexaEditor.Core.CharacterTable;
|
||||
|
||||
namespace WpfHexaEditor
|
||||
{
|
||||
internal class StringByte : BaseByte
|
||||
{
|
||||
#region Global class variables
|
||||
|
||||
private bool _tblShowMte = true;
|
||||
|
||||
#endregion Global variable
|
||||
|
||||
#region Contructor
|
||||
|
||||
public StringByte(HexEditor parent) : base(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion Contructor
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Next Byte of this instance (used for TBL/MTE decoding)
|
||||
/// </summary>
|
||||
public byte? ByteNext { get; set; }
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Characters tables
|
||||
|
||||
/// <summary>
|
||||
/// Show or not Multi Title Enconding (MTE) are loaded in TBL file
|
||||
/// </summary>
|
||||
public bool TblShowMte
|
||||
{
|
||||
get => _tblShowMte;
|
||||
set
|
||||
{
|
||||
_tblShowMte = value;
|
||||
UpdateTextRenderFromByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of caracter table are used un hexacontrol.
|
||||
/// For now, somes character table can be readonly but will change in future
|
||||
/// </summary>
|
||||
public CharacterTableType TypeOfCharacterTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom character table
|
||||
/// </summary>
|
||||
public TblStream TblCharacterTable { get; set; }
|
||||
|
||||
#endregion Characters tables
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Update the render of text derived bytecontrol from byte property
|
||||
/// </summary>
|
||||
public override void UpdateTextRenderFromByte()
|
||||
{
|
||||
if (Byte != null)
|
||||
{
|
||||
switch (TypeOfCharacterTable)
|
||||
{
|
||||
case CharacterTableType.Ascii:
|
||||
Text = ByteConverters.ByteToChar(Byte.Value).ToString();
|
||||
break;
|
||||
case CharacterTableType.TblFile:
|
||||
if (TblCharacterTable != null)
|
||||
{
|
||||
ReadOnlyMode = !TblCharacterTable.AllowEdit;
|
||||
|
||||
var content = "#";
|
||||
|
||||
if (TblShowMte && ByteNext.HasValue)
|
||||
content = TblCharacterTable.FindMatch(ByteConverters.ByteToHex(Byte.Value) +
|
||||
ByteConverters.ByteToHex(ByteNext.Value), true);
|
||||
|
||||
if (content == "#")
|
||||
content = TblCharacterTable.FindMatch(ByteConverters.ByteToHex(Byte.Value), true);
|
||||
|
||||
Text = content;
|
||||
}
|
||||
else
|
||||
goto case CharacterTableType.Ascii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Text = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Background,foreground and font property
|
||||
/// </summary>
|
||||
public override void UpdateVisual()
|
||||
{
|
||||
if (IsSelected)
|
||||
{
|
||||
FontWeight = _parent.FontWeight;
|
||||
Foreground = _parent.ForegroundContrast;
|
||||
|
||||
Background = FirstSelected ? _parent.SelectionFirstColor : _parent.SelectionSecondColor;
|
||||
}
|
||||
else if (IsHighLight)
|
||||
{
|
||||
FontWeight = _parent.FontWeight;
|
||||
Foreground = _parent.Foreground;
|
||||
Background = _parent.HighLightColor;
|
||||
}
|
||||
else if (Action != ByteAction.Nothing)
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case ByteAction.Modified:
|
||||
FontWeight = FontWeights.Bold;
|
||||
Background = _parent.ByteModifiedColor;
|
||||
Foreground = _parent.Foreground;
|
||||
break;
|
||||
|
||||
case ByteAction.Deleted:
|
||||
FontWeight = FontWeights.Bold;
|
||||
Background = _parent.ByteDeletedColor;
|
||||
Foreground = _parent.Foreground;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#region TBL COLORING
|
||||
var cbb = _parent.GetCustomBackgroundBlock(BytePositionInStream);
|
||||
|
||||
Description = cbb != null ? cbb.Description : "";
|
||||
|
||||
Background = cbb != null ? cbb.Color : Brushes.Transparent;
|
||||
FontWeight = _parent.FontWeight;
|
||||
Foreground = _parent.Foreground;
|
||||
|
||||
if (TypeOfCharacterTable == CharacterTableType.TblFile)
|
||||
switch (Dte.TypeDte(Text))
|
||||
{
|
||||
case DteType.DualTitleEncoding:
|
||||
Foreground = _parent.TbldteColor;
|
||||
break;
|
||||
case DteType.MultipleTitleEncoding:
|
||||
Foreground = _parent.TblmteColor;
|
||||
break;
|
||||
case DteType.EndLine:
|
||||
Foreground = _parent.TblEndLineColor;
|
||||
break;
|
||||
case DteType.EndBlock:
|
||||
Foreground = _parent.TblEndBlockColor;
|
||||
break;
|
||||
default:
|
||||
Foreground = _parent.TblDefaultColor;
|
||||
break;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
UpdateAutoHighLiteSelectionByteVisual();
|
||||
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render the control
|
||||
/// </summary>
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
base.OnRender(dc);
|
||||
|
||||
#region Update width of control
|
||||
//It's 8-10 time more fastest to update width on render for TBL string
|
||||
switch (TypeOfCharacterTable)
|
||||
{
|
||||
case CharacterTableType.Ascii:
|
||||
Width = 12;
|
||||
break;
|
||||
case CharacterTableType.TblFile:
|
||||
Width = TextFormatted?.Width > 12 ? TextFormatted.Width : 12;
|
||||
break;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear control
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
ByteNext = null;
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
||||
#region Events delegate
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if (Byte == null) return;
|
||||
|
||||
if (KeyValidation(e)) return;
|
||||
|
||||
//MODIFY ASCII...
|
||||
if (!ReadOnlyMode)
|
||||
{
|
||||
var isok = false;
|
||||
|
||||
if (Keyboard.GetKeyStates(Key.CapsLock) == KeyStates.Toggled)
|
||||
{
|
||||
if (Keyboard.Modifiers != ModifierKeys.Shift && Keyboard.Modifiers != ModifierKeys.Control &&
|
||||
e.Key != Key.RightShift && e.Key != Key.LeftShift)
|
||||
{
|
||||
Text = KeyValidator.GetCharFromKey(e.Key).ToString();
|
||||
isok = true;
|
||||
}
|
||||
else if (Keyboard.Modifiers == ModifierKeys.Shift && Keyboard.Modifiers != ModifierKeys.Control &&
|
||||
e.Key != Key.RightShift && e.Key != Key.LeftShift)
|
||||
{
|
||||
isok = true;
|
||||
Text = KeyValidator.GetCharFromKey(e.Key).ToString().ToLower();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Keyboard.Modifiers != ModifierKeys.Shift && Keyboard.Modifiers != ModifierKeys.Control &&
|
||||
e.Key != Key.RightShift && e.Key != Key.LeftShift)
|
||||
{
|
||||
Text = KeyValidator.GetCharFromKey(e.Key).ToString().ToLower();
|
||||
isok = true;
|
||||
}
|
||||
else if (Keyboard.Modifiers == ModifierKeys.Shift && Keyboard.Modifiers != ModifierKeys.Control &&
|
||||
e.Key != Key.RightShift && e.Key != Key.LeftShift)
|
||||
{
|
||||
isok = true;
|
||||
Text = KeyValidator.GetCharFromKey(e.Key).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
//Move focus event
|
||||
if (isok)
|
||||
{
|
||||
Action = ByteAction.Modified;
|
||||
Byte = ByteConverters.CharToByte(Text[0]);
|
||||
|
||||
//Insert byte at end of file
|
||||
if (_parent.Length == BytePositionInStream + 1)
|
||||
{
|
||||
byte[] byteToAppend = { 0 };
|
||||
_parent.AppendByte(byteToAppend);
|
||||
}
|
||||
|
||||
OnMoveNext(new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
#endregion Events delegate
|
||||
|
||||
#region Caret events
|
||||
|
||||
protected override void OnGotFocus(RoutedEventArgs e)
|
||||
{
|
||||
//TODO: complete caret implemention ....
|
||||
|
||||
_parent.SetCaretMode(CaretMode.Overwrite);
|
||||
|
||||
if (ReadOnlyMode || Byte == null)
|
||||
_parent.HideCaret();
|
||||
else
|
||||
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(0, 0)));
|
||||
|
||||
base.OnGotFocus(e);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
86
FModel/Forms/HexViewer/ToolTipDictionary.xaml
Normal file
86
FModel/Forms/HexViewer/ToolTipDictionary.xaml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="./MiscelanousDictionary.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- USED FOR TOOLTIP OF IBYTECONTROL -->
|
||||
<ToolTip x:Key="ByteToolTip">
|
||||
<ToolTip.RenderTransform>
|
||||
<ScaleTransform ScaleX="0.7" ScaleY="0.7" />
|
||||
</ToolTip.RenderTransform>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Value"
|
||||
FontWeight="Bold" />
|
||||
<Label
|
||||
Width="50"
|
||||
Content="Byte"
|
||||
FontWeight="Bold" />
|
||||
<Label Width="70" Content="{Binding Byte, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Content="Hex" FontWeight="Bold" />
|
||||
<Label Content="{Binding Byte, Converter={StaticResource LongHexConverter}, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Position"
|
||||
FontWeight="Bold" />
|
||||
<Label
|
||||
Width="50"
|
||||
Content="Long"
|
||||
FontWeight="Bold" />
|
||||
<Label Width="70" Content="{Binding BytePositionInStream, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Content="Hex" FontWeight="Bold" />
|
||||
<Label Content="{Binding BytePositionInStream, Converter={StaticResource LongHexConverter}, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
<Separator />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Byte action"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="{Binding Action, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
<Separator />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Description"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ToolTip>
|
||||
|
||||
<!-- USED FOR TOOLTIP OF SCROLL MARKER -->
|
||||
<ToolTip x:Key="ScrollMarkerSearchToolTip">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Position"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="Long" FontWeight="Bold" />
|
||||
<Label Content="{Binding BytePositionInStream, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Label Content="Hex" FontWeight="Bold" />
|
||||
<Label Content="{Binding BytePositionInStream, Converter={StaticResource LongHexConverter}, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label
|
||||
Width="120"
|
||||
Content="Description"
|
||||
FontWeight="Bold" />
|
||||
<Label Content="{Binding Description, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</StackPanel>
|
||||
<Separator />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="Click to go to at position." FontWeight="Bold" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ToolTip>
|
||||
</ResourceDictionary>
|
||||
240
FModel/Forms/MergeImages.Designer.cs
generated
240
FModel/Forms/MergeImages.Designer.cs
generated
|
|
@ -1,240 +0,0 @@
|
|||
namespace FModel.Forms
|
||||
{
|
||||
partial class MergeImages
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MergeImages));
|
||||
this.listBox1 = new System.Windows.Forms.ListBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.button3 = new System.Windows.Forms.Button();
|
||||
this.button4 = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.button7 = new System.Windows.Forms.Button();
|
||||
this.button6 = new System.Windows.Forms.Button();
|
||||
this.trackBar1 = new System.Windows.Forms.TrackBar();
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.button5 = new System.Windows.Forms.Button();
|
||||
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.groupBox1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// listBox1
|
||||
//
|
||||
this.listBox1.FormattingEnabled = true;
|
||||
this.listBox1.Location = new System.Drawing.Point(6, 48);
|
||||
this.listBox1.Name = "listBox1";
|
||||
this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
|
||||
this.listBox1.Size = new System.Drawing.Size(307, 238);
|
||||
this.listBox1.TabIndex = 0;
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Location = new System.Drawing.Point(6, 19);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(75, 23);
|
||||
this.button1.TabIndex = 1;
|
||||
this.button1.Text = "Add Images";
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
this.button2.Location = new System.Drawing.Point(515, 309);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(100, 23);
|
||||
this.button2.TabIndex = 2;
|
||||
this.button2.Text = "Save Image";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// button3
|
||||
//
|
||||
this.button3.Location = new System.Drawing.Point(122, 19);
|
||||
this.button3.Name = "button3";
|
||||
this.button3.Size = new System.Drawing.Size(75, 23);
|
||||
this.button3.TabIndex = 3;
|
||||
this.button3.Text = "Remove";
|
||||
this.button3.UseVisualStyleBackColor = true;
|
||||
this.button3.Click += new System.EventHandler(this.button3_Click);
|
||||
//
|
||||
// button4
|
||||
//
|
||||
this.button4.ForeColor = System.Drawing.Color.Red;
|
||||
this.button4.Location = new System.Drawing.Point(238, 19);
|
||||
this.button4.Name = "button4";
|
||||
this.button4.Size = new System.Drawing.Size(75, 23);
|
||||
this.button4.TabIndex = 4;
|
||||
this.button4.Text = "Clear";
|
||||
this.button4.UseVisualStyleBackColor = true;
|
||||
this.button4.Click += new System.EventHandler(this.button4_Click);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.button7);
|
||||
this.groupBox1.Controls.Add(this.button6);
|
||||
this.groupBox1.Controls.Add(this.button1);
|
||||
this.groupBox1.Controls.Add(this.listBox1);
|
||||
this.groupBox1.Controls.Add(this.button3);
|
||||
this.groupBox1.Controls.Add(this.button4);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(319, 320);
|
||||
this.groupBox1.TabIndex = 7;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "List";
|
||||
//
|
||||
// button7
|
||||
//
|
||||
this.button7.Location = new System.Drawing.Point(202, 291);
|
||||
this.button7.Name = "button7";
|
||||
this.button7.Size = new System.Drawing.Size(51, 23);
|
||||
this.button7.TabIndex = 6;
|
||||
this.button7.Text = "Down";
|
||||
this.button7.UseVisualStyleBackColor = true;
|
||||
this.button7.Click += new System.EventHandler(this.button7_Click);
|
||||
//
|
||||
// button6
|
||||
//
|
||||
this.button6.Location = new System.Drawing.Point(66, 291);
|
||||
this.button6.Name = "button6";
|
||||
this.button6.Size = new System.Drawing.Size(51, 23);
|
||||
this.button6.TabIndex = 5;
|
||||
this.button6.Text = "Up";
|
||||
this.button6.UseVisualStyleBackColor = true;
|
||||
this.button6.Click += new System.EventHandler(this.button6_Click);
|
||||
//
|
||||
// trackBar1
|
||||
//
|
||||
this.trackBar1.LargeChange = 0;
|
||||
this.trackBar1.Location = new System.Drawing.Point(337, 268);
|
||||
this.trackBar1.Maximum = 20;
|
||||
this.trackBar1.Minimum = 1;
|
||||
this.trackBar1.Name = "trackBar1";
|
||||
this.trackBar1.Size = new System.Drawing.Size(278, 45);
|
||||
this.trackBar1.SmallChange = 0;
|
||||
this.trackBar1.TabIndex = 1;
|
||||
this.trackBar1.Value = 7;
|
||||
this.trackBar1.Scroll += new System.EventHandler(this.TrackBar1_Scroll);
|
||||
//
|
||||
// pictureBox1
|
||||
//
|
||||
this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pictureBox1.Location = new System.Drawing.Point(337, 18);
|
||||
this.pictureBox1.Name = "pictureBox1";
|
||||
this.pictureBox1.Size = new System.Drawing.Size(278, 244);
|
||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBox1.TabIndex = 9;
|
||||
this.pictureBox1.TabStop = false;
|
||||
//
|
||||
// button5
|
||||
//
|
||||
this.button5.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
this.button5.Location = new System.Drawing.Point(409, 309);
|
||||
this.button5.Name = "button5";
|
||||
this.button5.Size = new System.Drawing.Size(100, 23);
|
||||
this.button5.TabIndex = 10;
|
||||
this.button5.Text = "Open Image";
|
||||
this.button5.UseVisualStyleBackColor = true;
|
||||
this.button5.Click += new System.EventHandler(this.Button5_Click);
|
||||
//
|
||||
// backgroundWorker1
|
||||
//
|
||||
this.backgroundWorker1.WorkerReportsProgress = true;
|
||||
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker1_DoWork);
|
||||
this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.BackgroundWorker1_ProgressChanged);
|
||||
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker1_RunWorkerCompleted);
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Location = new System.Drawing.Point(12, 338);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(603, 16);
|
||||
this.progressBar1.Step = 1;
|
||||
this.progressBar1.TabIndex = 11;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.ForeColor = System.Drawing.Color.Red;
|
||||
this.label1.Location = new System.Drawing.Point(337, 314);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(68, 13);
|
||||
this.label1.TabIndex = 12;
|
||||
this.label1.Text = "Delay 300ms";
|
||||
//
|
||||
// MergeImages
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(636, 364);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.progressBar1);
|
||||
this.Controls.Add(this.button5);
|
||||
this.Controls.Add(this.pictureBox1);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.button2);
|
||||
this.Controls.Add(this.trackBar1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "MergeImages";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Merge Images";
|
||||
this.Load += new System.EventHandler(this.MergeImages_Load);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ListBox listBox1;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.Button button3;
|
||||
private System.Windows.Forms.Button button4;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.TrackBar trackBar1;
|
||||
private System.Windows.Forms.PictureBox pictureBox1;
|
||||
private System.Windows.Forms.Button button5;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker1;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button button7;
|
||||
private System.Windows.Forms.Button button6;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,324 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Web.UI.WebControls;
|
||||
using Button = System.Windows.Forms.Button;
|
||||
using Image = System.Drawing.Image;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using FModel.Properties;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
public partial class MergeImages : Form
|
||||
{
|
||||
private static List<Image> selectedImages { get; set; }
|
||||
private static Bitmap bmp { get; set; }
|
||||
private static Timer _scrollingTimer = null;
|
||||
private static List<Control> allControls { get; set; }
|
||||
|
||||
public MergeImages()
|
||||
{
|
||||
InitializeComponent();
|
||||
AddAllControls();
|
||||
}
|
||||
|
||||
private void MergeImages_Load(object sender, EventArgs e)
|
||||
{
|
||||
listBox1.Items.Clear();
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog theDialog = new OpenFileDialog();
|
||||
theDialog.Multiselect = true;
|
||||
theDialog.InitialDirectory = App.DefaultOutputPath + "\\Icons\\";
|
||||
theDialog.Title = @"Choose your images";
|
||||
theDialog.Filter = @"PNG Files (*.png)|*.png|JPEG Files (*.jpg)|*.jpg|BMP Files (*.bmp)|*.bmp|All Files (*.*)|*.*";
|
||||
|
||||
if (theDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
AddFiles(theDialog.FileNames);
|
||||
|
||||
ReloadImages();
|
||||
}
|
||||
}
|
||||
private void AddFiles(string[] files)
|
||||
{
|
||||
if (files.Count() > 0)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
listBox1.Items.Add(new ListItem(Path.GetFileName(file), file));
|
||||
}
|
||||
}
|
||||
}
|
||||
private void mergeImages(List<Image> mySelectedImages)
|
||||
{
|
||||
int numperrow = 7;
|
||||
Invoke(new Action(() =>
|
||||
{
|
||||
numperrow = trackBar1.Value;
|
||||
}));
|
||||
var w = 527 * numperrow;
|
||||
if (mySelectedImages.Count * 527 < 527 * numperrow)
|
||||
{
|
||||
w = mySelectedImages.Count * 527;
|
||||
}
|
||||
|
||||
int h = int.Parse(Math.Ceiling(double.Parse(mySelectedImages.Count.ToString()) / numperrow).ToString(CultureInfo.InvariantCulture)) * 527;
|
||||
bmp = new Bitmap(w - 5, h - 5);
|
||||
|
||||
var num = 1;
|
||||
var curW = 0;
|
||||
var curH = 0;
|
||||
|
||||
for (int i = 0; i < mySelectedImages.Count; i++)
|
||||
{
|
||||
int percentage = (i + 1) * 100 / mySelectedImages.Count;
|
||||
backgroundWorker1.ReportProgress(percentage);
|
||||
|
||||
using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.DrawImage(ImageUtilities.ResizeImage(mySelectedImages[i], 522, 522), new PointF(curW, curH));
|
||||
if (num % numperrow == 0)
|
||||
{
|
||||
curW = 0;
|
||||
curH += 527;
|
||||
num += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
curW += 527;
|
||||
num += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (pictureBox1.Image != null)
|
||||
{
|
||||
SaveFileDialog saveTheDialog = new SaveFileDialog();
|
||||
saveTheDialog.Title = @"Save Icon";
|
||||
saveTheDialog.Filter = @"PNG Files (*.png)|*.png";
|
||||
saveTheDialog.InitialDirectory = App.DefaultOutputPath;
|
||||
saveTheDialog.FileName = "Merger";
|
||||
if (saveTheDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
pictureBox1.Image.Save(saveTheDialog.FileName, ImageFormat.Png);
|
||||
new UpdateMyConsole(Path.GetFileNameWithoutExtension(saveTheDialog.FileName), Color.Crimson).AppendToConsole();
|
||||
new UpdateMyConsole(" successfully saved", Color.Black, true).AppendToConsole();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listBox1.Items.Count > 0 && listBox1.SelectedIndices.Count > 0)
|
||||
{
|
||||
for (int i = listBox1.SelectedIndices.Count - 1; i >= 0; --i)
|
||||
{
|
||||
listBox1.Items.RemoveAt(listBox1.SelectedIndices[i]);
|
||||
}
|
||||
|
||||
ReloadImages();
|
||||
}
|
||||
}
|
||||
|
||||
private void button4_Click(object sender, EventArgs e)
|
||||
{
|
||||
listBox1.Items.Clear();
|
||||
pictureBox1.Image = null;
|
||||
progressBar1.Value = 0;
|
||||
}
|
||||
|
||||
private void Button5_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (pictureBox1.Image != null)
|
||||
{
|
||||
var newForm = new Form();
|
||||
PictureBox pb = new PictureBox();
|
||||
pb.Dock = DockStyle.Fill;
|
||||
pb.Image = pictureBox1.Image;
|
||||
pb.SizeMode = PictureBoxSizeMode.Zoom;
|
||||
|
||||
newForm.WindowState = FormWindowState.Maximized;
|
||||
newForm.Size = pb.Image.Size;
|
||||
newForm.Icon = Resources.FModel;
|
||||
newForm.Text = "Temporary Merged Image";
|
||||
newForm.StartPosition = FormStartPosition.CenterScreen;
|
||||
newForm.Controls.Add(pb);
|
||||
newForm.Show();
|
||||
}
|
||||
}
|
||||
|
||||
private void BackgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
|
||||
{
|
||||
if ((selectedImages != null && selectedImages.Count > 0) || listBox1.Items.Count > 0)
|
||||
{
|
||||
selectedImages = new List<Image>();
|
||||
for (int i = 0; i < listBox1.Items.Count; ++i)
|
||||
{
|
||||
selectedImages.Add(Image.FromFile(((ListItem)listBox1.Items[i]).Value));
|
||||
}
|
||||
mergeImages(selectedImages);
|
||||
}
|
||||
}
|
||||
|
||||
private void BackgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (bmp != null)
|
||||
{
|
||||
pictureBox1.Image = bmp;
|
||||
}
|
||||
|
||||
GC.Collect();
|
||||
backgroundWorker1.Dispose();
|
||||
|
||||
if (allControls.Count > 0)
|
||||
{
|
||||
foreach (Control control in allControls)
|
||||
{
|
||||
if (control != null)
|
||||
control.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BackgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
|
||||
{
|
||||
progressBar1.Value = e.ProgressPercentage;
|
||||
}
|
||||
|
||||
private void TrackBar1_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
if (_scrollingTimer == null)
|
||||
{
|
||||
_scrollingTimer = new Timer()
|
||||
{
|
||||
Enabled = false,
|
||||
Interval = 300,
|
||||
Tag = (sender as TrackBar).Value
|
||||
};
|
||||
_scrollingTimer.Tick += (s, ea) =>
|
||||
{
|
||||
// check to see if the value has changed since we last ticked
|
||||
if (trackBar1.Value == (int)_scrollingTimer.Tag)
|
||||
{
|
||||
// scrolling has stopped so we are good to go ahead and do stuff
|
||||
_scrollingTimer.Stop();
|
||||
|
||||
ReloadImages();
|
||||
|
||||
_scrollingTimer.Dispose();
|
||||
_scrollingTimer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// record the last value seen
|
||||
_scrollingTimer.Tag = trackBar1.Value;
|
||||
}
|
||||
};
|
||||
_scrollingTimer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void button6_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Up
|
||||
bool reloadImage = false;
|
||||
listBox1.BeginUpdate();
|
||||
int[] indices = listBox1.SelectedIndices.Cast<int>().ToArray();
|
||||
if (indices.Length > 0 && indices[0] > 0)
|
||||
{
|
||||
for (int i = 0; i < listBox1.Items.Count; ++i)
|
||||
{
|
||||
if (indices.Contains(i))
|
||||
{
|
||||
object moveItem = listBox1.Items[i];
|
||||
listBox1.Items.Remove(moveItem);
|
||||
listBox1.Items.Insert(i - 1, moveItem);
|
||||
listBox1.SetSelected(i - 1, true);
|
||||
|
||||
reloadImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listBox1.EndUpdate();
|
||||
|
||||
if (reloadImage)
|
||||
ReloadImages();
|
||||
}
|
||||
|
||||
private void button7_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Down
|
||||
bool reloadImage = false;
|
||||
listBox1.BeginUpdate();
|
||||
int[] indices = listBox1.SelectedIndices.Cast<int>().ToArray();
|
||||
if (indices.Length > 0 && indices[indices.Length - 1] < listBox1.Items.Count - 1)
|
||||
{
|
||||
for (int i = listBox1.Items.Count - 1; i > -1; --i)
|
||||
{
|
||||
if (indices.Contains(i))
|
||||
{
|
||||
object itemTemp = listBox1.Items[i];
|
||||
listBox1.Items.Remove(itemTemp);
|
||||
listBox1.Items.Insert(i + 1, itemTemp);
|
||||
listBox1.SetSelected(i + 1, true);
|
||||
reloadImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listBox1.EndUpdate();
|
||||
|
||||
if (reloadImage)
|
||||
ReloadImages();
|
||||
}
|
||||
|
||||
private void ReloadImages()
|
||||
{
|
||||
if (allControls.Count > 0)
|
||||
{
|
||||
foreach (Control control in allControls)
|
||||
{
|
||||
if (control != null)
|
||||
control.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (backgroundWorker1.IsBusy != true)
|
||||
backgroundWorker1.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void AddAllControls()
|
||||
{
|
||||
allControls = new List<Control>();
|
||||
|
||||
if (Controls.Count > 0)
|
||||
{
|
||||
foreach (Control control in Controls)
|
||||
{
|
||||
if (!allControls.Contains(control))
|
||||
allControls.Add(control);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupBox1.Controls.Count > 0)
|
||||
{
|
||||
foreach (Control control in groupBox1.Controls)
|
||||
{
|
||||
if (!allControls.Contains(control))
|
||||
allControls.Add(control);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user