FModel 3.0

This commit is contained in:
Asval 2019-10-27 19:12:00 +01:00
parent cc1b7d029e
commit 7d74ff4c2f
248 changed files with 36499 additions and 20526 deletions

2
.gitignore vendored
View File

@ -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/

View File

@ -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

View File

@ -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
View 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
View 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;
}
}
}

View 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));
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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.

View File

@ -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
View 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
View 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
}
}

View File

@ -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;
}
}

View File

@ -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

View 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>

View 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();
}
}
}

View File

@ -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;
}
}

View File

@ -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

View 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();
}
}
}

View 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
}
}

View 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; }
}
}

View 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;
}
}
}

View 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>

View 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);
}
}
}

View 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>

View 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));
}
}
}

View 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); } }
}
}

View 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>

View 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;
}
}
}

View 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="&lt;&lt; Simple" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="243,10,0,0" Height="27" Click="MinMaxViewButton_OnClick"/>
</Grid>
</DockPanel>
</Window>

View 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;
}
}
}
}

View 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>

View 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;
}
}
}
}
}

View 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>

View 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);
}
}
}

View 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>

View 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();
}
}
}

View 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>

View 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();
}
}
}
}
}
}
}

View 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>

View 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
}
}

View 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>

View 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();
}
}
}

View 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
}

View 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>

View 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}";
}
}

View 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));
}
}

View 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
}
}

File diff suppressed because it is too large Load Diff

View 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));
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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';
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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
}
}

View 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());
}
}

View 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;
}
}

View 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();
}
}

View 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)
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View 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);
}
}

View 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;
}
}

View 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>();
}
}
}

View 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>

View 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;
}
}
}

View 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)
{
}
}
}

View 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;
}
}
}

View 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>

View 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
}
}

View 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>

View 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;
}
}
}

View 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>

View 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;
}
}

View 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="&#x25b2;" />
</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="&#x25bc;" />
</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>

View 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
}
}

View 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
}
}

View 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>

File diff suppressed because it is too large Load Diff

View 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>

View 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();
}
}

View 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>

View 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>

View 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;
}
}

View 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
}
}

View 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>

View File

@ -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;
}
}

View File

@ -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