mirror of
https://github.com/4sval/FModel.git
synced 2026-06-20 15:00:12 -05:00
FModel 3.1
This commit is contained in:
parent
53443b0a31
commit
9b1385fdf1
18
FModel.sln
18
FModel.sln
|
|
@ -1,25 +1,29 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.452
|
||||
VisualStudioVersion = 16.0.29806.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FModel", "FModel\FModel.csproj", "{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FModel", "FModel\FModel.csproj", "{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|x64.Build.0 = Debug|x64
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|x64.ActiveCfg = Release|x64
|
||||
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {42CA5618-EB78-4DDF-95A4-BD589CC52791}
|
||||
SolutionGuid = {FE6EA91D-BBB8-4FBC-875C-25AD92EDB519}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -1,213 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="FModel.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<FModel.Properties.Settings>
|
||||
<setting name="FPak_Path" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="FOutput_Path" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="FPak_MainAES" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="FRarity_Design" serializeAs="String">
|
||||
<value>Default</value>
|
||||
</setting>
|
||||
<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>
|
||||
<setting name="ReloadAES" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="FOpenSounds" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="FAutoExtractRaw" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FAutoSaveJson" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FAutoSaveImg" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="FUM_AssetsType" serializeAs="String">
|
||||
<value>{
|
||||
"[BR] Cosmetics": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/Cosmetics/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] Cosmetics Variants": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/CosmeticVariantTokens/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] Banners": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/BannerToken/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] Challenges": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/ChallengeBundles/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] Consumables": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/Consumables/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[BR] Traps": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/Traps/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[BR] Weapons": {
|
||||
"Path": "/FortniteGame/Content/Athena/Items/Weapons/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] 2D Assets": {
|
||||
"Path": "/FortniteGame/Content/2dAssets/",
|
||||
"isChecked": "True"
|
||||
},
|
||||
"[BR] Featured Images": {
|
||||
"Path": "/FortniteGame/Content/UI/Foundation/Textures/BattleRoyale/FeaturedItems/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Heroes": {
|
||||
"Path": "/FortniteGame/Content/Heroes/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Defenders": {
|
||||
"Path": "/FortniteGame/Content/Items/Defenders/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Schematics": {
|
||||
"Path": "/FortniteGame/Content/Items/Schematics/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Traps": {
|
||||
"Path": "/FortniteGame/Content/Items/Traps/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Weapons": {
|
||||
"Path": "/FortniteGame/Content/Items/Weapons/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Ingredients": {
|
||||
"Path": "/FortniteGame/Content/Items/Ingredients/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] Persistent Resources": {
|
||||
"Path": "/FortniteGame/Content/Items/PersistentResources/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"[STW] CardPacks": {
|
||||
"Path": "/FortniteGame/Content/Items/CardPacks/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"Tokens": {
|
||||
"Path": "/FortniteGame/Content/Items/Tokens/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"Icons": {
|
||||
"Path": "/FortniteGame/Content/UI/Foundation/Textures/Icons/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"Additional Banners": {
|
||||
"Path": "/FortniteGame/Content/UI/Foundation/Textures/Banner/",
|
||||
"isChecked": "False"
|
||||
},
|
||||
"Additional Loading Screens": {
|
||||
"Path": "/FortniteGame/Content/UI/Foundation/Textures/LoadingScreens/",
|
||||
"isChecked": "False"
|
||||
}
|
||||
}</value>
|
||||
</setting>
|
||||
<setting name="ELauncherToken" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="ELauncherExpiration" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
</FModel.Properties.Settings>
|
||||
</userSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="SkiaSharp" publicKeyToken="0738eb9f132ed756" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.68.0.0" newVersion="1.68.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
<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"
|
||||
StartupUri="MainWindow.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 Source="pack://application:,,,/Theme/Style.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/ToastNotifications.Messages;component/Themes/Default.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,80 @@
|
|||
using FModel.Methods.MessageBox;
|
||||
using FModel.Methods.Utilities;
|
||||
using FModel.Discord;
|
||||
using FModel.Logger;
|
||||
using FModel.Utils;
|
||||
using FModel.ViewModels.StatusBar;
|
||||
using FModel.Windows.DarkMessageBox;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace FModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour App.xaml
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
internal static Stopwatch StartTimer { get; private set; }
|
||||
static bool framerateSet = false;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
string errorMessage = string.Format("An unhandled exception occurred: {0}", e.Exception.Message);
|
||||
StartTimer = Stopwatch.StartNew();
|
||||
|
||||
//Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
|
||||
|
||||
DebugHelper.Init(LogsFilePath);
|
||||
DebugHelper.WriteLine("{0} {1}", "[FModel]", "––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––");
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Version]", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Build]", Globals.Build);
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[OS]", Logger.Logger.GetOperatingSystemProductName(true));
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Runtime]", RuntimeInformation.FrameworkDescription);
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Culture]", Thread.CurrentThread.CurrentUICulture);
|
||||
|
||||
StatusBarVm.statusBarViewModel.Set(FModel.Properties.Resources.Initializing, FModel.Properties.Resources.Loading);
|
||||
DiscordIntegration.StartClient();
|
||||
|
||||
base.OnStartup(e);
|
||||
}
|
||||
|
||||
public static string LogsFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
string filename = string.Format("FModel-Log-{0:yyyy-MM-dd}.txt", DateTime.Now);
|
||||
|
||||
// Copy user settings from previous application version if necessary
|
||||
if (FModel.Properties.Settings.Default.UpdateSettings)
|
||||
FModel.Properties.Settings.Default.Upgrade();
|
||||
|
||||
Folders.LoadFolders();
|
||||
|
||||
return Path.Combine(FModel.Properties.Settings.Default.OutputPath + "\\Logs", filename);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
string errorMessage = string.Format(FModel.Properties.Resources.UnhandledExceptionOccured, e.Exception.Message);
|
||||
DebugHelper.WriteException(e.Exception, "thrown in App.xaml.cs by OnDispatcherUnhandledException");
|
||||
DarkMessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
DarkMessageBoxHelper.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
internal static void SetFramerate()
|
||||
{
|
||||
if (!framerateSet)
|
||||
{
|
||||
System.Windows.Media.Animation.Timeline.DesiredFrameRateProperty.OverrideMetadata(
|
||||
typeof(System.Windows.Media.Animation.Timeline),
|
||||
new FrameworkPropertyMetadata { DefaultValue = 10 });
|
||||
framerateSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
FModel/AssemblyInfo.cs
Normal file
10
FModel/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
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));
|
||||
}
|
||||
}
|
||||
102
FModel/Creator/BaseBundle.cs
Normal file
102
FModel/Creator/BaseBundle.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using FModel.Creator.Bundles;
|
||||
using FModel.Creator.Texts;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
public class BaseBundle
|
||||
{
|
||||
public Header DisplayStyle;
|
||||
public string DisplayName;
|
||||
public string FolderName;
|
||||
public string Watermark;
|
||||
public int Width = 1024;
|
||||
public int HeaderHeight = 261; // height is the header basically
|
||||
public int AdditionalSize = 50; // must be increased depending on the number of quests to draw
|
||||
public bool IsDisplayNameShifted;
|
||||
public List<Quest> Quests;
|
||||
public List<CompletionReward> CompletionRewards;
|
||||
|
||||
public BaseBundle()
|
||||
{
|
||||
DisplayStyle = new Header();
|
||||
DisplayName = "";
|
||||
FolderName = "";
|
||||
Watermark = Properties.Settings.Default.ChallengeBannerWatermark;
|
||||
Quests = new List<Quest>();
|
||||
CompletionRewards = new List<CompletionReward>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// used for the settings
|
||||
/// </summary>
|
||||
public BaseBundle(string watermark) : this()
|
||||
{
|
||||
DisplayName = "{DisplayName}";
|
||||
FolderName = "{FolderName}";
|
||||
Watermark = watermark;
|
||||
Quests.Add(new Quest { Description = "", Count = 999, Reward = null });
|
||||
AdditionalSize += 89;
|
||||
}
|
||||
|
||||
public BaseBundle(IUExport export, string assetFolder) : this()
|
||||
{
|
||||
if (export.GetExport<StructProperty>("DisplayStyle") is StructProperty displayStyle)
|
||||
DisplayStyle = new Header(displayStyle, assetFolder);
|
||||
if (export.GetExport<TextProperty>("DisplayName") is TextProperty displayName)
|
||||
DisplayName = Text.GetTextPropertyBase(displayName);
|
||||
|
||||
if (export.GetExport<ArrayProperty>("CareerQuestBitShifts") is ArrayProperty careerQuestBitShifts)
|
||||
{
|
||||
foreach (SoftObjectProperty questPath in careerQuestBitShifts.Value)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(questPath.Value.AssetPathName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
Quests.Add(new Quest(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (export.GetExport<ArrayProperty>("BundleCompletionRewards") is ArrayProperty bundleCompletionRewards)
|
||||
{
|
||||
foreach (StructProperty completionReward in bundleCompletionRewards.Value)
|
||||
{
|
||||
if (completionReward.Value is UObject reward &&
|
||||
reward.TryGetValue("CompletionCount", out var c) && c is IntProperty completionCount &&
|
||||
reward.TryGetValue("Rewards", out var r) && r is ArrayProperty rewards)
|
||||
{
|
||||
foreach (StructProperty rew in rewards.Value)
|
||||
{
|
||||
if (rew.Value is UObject re &&
|
||||
re.TryGetValue("Quantity", out var q) && q is IntProperty quantity &&
|
||||
re.TryGetValue("TemplateId", out var t) && t is StrProperty templateId &&
|
||||
re.TryGetValue("ItemDefinition", out var d) && d is SoftObjectProperty itemDefinition)
|
||||
{
|
||||
if (!itemDefinition.Value.AssetPathName.IsNone &&
|
||||
!itemDefinition.Value.AssetPathName.String.StartsWith("/Game/Items/Tokens/") &&
|
||||
!itemDefinition.Value.AssetPathName.String.StartsWith("/Game/Athena/Items/Quests"))
|
||||
{
|
||||
CompletionRewards.Add(new CompletionReward(completionCount, quantity, itemDefinition));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(templateId.Value))
|
||||
{
|
||||
CompletionRewards.Add(new CompletionReward(completionCount, quantity, templateId.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FolderName = assetFolder;
|
||||
AdditionalSize += 95 * Quests.Count;
|
||||
if (CompletionRewards.Count > 0) AdditionalSize += 50 + (95 * CompletionRewards.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
126
FModel/Creator/BaseIcon.cs
Normal file
126
FModel/Creator/BaseIcon.cs
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
using FModel.Creator.Icons;
|
||||
using FModel.Creator.Rarities;
|
||||
using FModel.Creator.Stats;
|
||||
using FModel.Creator.Texts;
|
||||
using FModel.Utils;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
public class BaseIcon
|
||||
{
|
||||
public SKBitmap FallbackImage;
|
||||
public SKBitmap IconImage;
|
||||
public SKBitmap RarityBackgroundImage;
|
||||
public SKBitmap[] UserFacingFlags;
|
||||
public SKColor[] RarityBackgroundColors;
|
||||
public SKColor[] RarityBorderColor;
|
||||
public string DisplayName;
|
||||
public string Description;
|
||||
public string ShortDescription;
|
||||
public string CosmeticSource;
|
||||
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
|
||||
public int AdditionalSize = 0; // must be increased if there are weapon stats, hero abilities or more to draw/show
|
||||
public int Margin = 2;
|
||||
public List<Statistic> Stats;
|
||||
|
||||
public BaseIcon()
|
||||
{
|
||||
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png")).Stream);
|
||||
IconImage = FallbackImage;
|
||||
RarityBackgroundImage = null;
|
||||
UserFacingFlags = null;
|
||||
RarityBackgroundColors = new SKColor[2] { SKColor.Parse("5EBC36"), SKColor.Parse("305C15") };
|
||||
RarityBorderColor = new SKColor[2] { SKColor.Parse("74EF52"), SKColor.Parse("74EF52") };
|
||||
DisplayName = "";
|
||||
Description = "";
|
||||
ShortDescription = "";
|
||||
CosmeticSource = "";
|
||||
Stats = new List<Statistic>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// used to get low res icons ONLY
|
||||
/// </summary>
|
||||
/// <param name="export"></param>
|
||||
/// <param name="assetName"></param>
|
||||
public BaseIcon(IUExport export, string assetName) : this()
|
||||
{
|
||||
if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
|
||||
LargeSmallImage.GetPreviewImage(this, itemDef, assetName, false);
|
||||
else if (export.GetExport<SoftObjectProperty>("SmallPreviewImage", "SmallImage") is SoftObjectProperty previewImage)
|
||||
LargeSmallImage.GetPreviewImage(this, previewImage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Order:
|
||||
/// 1. Rarity
|
||||
/// 2. Image
|
||||
/// 3. Text
|
||||
/// 1. DisplayName
|
||||
/// 2. Description
|
||||
/// 3. Misc
|
||||
/// 4. GameplayTags
|
||||
/// 1. order doesn't matter
|
||||
/// 2. the importance here is to get the description before gameplay tags
|
||||
/// </summary>
|
||||
public BaseIcon(IUExport export, string exportType, string assetName) : this()
|
||||
{
|
||||
// rarity
|
||||
if (export.GetExport<ObjectProperty>("Series") is ObjectProperty series)
|
||||
Serie.GetRarity(this, series);
|
||||
else if (Properties.Settings.Default.UseGameColors) // override default green
|
||||
Rarity.GetInGameRarity(this, export.GetExport<EnumProperty>("Rarity")); // uncommon will be triggered by Rarity being null
|
||||
else if (export.GetExport<EnumProperty>("Rarity") is EnumProperty rarity)
|
||||
Rarity.GetHardCodedRarity(this, rarity);
|
||||
|
||||
// image
|
||||
if (Properties.Settings.Default.UseItemShopIcon &&
|
||||
DisplayAssetImage.GetDisplayAssetImage(this, export.GetExport<SoftObjectProperty>("DisplayAssetPath"), assetName))
|
||||
{ } // ^^^^ will return false if image not found, if so, we try to get the normal icon
|
||||
else if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
|
||||
LargeSmallImage.GetPreviewImage(this, itemDef, assetName);
|
||||
else if (export.GetExport<SoftObjectProperty>("LargePreviewImage", "SmallPreviewImage", "ItemDisplayAsset") is SoftObjectProperty previewImage)
|
||||
LargeSmallImage.GetPreviewImage(this, previewImage);
|
||||
else if (export.GetExport<StructProperty>("IconBrush") is StructProperty iconBrush) // abilities
|
||||
LargeSmallImage.GetPreviewImage(this, iconBrush);
|
||||
|
||||
// text
|
||||
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is TextProperty displayName)
|
||||
DisplayName = Text.GetTextPropertyBase(displayName);
|
||||
if (export.GetExport<TextProperty>("Description", "DefaultBodyText") is TextProperty description)
|
||||
Description = Text.GetTextPropertyBase(description);
|
||||
else if (export.GetExport<ArrayProperty>("Description") is ArrayProperty arrayDescription) // abilities
|
||||
Description = Text.GetTextPropertyBase(arrayDescription);
|
||||
if (export.GetExport<StructProperty>("MaxStackSize") is StructProperty maxStackSize)
|
||||
ShortDescription = Text.GetMaxStackSize(maxStackSize);
|
||||
else if (export.GetExport<TextProperty>("ShortDescription") is TextProperty shortDescription)
|
||||
ShortDescription = Text.GetTextPropertyBase(shortDescription);
|
||||
else if (exportType.Equals("AthenaItemWrapDefinition")) // if no ShortDescription it's most likely a wrap
|
||||
ShortDescription = Localizations.GetLocalization("Fort.Cosmetics", "ItemWrapShortDescription", "Wrap");
|
||||
|
||||
// gameplaytags
|
||||
if (export.GetExport<StructProperty>("GameplayTags") is StructProperty gameplayTags)
|
||||
GameplayTag.GetGameplayTags(this, gameplayTags, exportType);
|
||||
else if (export.GetExport<ObjectProperty>("cosmetic_item") is ObjectProperty cosmeticItem) // variants
|
||||
CosmeticSource = cosmeticItem.Value.Resource.ObjectName.String;
|
||||
|
||||
if (export.GetExport<SoftObjectProperty>("AmmoData") is SoftObjectProperty ammoData)
|
||||
Statistics.GetAmmoData(this, ammoData);
|
||||
if (export.GetExport<StructProperty>("WeaponStatHandle") is StructProperty weaponStatHandle)
|
||||
Statistics.GetWeaponStats(this, weaponStatHandle);
|
||||
if (export.GetExport<ObjectProperty>("HeroGameplayDefinition") is ObjectProperty heroGameplayDefinition)
|
||||
Statistics.GetHeroStats(this, heroGameplayDefinition);
|
||||
|
||||
/* Please do not add Schematics support because it takes way too much memory */
|
||||
/* Thank the STW Dev Team for using a 5,69Mb file to get... Oh nvm, they all left */
|
||||
|
||||
AdditionalSize = 48 * Stats.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
FModel/Creator/BaseUserOption.cs
Normal file
166
FModel/Creator/BaseUserOption.cs
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
using FModel.Creator.Texts;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
public class Options
|
||||
{
|
||||
public string Option;
|
||||
public SKColor Color = SKColor.Parse("55C5FC").WithAlpha(150);
|
||||
}
|
||||
|
||||
public class BaseUserOption
|
||||
{
|
||||
private readonly SKPaint descriptionPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = Text.TypeFaces.DisplayNameTypeface,
|
||||
TextSize = 25,
|
||||
Color = SKColor.Parse("88DBFF"),
|
||||
};
|
||||
|
||||
public string OptionDisplayName;
|
||||
public string OptionDescription;
|
||||
public List<Options> OptionValues = new List<Options>();
|
||||
public int Width = 512;
|
||||
public int Height = 128;
|
||||
public int Margin = 32;
|
||||
|
||||
public BaseUserOption(IUExport export)
|
||||
{
|
||||
if (export.GetExport<TextProperty>("OptionDisplayName") is TextProperty optionDisplayName)
|
||||
OptionDisplayName = Text.GetTextPropertyBase(optionDisplayName).ToUpperInvariant();
|
||||
if (export.GetExport<TextProperty>("OptionDescription") is TextProperty optionDescription)
|
||||
{
|
||||
OptionDescription = Text.GetTextPropertyBase(optionDescription);
|
||||
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(OptionDescription, descriptionPaint, Width - Margin).Length;
|
||||
Height += (int)descriptionPaint.TextSize;
|
||||
}
|
||||
|
||||
if (export.GetExport<ArrayProperty>("OptionValues") is ArrayProperty optionValues)
|
||||
{
|
||||
OptionValues = new List<Options>(optionValues.Value.Length);
|
||||
for (int i = 0; i < OptionValues.Capacity; i++)
|
||||
{
|
||||
if (optionValues.Value[i] is StructProperty s && s.Value is UObject option)
|
||||
{
|
||||
if (option.TryGetValue("DisplayName", out var v1) && v1 is TextProperty displayName)
|
||||
{
|
||||
var opt = new Options { Option = Text.GetTextPropertyBase(displayName).ToUpperInvariant() };
|
||||
if (option.TryGetValue("Value", out var v) && v is StructProperty value && value.Value is FLinearColor color)
|
||||
opt.Color = SKColor.Parse(color.Hex).WithAlpha(150);
|
||||
OptionValues.Add(opt);
|
||||
}
|
||||
else if (option.TryGetValue("PrimaryAssetName", out var v2) && v2 is NameProperty primaryAssetName)
|
||||
OptionValues.Add(new Options { Option = primaryAssetName.Value.String });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (export.GetExport<TextProperty>("OptionOnText") is TextProperty optionOnText)
|
||||
OptionValues.Add(new Options { Option = Text.GetTextPropertyBase(optionOnText).ToUpperInvariant() });
|
||||
if (export.GetExport<TextProperty>("OptionOffText") is TextProperty optionOffText)
|
||||
OptionValues.Add(new Options { Option = Text.GetTextPropertyBase(optionOffText).ToUpperInvariant() });
|
||||
|
||||
if (export.GetExport<IntProperty>("Min", "DefaultValue") is IntProperty iMin &&
|
||||
export.GetExport<IntProperty>("Max") is IntProperty iMax)
|
||||
{
|
||||
int increment = iMin.Value;
|
||||
if (export.GetExport<IntProperty>("IncrementValue") is IntProperty incrementValue)
|
||||
increment = incrementValue.Value;
|
||||
|
||||
for (int i = iMin.Value; i <= iMax.Value; i += increment)
|
||||
{
|
||||
OptionValues.Add(new Options { Option = i.ToString() });
|
||||
}
|
||||
}
|
||||
|
||||
if (export.GetExport<FloatProperty>("Min") is FloatProperty fMin &&
|
||||
export.GetExport<FloatProperty>("Max") is FloatProperty fMax)
|
||||
{
|
||||
float increment = fMin.Value;
|
||||
if (export.GetExport<FloatProperty>("IncrementValue") is FloatProperty incrementValue)
|
||||
increment = incrementValue.Value;
|
||||
|
||||
for (float i = fMin.Value; i <= fMax.Value; i += increment)
|
||||
{
|
||||
OptionValues.Add(new Options { Option = i.ToString() });
|
||||
}
|
||||
}
|
||||
|
||||
Height += Margin;
|
||||
Height += 35 * OptionValues.Count;
|
||||
}
|
||||
|
||||
public void Draw(SKCanvas c)
|
||||
{
|
||||
c.DrawRect(new SKRect(0, 0, Width, Height),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Shader = SKShader.CreateLinearGradient(
|
||||
new SKPoint(Width / 2, Height),
|
||||
new SKPoint(Width, Height / 4),
|
||||
new SKColor[2] { SKColor.Parse("01369C"), SKColor.Parse("1273C8") },
|
||||
SKShaderTileMode.Clamp)
|
||||
});
|
||||
|
||||
int textSize = 45;
|
||||
SKPaint namePaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = Text.TypeFaces.DisplayNameTypeface,
|
||||
TextSize = textSize,
|
||||
Color = SKColors.White,
|
||||
TextAlign = SKTextAlign.Left
|
||||
};
|
||||
|
||||
// resize if too long
|
||||
while (namePaint.MeasureText(OptionDisplayName) > (Width - (Margin * 2)))
|
||||
{
|
||||
namePaint.TextSize = textSize -= 2;
|
||||
}
|
||||
int y = Margin + textSize;
|
||||
c.DrawText(OptionDisplayName, Margin, y, namePaint);
|
||||
y += (int)descriptionPaint.TextSize + (Margin / 2);
|
||||
|
||||
// wrap if too long
|
||||
Helper.DrawMultilineText(c, OptionDescription, Width, Margin, ETextSide.Left,
|
||||
new SKRect(Margin, y, Width - Margin, 256), descriptionPaint, out int top);
|
||||
|
||||
int height = 30;
|
||||
int space = 5;
|
||||
foreach (Options option in OptionValues)
|
||||
{
|
||||
c.DrawRect(new SKRect(Margin, top, Width - Margin, top + height),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = option.Color
|
||||
});
|
||||
|
||||
int ts = 20;
|
||||
c.DrawText(option.Option, Margin + (space * 2), top + (ts * 1.1f),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = Text.TypeFaces.DisplayNameTypeface,
|
||||
TextSize = ts,
|
||||
Color = SKColor.Parse("EEFFFF"),
|
||||
TextAlign = SKTextAlign.Left
|
||||
});
|
||||
|
||||
top += height + space;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
FModel/Creator/Bundles/CompletionReward.cs
Normal file
60
FModel/Creator/Bundles/CompletionReward.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using FModel.Utils;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using System;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
public class CompletionReward
|
||||
{
|
||||
private const string _TRIGGER1 = "<text color=\"FFF\" case=\"upper\" fontface=\"black\">";
|
||||
private const string _TRIGGER2 = "</>";
|
||||
public string CompletionText;
|
||||
public Reward Reward;
|
||||
|
||||
public CompletionReward(IntProperty completionCount)
|
||||
{
|
||||
string all = Localizations.GetLocalization("AthenaChallengeDetailsEntry", "CompletionRewardFormat_All", "Complete <text color=\"FFF\" case=\"upper\" fontface=\"black\">all {0} challenges</> to earn the reward item");
|
||||
string allFormated = ReformatString(all, completionCount.Value.ToString(), true);
|
||||
string any = Localizations.GetLocalization("AthenaChallengeDetailsEntry", "CompletionRewardFormat", "Complete <text color=\"FFF\" case=\"upper\" fontface=\"black\">any {0} challenges</> to earn the reward item");
|
||||
string anyFormated = ReformatString(any, completionCount.Value.ToString(), false);
|
||||
CompletionText = completionCount.Value >= 0 ? anyFormated : allFormated;
|
||||
|
||||
Reward = null;
|
||||
}
|
||||
|
||||
public CompletionReward(IntProperty completionCount, IntProperty quantity, SoftObjectProperty itemDefinition) : this(completionCount)
|
||||
{
|
||||
Reward = new Reward(quantity, itemDefinition);
|
||||
}
|
||||
|
||||
public CompletionReward(IntProperty completionCount, IntProperty quantity, string reward) : this(completionCount)
|
||||
{
|
||||
Reward = new Reward(quantity, reward);
|
||||
}
|
||||
|
||||
private string ReformatString(string s, string completionCount, bool isAll)
|
||||
{
|
||||
s = s.Replace("({0})", "{0}").Replace("{QuestNumber}", "<text color=\"FFF\" case=\"upper\" fontface=\"black\">{0}</>");
|
||||
|
||||
int index = s.IndexOf("|plural(", StringComparison.CurrentCultureIgnoreCase);
|
||||
if (index > -1)
|
||||
{
|
||||
int i = s.Substring(index).IndexOf(')', StringComparison.CurrentCultureIgnoreCase);
|
||||
s = s.Replace(s.Substring(index, i + 1), string.Empty).Replace("{0} {0}", "{0}");
|
||||
}
|
||||
|
||||
int index1 = s.IndexOf(_TRIGGER1, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (index1 < 0) index1 = 0;
|
||||
string partOne = s.Substring(0, index1);
|
||||
|
||||
string partTemp = s.Substring(index1 + _TRIGGER1.Length);
|
||||
int index2 = partTemp.IndexOf(_TRIGGER2, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (index2 < 0) index2 = 0;
|
||||
string partUpper = partTemp.Substring(0, index2).ToUpper().Replace("{0}", isAll ? string.Empty : completionCount);
|
||||
|
||||
string partTwo = partTemp.Substring(index2 + _TRIGGER2.Length);
|
||||
|
||||
return string.Format("{0}{1}{2}", partOne, partUpper, partTwo).Replace(" ", " ").Replace(" ,", ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
106
FModel/Creator/Bundles/Header.cs
Normal file
106
FModel/Creator/Bundles/Header.cs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
public class Header
|
||||
{
|
||||
public SKColor PrimaryColor;
|
||||
public SKColor SecondaryColor;
|
||||
public SKColor AccentColor;
|
||||
public SKBitmap DisplayImage; // 256x256
|
||||
public SKBitmap CustomBackground; // 1024x256
|
||||
|
||||
private readonly Random _random = new Random(Environment.TickCount);
|
||||
private readonly string[] _randomColors = new string[255]
|
||||
{
|
||||
"F44336", "FFEBEE", "FFCDD2", "EF9A9A", "E57373", "EF5350", "E53935", "D32F2F", "C62828", "B71C1C",
|
||||
"FF8A80", "FF5252", "FF1744", "D50000", "FCE4EC", "F8BBD0", "F48FB1", "F06292", "EC407A", "E91E63",
|
||||
"D81B60", "C2185B", "AD1457", "880E4F", "FF80AB", "FF4081", "F50057", "C51162", "F3E5F5", "E1BEE7",
|
||||
"CE93D8", "BA68C8", "AB47BC", "9C27B0", "8E24AA", "7B1FA2", "6A1B9A", "4A148C", "EA80FC", "E040FB",
|
||||
"D500F9", "AA00FF", "EDE7F6", "D1C4E9", "B39DDB", "9575CD", "7E57C2", "673AB7", "5E35B1", "512DA8",
|
||||
"4527A0", "311B92", "B388FF", "7C4DFF", "651FFF", "6200EA", "E8EAF6", "C5CAE9", "9FA8DA", "7986CB",
|
||||
"5C6BC0", "3F51B5", "3949AB", "303F9F", "283593", "1A237E", "8C9EFF", "536DFE", "3D5AFE", "304FFE",
|
||||
"E3F2FD", "BBDEFB", "90CAF9", "64B5F6", "42A5F5", "2196F3", "1E88E5", "1976D2", "1565C0", "0D47A1",
|
||||
"82B1FF", "448AFF", "2979FF", "2962FF", "E1F5FE", "B3E5FC", "81D4FA", "4FC3F7", "29B6F6", "03A9F4",
|
||||
"039BE5", "0288D1", "0277BD", "01579B", "80D8FF", "40C4FF", "00B0FF", "0091EA", "E0F7FA", "B2EBF2",
|
||||
"80DEEA", "4DD0E1", "26C6DA", "00BCD4", "00ACC1", "0097A7", "00838F", "006064", "84FFFF", "18FFFF",
|
||||
"00E5FF", "00B8D4", "E0F2F1", "B2DFDB", "80CBC4", "4DB6AC", "26A69A", "009688", "00897B", "00796B",
|
||||
"00695C", "004D40", "A7FFEB", "64FFDA", "1DE9B6", "00BFA5", "E8F5E9", "C8E6C9", "A5D6A7", "81C784",
|
||||
"66BB6A", "4CAF50", "43A047", "388E3C", "2E7D32", "1B5E20", "B9F6CA", "69F0AE", "00E676", "00C853",
|
||||
"F1F8E9", "DCEDC8", "C5E1A5", "AED581", "9CCC65", "8BC34A", "7CB342", "689F38", "558B2F", "33691E",
|
||||
"CCFF90", "B2FF59", "76FF03", "64DD17", "F9FBE7", "F0F4C3", "E6EE9C", "DCE775", "D4E157", "CDDC39",
|
||||
"C0CA33", "AFB42B", "9E9D24", "827717", "F4FF81", "EEFF41", "C6FF00", "AEEA00", "FFFDE7", "FFF9C4",
|
||||
"FFF59D", "FFF176", "FFEE58", "FFEB3B", "FDD835", "FBC02D", "F9A825", "F57F17", "FFFF8D", "FFFF00",
|
||||
"FFEA00", "FFD600", "FFF8E1", "FFECB3", "FFE082", "FFD54F", "FFCA28", "FFC107", "FFB300", "FFA000",
|
||||
"FF8F00", "FF6F00", "FFE57F", "FFD740", "FFC400", "FFAB00", "FFF3E0", "FFE0B2", "FFCC80", "FFB74D",
|
||||
"FFA726", "FF9800", "FB8C00", "F57C00", "EF6C00", "E65100", "FFD180", "FFAB40", "FF9100", "FF6D00",
|
||||
"FBE9E7", "FFCCBC", "FFAB91", "FF8A65", "FF7043", "FF5722", "F4511E", "E64A19", "D84315", "BF360C",
|
||||
"FF9E80", "FF6E40", "FF3D00", "DD2C00", "EFEBE9", "D7CCC8", "BCAAA4", "A1887F", "8D6E63", "795548",
|
||||
"6D4C41", "5D4037", "4E342E", "3E2723", "FAFAFA", "F5F5F5", "EEEEEE", "E0E0E0", "BDBDBD", "9E9E9E",
|
||||
"757575", "616161", "424242", "212121", "ECEFF1", "CFD8DC", "B0BEC5", "90A4AE", "78909C", "607D8B",
|
||||
"546E7A", "455A64", "37474F", "263238", "000000",
|
||||
};
|
||||
|
||||
public Header()
|
||||
{
|
||||
if (Properties.Settings.Default.UseChallengeBanner)
|
||||
{
|
||||
SKColor mainColor = SKColor.Parse(Properties.Settings.Default.ChallengeBannerPrimaryColor);
|
||||
mainColor.ToHsl(out float h, out float s, out float l);
|
||||
float i = l + 20.0F > 100.0F ? 100.0F - l : 20.0F;
|
||||
|
||||
PrimaryColor = mainColor;
|
||||
SecondaryColor = SKColor.Parse(Properties.Settings.Default.ChallengeBannerSecondaryColor);
|
||||
AccentColor = SKColor.FromHsl(h += i, s, l);
|
||||
DisplayImage = null;
|
||||
if (!string.IsNullOrEmpty(Properties.Settings.Default.ChallengeBannerPath))
|
||||
CustomBackground = SKBitmap.Decode(new FileInfo(Properties.Settings.Default.ChallengeBannerPath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||
else CustomBackground = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SKColor mainColor = SKColor.Parse(_randomColors[_random.Next(0, 255)]);
|
||||
mainColor.ToHsl(out float h, out float s, out float l);
|
||||
while (l > 75 || l < 10)
|
||||
{
|
||||
mainColor = SKColor.Parse(_randomColors[_random.Next(0, 255)]);
|
||||
mainColor.ToHsl(out float _, out float _, out l);
|
||||
}
|
||||
float i = l + 20.0F > 100.0F ? 100.0F - l : 20.0F;
|
||||
|
||||
PrimaryColor = mainColor;
|
||||
SecondaryColor = SKColor.FromHsl(h, s, l += i);
|
||||
AccentColor = SKColor.FromHsl(h += i, s, l);
|
||||
DisplayImage = null;
|
||||
CustomBackground = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Header(StructProperty displayStyle, string assetFolder) : this()
|
||||
{
|
||||
if (displayStyle.Value is UObject o)
|
||||
{
|
||||
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue(out var c1, "PrimaryColor", "Context_LimitedTimeColor") && c1 is StructProperty s1 && s1.Value is FLinearColor primaryColor)
|
||||
PrimaryColor = SKColor.Parse(primaryColor.Hex);
|
||||
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue(out var c2, "SecondaryColor", "Context_BaseColor") && c2 is StructProperty s2 && s2.Value is FLinearColor secondaryColor)
|
||||
SecondaryColor = SKColor.Parse(secondaryColor.Hex);
|
||||
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue("AccentColor", out var c3) && c3 is StructProperty s3 && s3.Value is FLinearColor accentColor)
|
||||
{
|
||||
AccentColor = SKColor.Parse(accentColor.Hex);
|
||||
if (SecondaryColor.Red + SecondaryColor.Green + SecondaryColor.Blue <= 75 || assetFolder.Equals("LTM", StringComparison.CurrentCultureIgnoreCase)) // if secondary is too dark
|
||||
SecondaryColor = AccentColor; // use accent and pray for accent to be ligher
|
||||
}
|
||||
|
||||
if (o.TryGetValue("DisplayImage", out var i) && i is SoftObjectProperty displayImage)
|
||||
DisplayImage = Utils.GetSoftObjectTexture(displayImage);
|
||||
if (CustomBackground == null && o.TryGetValue("CustomBackground", out var b) && b is SoftObjectProperty customBackground)
|
||||
CustomBackground = Utils.GetSoftObjectTexture(customBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
FModel/Creator/Bundles/HeaderStyle.cs
Normal file
98
FModel/Creator/Bundles/HeaderStyle.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
using FModel.Creator.Texts;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
static class HeaderStyle
|
||||
{
|
||||
public static void DrawHeaderPaint(SKCanvas c, BaseBundle icon)
|
||||
{
|
||||
c.DrawRect(new SKRect(0, 0, icon.Width, icon.HeaderHeight), new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = icon.DisplayStyle.PrimaryColor
|
||||
});
|
||||
|
||||
if (icon.DisplayStyle.CustomBackground != null && icon.DisplayStyle.CustomBackground.Height != icon.DisplayStyle.CustomBackground.Width)
|
||||
{
|
||||
icon.IsDisplayNameShifted = false;
|
||||
var bgPaint = new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High, BlendMode = SKBlendMode.Screen };
|
||||
if (Properties.Settings.Default.UseChallengeBanner) bgPaint.Color = SKColors.Transparent.WithAlpha((byte)Properties.Settings.Default.ChallengeBannerOpacity);
|
||||
c.DrawBitmap(icon.DisplayStyle.CustomBackground, new SKRect(0, 0, 1024, 256), bgPaint);
|
||||
}
|
||||
else if (icon.DisplayStyle.DisplayImage != null)
|
||||
{
|
||||
icon.IsDisplayNameShifted = true;
|
||||
if (icon.DisplayStyle.CustomBackground != null && icon.DisplayStyle.CustomBackground.Height == icon.DisplayStyle.CustomBackground.Width)
|
||||
c.DrawBitmap(icon.DisplayStyle.CustomBackground, new SKRect(0, 0, icon.HeaderHeight, icon.HeaderHeight),
|
||||
new SKPaint {
|
||||
IsAntialias = true, FilterQuality = SKFilterQuality.High, BlendMode = SKBlendMode.Screen,
|
||||
ImageFilter = SKImageFilter.CreateDropShadow(2.5F, 0, 20, 0, icon.DisplayStyle.SecondaryColor.WithAlpha(25), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
|
||||
});
|
||||
|
||||
c.DrawBitmap(icon.DisplayStyle.DisplayImage, new SKRect(0, 0, icon.HeaderHeight, icon.HeaderHeight),
|
||||
new SKPaint {
|
||||
IsAntialias = true, FilterQuality = SKFilterQuality.High,
|
||||
ImageFilter = SKImageFilter.CreateDropShadow(-2.5F, 0, 20, 0, icon.DisplayStyle.SecondaryColor.WithAlpha(50), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
|
||||
});
|
||||
}
|
||||
|
||||
SKPath pathTop = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
pathTop.MoveTo(0, icon.HeaderHeight);
|
||||
pathTop.LineTo(icon.Width, icon.HeaderHeight);
|
||||
pathTop.LineTo(icon.Width, icon.HeaderHeight - 19);
|
||||
pathTop.LineTo(icon.Width / 2 + 7, icon.HeaderHeight - 23);
|
||||
pathTop.LineTo(icon.Width / 2 + 13, icon.HeaderHeight - 7);
|
||||
pathTop.LineTo(0, icon.HeaderHeight - 19);
|
||||
pathTop.Close();
|
||||
c.DrawPath(pathTop, new SKPaint {
|
||||
IsAntialias = true, FilterQuality = SKFilterQuality.High, Color = icon.DisplayStyle.SecondaryColor,
|
||||
ImageFilter = SKImageFilter.CreateDropShadow(-5, -5, 0, 0, icon.DisplayStyle.AccentColor.WithAlpha(75), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
|
||||
});
|
||||
|
||||
c.DrawRect(new SKRect(0, icon.HeaderHeight, icon.Width, icon.HeaderHeight + icon.AdditionalSize), new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = icon.DisplayStyle.PrimaryColor.WithAlpha(200) // default background is black, so i'm kinda lowering the brightness here and that's what i want
|
||||
});
|
||||
}
|
||||
|
||||
public static void DrawHeaderText(SKCanvas c, BaseBundle icon)
|
||||
{
|
||||
using SKPaint paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = Text.TypeFaces.BundleDisplayNameTypeface,
|
||||
TextSize = 50,
|
||||
Color = SKColors.White,
|
||||
TextAlign = SKTextAlign.Left,
|
||||
};
|
||||
|
||||
string text = icon.DisplayName.ToUpper();
|
||||
int x = icon.IsDisplayNameShifted ? 300 : 50;
|
||||
while (paint.MeasureText(text) > (icon.Width - x))
|
||||
{
|
||||
paint.TextSize -= 2;
|
||||
}
|
||||
c.DrawText(text, x, 155, paint);
|
||||
|
||||
paint.Color = SKColors.White.WithAlpha(150);
|
||||
paint.TextAlign = SKTextAlign.Right;
|
||||
paint.TextSize = 23;
|
||||
c.DrawText(icon.Watermark
|
||||
.Replace("{BundleName}", text)
|
||||
.Replace("{Date}", DateTime.Now.ToString("dd/MM/yyyy")),
|
||||
icon.Width - 25, icon.HeaderHeight - 40, paint);
|
||||
|
||||
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
|
||||
paint.Color = icon.DisplayStyle.SecondaryColor;
|
||||
paint.TextAlign = SKTextAlign.Left;
|
||||
paint.TextSize = 30;
|
||||
c.DrawText(icon.FolderName.ToUpper(), x, 95, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
FModel/Creator/Bundles/Quest.cs
Normal file
94
FModel/Creator/Bundles/Quest.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
using FModel.Creator.Texts;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
public class Quest
|
||||
{
|
||||
public string Description;
|
||||
public int Count;
|
||||
public Reward Reward;
|
||||
|
||||
public Quest()
|
||||
{
|
||||
Description = "";
|
||||
Count = 0;
|
||||
Reward = null;
|
||||
}
|
||||
|
||||
public Quest(UObject obj) : this()
|
||||
{
|
||||
if (obj.TryGetValue("Description", out var d) && d is TextProperty description)
|
||||
Description = Text.GetTextPropertyBase(description);
|
||||
if (obj.TryGetValue("ObjectiveCompletionCount", out var o) && o is IntProperty objectiveCompletionCount)
|
||||
Count = objectiveCompletionCount.Value;
|
||||
|
||||
if (obj.TryGetValue("Objectives", out var v1) && v1 is ArrayProperty a1 &&
|
||||
a1.Value.Length > 0 && a1.Value[0] is StructProperty s && s.Value is UObject objectives)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Description) && objectives.TryGetValue("Description", out var od) && od is TextProperty objectivesDescription)
|
||||
Description = Text.GetTextPropertyBase(objectivesDescription);
|
||||
|
||||
if (Count == 0 && objectives.TryGetValue("Count", out var c) && c is IntProperty count)
|
||||
Count = count.Value;
|
||||
}
|
||||
|
||||
if (obj.TryGetValue("RewardsTable", out var v4) && v4 is ObjectProperty rewardsTable)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(rewardsTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var u = p.GetExport<UDataTable>();
|
||||
if (u != null && u.TryGetValue("Default", out var i) && i is UObject r &&
|
||||
r.TryGetValue("TemplateId", out var i1) && i1 is NameProperty templateId &&
|
||||
r.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
|
||||
{
|
||||
Reward = new Reward(quantity, templateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Reward == null && obj.TryGetValue("Rewards", out var v2) && v2 is ArrayProperty rewards)
|
||||
{
|
||||
foreach (StructProperty reward in rewards.Value)
|
||||
{
|
||||
if (reward.Value is UObject r1 &&
|
||||
r1.TryGetValue("ItemPrimaryAssetId", out var i1) && i1 is StructProperty itemPrimaryAssetId &&
|
||||
r1.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
|
||||
{
|
||||
if (itemPrimaryAssetId.Value is UObject r2 &&
|
||||
r2.TryGetValue("PrimaryAssetType", out var t1) && t1 is StructProperty primaryAssetType &&
|
||||
r2.TryGetValue("PrimaryAssetName", out var t2) && t2 is NameProperty primaryAssetName)
|
||||
{
|
||||
if (primaryAssetType.Value is UObject r3 && r3.TryGetValue("Name", out var k) && k is NameProperty name)
|
||||
{
|
||||
if (!name.Value.String.Equals("Quest") && !name.Value.String.Equals("Token") &&
|
||||
!name.Value.String.Equals("ChallengeBundle") && !name.Value.String.Equals("GiftBox"))
|
||||
{
|
||||
Reward = new Reward(quantity, primaryAssetName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Reward == null && obj.TryGetValue("HiddenRewards", out var v3) && v3 is ArrayProperty hiddenRewards)
|
||||
{
|
||||
foreach (StructProperty reward in hiddenRewards.Value)
|
||||
{
|
||||
if (reward.Value is UObject r1 &&
|
||||
r1.TryGetValue("TemplateId", out var i1) && i1 is NameProperty templateId &&
|
||||
r1.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
|
||||
{
|
||||
Reward = new Reward(quantity, templateId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
174
FModel/Creator/Bundles/QuestStyle.cs
Normal file
174
FModel/Creator/Bundles/QuestStyle.cs
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
using FModel.Creator.Texts;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
static class QuestStyle
|
||||
{
|
||||
public static void DrawQuests(SKCanvas c, BaseBundle icon)
|
||||
{
|
||||
using SKPaint paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
TextSize = 27,
|
||||
Color = SKColors.White,
|
||||
TextAlign = SKTextAlign.Left,
|
||||
Typeface = Text.TypeFaces.BundleDisplayNameTypeface
|
||||
};
|
||||
|
||||
int y = icon.HeaderHeight + 50;
|
||||
foreach (Quest q in icon.Quests)
|
||||
{
|
||||
DrawQuestBackground(c, icon, y, true);
|
||||
|
||||
paint.TextSize = 27;
|
||||
paint.ImageFilter = null;
|
||||
paint.Color = SKColors.White;
|
||||
paint.TextAlign = SKTextAlign.Left;
|
||||
paint.Typeface = Text.TypeFaces.BundleDisplayNameTypeface;
|
||||
while (paint.MeasureText(q.Description) > icon.Width - 65 - 165)
|
||||
{
|
||||
paint.TextSize -= 1;
|
||||
}
|
||||
c.DrawText(q.Description, new SKPoint(65, y + paint.TextSize + 11), paint);
|
||||
|
||||
paint.TextSize = 16;
|
||||
paint.Color = SKColors.White.WithAlpha(200);
|
||||
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
|
||||
c.DrawText(q.Count.ToString(), new SKPoint(93 + icon.Width - (175 * 3), y + 60), paint);
|
||||
|
||||
if (q.Reward?.RewardIcon != null)
|
||||
{
|
||||
if (q.Reward.IsCountShifted)
|
||||
{
|
||||
int l = q.Reward.RewardQuantity.ToString().Length;
|
||||
paint.TextSize = l >= 5 ? 30 : 35;
|
||||
paint.TextAlign = SKTextAlign.Right;
|
||||
paint.Color = SKColor.Parse(q.Reward.RewardFillColor);
|
||||
paint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 5, 5, SKColor.Parse(q.Reward.RewardBorderColor).WithAlpha(200), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground);
|
||||
c.DrawText(q.Reward.RewardQuantity.ToString(), new SKPoint(icon.Width - 85, y + 47.5F), paint);
|
||||
c.DrawBitmap(q.Reward.RewardIcon, new SKPoint(icon.Width - 30 - q.Reward.RewardIcon.Width, y + 12.5F),
|
||||
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
|
||||
}
|
||||
else
|
||||
c.DrawBitmap(q.Reward.RewardIcon, new SKPoint(icon.Width - 125, y + 5),
|
||||
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
|
||||
}
|
||||
|
||||
y += 95;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawCompletionRewards(SKCanvas c, BaseBundle icon)
|
||||
{
|
||||
using SKPaint paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
TextSize = 35,
|
||||
Color = SKColors.White,
|
||||
TextAlign = SKTextAlign.Left,
|
||||
Typeface = Text.TypeFaces.BundleDisplayNameTypeface
|
||||
};
|
||||
|
||||
int y = icon.HeaderHeight + (50 * 2) + (95 * icon.Quests.Count);
|
||||
foreach (CompletionReward r in icon.CompletionRewards)
|
||||
{
|
||||
DrawQuestBackground(c, icon, y, false);
|
||||
|
||||
paint.TextSize = 35;
|
||||
paint.ImageFilter = null;
|
||||
paint.Color = SKColors.White;
|
||||
paint.TextAlign = SKTextAlign.Left;
|
||||
paint.Typeface = Text.TypeFaces.BundleDisplayNameTypeface;
|
||||
while (paint.MeasureText(r.CompletionText) > icon.Width - 65 - 165)
|
||||
{
|
||||
paint.TextSize -= 1;
|
||||
}
|
||||
c.DrawText(r.CompletionText, new SKPoint(65, y + paint.TextSize + 15), paint);
|
||||
|
||||
if (r.Reward?.RewardIcon != null)
|
||||
{
|
||||
if (r.Reward.IsCountShifted)
|
||||
{
|
||||
int l = r.Reward.RewardQuantity.ToString().Length;
|
||||
paint.TextSize = l >= 5 ? 30 : 35;
|
||||
paint.TextAlign = SKTextAlign.Right;
|
||||
paint.Color = SKColor.Parse(r.Reward.RewardFillColor);
|
||||
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
|
||||
paint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 5, 5, SKColor.Parse(r.Reward.RewardBorderColor).WithAlpha(200), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground);
|
||||
c.DrawText(r.Reward.RewardQuantity.ToString(), new SKPoint(icon.Width - 85, y + 47.5F), paint);
|
||||
c.DrawBitmap(r.Reward.RewardIcon, new SKPoint(icon.Width - 30 - r.Reward.RewardIcon.Width, y + 12.5F),
|
||||
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
|
||||
}
|
||||
else
|
||||
c.DrawBitmap(r.Reward.RewardIcon, new SKPoint(icon.Width - 125, y + 5),
|
||||
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
|
||||
}
|
||||
|
||||
y += 95;
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawQuestBackground(SKCanvas c, BaseBundle icon, int y, bool hasSlider)
|
||||
{
|
||||
SKColor baseColor = icon.DisplayStyle.PrimaryColor;
|
||||
using SKPaint paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = baseColor
|
||||
};
|
||||
using SKPath secondaryRect = new SKPath
|
||||
{
|
||||
FillType = SKPathFillType.EvenOdd
|
||||
};
|
||||
using SKPath selector = new SKPath
|
||||
{
|
||||
FillType = SKPathFillType.EvenOdd
|
||||
};
|
||||
using SKPath slider = new SKPath
|
||||
{
|
||||
FillType = SKPathFillType.EvenOdd
|
||||
};
|
||||
|
||||
c.DrawRect(new SKRect(25, y, icon.Width - 25, y + 75), paint);
|
||||
|
||||
baseColor.ToHsl(out float h, out float s, out float l);
|
||||
baseColor = SKColor.FromHsl(h, s, l + 5);
|
||||
paint.Color = baseColor;
|
||||
|
||||
secondaryRect.MoveTo(32, y + 5);
|
||||
secondaryRect.LineTo(icon.Width - 155, y + 4);
|
||||
secondaryRect.LineTo(icon.Width - 175, y + 68);
|
||||
secondaryRect.LineTo(29, y + 71);
|
||||
secondaryRect.Close();
|
||||
c.DrawPath(secondaryRect, paint);
|
||||
|
||||
paint.Color = icon.DisplayStyle.SecondaryColor;
|
||||
selector.MoveTo(41, y + 38);
|
||||
selector.LineTo(48, y + 34);
|
||||
selector.LineTo(52, y + 39);
|
||||
selector.LineTo(46, y + 44);
|
||||
selector.Close();
|
||||
c.DrawPath(selector, paint);
|
||||
|
||||
if (hasSlider)
|
||||
{
|
||||
slider.MoveTo(65, y + 53);
|
||||
slider.LineTo(65 + icon.Width - (175 * 3), y + 53);
|
||||
slider.LineTo(65 + icon.Width - (175 * 3), y + 58);
|
||||
slider.LineTo(65, y + 58);
|
||||
slider.Close();
|
||||
c.DrawPath(slider, paint);
|
||||
|
||||
paint.TextSize = 14;
|
||||
paint.Color = SKColors.White;
|
||||
paint.TextAlign = SKTextAlign.Left;
|
||||
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
|
||||
c.DrawText("0 / ", new SKPoint(75 + icon.Width - (175 * 3), y + 59), paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
FModel/Creator/Bundles/Reward.cs
Normal file
134
FModel/Creator/Bundles/Reward.cs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace FModel.Creator.Bundles
|
||||
{
|
||||
public class Reward
|
||||
{
|
||||
public int RewardQuantity;
|
||||
public SKBitmap RewardIcon;
|
||||
public string RewardFillColor;
|
||||
public string RewardBorderColor;
|
||||
public bool IsCountShifted;
|
||||
|
||||
public Reward()
|
||||
{
|
||||
RewardQuantity = 0;
|
||||
RewardIcon = null;
|
||||
RewardFillColor = "";
|
||||
RewardBorderColor = "";
|
||||
IsCountShifted = false;
|
||||
}
|
||||
|
||||
public Reward(IntProperty quantity, NameProperty primaryAssetName) : this(quantity, primaryAssetName.Value.String) { }
|
||||
public Reward(IntProperty quantity, string assetName) : this()
|
||||
{
|
||||
RewardQuantity = quantity.Value;
|
||||
|
||||
if (assetName.Contains(':'))
|
||||
{
|
||||
string[] parts = assetName.Split(':');
|
||||
if (parts[0].Equals("HomebaseBannerIcon", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage("/Game/Banners/BannerIcons");
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var c = p.GetExport<UDataTable>();
|
||||
if (c != null && c.TryGetCaseInsensitiveValue(parts[1], out var s) && s is UObject banner)
|
||||
{
|
||||
RewardIcon = new BaseIcon(banner, "BannerIcons.uasset").IconImage.Resize(64, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
else GetReward(parts[1]);
|
||||
}
|
||||
else GetReward(assetName);
|
||||
}
|
||||
|
||||
public Reward(IntProperty quantity, SoftObjectProperty itemDefinition) : this()
|
||||
{
|
||||
RewardQuantity = quantity.Value;
|
||||
|
||||
PakPackage p = Utils.GetPropertyPakPackage(itemDefinition.Value.AssetPathName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var d = p.GetExport<UObject>();
|
||||
if (d != null)
|
||||
{
|
||||
int s1 = itemDefinition.Value.AssetPathName.String.LastIndexOf('/');
|
||||
if (s1 < 0) s1 = 0;
|
||||
int s2 = itemDefinition.Value.AssetPathName.String.LastIndexOf('.') - s1;
|
||||
switch (itemDefinition.Value.AssetPathName.String)
|
||||
{
|
||||
case "/Game/Items/PersistentResources/AthenaBattleStar.AthenaBattleStar":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "FFDB67";
|
||||
RewardBorderColor = "8F4A20";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-BattlePoints").Resize(48, 48);
|
||||
break;
|
||||
case "/Game/Items/PersistentResources/AthenaSeasonalXP.AthenaSeasonalXP":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "E6FDB1";
|
||||
RewardBorderColor = "51830F";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-XPMedium").Resize(48, 48);
|
||||
break;
|
||||
case "/Game/Items/Currency/MtxGiveaway.MtxGiveaway":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "DCE6FF";
|
||||
RewardBorderColor = "64A0AF";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-Items-MTX").Resize(48, 48);
|
||||
break;
|
||||
default:
|
||||
IsCountShifted = false;
|
||||
RewardIcon = new BaseIcon(d, itemDefinition.Value.AssetPathName.String.Substring(s1, s2) + ".uasset").IconImage.Resize(64, 64);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetReward(string trigger)
|
||||
{
|
||||
switch (trigger.ToLower())
|
||||
{
|
||||
case "athenabattlestar":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "FFDB67";
|
||||
RewardBorderColor = "8F4A20";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-BattlePoints").Resize(48, 48);
|
||||
break;
|
||||
case "athenaseasonalxp":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "E6FDB1";
|
||||
RewardBorderColor = "51830F";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-XPMedium").Resize(48, 48);
|
||||
break;
|
||||
case "mtxgiveaway":
|
||||
IsCountShifted = true;
|
||||
RewardFillColor = "DCE6FF";
|
||||
RewardBorderColor = "64A0AF";
|
||||
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-Items-MTX").Resize(48, 48);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
string path = Utils.GetFullPath($"/FortniteGame/Content/Athena/.*?/{trigger}.*").Replace("FortniteGame/Content", "Game");
|
||||
PakPackage p = Utils.GetPropertyPakPackage(path);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var d = p.GetExport<UObject>();
|
||||
if (d != null)
|
||||
{
|
||||
int i = path.LastIndexOf('/');
|
||||
IsCountShifted = false;
|
||||
RewardIcon = new BaseIcon(d, path.Substring(i > 0 ? i : 0) + ".uasset").IconImage.Resize(64, 64);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
180
FModel/Creator/Creator.cs
Normal file
180
FModel/Creator/Creator.cs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
using FModel.Creator.Bundles;
|
||||
using FModel.Creator.Icons;
|
||||
using FModel.Creator.Rarities;
|
||||
using FModel.Creator.Stats;
|
||||
using FModel.Creator.Texts;
|
||||
using FModel.ViewModels.ImageBox;
|
||||
using PakReader.Parsers.Class;
|
||||
using SkiaSharp;
|
||||
using System.IO;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
static class Creator
|
||||
{
|
||||
/// <summary>
|
||||
/// we draw based on the fist export type of the asset, no need to check others it's a waste of time
|
||||
/// i don't cache images because i don't wanna store a lot of SKCanvas in the memory
|
||||
/// </summary>
|
||||
/// <returns>true if an icon has been drawn</returns>
|
||||
public static bool TryDrawIcon(string assetPath, string exportType, IUExport export)
|
||||
{
|
||||
var d = new DirectoryInfo(assetPath);
|
||||
string assetName = d.Name;
|
||||
string assetFolder = d.Parent.Name;
|
||||
if (Text.TypeFaces.NeedReload(false))
|
||||
Text.TypeFaces = new Typefaces(); // when opening bundle creator settings without loading paks first
|
||||
|
||||
// please respect my wave if you wanna add a new exportType
|
||||
// Athena first, then Fort, thank you
|
||||
switch (exportType)
|
||||
{
|
||||
case "AthenaConsumableEmoteItemDefinition":
|
||||
case "AthenaSkyDiveContrailItemDefinition":
|
||||
case "AthenaLoadingScreenItemDefinition":
|
||||
case "AthenaVictoryPoseItemDefinition":
|
||||
case "AthenaPetCarrierItemDefinition":
|
||||
case "AthenaMusicPackItemDefinition":
|
||||
case "AthenaBattleBusItemDefinition":
|
||||
case "AthenaCharacterItemDefinition":
|
||||
case "AthenaBackpackItemDefinition":
|
||||
case "AthenaPickaxeItemDefinition":
|
||||
case "AthenaGadgetItemDefinition":
|
||||
case "AthenaGliderItemDefinition":
|
||||
case "AthenaDailyQuestDefinition":
|
||||
case "AthenaSprayItemDefinition":
|
||||
case "AthenaDanceItemDefinition":
|
||||
case "AthenaEmojiItemDefinition":
|
||||
case "AthenaItemWrapDefinition":
|
||||
case "AthenaToyItemDefinition":
|
||||
case "FortHeroType":
|
||||
case "FortTokenType":
|
||||
case "FortAbilityKit":
|
||||
case "FortWorkerType":
|
||||
case "FortBannerTokenType":
|
||||
case "FortVariantTokenType":
|
||||
case "FortFeatItemDefinition":
|
||||
case "FortStatItemDefinition":
|
||||
case "FortTrapItemDefinition":
|
||||
case "FortAmmoItemDefinition":
|
||||
case "FortQuestItemDefinition":
|
||||
case "FortBadgeItemDefinition":
|
||||
case "FortAwardItemDefinition":
|
||||
case "FortGadgetItemDefinition":
|
||||
case "FortPlaysetItemDefinition":
|
||||
case "FortGiftBoxItemDefinition":
|
||||
case "FortSpyTechItemDefinition":
|
||||
case "FortAccoladeItemDefinition":
|
||||
case "FortCardPackItemDefinition":
|
||||
case "FortDefenderItemDefinition":
|
||||
case "FortCurrencyItemDefinition":
|
||||
case "FortResourceItemDefinition":
|
||||
case "FortSchematicItemDefinition":
|
||||
case "FortIngredientItemDefinition":
|
||||
case "FortWeaponMeleeItemDefinition":
|
||||
case "FortContextTrapItemDefinition":
|
||||
case "FortPlayerPerksItemDefinition":
|
||||
case "FortPlaysetPropItemDefinition":
|
||||
case "FortHomebaseNodeItemDefinition":
|
||||
case "FortWeaponRangedItemDefinition":
|
||||
case "FortNeverPersistItemDefinition":
|
||||
case "FortPlaysetGrenadeItemDefinition":
|
||||
case "FortPersonalVehicleItemDefinition":
|
||||
case "FortHardcoreModifierItemDefinition":
|
||||
case "FortConsumableAccountItemDefinition":
|
||||
case "FortConversionControlItemDefinition":
|
||||
case "FortPersistentResourceItemDefinition":
|
||||
case "FortCampaignHeroLoadoutItemDefinition":
|
||||
case "FortConditionalResourceItemDefinition":
|
||||
case "FortChallengeBundleScheduleDefinition":
|
||||
case "FortWeaponMeleeDualWieldItemDefinition":
|
||||
case "FortDailyRewardScheduleTokenDefinition":
|
||||
{
|
||||
BaseIcon icon = new BaseIcon(export, exportType, assetName);
|
||||
int height = icon.Size + icon.AdditionalSize;
|
||||
using (var ret = new SKBitmap(icon.Size, height, SKColorType.Rgba8888, SKAlphaType.Opaque))
|
||||
using (var c = new SKCanvas(ret))
|
||||
{
|
||||
Rarity.DrawRarity(c, icon);
|
||||
LargeSmallImage.DrawPreviewImage(c, icon);
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.NoText)
|
||||
{
|
||||
Text.DrawBackground(c, icon);
|
||||
Text.DrawDisplayName(c, icon);
|
||||
Text.DrawDescription(c, icon);
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.Mini)
|
||||
{
|
||||
if (!icon.ShortDescription.Equals(icon.DisplayName) && !icon.ShortDescription.Equals(icon.Description))
|
||||
Text.DrawToBottom(c, icon, ETextSide.Left, icon.ShortDescription);
|
||||
Text.DrawToBottom(c, icon, ETextSide.Right, icon.CosmeticSource);
|
||||
}
|
||||
}
|
||||
UserFacingFlag.DrawUserFacingFlags(c, icon);
|
||||
|
||||
// has more things to show
|
||||
if (height > icon.Size)
|
||||
{
|
||||
Statistics.DrawStats(c, icon);
|
||||
}
|
||||
|
||||
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
|
||||
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "FortItemSeriesDefinition":
|
||||
{
|
||||
BaseIcon icon = new BaseIcon();
|
||||
using (var ret = new SKBitmap(icon.Size, icon.Size, SKColorType.Rgba8888, SKAlphaType.Opaque))
|
||||
using (var c = new SKCanvas(ret))
|
||||
{
|
||||
Serie.GetRarity(icon, export);
|
||||
Rarity.DrawRarity(c, icon);
|
||||
|
||||
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
|
||||
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "PlaylistUserOptionEnum":
|
||||
case "PlaylistUserOptionBool":
|
||||
case "PlaylistUserOptionString":
|
||||
case "PlaylistUserOptionIntEnum":
|
||||
case "PlaylistUserOptionIntRange":
|
||||
case "PlaylistUserOptionColorEnum":
|
||||
case "PlaylistUserOptionFloatEnum":
|
||||
case "PlaylistUserOptionFloatRange":
|
||||
case "PlaylistUserOptionPrimaryAsset":
|
||||
case "PlaylistUserOptionCollisionProfileEnum":
|
||||
{
|
||||
BaseUserOption icon = new BaseUserOption(export);
|
||||
using (var ret = new SKBitmap(icon.Width, icon.Height, SKColorType.Rgba8888, SKAlphaType.Opaque))
|
||||
using (var c = new SKCanvas(ret))
|
||||
{
|
||||
icon.Draw(c);
|
||||
|
||||
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
|
||||
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "FortChallengeBundleItemDefinition":
|
||||
{
|
||||
BaseBundle icon = new BaseBundle(export, assetFolder);
|
||||
using (var ret = new SKBitmap(icon.Width, icon.HeaderHeight + icon.AdditionalSize, SKColorType.Rgba8888, SKAlphaType.Opaque))
|
||||
using (var c = new SKCanvas(ret))
|
||||
{
|
||||
HeaderStyle.DrawHeaderPaint(c, icon);
|
||||
HeaderStyle.DrawHeaderText(c, icon);
|
||||
QuestStyle.DrawQuests(c, icon);
|
||||
QuestStyle.DrawCompletionRewards(c, icon);
|
||||
|
||||
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
FModel/Creator/Icons/DisplayAssetImage.cs
Normal file
55
FModel/Creator/Icons/DisplayAssetImage.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
namespace FModel.Creator.Icons
|
||||
{
|
||||
static class DisplayAssetImage
|
||||
{
|
||||
public static bool GetDisplayAssetImage(BaseIcon icon, SoftObjectProperty o, string assetName)
|
||||
{
|
||||
string imageType = "DetailsImage";
|
||||
switch ("DA_Featured_" + assetName)
|
||||
{
|
||||
case "DA_Featured_Glider_ID_141_AshtonBoardwalk.uasset":
|
||||
case "DA_Featured_Glider_ID_150_TechOpsBlue.uasset":
|
||||
case "DA_Featured_Glider_ID_131_SpeedyMidnight.uasset":
|
||||
case "DA_Featured_Pickaxe_ID_178_SpeedyMidnight.uasset":
|
||||
case "DA_Featured_Glider_ID_015_Brite.uasset":
|
||||
case "DA_Featured_Glider_ID_016_Tactical.uasset":
|
||||
case "DA_Featured_Glider_ID_017_Assassin.uasset":
|
||||
case "DA_Featured_Pickaxe_ID_027_Scavenger.uasset":
|
||||
case "DA_Featured_Pickaxe_ID_028_Space.uasset":
|
||||
case "DA_Featured_Pickaxe_ID_029_Assassin.uasset":
|
||||
return false;
|
||||
case "DA_Featured_Glider_ID_070_DarkViking.uasset":
|
||||
case "DA_Featured_CID_319_Athena_Commando_F_Nautilus.uasset":
|
||||
imageType = "TileImage";
|
||||
break;
|
||||
}
|
||||
|
||||
string path = o?.Value.AssetPathName.String;
|
||||
if (string.IsNullOrEmpty(path))
|
||||
path = "/Game/Catalog/DisplayAssets/DA_Featured_" + assetName.Substring(0, assetName.LastIndexOf("."));
|
||||
|
||||
PakPackage p = Utils.GetPropertyPakPackage(path);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj.TryGetValue(imageType, out var v1) && v1 is StructProperty s && s.Value is UObject type &&
|
||||
type.TryGetValue("ResourceObject", out var v2) && v2 is ObjectProperty resourceObject)
|
||||
{
|
||||
if (!resourceObject.Value.Resource.OuterIndex.Resource.ObjectName.String.Contains("/Game/Athena/Prototype/Textures/"))
|
||||
{
|
||||
icon.IconImage = Utils.GetObjectTexture(resourceObject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
FModel/Creator/Icons/LargeSmallImage.cs
Normal file
41
FModel/Creator/Icons/LargeSmallImage.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Icons
|
||||
{
|
||||
static class LargeSmallImage
|
||||
{
|
||||
public static void GetPreviewImage(BaseIcon icon, StructProperty u)
|
||||
{
|
||||
if (u.Value is UObject o && o.TryGetValue("ResourceObject", out var v) && v is ObjectProperty resourceObject)
|
||||
icon.IconImage = Utils.GetObjectTexture(resourceObject);
|
||||
}
|
||||
public static void GetPreviewImage(BaseIcon icon, ObjectProperty o, string assetName) => GetPreviewImage(icon, o, assetName, true);
|
||||
public static void GetPreviewImage(BaseIcon icon, ObjectProperty o, string assetName, bool hightRes)
|
||||
{
|
||||
string path = o.Value.Resource.OuterIndex.Resource.ObjectName.String;
|
||||
if (path.Equals("/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_STWCosmetic_Tier"))
|
||||
path += "_" + assetName.Substring(assetName.LastIndexOf(".") - 1, 1);
|
||||
|
||||
PakPackage p = Utils.GetPropertyPakPackage(path);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
{
|
||||
if (hightRes && obj.TryGetValue("LargePreviewImage", out var sLarge) && sLarge is SoftObjectProperty largePreviewImage)
|
||||
GetPreviewImage(icon, largePreviewImage);
|
||||
else if (obj.TryGetValue("SmallPreviewImage", out var sSmall) && sSmall is SoftObjectProperty smallPreviewImage)
|
||||
GetPreviewImage(icon, smallPreviewImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void GetPreviewImage(BaseIcon icon, SoftObjectProperty s) => icon.IconImage = Utils.GetSoftObjectTexture(s);
|
||||
|
||||
public static void DrawPreviewImage(SKCanvas c, BaseIcon icon) =>
|
||||
c.DrawBitmap(icon.IconImage ?? icon.FallbackImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
|
||||
}
|
||||
}
|
||||
72
FModel/Creator/Icons/UserFacingFlag.cs
Normal file
72
FModel/Creator/Icons/UserFacingFlag.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator.Icons
|
||||
{
|
||||
static class UserFacingFlag
|
||||
{
|
||||
public static void GetUserFacingFlags(List<string> uffs, BaseIcon icon, string exportType)
|
||||
{
|
||||
if (uffs.Count > 0)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage("/Game/Items/ItemCategories"); //PrimaryCategories - SecondaryCategories - TertiaryCategories
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var o = p.GetExport<UObject>();
|
||||
if (o != null && o.TryGetValue("TertiaryCategories", out var tertiaryCategories) && tertiaryCategories is ArrayProperty tertiaryArray)
|
||||
{
|
||||
icon.UserFacingFlags = new SKBitmap[uffs.Count];
|
||||
for (int i = 0; i < uffs.Count; i++)
|
||||
{
|
||||
if (uffs[i].Equals("Cosmetics.UserFacingFlags.HasUpgradeQuests"))
|
||||
{
|
||||
if (exportType.Equals("AthenaPetCarrierItemDefinition"))
|
||||
icon.UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Pets-64.png")).Stream);
|
||||
else
|
||||
icon.UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Quests-64.png")).Stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (StructProperty structProp in tertiaryArray.Value)
|
||||
{
|
||||
if (structProp.Value is UObject mainUObject &&
|
||||
mainUObject.TryGetValue("TagContainer", out var struc1) && struc1 is StructProperty tagContainer && tagContainer.Value is FGameplayTagContainer f && f.GameplayTags.TryGetGameplayTag(uffs[i], out var _) &&
|
||||
mainUObject.TryGetValue("CategoryBrush", out var struc2) && struc2 is StructProperty categoryBrush && categoryBrush.Value is UObject categoryUObject &&
|
||||
categoryUObject.TryGetValue("Brush_XXS", out var struc3) && struc3 is StructProperty brushXXS && brushXXS.Value is UObject brushUObject &&
|
||||
brushUObject.TryGetValue("ResourceObject", out var object1) && object1 is ObjectProperty resourceObject)
|
||||
{
|
||||
icon.UserFacingFlags[i] = Utils.GetObjectTexture(resourceObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawUserFacingFlags(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
if (icon.UserFacingFlags != null)
|
||||
{
|
||||
int size = 25;
|
||||
int x = icon.Margin * (int)2.5;
|
||||
foreach (SKBitmap b in icon.UserFacingFlags)
|
||||
{
|
||||
if (b == null)
|
||||
continue;
|
||||
|
||||
c.DrawBitmap(b.Resize(size, size), new SKPoint(x, icon.Margin * (int)2.5), new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
|
||||
x += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
FModel/Creator/Icons/Watermark.cs
Normal file
31
FModel/Creator/Icons/Watermark.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using SkiaSharp;
|
||||
using System.IO;
|
||||
|
||||
namespace FModel.Creator.Icons
|
||||
{
|
||||
static class Watermark
|
||||
{
|
||||
public static void DrawWatermark(SKCanvas c)
|
||||
{
|
||||
if (Properties.Settings.Default.UseIconWatermark && !string.IsNullOrWhiteSpace(Properties.Settings.Default.IconWatermarkPath))
|
||||
{
|
||||
using SKBitmap watermarkBase = SKBitmap.Decode(new FileInfo(Properties.Settings.Default.IconWatermarkPath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||
int sizeX = watermarkBase.Width * (int)Properties.Settings.Default.IconWatermarkScale / 512;
|
||||
int sizeY = watermarkBase.Height * (int)Properties.Settings.Default.IconWatermarkScale / 512;
|
||||
SKBitmap watermark = watermarkBase.Resize(sizeX, sizeY);
|
||||
|
||||
float left = Properties.Settings.Default.IconWatermarkX;
|
||||
float top = Properties.Settings.Default.IconWatermarkY;
|
||||
float right = left + watermark.Width;
|
||||
float bottom = top + watermark.Height;
|
||||
c.DrawBitmap(watermark, new SKRect(left, top, right, bottom),
|
||||
new SKPaint
|
||||
{
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
IsAntialias = true,
|
||||
Color = SKColors.Transparent.WithAlpha((byte)Properties.Settings.Default.IconWatermarkOpacity)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
FModel/Creator/Rarities/EFortRarity.cs
Normal file
15
FModel/Creator/Rarities/EFortRarity.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace FModel.Creator.Rarities
|
||||
{
|
||||
public enum EFortRarity : int
|
||||
{
|
||||
Common,
|
||||
Uncommon,
|
||||
Rare,
|
||||
Epic,
|
||||
Legendary,
|
||||
Mythic,
|
||||
Transcendent,
|
||||
Unattainable,
|
||||
//Impossible
|
||||
}
|
||||
}
|
||||
171
FModel/Creator/Rarities/Rarity.cs
Normal file
171
FModel/Creator/Rarities/Rarity.cs
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System.Linq;
|
||||
|
||||
namespace FModel.Creator.Rarities
|
||||
{
|
||||
static class Rarity
|
||||
{
|
||||
public static void GetInGameRarity(BaseIcon icon, EnumProperty e)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage("/Game/Balance/RarityData");
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var d = p.GetExport<UObject>();
|
||||
if (d != null)
|
||||
{
|
||||
EFortRarity rarity = EFortRarity.Uncommon;
|
||||
switch (e?.Value.String)
|
||||
{
|
||||
case "EFortRarity::Common":
|
||||
rarity = EFortRarity.Common;
|
||||
break;
|
||||
case "EFortRarity::Rare":
|
||||
rarity = EFortRarity.Rare;
|
||||
break;
|
||||
case "EFortRarity::Epic":
|
||||
case "EFortRarity::Quality":
|
||||
rarity = EFortRarity.Epic;
|
||||
break;
|
||||
case "EFortRarity::Legendary":
|
||||
rarity = EFortRarity.Legendary;
|
||||
break;
|
||||
case "EFortRarity::Mythic":
|
||||
rarity = EFortRarity.Mythic;
|
||||
break;
|
||||
case "EFortRarity::Transcendent":
|
||||
rarity = EFortRarity.Transcendent;
|
||||
break;
|
||||
case "EFortRarity::Unattainable":
|
||||
rarity = EFortRarity.Unattainable;
|
||||
break;
|
||||
}
|
||||
|
||||
if (d.Values.ElementAt((int)rarity) is StructProperty s && s.Value is UObject colors)
|
||||
{
|
||||
if (colors.TryGetValue("Color1", out var c1) && c1 is StructProperty s1 && s1.Value is FLinearColor color1 &&
|
||||
colors.TryGetValue("Color2", out var c2) && c2 is StructProperty s2 && s2.Value is FLinearColor color2 &&
|
||||
colors.TryGetValue("Color3", out var c3) && c3 is StructProperty s3 && s3.Value is FLinearColor color3)
|
||||
{
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse(color1.Hex), SKColor.Parse(color3.Hex) };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse(color2.Hex), SKColor.Parse(color1.Hex) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else GetHardCodedRarity(icon, e);
|
||||
}
|
||||
|
||||
public static void GetHardCodedRarity(BaseIcon icon, EnumProperty e)
|
||||
{
|
||||
switch (e?.Value.String)
|
||||
{
|
||||
case "EFortRarity::Common":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("6D6D6D"), SKColor.Parse("333333") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("9E9E9E"), SKColor.Parse("9E9E9E") };
|
||||
break;
|
||||
case "EFortRarity::Rare":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("3669BB"), SKColor.Parse("133254") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("5180EE"), SKColor.Parse("5180EE") };
|
||||
break;
|
||||
case "EFortRarity::Epic":
|
||||
case "EFortRarity::Quality":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("8138C2"), SKColor.Parse("35155C") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("B251ED"), SKColor.Parse("B251ED") };
|
||||
break;
|
||||
case "EFortRarity::Legendary":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("C06A38"), SKColor.Parse("5C2814") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("EC9650"), SKColor.Parse("EC9650") };
|
||||
break;
|
||||
case "EFortRarity::Mythic":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("BA9C36"), SKColor.Parse("594415") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("EED951"), SKColor.Parse("EED951") };
|
||||
break;
|
||||
case "EFortRarity::Transcendent":
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("D51944"), SKColor.Parse("660522") };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("FF3F58"), SKColor.Parse("FF3F58") };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawRarity(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
// border
|
||||
c.DrawRect(new SKRect(0, 0, icon.Size, icon.Size),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Shader = SKShader.CreateLinearGradient(
|
||||
new SKPoint(icon.Size / 2, icon.Size),
|
||||
new SKPoint(icon.Size, icon.Size / 4),
|
||||
icon.RarityBorderColor,
|
||||
SKShaderTileMode.Clamp)
|
||||
});
|
||||
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Flat:
|
||||
{
|
||||
if (icon.RarityBackgroundImage != null)
|
||||
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
|
||||
else
|
||||
{
|
||||
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = icon.RarityBackgroundColors[0]
|
||||
});
|
||||
|
||||
var paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = icon.RarityBackgroundColors[1].WithAlpha(75)
|
||||
};
|
||||
var pathTop = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
pathTop.MoveTo(icon.Margin, icon.Margin);
|
||||
pathTop.LineTo(icon.Margin + (icon.Size / 17 * 10), icon.Margin);
|
||||
pathTop.LineTo(icon.Margin, icon.Margin + (icon.Size / 17));
|
||||
pathTop.Close();
|
||||
c.DrawPath(pathTop, paint);
|
||||
|
||||
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
|
||||
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
|
||||
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
|
||||
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
|
||||
pathBottom.Close();
|
||||
c.DrawPath(pathBottom, paint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (icon.RarityBackgroundImage != null)
|
||||
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
|
||||
else
|
||||
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Shader = SKShader.CreateRadialGradient(
|
||||
new SKPoint(icon.Size / 2, icon.Size / 2),
|
||||
icon.Size / 5 * 4,
|
||||
icon.RarityBackgroundColors,
|
||||
SKShaderTileMode.Clamp)
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
FModel/Creator/Rarities/Serie.cs
Normal file
40
FModel/Creator/Rarities/Serie.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using FModel.Creator.Texts;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Rarities
|
||||
{
|
||||
static class Serie
|
||||
{
|
||||
public static void GetRarity(BaseIcon icon, ObjectProperty o)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(o.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
GetRarity(icon, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetRarity(BaseIcon icon, IUExport export)
|
||||
{
|
||||
if (export.TryGetValue("BackgroundTexture", out var t) && t is SoftObjectProperty sop)
|
||||
icon.RarityBackgroundImage = Utils.GetSoftObjectTexture(sop);
|
||||
|
||||
if (export.TryGetValue("Colors", out var v) && v is StructProperty s && s.Value is UObject colors)
|
||||
{
|
||||
if (colors.TryGetValue("Color1", out var c1) && c1 is StructProperty s1 && s1.Value is FLinearColor color1 &&
|
||||
colors.TryGetValue("Color2", out var c2) && c2 is StructProperty s2 && s2.Value is FLinearColor color2 &&
|
||||
colors.TryGetValue("Color4", out var c4) && c4 is StructProperty s4 && s4.Value is FLinearColor color4)
|
||||
{
|
||||
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse(color1.Hex), SKColor.Parse(color4.Hex) };
|
||||
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse(color2.Hex), SKColor.Parse(color1.Hex) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
FModel/Creator/Stats/Statistic.cs
Normal file
10
FModel/Creator/Stats/Statistic.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Stats
|
||||
{
|
||||
public class Statistic
|
||||
{
|
||||
public SKBitmap Icon;
|
||||
public string Description;
|
||||
}
|
||||
}
|
||||
203
FModel/Creator/Stats/Statistics.cs
Normal file
203
FModel/Creator/Stats/Statistics.cs
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
using FModel.Creator.Texts;
|
||||
using FModel.Utils;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator.Stats
|
||||
{
|
||||
static class Statistics
|
||||
{
|
||||
public static void GetAmmoData(BaseIcon icon, SoftObjectProperty ammoData)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(ammoData.Value.AssetPathName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj.TryGetValue("DisplayName", out var v1) && v1 is TextProperty displayName &&
|
||||
obj.TryGetValue("SmallPreviewImage", out var v2) && v2 is SoftObjectProperty smallPreviewImage)
|
||||
{
|
||||
icon.Stats.Add(new Statistic
|
||||
{
|
||||
Icon = Utils.GetSoftObjectTexture(smallPreviewImage),
|
||||
Description = Text.GetTextPropertyBase(displayName).ToUpper()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetWeaponStats(BaseIcon icon, StructProperty weaponStatHandle)
|
||||
{
|
||||
if (weaponStatHandle.Value is UObject o1 &&
|
||||
o1.TryGetValue("DataTable", out var c1) && c1 is ObjectProperty dataTable &&
|
||||
o1.TryGetValue("RowName", out var c2) && c2 is NameProperty rowName)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(dataTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var table = p.GetExport<UDataTable>();
|
||||
if (table != null)
|
||||
{
|
||||
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject stats)
|
||||
{
|
||||
if (stats.TryGetValue("ReloadTime", out var s1) && s1 is FloatProperty reloadTime && reloadTime.Value != 0)
|
||||
icon.Stats.Add(new Statistic
|
||||
{
|
||||
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_ReloadTime_Weapon_Stats.png")).Stream),
|
||||
Description = $"{Localizations.GetLocalization(string.Empty, "6EA26D1A4252034FBD869A90F9A6E49A", "Reload Time")} ({Localizations.GetLocalization(string.Empty, "6BA53D764BA5CC13E821D2A807A72365", "seconds")}) : {reloadTime.Value:0.0}".ToUpper()
|
||||
});
|
||||
|
||||
if (stats.TryGetValue("ClipSize", out var s2) && s2 is IntProperty clipSize && clipSize.Value != 0)
|
||||
icon.Stats.Add(new Statistic
|
||||
{
|
||||
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_ClipSize_Weapon_Stats.png")).Stream),
|
||||
Description = $"{Localizations.GetLocalization(string.Empty, "068239DD4327B36124498C9C5F61C038", "Magazine Size")} : {clipSize.Value}".ToUpper()
|
||||
});
|
||||
|
||||
if (stats.TryGetValue("DmgPB", out var s3) && s3 is FloatProperty dmgPB && dmgPB.Value != 0)
|
||||
icon.Stats.Add(new Statistic
|
||||
{
|
||||
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_DamagePerBullet_Weapon_Stats.png")).Stream),
|
||||
Description = $"{Localizations.GetLocalization(string.Empty, "BF7E3CF34A9ACFF52E95EAAD4F09F133", "Damage to Player")} : {dmgPB.Value}".ToUpper()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetHeroStats(BaseIcon icon, ObjectProperty heroGameplayDefinition)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(heroGameplayDefinition.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var obj = p.GetExport<UObject>();
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj.TryGetValue("HeroPerk", out var v1) && v1 is StructProperty s1 && s1.Value is UObject heroPerk)
|
||||
{
|
||||
GetAbilityKit(icon, heroPerk);
|
||||
}
|
||||
|
||||
if (obj.TryGetValue("TierAbilityKits", out var v2) && v2 is ArrayProperty tierAbilityKits)
|
||||
{
|
||||
foreach (StructProperty abilityKit in tierAbilityKits.Value)
|
||||
{
|
||||
if (abilityKit.Value is UObject kit)
|
||||
{
|
||||
GetAbilityKit(icon, kit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetAbilityKit(BaseIcon icon, UObject parent)
|
||||
{
|
||||
if (parent.TryGetValue("GrantedAbilityKit", out var v) && v is SoftObjectProperty grantedAbilityKit)
|
||||
{
|
||||
PakPackage k = Utils.GetPropertyPakPackage(grantedAbilityKit.Value.AssetPathName.String);
|
||||
if (k.HasExport() && !k.Equals(default))
|
||||
{
|
||||
var kit = k.GetExport<UObject>();
|
||||
if (kit != null &&
|
||||
kit.GetExport<TextProperty>("DisplayName") is TextProperty displayName &&
|
||||
kit.GetExport<StructProperty>("IconBrush") is StructProperty brush && brush.Value is UObject iconBrush &&
|
||||
iconBrush.TryGetValue("ResourceObject", out var s) && s is ObjectProperty resourceObject)
|
||||
{
|
||||
icon.Stats.Add(new Statistic
|
||||
{
|
||||
Icon = Utils.GetObjectTexture(resourceObject),
|
||||
Description = Text.GetTextPropertyBase(displayName).ToUpper()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawStats(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
int size = 48;
|
||||
int iconSize = 40;
|
||||
int textSize = 25;
|
||||
int y = icon.Size;
|
||||
foreach (Statistic stat in icon.Stats)
|
||||
{
|
||||
c.DrawRect(new SKRect(0, y, icon.Size, y + size),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Shader = SKShader.CreateLinearGradient(
|
||||
new SKPoint(icon.Size / 2, icon.Size),
|
||||
new SKPoint(icon.Size, icon.Size / 4),
|
||||
icon.RarityBorderColor,
|
||||
SKShaderTileMode.Clamp)
|
||||
});
|
||||
|
||||
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign == EIconDesign.Flat)
|
||||
{
|
||||
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = icon.RarityBackgroundColors[0]
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Shader = SKShader.CreateRadialGradient(
|
||||
new SKPoint(icon.Size / 2, icon.Size / 2),
|
||||
icon.Size / 5 * 4,
|
||||
icon.RarityBackgroundColors,
|
||||
SKShaderTileMode.Clamp)
|
||||
});
|
||||
}
|
||||
|
||||
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = new SKColor(0, 0, 50, 75)
|
||||
});
|
||||
|
||||
c.DrawBitmap(stat.Icon.Resize(iconSize, iconSize), new SKPoint(icon.Margin * (int)2.5, y + 4), new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
|
||||
|
||||
var statPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = Text.TypeFaces.DisplayNameTypeface,
|
||||
TextSize = textSize,
|
||||
Color = SKColors.White,
|
||||
TextAlign = SKTextAlign.Center,
|
||||
};
|
||||
|
||||
// resize if too long
|
||||
while (statPaint.MeasureText(stat.Description) > (icon.Size - (icon.Margin * 2) - iconSize))
|
||||
{
|
||||
statPaint.TextSize = textSize -= 2;
|
||||
}
|
||||
|
||||
c.DrawText(stat.Description, icon.Size / 2, y + 32, statPaint);
|
||||
|
||||
y += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
FModel/Creator/Texts/ETextSide.cs
Normal file
9
FModel/Creator/Texts/ETextSide.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace FModel.Creator.Texts
|
||||
{
|
||||
public enum ETextSide
|
||||
{
|
||||
Center,
|
||||
Right,
|
||||
Left
|
||||
}
|
||||
}
|
||||
72
FModel/Creator/Texts/GameplayTag.cs
Normal file
72
FModel/Creator/Texts/GameplayTag.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using FModel.Creator.Icons;
|
||||
using FModel.Utils;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
static class GameplayTag
|
||||
{
|
||||
public static void GetGameplayTags(BaseIcon icon, StructProperty s, string exportType)
|
||||
{
|
||||
if (s.Value is FGameplayTagContainer g)
|
||||
{
|
||||
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Source.", out var source))
|
||||
icon.CosmeticSource = source.String.Substring("Cosmetics.Source.".Length);
|
||||
else if(g.GameplayTags.TryGetGameplayTag("Athena.ItemAction.", out var action))
|
||||
icon.CosmeticSource = action.String.Substring("Athena.ItemAction.".Length);
|
||||
|
||||
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Set.", out var set))
|
||||
icon.Description += GetCosmeticSet(set.String);
|
||||
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Filter.Season.", out var season))
|
||||
icon.Description += GetCosmeticSeason(season.String);
|
||||
|
||||
UserFacingFlag.GetUserFacingFlags(
|
||||
g.GameplayTags.GetAllGameplayTag("Cosmetics.UserFacingFlags.", "Homebase.Class.", "NPC.CharacterType.Survivor.Defender."),
|
||||
icon, exportType);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetCosmeticSet(string setName)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage("/Game/Athena/Items/Cosmetics/Metadata/CosmeticSets");
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var d = p.GetExport<UDataTable>();
|
||||
if (d != null && d.TryGetValue(setName, out var obj) && obj is UObject o)
|
||||
{
|
||||
if (o.TryGetValue("DisplayName", out var displayName) && displayName is TextProperty t)
|
||||
{
|
||||
(string n, string k, string s) = Text.GetTextPropertyBases(t);
|
||||
string set = Localizations.GetLocalization(n, k, s);
|
||||
string format = Localizations.GetLocalization("Fort.Cosmetics", "CosmeticItemDescription_SetMembership_NotRich", "\nPart of the {0} set.");
|
||||
return string.Format(format, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string GetCosmeticSeason(string seasonNumber)
|
||||
{
|
||||
string s = seasonNumber.Substring("Cosmetics.Filter.Season.".Length);
|
||||
int number = int.Parse(s);
|
||||
if (number == 10)
|
||||
s = "X";
|
||||
|
||||
string season = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "SeasonTextFormat", "Season {0}");
|
||||
string introduced = Localizations.GetLocalization("Fort.Cosmetics", "CosmeticItemDescription_Season", "\nIntroduced in <SeasonText>{0}</>.")
|
||||
.Replace("<SeasonText>", string.Empty).Replace("</>", string.Empty);
|
||||
if (number > 10)
|
||||
{
|
||||
string chapter = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "ChapterTextFormat", "Chapter {0}");
|
||||
string chapterFormat = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "ChapterSeasonTextFormat", "{0}, {1}");
|
||||
string d = string.Format(chapterFormat, string.Format(chapter, number / 10 + 1), string.Format(season, s[^1..]));
|
||||
return string.Format(introduced, d);
|
||||
}
|
||||
else return string.Format(introduced, string.Format(season, s));
|
||||
}
|
||||
}
|
||||
}
|
||||
110
FModel/Creator/Texts/Helper.cs
Normal file
110
FModel/Creator/Texts/Helper.cs
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
static class Helper
|
||||
{
|
||||
public class Line
|
||||
{
|
||||
public string Value { get; set; }
|
||||
public float Width { get; set; }
|
||||
}
|
||||
|
||||
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, BaseIcon icon, ETextSide side, SKRect area, SKPaint paint)
|
||||
=> DrawCenteredMultilineText(canvas, text, maxLineCount, icon.Size, icon.Margin, side, area, paint);
|
||||
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, int size, int margin, ETextSide side, SKRect area, SKPaint paint)
|
||||
{
|
||||
float lineHeight = paint.TextSize * 1.2f;
|
||||
Line[] lines = SplitLines(text, paint, area.Width - margin);
|
||||
|
||||
if (lines == null)
|
||||
return;
|
||||
if (lines.Length <= maxLineCount)
|
||||
maxLineCount = lines.Length;
|
||||
|
||||
float height = maxLineCount * lineHeight;
|
||||
float y = area.MidY - height / 2;
|
||||
for (int i = 0; i < maxLineCount; i++)
|
||||
{
|
||||
y += lineHeight;
|
||||
float x = side switch
|
||||
{
|
||||
ETextSide.Center => area.MidX - lines[i].Width / 2,
|
||||
ETextSide.Right => size - margin - lines[i].Width,
|
||||
ETextSide.Left => margin,
|
||||
_ => area.MidX - lines[i].Width / 2
|
||||
};
|
||||
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawMultilineText(SKCanvas canvas, string text, int size, int margin, ETextSide side, SKRect area, SKPaint paint, out int yPos)
|
||||
{
|
||||
float lineHeight = paint.TextSize * 1.2f;
|
||||
Line[] lines = SplitLines(text, paint, area.Width - margin);
|
||||
if (lines == null)
|
||||
{
|
||||
yPos = (int)area.Top;
|
||||
return;
|
||||
}
|
||||
|
||||
float y = area.Top;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
float x = side switch
|
||||
{
|
||||
ETextSide.Center => area.MidX - lines[i].Width / 2,
|
||||
ETextSide.Right => size - margin - lines[i].Width,
|
||||
ETextSide.Left => margin,
|
||||
_ => area.MidX - lines[i].Width / 2
|
||||
};
|
||||
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
|
||||
y += lineHeight;
|
||||
}
|
||||
yPos = (int)area.Top + ((int)lineHeight * lines.Length);
|
||||
}
|
||||
|
||||
public static Line[] SplitLines(string text, SKPaint paint, float maxWidth)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return null;
|
||||
|
||||
float spaceWidth = paint.MeasureText(" ");
|
||||
string[] lines = text.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
List<Line> ret = new List<Line>(lines.Length);
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(lines[i]))
|
||||
continue;
|
||||
|
||||
float width = 0;
|
||||
var lineResult = new StringBuilder();
|
||||
string[] words = lines[i].Split(' ', StringSplitOptions.None);
|
||||
foreach (var word in words)
|
||||
{
|
||||
float wordWidth = paint.MeasureText(word);
|
||||
float wordWithSpaceWidth = wordWidth + spaceWidth;
|
||||
string wordWithSpace = word + " ";
|
||||
|
||||
if (width + wordWidth > maxWidth)
|
||||
{
|
||||
ret.Add(new Line { Value = lineResult.ToString(), Width = width });
|
||||
lineResult = new StringBuilder(wordWithSpace);
|
||||
width = wordWithSpaceWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineResult.Append(wordWithSpace);
|
||||
width += wordWithSpaceWidth;
|
||||
}
|
||||
}
|
||||
ret.Add(new Line { Value = lineResult.ToString(), Width = width });
|
||||
}
|
||||
return ret.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
217
FModel/Creator/Texts/Text.cs
Normal file
217
FModel/Creator/Texts/Text.cs
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.Objects;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
static class Text
|
||||
{
|
||||
public static Typefaces TypeFaces = new Typefaces();
|
||||
private const int _STARTER_TEXT_POSITION = 380;
|
||||
private static int _BOTTOM_TEXT_SIZE = 15;
|
||||
private static int _NAME_TEXT_SIZE = 45;
|
||||
|
||||
public static string GetTextPropertyBase(TextProperty t)
|
||||
{
|
||||
if (t.Value is FText text)
|
||||
if (text.Text is FTextHistory.Base b)
|
||||
return b.SourceString.Replace("<Emphasized>", string.Empty).Replace("</>", string.Empty);
|
||||
else if (text.Text is FTextHistory.StringTableEntry s)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(s.TableId.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var table = p.GetExport<UStringTable>();
|
||||
if (table != null)
|
||||
{
|
||||
if (table.TryGetValue("StringTable", out var v1) && v1 is FStringTable stringTable &&
|
||||
stringTable.KeysToMetadata.TryGetValue(stringTable.TableNamespace, out var v2) && v2 is Dictionary<string, string> dico &&
|
||||
dico.TryGetValue(s.Key, out var ret))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
public static string GetTextPropertyBase(ArrayProperty a)
|
||||
{
|
||||
if (a.Value.Length > 0 && a.Value[0] is TextProperty t)
|
||||
return GetTextPropertyBase(t);
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static (string, string, string) GetTextPropertyBases(TextProperty t)
|
||||
{
|
||||
if (t.Value is FText text && text.Text is FTextHistory.Base b)
|
||||
return (b.Namespace, b.Key, b.SourceString);
|
||||
return (string.Empty, string.Empty, string.Empty);
|
||||
}
|
||||
|
||||
public static string GetMaxStackSize(StructProperty maxStackSize)
|
||||
{
|
||||
if (maxStackSize.Value is UObject o1)
|
||||
{
|
||||
if (o1.TryGetValue("Value", out var c) && c is FloatProperty value && value.Value != -1) // old way
|
||||
return $"MaxStackSize : {value.Value}";
|
||||
else if (
|
||||
o1.TryGetValue("Curve", out var c1) && c1 is StructProperty curve && curve.Value is UObject o2 &&
|
||||
o2.TryGetValue("CurveTable", out var c2) && c2 is ObjectProperty curveTable &&
|
||||
o2.TryGetValue("RowName", out var c3) && c3 is NameProperty rowName) // new way
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(curveTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var table = p.GetExport<UCurveTable>();
|
||||
if (table != null)
|
||||
{
|
||||
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject maxStackAmount &&
|
||||
maxStackAmount.TryGetValue("Keys", out var v2) && v2 is ArrayProperty keys &&
|
||||
keys.Value.Length > 0 && (keys.Value[0] as StructProperty).Value is FSimpleCurveKey amount &&
|
||||
amount.KeyValue != -1)
|
||||
{
|
||||
return $"MaxStackSize : {amount.KeyValue}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static void DrawBackground(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Flat:
|
||||
{
|
||||
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
|
||||
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
|
||||
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
|
||||
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
|
||||
pathBottom.Close();
|
||||
c.DrawPath(pathBottom, new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = new SKColor(0, 0, 50, 75),
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
c.DrawRect(
|
||||
new SKRect(icon.Margin, _STARTER_TEXT_POSITION, icon.Size - icon.Margin, icon.Size - icon.Margin),
|
||||
new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Color = new SKColor(0, 0, 50, 75),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawDisplayName(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
_NAME_TEXT_SIZE = 45;
|
||||
string text = icon.DisplayName;
|
||||
SKTextAlign side = SKTextAlign.Center;
|
||||
int x = icon.Size / 2;
|
||||
int y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE;
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Mini:
|
||||
{
|
||||
_NAME_TEXT_SIZE = 47;
|
||||
text = text.ToUpper();
|
||||
break;
|
||||
}
|
||||
case EIconDesign.Flat:
|
||||
{
|
||||
_NAME_TEXT_SIZE = 47;
|
||||
side = SKTextAlign.Right;
|
||||
x = icon.Size - icon.Margin * 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SKPaint namePaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = TypeFaces.DisplayNameTypeface,
|
||||
TextSize = _NAME_TEXT_SIZE,
|
||||
Color = SKColors.White,
|
||||
TextAlign = side,
|
||||
};
|
||||
|
||||
// resize if too long
|
||||
while (namePaint.MeasureText(text) > (icon.Size - (icon.Margin * 2)))
|
||||
{
|
||||
namePaint.TextSize = _NAME_TEXT_SIZE -= 2;
|
||||
}
|
||||
|
||||
c.DrawText(text, x, y, namePaint);
|
||||
}
|
||||
|
||||
public static void DrawDescription(SKCanvas c, BaseIcon icon)
|
||||
{
|
||||
int maxLine = 4;
|
||||
_BOTTOM_TEXT_SIZE = 15;
|
||||
string text = icon.Description;
|
||||
ETextSide side = ETextSide.Center;
|
||||
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
|
||||
{
|
||||
case EIconDesign.Mini:
|
||||
{
|
||||
maxLine = 5;
|
||||
_BOTTOM_TEXT_SIZE = icon.Margin;
|
||||
text = text.ToUpper();
|
||||
break;
|
||||
}
|
||||
case EIconDesign.Flat:
|
||||
{
|
||||
side = ETextSide.Right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SKPaint descriptionPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = TypeFaces.DescriptionTypeface,
|
||||
TextSize = 13,
|
||||
Color = SKColors.White,
|
||||
};
|
||||
|
||||
// wrap if too long
|
||||
Helper.DrawCenteredMultilineText(c, text, maxLine, icon, side,
|
||||
new SKRect(icon.Margin, _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE, icon.Size - icon.Margin, icon.Size - _BOTTOM_TEXT_SIZE),
|
||||
descriptionPaint);
|
||||
}
|
||||
|
||||
public static void DrawToBottom(SKCanvas c, BaseIcon icon, ETextSide side, string text)
|
||||
{
|
||||
SKPaint shortDescriptionPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
FilterQuality = SKFilterQuality.High,
|
||||
Typeface = side == ETextSide.Left ? TypeFaces.DisplayNameTypeface : TypeFaces.DefaultTypeface,
|
||||
TextSize = 15,
|
||||
Color = SKColors.White,
|
||||
TextAlign = side == ETextSide.Left ? SKTextAlign.Left : SKTextAlign.Right,
|
||||
};
|
||||
|
||||
c.DrawText(text, side == ETextSide.Left ? icon.Margin * 2.5f : icon.Size - (icon.Margin * 2.5f), icon.Size - (icon.Margin * 2.5f), shortDescriptionPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
FModel/Creator/Texts/Typefaces.cs
Normal file
105
FModel/Creator/Texts/Typefaces.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using FModel.Utils;
|
||||
using FModel.ViewModels.DataGrid;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator.Texts
|
||||
{
|
||||
public class Typefaces
|
||||
{
|
||||
#pragma warning disable IDE0051
|
||||
private const string _BASE_PATH = "/Game/UI/Foundation/Fonts/";
|
||||
private const string _ASIA_ERINM = "AsiaERINM"; // korean fortnite
|
||||
private const string _BURBANK_BIG_CONDENSED_BLACK = "BurbankBigCondensed-Black";
|
||||
private readonly Uri _BURBANK_BIG_CONDENSED_BOLD = new Uri("pack://application:,,,/Resources/BurbankBigCondensed-Bold.ttf"); // other languages fortnite unofficial
|
||||
private const string _BURBANK_BIG_REGULAR_BLACK = "BurbankBigRegular-Black";
|
||||
private const string _BURBANK_BIG_REGULAR_BOLD = "BurbankBigRegular-Bold"; // official fortnite but it's too big so i use it for russian only
|
||||
private const string _BURBANK_SMALL_MEDIUM = "BurbankSmall-Medium";
|
||||
private const string _DROID_SANS_FORTNITE_SUBSET = "DroidSans-Fortnite-Subset";
|
||||
private const string _NIS_JYAU = "NIS_JYAU"; // japanese fortnite
|
||||
private const string _NOTO_COLOR_EMOJI = "NotoColorEmoji";
|
||||
private const string _NOTO_SANS_BOLD = "NotoSans-Bold";
|
||||
private const string _NOTO_SANS_FORTNITE_BOLD = "NotoSans-Fortnite-Bold";
|
||||
private const string _NOTO_SANS_FORTNITE_ITALIC = "NotoSans-Fortnite-Italic";
|
||||
private const string _NOTO_SANS_FORTNITE_REGULAR = "NotoSans-Fortnite-Regular";
|
||||
private const string _NOTO_SANS_ITALIC = "NotoSans-Italic";
|
||||
private const string _NOTO_SANS_REGULAR = "NotoSans-Regular";
|
||||
private const string _NOTO_SANS_ARABIC_BLACK = "NotoSansArabic-Black"; // arabic fortnite
|
||||
private const string _NOTO_SANS_ARABIC_BOLD = "NotoSansArabic-Bold";
|
||||
private const string _NOTO_SANS_ARABIC_REGULAR = "NotoSansArabic-Regular";
|
||||
private const string _NOTO_SANS_JP_BOLD = "NotoSansJP-Bold";
|
||||
private const string _NOTO_SANS_KR_REGULAR = "NotoSansKR-Regular";
|
||||
private const string _NOTO_SANS_SC_BLACK = "NotoSansSC-Black"; // traditional chinese fortnite
|
||||
private const string _NOTO_SANS_SC_REGULAR = "NotoSansSC-Regular";
|
||||
private const string _NOTO_SANS_TC_BLACK = "NotoSansTC-Black"; // simplified chinese fortnite
|
||||
private const string _NOTO_SANS_TC_REGULAR = "NotoSansTC-Regular";
|
||||
private const string _BURBANK_SMALL_BLACK = "burbanksmall-black";
|
||||
private const string _BURBANK_SMALL_BOLD = "burbanksmall-bold";
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
public SKTypeface DefaultTypeface; // used as default font for all untranslated strings (item source, ...)
|
||||
public SKTypeface BundleDefaultTypeface; // used for the last folder string
|
||||
public SKTypeface DisplayNameTypeface;
|
||||
public SKTypeface DescriptionTypeface;
|
||||
public SKTypeface BundleDisplayNameTypeface;
|
||||
|
||||
public Typefaces()
|
||||
{
|
||||
DefaultTypeface = SKTypeface.FromStream(Application.GetResourceStream(_BURBANK_BIG_CONDENSED_BOLD).Stream);
|
||||
|
||||
ArraySegment<byte>[] t = Utils.GetPropertyArraySegmentByte(_BASE_PATH + _BURBANK_BIG_CONDENSED_BLACK);
|
||||
if (t != null && t.Length == 3)
|
||||
BundleDefaultTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else BundleDefaultTypeface = DefaultTypeface;
|
||||
|
||||
string namePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_REGULAR_BOLD :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_BLACK :
|
||||
string.Empty);
|
||||
if (!namePath.Equals(_BASE_PATH))
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(namePath);
|
||||
if (t != null && t.Length == 3)
|
||||
DisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
}
|
||||
else DisplayNameTypeface = DefaultTypeface;
|
||||
|
||||
string descriptionPath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _NOTO_SANS_KR_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NOTO_SANS_JP_BOLD :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_REGULAR :
|
||||
_NOTO_SANS_REGULAR);
|
||||
t = Utils.GetPropertyArraySegmentByte(descriptionPath);
|
||||
if (t != null && t.Length == 3)
|
||||
DescriptionTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else DescriptionTypeface = DefaultTypeface;
|
||||
|
||||
string bundleNamePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_REGULAR_BOLD :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_BLACK :
|
||||
string.Empty);
|
||||
if (!bundleNamePath.Equals(_BASE_PATH))
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(bundleNamePath);
|
||||
if (t != null && t.Length == 3)
|
||||
BundleDisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
}
|
||||
else BundleDisplayNameTypeface = BundleDefaultTypeface;
|
||||
}
|
||||
|
||||
public bool NeedReload(bool forceReload) => forceReload ?
|
||||
DataGridVm.dataGridViewModel.Count > 0 : //reload only if at least one pak is loaded
|
||||
DataGridVm.dataGridViewModel.Count > 0 && (BundleDefaultTypeface == DefaultTypeface && DisplayNameTypeface == DefaultTypeface && DescriptionTypeface == DefaultTypeface && BundleDisplayNameTypeface == BundleDefaultTypeface);
|
||||
}
|
||||
}
|
||||
78
FModel/Creator/Utils.cs
Normal file
78
FModel/Creator/Utils.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using FModel.Utils;
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
static class Utils
|
||||
{
|
||||
public static string GetFullPath(string partialPath)
|
||||
{
|
||||
foreach (var fileReader in Globals.CachedPakFiles.Values)
|
||||
if (fileReader.TryGetPartialKey(partialPath, out var fullPath))
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static PakPackage GetPropertyPakPackage(string value)
|
||||
{
|
||||
string path = Strings.FixPath(value);
|
||||
foreach (var fileReader in Globals.CachedPakFiles.Values)
|
||||
if (fileReader.TryGetValue(path, out var entry))
|
||||
{
|
||||
// kinda sad to use Globals.CachedPakFileMountPoint when the mount point is already in the path ¯\_(ツ)_/¯
|
||||
string mount = path.Substring(0, path.Length - entry.Name.Substring(0, entry.Name.LastIndexOf(".")).Length);
|
||||
return Assets.GetPakPackage(entry, mount);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static ArraySegment<byte>[] GetPropertyArraySegmentByte(string value)
|
||||
{
|
||||
string path = Strings.FixPath(value);
|
||||
foreach (var fileReader in Globals.CachedPakFiles.Values)
|
||||
if (fileReader.TryGetValue(path, out var entry))
|
||||
{
|
||||
// kinda sad to use Globals.CachedPakFileMountPoint when the mount point is already in the path ¯\_(ツ)_/¯
|
||||
string mount = path.Substring(0, path.Length - entry.Name.Substring(0, entry.Name.LastIndexOf(".")).Length);
|
||||
return Assets.GetArraySegmentByte(entry, mount);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static SKBitmap NewZeroedBitmap(int width, int height) => new SKBitmap(new SKImageInfo(width, height), SKBitmapAllocFlags.ZeroPixels);
|
||||
public static SKBitmap Resize(this SKBitmap me, int width, int height)
|
||||
{
|
||||
var bmp = NewZeroedBitmap(width, height);
|
||||
using var pixmap = bmp.PeekPixels();
|
||||
me.ScalePixels(pixmap, SKFilterQuality.Medium);
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static SKBitmap GetObjectTexture(ObjectProperty o) => GetTexture(o.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
public static SKBitmap GetSoftObjectTexture(SoftObjectProperty s) => GetTexture(s.Value.AssetPathName.String);
|
||||
public static SKBitmap GetTexture(string s)
|
||||
{
|
||||
PakPackage p = GetPropertyPakPackage(s);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
{
|
||||
var i = p.GetExport<UTexture2D>();
|
||||
if (i != null)
|
||||
return SKBitmap.Decode(i.Image.Encode());
|
||||
|
||||
var u = p.GetExport<UObject>();
|
||||
if (u != null)
|
||||
if (u.TryGetValue("TextureParameterValues", out var v) && v is ArrayProperty a)
|
||||
if (a.Value.Length > 0 && a.Value[0] is StructProperty str && str.Value is UObject o)
|
||||
if (o.TryGetValue("ParameterValue", out var obj) && obj is ObjectProperty parameterValue)
|
||||
return GetObjectTexture(parameterValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
FModel/Discord/DiscordIntegration.cs
Normal file
66
FModel/Discord/DiscordIntegration.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using DiscordRPC;
|
||||
using DiscordRPC.Logging;
|
||||
using FModel.Logger;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FModel.Discord
|
||||
{
|
||||
static class DiscordIntegration
|
||||
{
|
||||
private const string _DISCORD_APP_ID = "684489366189768767";
|
||||
|
||||
private static readonly Timestamps _baseTimestamp = new Timestamps { Start = DateTime.UtcNow };
|
||||
private static readonly Assets _assets = new Assets
|
||||
{
|
||||
LargeImageKey = "official_logo",
|
||||
SmallImageKey = "verified",
|
||||
SmallImageText = $"v{Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5)}"
|
||||
};
|
||||
private static readonly DiscordRpcClient _client = new DiscordRpcClient(_DISCORD_APP_ID);
|
||||
private static RichPresence _presence;
|
||||
|
||||
public static void Dispose() => _client.Dispose();
|
||||
private static void Initialize()
|
||||
{
|
||||
_client.Logger = new ConsoleLogger() { Level = LogLevel.Warning };
|
||||
_client.OnReady += (sender, e) =>
|
||||
{
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Discord RPC]", $"Ready for {e.User.Username}#{e.User.Discriminator} ({e.User.ID})");
|
||||
};
|
||||
_client.Initialize();
|
||||
}
|
||||
|
||||
public static void StartClient()
|
||||
{
|
||||
_client.SetPresence(new RichPresence
|
||||
{
|
||||
Assets = _assets,
|
||||
Timestamps = _baseTimestamp,
|
||||
State = Properties.Resources.Idling
|
||||
});
|
||||
Initialize();
|
||||
SaveCurrentPresence();
|
||||
}
|
||||
|
||||
public static void Update(string detail = null, string state = null)
|
||||
{
|
||||
_client.SetPresence(new RichPresence
|
||||
{
|
||||
Assets = _assets,
|
||||
Timestamps = _baseTimestamp,
|
||||
Details = string.IsNullOrEmpty(detail) ? _presence.Details : detail,
|
||||
State = string.IsNullOrEmpty(state) ? _presence.State : state
|
||||
});
|
||||
_client.Invoke();
|
||||
}
|
||||
|
||||
public static void Restore()
|
||||
{
|
||||
_client.SetPresence(_presence);
|
||||
_client.Invoke();
|
||||
}
|
||||
|
||||
public static void SaveCurrentPresence() => _presence = _client.CurrentPresence;
|
||||
}
|
||||
}
|
||||
60
FModel/Enums.cs
Normal file
60
FModel/Enums.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
namespace FModel
|
||||
{
|
||||
public enum EGame
|
||||
{
|
||||
Unknown,
|
||||
Fortnite,
|
||||
Valorant
|
||||
}
|
||||
|
||||
public enum EFModel
|
||||
{
|
||||
Debug,
|
||||
Release,
|
||||
Unknown
|
||||
}
|
||||
|
||||
public enum EPakLoader
|
||||
{
|
||||
Single,
|
||||
All,
|
||||
New,
|
||||
Modified,
|
||||
NewModified
|
||||
}
|
||||
|
||||
public enum ECopy
|
||||
{
|
||||
Path,
|
||||
PathNoExt,
|
||||
File,
|
||||
FileNoExt
|
||||
}
|
||||
|
||||
public enum ELanguage : long
|
||||
{
|
||||
English,
|
||||
French,
|
||||
German,
|
||||
Italian,
|
||||
Spanish,
|
||||
SpanishLatin,
|
||||
Arabic,
|
||||
Japanese,
|
||||
Korean,
|
||||
Polish,
|
||||
PortugueseBrazil,
|
||||
Russian,
|
||||
Turkish,
|
||||
Chinese,
|
||||
TraditionalChinese
|
||||
}
|
||||
|
||||
public enum EIconDesign : long
|
||||
{
|
||||
Default,
|
||||
NoText,
|
||||
Mini,
|
||||
Flat
|
||||
}
|
||||
}
|
||||
|
|
@ -1,634 +1,236 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>FModel</RootNamespace>
|
||||
<AssemblyName>FModel</AssemblyName>
|
||||
<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>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>FModel.ico</ApplicationIcon>
|
||||
<StartupObject>FModel.App</StartupObject>
|
||||
<Authors>Asval</Authors>
|
||||
<Company></Company>
|
||||
<AssemblyVersion>3.1.0.0</AssemblyVersion>
|
||||
<FileVersion>3.1.0.0</FileVersion>
|
||||
<PackageIcon>FModel.ico</PackageIcon>
|
||||
<PackageIconUrl />
|
||||
<PackageProjectUrl>https://github.com/iAmAsval/FModel</PackageProjectUrl>
|
||||
<Description></Description>
|
||||
<Version>3.1.0</Version>
|
||||
<Platforms>x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
<NoWarn>1701;1702;NU1701</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<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>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>FModel.Program</StartupObject>
|
||||
<NoWarn>1701;1702;NU1701</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="AutoUpdater.NET, Version=1.5.8.0, Culture=neutral, PublicKeyToken=501435c91b35f4bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Autoupdater.NET.Official.1.5.8\lib\net40\AutoUpdater.NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.11.17.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\HtmlAgilityPack.1.11.17\lib\Net45\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<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.3\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="SkiaSharp, Version=1.68.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SkiaSharp.1.68.1\lib\net45\SkiaSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.0-preview5.19224.8\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<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>
|
||||
<None Remove="FModel.ico" />
|
||||
<None Remove="Resources\alert.ico" />
|
||||
<None Remove="Resources\alpha-a-box.png" />
|
||||
<None Remove="Resources\api-off.ico" />
|
||||
<None Remove="Resources\api.ico" />
|
||||
<None Remove="Resources\backup-restore.png" />
|
||||
<None Remove="Resources\bug.png" />
|
||||
<None Remove="Resources\BurbankBigCondensed-Bold.ttf" />
|
||||
<None Remove="Resources\cast-audio.png" />
|
||||
<None Remove="Resources\challenge-theme-creator.png" />
|
||||
<None Remove="Resources\check-circle.ico" />
|
||||
<None Remove="Resources\ColorPickerOne.png" />
|
||||
<None Remove="Resources\ColorPickerTwo.png" />
|
||||
<None Remove="Resources\content-copy.png" />
|
||||
<None Remove="Resources\content-save.png" />
|
||||
<None Remove="Resources\delete-forever.png" />
|
||||
<None Remove="Resources\discord.png" />
|
||||
<None Remove="Resources\egl2.ico" />
|
||||
<None Remove="Resources\EIconDesign_Default.png" />
|
||||
<None Remove="Resources\EIconDesign_Flat.png" />
|
||||
<None Remove="Resources\EIconDesign_Mini.png" />
|
||||
<None Remove="Resources\EIconDesign_NoText.png" />
|
||||
<None Remove="Resources\file-export.png" />
|
||||
<None Remove="Resources\file-image.ico" />
|
||||
<None Remove="Resources\file-multiple.png" />
|
||||
<None Remove="Resources\file-restore.png" />
|
||||
<None Remove="Resources\file.png" />
|
||||
<None Remove="Resources\fmodel.png" />
|
||||
<None Remove="Resources\folder-download.png" />
|
||||
<None Remove="Resources\folder-open.png" />
|
||||
<None Remove="Resources\fortnite.ico" />
|
||||
<None Remove="Resources\gamepad-variant.png" />
|
||||
<None Remove="Resources\github-circle.png" />
|
||||
<None Remove="Resources\icon-creator.png" />
|
||||
<None Remove="Resources\image-filter-black-white.png" />
|
||||
<None Remove="Resources\image-move.png" />
|
||||
<None Remove="Resources\image-plus.png" />
|
||||
<None Remove="Resources\image-remove.png" />
|
||||
<None Remove="Resources\information.png" />
|
||||
<None Remove="Resources\Ini.xshd" />
|
||||
<None Remove="Resources\Json.xshd" />
|
||||
<None Remove="Resources\key.png" />
|
||||
<None Remove="Resources\lock-open-variant.ico" />
|
||||
<None Remove="Resources\magnify.png" />
|
||||
<None Remove="Resources\open-in-new.png" />
|
||||
<None Remove="Resources\pause.png" />
|
||||
<None Remove="Resources\paypal.png" />
|
||||
<None Remove="Resources\pencil.png" />
|
||||
<None Remove="Resources\play.png" />
|
||||
<None Remove="Resources\playlist-plus.png" />
|
||||
<None Remove="Resources\power.png" />
|
||||
<None Remove="Resources\progress-download.png" />
|
||||
<None Remove="Resources\refresh.png" />
|
||||
<None Remove="Resources\settings.png" />
|
||||
<None Remove="Resources\share-all.png" />
|
||||
<None Remove="Resources\share.png" />
|
||||
<None Remove="Resources\sign-direction-plus.png" />
|
||||
<None Remove="Resources\sign-direction-remove.png" />
|
||||
<None Remove="Resources\sign-direction.png" />
|
||||
<None Remove="Resources\stop.png" />
|
||||
<None Remove="Resources\T-Icon-Pets-64.png" />
|
||||
<None Remove="Resources\T-Icon-Quests-64.png" />
|
||||
<None Remove="Resources\T_ClipSize_Weapon_Stats.png" />
|
||||
<None Remove="Resources\T_DamagePerBullet_Weapon_Stats.png" />
|
||||
<None Remove="Resources\T_Placeholder_Challenge_Image.png" />
|
||||
<None Remove="Resources\T_Placeholder_Item_Image.png" />
|
||||
<None Remove="Resources\T_ReloadTime_Weapon_Stats.png" />
|
||||
<None Remove="Resources\valorant.live.ico" />
|
||||
<None Remove="Resources\view-dashboard.png" />
|
||||
<None Remove="Resources\volume-minus.png" />
|
||||
<None Remove="Resources\volume-mute.png" />
|
||||
<None Remove="Resources\volume-plus.png" />
|
||||
<None Remove="Resources\wifi-strength-off.ico" />
|
||||
<None Remove="Resources\zip-box.png" />
|
||||
<None Include="FModel.ico">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath></PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</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\FModel_UpdateMode.xaml.cs">
|
||||
<DependentUpon>FModel_UpdateMode.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\CosmeticSeason.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\Auth\AuthFlow.cs" />
|
||||
<Compile Include="Methods\Auth\Requests.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\AssetRegReader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\AssetReader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\ExportObject.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UDictionary\FDictionaryHeader\FDictionaryHeader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UDictionary\FDictionaryHeader\FOodleCompressedData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FObjectExport.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPackageIndex.cs" />
|
||||
<Compile Include="Methods\PakReader\DDSDecoder.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FAnimKeyHeader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FCompressedOffsetData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FCompressedSegment.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptArray.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptMap.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FDateTime.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLevelSequenceObjectReferenceMap\FLevelSequenceLegacyObjectReference.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLevelSequenceObjectReferenceMap\FLevelSequenceObjectReferenceMap.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FRichCurveKey.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FScriptDelegate.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSimpleCurveKey.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSmartName.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTrack.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UAnimSequence\UAnimSequence.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPropertyTag\FPropertyTag.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPropertyTag\FPropertyTagType.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UObject\UObject.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FColor.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FGameplayTagContainer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FGuid.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FIntPoint.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLinearColor.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoftObjectPath.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoftObjectPathMap.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStructFallback.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FText.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FVector2D.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\UScriptStruct.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FQuat.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FRotator.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMeshLODInfo.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FColorVertexBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FMultisizeIndexContainer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FPositionVertexBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FGPUVert4Float.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FGPUVert4Half.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FMeshUV\FMeshUVFloat.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FMeshUV\FMeshUVHalf.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FPackedNormal.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightVertexBuffer\FSkinWeightInfo.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightVertexBuffer\FSkinWeightVertexBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshUVItem4\FPackedRGBA16N.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshUVItem4\FStaticMeshUVItem4.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FSkeletalMeshVertexBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexClothBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FRuntimeSkinWeightProfileData\FRuntimeSkinWeightProfileData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FRuntimeSkinWeightProfileData\FSkinWeightOverrideInfo.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FSkinWeightProfilesData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshVertexBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FVector.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferencePose.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\USkeleton\USkeleton.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoundFormatData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStreamedAudioChunk.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\USoundWave\USoundWave.cs" />
|
||||
<Compile Include="Methods\PakReader\Extensions.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FByteBulkData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FByteBulkDataHeader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FNameEntrySerialized.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FObjectImport.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStripDataFlags.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\FontFace\FontFace.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\PakReader.cs" />
|
||||
<Compile Include="Methods\PakReader\SigReader.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTexturePlatformData\FTexture2DMipMap.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTexturePlatformData\FTexturePlatformData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\Texture2D\Texture2D.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UCurveTable\ECurveTableMode.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UCurveTable\UCurveTable.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UDataTable\UDataTable.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UDictionary\UDictionary.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FBoxSphereBounds.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FMeshBoneInfo.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMaterial\FMeshUVChannelInfo.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FReferenceSkeleton.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMaterial\FSkeletalMaterial.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FApexClothPhysToRenderVertData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FClothingSectionData.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FDuplicatedVerticesBuffer\FDuplicatedVerticesBuffer.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FDuplicatedVerticesBuffer\FIndexLengthPair.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FSkelMeshSection.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FVector4.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticLODModel.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FTransform.cs" />
|
||||
<Compile Include="Methods\PakReader\ExportObject\USkeletalMesh\USkeletalMesh.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\DebugHelper.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\Logger.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>
|
||||
<EmbeddedResource Include="Resources\Ini.xshd" />
|
||||
<EmbeddedResource Include="Resources\Json.xshd" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.6.0" />
|
||||
<PackageReference Include="AvalonEdit" Version="6.0.1" />
|
||||
<PackageReference Include="CSCore" Version="1.2.1.2" />
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="3.8.1" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.1.11" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.1" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="1.68.2.1" />
|
||||
<PackageReference Include="ToastNotifications" Version="2.5.1" />
|
||||
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
|
||||
<PackageReference Include="WriteableBitmapEx" Version="1.6.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="FModel.ico" />
|
||||
<Resource Include="Resources\alert.ico" />
|
||||
<Resource Include="Resources\alpha-a-box.png" />
|
||||
<Resource Include="Resources\api-off.ico" />
|
||||
<Resource Include="Resources\api.ico" />
|
||||
<Resource Include="Resources\backup-restore.png" />
|
||||
<Resource Include="Resources\bug.png" />
|
||||
<Resource Include="Resources\BurbankBigCondensed-Bold.ttf" />
|
||||
<Resource Include="Resources\cast-audio.png" />
|
||||
<Resource Include="Resources\challenge-theme-creator.png" />
|
||||
<Resource Include="Resources\check-circle.ico" />
|
||||
<Resource Include="Resources\ColorPickerOne.png" />
|
||||
<Resource Include="Resources\ColorPickerTwo.png" />
|
||||
<Resource Include="Resources\content-copy.png" />
|
||||
<Resource Include="Resources\content-save.png" />
|
||||
<Resource Include="Resources\delete-forever.png" />
|
||||
<Resource Include="Resources\discord.png" />
|
||||
<Resource Include="Resources\egl2.ico" />
|
||||
<Resource Include="Resources\EIconDesign_Default.png" />
|
||||
<Resource Include="Resources\EIconDesign_Flat.png" />
|
||||
<Resource Include="Resources\EIconDesign_Mini.png" />
|
||||
<Resource Include="Resources\EIconDesign_NoText.png" />
|
||||
<Resource Include="Resources\file-export.png" />
|
||||
<Resource Include="Resources\file-image.ico" />
|
||||
<Resource Include="Resources\file-multiple.png" />
|
||||
<Resource Include="Resources\file-restore.png" />
|
||||
<Resource Include="Resources\file.png" />
|
||||
<Resource Include="Resources\fmodel.png" />
|
||||
<Resource Include="Resources\folder-download.png" />
|
||||
<Resource Include="Resources\folder-open.png" />
|
||||
<Resource Include="Resources\fortnite.ico" />
|
||||
<Resource Include="Resources\gamepad-variant.png" />
|
||||
<Resource Include="Resources\github-circle.png" />
|
||||
<Resource Include="Resources\icon-creator.png" />
|
||||
<Resource Include="Resources\image-filter-black-white.png" />
|
||||
<Resource Include="Resources\image-move.png" />
|
||||
<Resource Include="Resources\image-plus.png" />
|
||||
<Resource Include="Resources\image-remove.png" />
|
||||
<Resource Include="Resources\information.png" />
|
||||
<Resource Include="Resources\key.png" />
|
||||
<Resource Include="Resources\lock-open-variant.ico" />
|
||||
<Resource Include="Resources\magnify.png" />
|
||||
<Resource Include="Resources\open-in-new.png" />
|
||||
<Resource Include="Resources\pause.png" />
|
||||
<Resource Include="Resources\paypal.png" />
|
||||
<Resource Include="Resources\pencil.png" />
|
||||
<Resource Include="Resources\play.png" />
|
||||
<Resource Include="Resources\playlist-plus.png" />
|
||||
<Resource Include="Resources\power.png" />
|
||||
<Resource Include="Resources\progress-download.png" />
|
||||
<Resource Include="Resources\refresh.png" />
|
||||
<Resource Include="Resources\settings.png" />
|
||||
<Resource Include="Resources\share-all.png" />
|
||||
<Resource Include="Resources\share.png" />
|
||||
<Resource Include="Resources\sign-direction-plus.png" />
|
||||
<Resource Include="Resources\sign-direction-remove.png" />
|
||||
<Resource Include="Resources\sign-direction.png" />
|
||||
<Resource Include="Resources\stop.png" />
|
||||
<Resource Include="Resources\T-Icon-Pets-64.png" />
|
||||
<Resource Include="Resources\T-Icon-Quests-64.png" />
|
||||
<Resource Include="Resources\T_ClipSize_Weapon_Stats.png" />
|
||||
<Resource Include="Resources\T_DamagePerBullet_Weapon_Stats.png" />
|
||||
<Resource Include="Resources\T_Placeholder_Challenge_Image.png" />
|
||||
<Resource Include="Resources\T_Placeholder_Item_Image.png" />
|
||||
<Resource Include="Resources\T_ReloadTime_Weapon_Stats.png" />
|
||||
<Resource Include="Resources\valorant.live.ico" />
|
||||
<Resource Include="Resources\view-dashboard.png" />
|
||||
<Resource Include="Resources\volume-minus.png" />
|
||||
<Resource Include="Resources\volume-mute.png" />
|
||||
<Resource Include="Resources\volume-plus.png" />
|
||||
<Resource Include="Resources\wifi-strength-off.ico" />
|
||||
<Resource Include="Resources\zip-box.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<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\FModel_UpdateMode.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">
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</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="Methods\PakReader\LICENSE" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>PublicSettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Resource Include="Resources\TT-JTCじゃんけんU & TT-JTCじゃんけんUP.TTC" />
|
||||
<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>
|
||||
<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>
|
||||
<Resource Include="Resources\Template_AC_F.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Template_AC_N.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="AfterResolveReferences">
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
|
||||
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<Import Project="..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets" Condition="Exists('..\packages\SkiaSharp.1.68.1\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.1\build\net45\SkiaSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
BIN
FModel/FModel.ico
Normal file
BIN
FModel/FModel.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
|
|
@ -1,196 +0,0 @@
|
|||
<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:properties="clr-namespace:FModel.Properties"
|
||||
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_ReloadAESs" Header="Reload AES Keys" Click="MI_ReloadAESs_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" 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" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoExtractRaw, Mode=TwoWay}"/>
|
||||
<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" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoSaveJson, Mode=TwoWay}"/>
|
||||
<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" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoSaveImg, Mode=TwoWay}"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="Images Merger" InputGestureText="F4" Command="{x:Static commands:FModel_Commands.MergeImages}"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem x:Name="MI_Changelog" Header="Changelog" Click="MI_Changelog_Click"/>
|
||||
<MenuItem x:Name="MI_BugReports" Header="Bugs Report" Click="MI_BugReports_Click"/>
|
||||
<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>
|
||||
|
|
@ -1,385 +0,0 @@
|
|||
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;
|
||||
|
||||
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);
|
||||
|
||||
DebugHelper.WriteLine("AutoUpdater: Checking for updates");
|
||||
AutoUpdater.CheckForUpdateEvent += UIHelper.AutoUpdaterOnCheckForUpdateEvent;
|
||||
AutoUpdater.Start("https://cdn.asval.tk/d/FModel/FModel.xml");
|
||||
|
||||
DebugHelper.WriteUserSettings();
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
FoldersUtility.CheckWatermark();
|
||||
RegisterFromPath.CheckFortniteVersion();
|
||||
RegisterFromPath.FilterPAKs();
|
||||
DynamicKeysChecker.SetDynamicKeys();
|
||||
RegisterDownloadedBackups.LoadBackupFiles();
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
Dispatcher.InvokeAsync(() => AvalonEdit.SetAEConfig());
|
||||
Program.StartTimer.Stop();
|
||||
DebugHelper.WriteLine("Startup time: {0} ms", Program.StartTimer.ElapsedMilliseconds);
|
||||
});
|
||||
}
|
||||
|
||||
#region BUTTON EVENTS
|
||||
private void Button_AESManager_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: AES Manager");
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: Opening image of " + FWindow.FCurrentAsset);
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("Thread canceled by user");
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
await PAKsLoader.LoadDifference(true);
|
||||
if (PAKsLoader.umIsOk)
|
||||
await AssetsLoader.ExtractUpdateMode();
|
||||
}
|
||||
}
|
||||
private void MI_ReloadAESs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DynamicKeysChecker.SetDynamicKeys(true);
|
||||
}
|
||||
private async void MI_BackupPAKs_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await BackupPAKs.CreateBackupFile();
|
||||
}
|
||||
private void MI_Settings_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: Settings");
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Settings"))
|
||||
{
|
||||
new FModel_Settings().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Settings").Focus(); }
|
||||
}
|
||||
private void MI_Search_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: Search Files");
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Search"))
|
||||
{
|
||||
new FModel_SearchFiles().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Search").Focus(); }
|
||||
}
|
||||
private void MI_HexViewer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: Hex Viewer");
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: Images Merger");
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Images Merger"))
|
||||
{
|
||||
new FModel_ImagesMerger().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Images Merger").Focus(); }
|
||||
}
|
||||
private void MI_Changelog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel/releases/latest");
|
||||
}
|
||||
private void MI_BugReports_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel/issues/new");
|
||||
}
|
||||
private void MI_About_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DebugHelper.WriteLine("FWindow: About");
|
||||
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;
|
||||
MI_Auto_Save_Images.IsChecked = true; //auto save images
|
||||
|
||||
if (MI_DifferenceMode.IsChecked && MI_UpdateMode.IsChecked)
|
||||
{
|
||||
if (!FormsUtility.IsWindowOpen<Window>("Update Mode"))
|
||||
{
|
||||
new FModel_UpdateMode().Show();
|
||||
}
|
||||
else { FormsUtility.GetOpenedWindow<Window>("Update Mode").Focus(); }
|
||||
}
|
||||
}
|
||||
if (!MI_UpdateMode.IsChecked)
|
||||
{
|
||||
MI_LoadAllPAKs.Header = "Load Difference";
|
||||
MI_Auto_Save_Images.IsChecked = false;
|
||||
}
|
||||
|
||||
//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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<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="https://benbotfn.tk/api/v1/aes" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF">Latest Fortnite AES Keys</Hyperlink>
|
||||
</TextBlock>
|
||||
</Label>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
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))
|
||||
{
|
||||
Label PakLabel = new Label
|
||||
{
|
||||
Content = Path.GetFileNameWithoutExtension(Pak.ThePAKPath),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
Margin = new Thickness(2, yPos - 2, 0, 0),
|
||||
VerticalAlignment = VerticalAlignment.Top,
|
||||
Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239))
|
||||
};
|
||||
|
||||
TextBox PakTextBox = new TextBox
|
||||
{
|
||||
Height = 19,
|
||||
TextWrapping = TextWrapping.NoWrap,
|
||||
AcceptsReturn = false,
|
||||
Margin = new Thickness(160, yPos, 5, 0),
|
||||
VerticalAlignment = VerticalAlignment.Top,
|
||||
Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239)),
|
||||
Name = $"TxtBox_{Regex.Match(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), @"\d+").Value}"
|
||||
};
|
||||
|
||||
string PAKKeyFromXML = string.Empty;
|
||||
if (AESEntries.AESEntriesList != null && AESEntries.AESEntriesList.Any())
|
||||
{
|
||||
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);
|
||||
|
||||
DebugHelper.WriteLine($"AESManager GET: {Pak.ThePAKPath} with key: {PAKKeyFromXML}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetUserSettings()
|
||||
{
|
||||
MAesTextBox.Text = $"0x{FProp.Default.FPak_MainAES}";
|
||||
DebugHelper.WriteLine($"AESManager GET: Main PAKs with key: {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; }
|
||||
DebugHelper.WriteLine($"AESManager SET: Main PAKs with key: {MAesTextBox.Text}");
|
||||
|
||||
//DYNAMIC AESs
|
||||
AESEntries.AESEntriesList = new List<AESInfosEntry>();
|
||||
if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any())
|
||||
{
|
||||
foreach (PAKInfosEntry Pak in PAKEntries.PAKEntriesList.Where(x => x.bTheDynamicPAK))
|
||||
{
|
||||
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); }
|
||||
DebugHelper.WriteLine($"AESManager SET: {Pak.ThePAKPath} with key: {PakTextBox.Text}");
|
||||
}
|
||||
|
||||
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();
|
||||
DebugHelper.WriteLine($"AESManager: Saved");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<Window
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:colorPickerWpf="clr-namespace:ColorPickerWPF"
|
||||
x:Class="ColorPickerWPF.ColorPickerWindow"
|
||||
mc:Ignorable="d"
|
||||
Style="{StaticResource {x:Type Window}}"
|
||||
Title="Color Picker" Width="574" MinWidth="342" SizeToContent="Height" MinHeight="450" Icon="/FModel;component/Logo.ico" ResizeMode="CanMinimize">
|
||||
<DockPanel LastChildFill="False">
|
||||
|
||||
<colorPickerWpf:ColorPickerControl x:Name="ColorPicker" DockPanel.Dock="Top" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" MinHeight="372"/>
|
||||
|
||||
<Grid DockPanel.Dock="Bottom" MinHeight="47">
|
||||
<Button x:Name="CloseButton" Content="Close" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="90,10,0,0" Height="27" Click="CloseButton_Click" IsCancel="True"/>
|
||||
<Button x:Name="OKButton" Content="OK" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="10,10,0,10" Height="27" Click="OKButton_Click" IsDefault="True"/>
|
||||
<Button x:Name="MinMaxViewButton" Content="<< Simple" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="243,10,0,0" Height="27" Click="MinMaxViewButton_OnClick"/>
|
||||
</Grid>
|
||||
|
||||
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
using System.Windows;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_About.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_About : Window
|
||||
{
|
||||
public FModel_About()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<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="Up_Button" Content="🡹" HorizontalAlignment="Left" Margin="110,10,0,0" VerticalAlignment="Top" Width="30" Click="Up_Button_Click"/>
|
||||
<Button x:Name="Down_Button" Content="🡻" HorizontalAlignment="Left" Margin="145,10,0,0" VerticalAlignment="Top" Width="30" Click="Down_Button_Click"/>
|
||||
<Button x:Name="RemoveImage_Button" Content="Remove" HorizontalAlignment="Center" Margin="184,10,105,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>
|
||||
|
|
@ -1,308 +0,0 @@
|
|||
using FModel.Methods.Utilities;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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()
|
||||
{
|
||||
DebugHelper.WriteLine("Merger: Merging images of the listbox");
|
||||
|
||||
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)));
|
||||
|
||||
int num = 1;
|
||||
int curW = 0;
|
||||
int curH = 0;
|
||||
int maxHeight = 0;
|
||||
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
DebugHelper.WriteLine("Merger: Images of the listbox merged successfully");
|
||||
}
|
||||
|
||||
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.Length > 0)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
ListBoxItem itm = new ListBoxItem();
|
||||
itm.ContentStringFormat = file;
|
||||
itm.Content = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
ImagesListBox.Items.Add(itm);
|
||||
DebugHelper.WriteLine($"Merger: {file} added to the listbox");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("Merger: Opening preview of the merged image");
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("Merger: Saving image...");
|
||||
|
||||
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))
|
||||
{
|
||||
DebugHelper.WriteLine("Merger: Image saved at " + path);
|
||||
|
||||
new UpdateMyConsole(Path.GetFileNameWithoutExtension(path), CColors.Blue).Append();
|
||||
new UpdateMyConsole(" successfully saved", CColors.White, true).Append();
|
||||
}
|
||||
else //just in case
|
||||
{
|
||||
DebugHelper.WriteLine("Merger: Image couldn't be saved at " + path);
|
||||
|
||||
new UpdateMyConsole("Bruh moment\nCouldn't save ", CColors.White).Append();
|
||||
new UpdateMyConsole(Path.GetFileNameWithoutExtension(path), CColors.Blue, true).Append();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void Up_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
|
||||
{
|
||||
bool reloadImage = false;
|
||||
|
||||
int[] indices = ImagesListBox.SelectedItems.Cast<object>().Select(i => ImagesListBox.Items.IndexOf(i)).ToArray();
|
||||
if (indices.Length > 0 && indices[0] > 0)
|
||||
{
|
||||
for (int i = 0; i < ImagesListBox.Items.Count; i++)
|
||||
{
|
||||
if (indices.Contains(i))
|
||||
{
|
||||
object moveItem = ImagesListBox.Items[i];
|
||||
ImagesListBox.Items.Remove(moveItem);
|
||||
ImagesListBox.Items.Insert(i - 1, moveItem);
|
||||
((ListBoxItem)moveItem).IsSelected = true;
|
||||
reloadImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImagesListBox.SelectedItems.Add(indices);
|
||||
|
||||
if (reloadImage)
|
||||
await UpdateMergerPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private async void Down_Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
|
||||
{
|
||||
bool reloadImage = false;
|
||||
|
||||
int[] indices = ImagesListBox.SelectedItems.Cast<object>().Select(i => ImagesListBox.Items.IndexOf(i)).ToArray();
|
||||
if (indices.Length > 0 && indices[indices.Length - 1] < ImagesListBox.Items.Count - 1)
|
||||
{
|
||||
for (int i = ImagesListBox.Items.Count - 1; i > -1; --i)
|
||||
{
|
||||
if (indices.Contains(i))
|
||||
{
|
||||
object moveItem = ImagesListBox.Items[i];
|
||||
ImagesListBox.Items.Remove(moveItem);
|
||||
ImagesListBox.Items.Insert(i + 1, moveItem);
|
||||
((ListBoxItem)moveItem).IsSelected = true;
|
||||
reloadImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reloadImage)
|
||||
await UpdateMergerPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
<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="1100"
|
||||
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/info_16x.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="Left" VerticalAlignment="Center" Width="120" Click="GoTo_Button_Click" Margin="10,0,0,0"/>
|
||||
<Label x:Name="FoundNumber_Label" Content="Found 0 asset" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,10,0" Padding="0"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -1,284 +0,0 @@
|
|||
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;
|
||||
using System.Globalization;
|
||||
|
||||
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)
|
||||
{
|
||||
DebugHelper.WriteLine("SearchFiles: Populating DataGrid...");
|
||||
|
||||
FilterTextBox_Search.IsReadOnly = true;
|
||||
FileNames = new List<FileInfo>();
|
||||
await PopulateDataGrid();
|
||||
DataGrid_Search.ItemsSource = FileNames;
|
||||
FilterTextBox_Search.IsReadOnly = false;
|
||||
|
||||
DebugHelper.WriteLine("SearchFiles: Populated DataGrid");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PopulateDataGrid()
|
||||
{
|
||||
Dictionary<string, string> IfExistChecker = new Dictionary<string, string>();
|
||||
int i = 0;
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(FWindow.FCurrentPAK))
|
||||
{
|
||||
FPakEntry[] ohyeah = PAKEntries.PAKToDisplay[FWindow.FCurrentPAK];
|
||||
FillList(ohyeah, IfExistChecker);
|
||||
i = ohyeah.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (FPakEntry[] PAKsFileInfos in PAKEntries.PAKToDisplay.Values)
|
||||
{
|
||||
FillList(PAKsFileInfos, IfExistChecker);
|
||||
i += PAKsFileInfos.Length;
|
||||
}
|
||||
}
|
||||
}).ContinueWith(TheTask =>
|
||||
{
|
||||
TasksUtility.TaskCompleted(TheTask.Exception);
|
||||
});
|
||||
|
||||
//max = million
|
||||
string number = i.ToString("# ### ###", new NumberFormatInfo { NumberGroupSeparator = " " }).Trim();
|
||||
DebugHelper.WriteLine($"SearchFiles: Loaded {number} assets");
|
||||
FoundNumber_Label.Content = $"Found {number} assets";
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
<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="581.5"
|
||||
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="70" 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,35,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
<Button x:Name="BrowseInput_Button" Content="..." HorizontalAlignment="Left" Margin="532,4,0,0" VerticalAlignment="Top" Width="20" Click="BrowseInput_Button_Click"/>
|
||||
<CheckBox x:Name="bDiffFileSize" Content="Diff w/ File Size" HorizontalAlignment="Left" Margin="10,31,0,0" VerticalAlignment="Top"/>
|
||||
<CheckBox x:Name="bReloadAES" Content="Reload AES Keys at Launch" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="124,31,0,0" IsChecked="True"/>
|
||||
<CheckBox x:Name="bOpenSounds" Content="Auto Open Sounds" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="292,31,0,0" IsChecked="True"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Extraction" HorizontalAlignment="Left" Height="48" Margin="10,85,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,138,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"/>
|
||||
<ComboBoxItem Content="Accurate Colors"/>
|
||||
</ComboBox>
|
||||
<Border BorderThickness="1" BorderBrush="#7F748198" 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,349,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" BorderBrush="#7F748198" 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>
|
||||
|
|
@ -1,602 +0,0 @@
|
|||
using FModel.Methods.MessageBox;
|
||||
using System.Windows;
|
||||
using System;
|
||||
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;
|
||||
using FProp = FModel.Properties.Settings;
|
||||
|
||||
namespace FModel.Forms
|
||||
{
|
||||
/// <summary>
|
||||
/// Logique d'interaction pour FModel_Settings.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_Settings : Window
|
||||
{
|
||||
private const string CHALLENGE_TEMPLATE_ICON = "pack://application:,,,/Resources/Template_Challenge.png";
|
||||
private const string RARITY_DEFAULT_FEATURED = "pack://application:,,,/Resources/Template_D_F.png";
|
||||
private const string RARITY_DEFAULT_NORMAL = "pack://application:,,,/Resources/Template_D_N.png";
|
||||
private const string RARITY_FLAT_FEATURED = "pack://application:,,,/Resources/Template_F_F.png";
|
||||
private const string RARITY_FLAT_NORMAL = "pack://application:,,,/Resources/Template_F_N.png";
|
||||
private const string RARITY_MINIMALIST_FEATURED = "pack://application:,,,/Resources/Template_M_F.png";
|
||||
private const string RARITY_MINIMALIST_NORMAL = "pack://application:,,,/Resources/Template_M_N.png";
|
||||
private const string RARITY_ACCURATECOLORS_FEATURED = "pack://application:,,,/Resources/Template_AC_F.png";
|
||||
private const string RARITY_ACCURATECOLORS_NORMAL = "pack://application:,,,/Resources/Template_AC_N.png";
|
||||
|
||||
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,
|
||||
[Description("Accurate Colors")]
|
||||
Accurate = 3
|
||||
}
|
||||
|
||||
public static T GetEnumValueFromDescription<T>(string description)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (!type.IsEnum) { throw new ArgumentException("Enum type is null, bruh"); }
|
||||
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;
|
||||
bReloadAES.IsChecked = FProp.Default.ReloadAES;
|
||||
bOpenSounds.IsChecked = FProp.Default.FOpenSounds;
|
||||
|
||||
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()
|
||||
{
|
||||
bool restart = false;
|
||||
|
||||
if (!string.Equals(FProp.Default.FPak_Path, InputTextBox.Text))
|
||||
{
|
||||
FProp.Default.FPak_Path = InputTextBox.Text;
|
||||
restart = true;
|
||||
}
|
||||
|
||||
FProp.Default.FDiffFileSize = (bool)bDiffFileSize.IsChecked;
|
||||
FProp.Default.ReloadAES = (bool)bReloadAES.IsChecked;
|
||||
FProp.Default.FOpenSounds = (bool)bOpenSounds.IsChecked;
|
||||
|
||||
if (!string.Equals(FProp.Default.FOutput_Path, OutputTextBox.Text))
|
||||
{
|
||||
FProp.Default.FOutput_Path = OutputTextBox.Text;
|
||||
restart = true;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (restart)
|
||||
{
|
||||
DarkMessageBox.Show("FModel is about to restart because you applied your new path(s)", "FModel Path(s) Changed", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
DebugHelper.WriteLine("FModel is restarting");
|
||||
System.Windows.Forms.Application.Restart();
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
else
|
||||
DebugHelper.WriteUserSettings();
|
||||
}
|
||||
|
||||
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 ? RARITY_DEFAULT_FEATURED : RARITY_DEFAULT_NORMAL));
|
||||
break;
|
||||
case "Flat":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_FLAT_FEATURED : RARITY_FLAT_NORMAL));
|
||||
break;
|
||||
case "Minimalist":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_MINIMALIST_FEATURED : RARITY_MINIMALIST_NORMAL));
|
||||
break;
|
||||
case "Accurate Colors":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_ACCURATECOLORS_FEATURED : RARITY_ACCURATECOLORS_NORMAL));
|
||||
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))
|
||||
{
|
||||
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, bmp.Width * (scale / 515), bmp.Height * (scale / 515)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(CHALLENGE_TEMPLATE_ICON));
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
<Window x:Class="FModel.Forms.FModel_UpdateMode"
|
||||
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="Update Mode" Height="315" Width="700" UseLayoutRounding="True"
|
||||
Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Logo.ico" ResizeMode="CanMinimize" Loaded="Window_Loaded">
|
||||
<Grid>
|
||||
<ListBox x:Name="AssetsListBox" HorizontalAlignment="Left" Height="225" Margin="10,10,0,0" VerticalAlignment="Top" Width="250" ItemsSource="{Binding Assets}" SelectionChanged="AssetsListBox_SelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
|
||||
<MenuItem.Icon>
|
||||
<Image Width="16" Height="16" Source="/FModel;component/Resources/info_16x.png"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</ListBox.ContextMenu>
|
||||
</ListBox>
|
||||
|
||||
<Label Content="Name:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,10,0,0"/>
|
||||
<TextBox x:Name="NameTextBox" Height="19" Margin="307,13,10,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
<Label Content="Path:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,35,0,0"/>
|
||||
<TextBox x:Name="PathTextBox" Text="/FortniteGame/Content/Athena/..." Height="19" Margin="307,38,10,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
|
||||
<Button x:Name="Button_AddAssetType" Content="Add" HorizontalAlignment="Right" Margin="0,62,10,0" VerticalAlignment="Top" Width="80" Height="19" Click="Button_AddAssetType_Click"/>
|
||||
<Button x:Name="Button_RemoveAssetType" Content="Remove Selected" HorizontalAlignment="Right" Margin="0,62,95,0" VerticalAlignment="Top" Width="110" Height="19" IsEnabled="False" Click="Button_RemoveAssetType_Click"/>
|
||||
|
||||
<Border BorderThickness="1" BorderBrush="#7F748198" Background="#FF252D36" HorizontalAlignment="Left" Height="144" Margin="265,91,0,0" Width="411" VerticalAlignment="Top">
|
||||
<Image x:Name="ImageBox_RarityPreview" Source="/FModel;component/Resources/Template_D_N.png" UseLayoutRounding="True" HorizontalAlignment="Right" Height="140" Width="140" Margin="0,0,1,0"/>
|
||||
</Border>
|
||||
<Label Content="Language:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,91,0,0"/>
|
||||
<ComboBox x:Name="ComboBox_Language" HorizontalAlignment="Left" Margin="324,94,0,0" VerticalAlignment="Top" Width="202" 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="265,116,0,0"/>
|
||||
<ComboBox x:Name="ComboBox_Design" HorizontalAlignment="Left" Margin="341,119,0,0" VerticalAlignment="Top" Width="185" BorderBrush="#7F748198" Background="#FF333C46" IsReadOnly="True" SelectionChanged="UpdateImageBox">
|
||||
<ComboBoxItem Content="Default"/>
|
||||
<ComboBoxItem Content="Flat"/>
|
||||
<ComboBoxItem Content="Minimalist"/>
|
||||
<ComboBoxItem Content="Accurate Colors"/>
|
||||
</ComboBox>
|
||||
<CheckBox x:Name="bFeaturedIcon" Content="Shop Item Icon" HorizontalAlignment="Left" Margin="438,143,0,0" VerticalAlignment="Top" Checked="UpdateImageBox" Unchecked="UpdateImageBox"/>
|
||||
<CheckBox x:Name="bWatermarkIcon" Content="Watermark" HorizontalAlignment="Left" Margin="271,188,0,0" VerticalAlignment="Top" Checked="EnableDisableWatermark" Unchecked="EnableDisableWatermark"/>
|
||||
<Button x:Name="OpenFile_Button" Content="+" HorizontalAlignment="Left" Margin="352,184,0,0" VerticalAlignment="Top" Width="19" IsEnabled="False" Click="OpenFile_Button_Click"/>
|
||||
<Label x:Name="Watermark_Label" Content="File Name: " MaxWidth="240" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="376,183,0,0"/>
|
||||
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,205,0,0"/>
|
||||
<Slider x:Name="Opacity_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="330,208,0,0" VerticalAlignment="Top" Maximum="255" Width="196" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
|
||||
|
||||
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
@ -1,382 +0,0 @@
|
|||
using FModel.Methods;
|
||||
using FModel.Methods.Assets;
|
||||
using FModel.Methods.MessageBox;
|
||||
using FModel.Methods.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
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_UpdateMode.xaml
|
||||
/// </summary>
|
||||
public partial class FModel_UpdateMode : Window
|
||||
{
|
||||
private const string CHALLENGE_TEMPLATE_ICON = "pack://application:,,,/Resources/Template_Challenge.png";
|
||||
private const string RARITY_DEFAULT_FEATURED = "pack://application:,,,/Resources/Template_D_F.png";
|
||||
private const string RARITY_DEFAULT_NORMAL = "pack://application:,,,/Resources/Template_D_N.png";
|
||||
private const string RARITY_FLAT_FEATURED = "pack://application:,,,/Resources/Template_F_F.png";
|
||||
private const string RARITY_FLAT_NORMAL = "pack://application:,,,/Resources/Template_F_N.png";
|
||||
private const string RARITY_MINIMALIST_FEATURED = "pack://application:,,,/Resources/Template_M_F.png";
|
||||
private const string RARITY_MINIMALIST_NORMAL = "pack://application:,,,/Resources/Template_M_N.png";
|
||||
private const string RARITY_ACCURATECOLORS_FEATURED = "pack://application:,,,/Resources/Template_AC_F.png";
|
||||
private const string RARITY_ACCURATECOLORS_NORMAL = "pack://application:,,,/Resources/Template_AC_N.png";
|
||||
|
||||
#region CLASS
|
||||
public class AssetProperties : INotifyPropertyChanged
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Path { get; set; }
|
||||
|
||||
//Provide change-notification for IsChecked
|
||||
[JsonIgnore]
|
||||
private bool _fIsChecked = false;
|
||||
public bool IsChecked
|
||||
{
|
||||
get { return _fIsChecked; }
|
||||
set
|
||||
{
|
||||
_fIsChecked = value;
|
||||
this.OnPropertyChanged("IsChecked");
|
||||
}
|
||||
}
|
||||
//Provide change-notification for IsSelected
|
||||
[JsonIgnore]
|
||||
private bool _fIsSelected = false;
|
||||
public bool IsSelected
|
||||
{
|
||||
get { return _fIsSelected; }
|
||||
set
|
||||
{
|
||||
_fIsSelected = value;
|
||||
this.OnPropertyChanged("IsSelected");
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged(string strPropertyName)
|
||||
{
|
||||
if (PropertyChanged != null)
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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,
|
||||
[Description("Accurate Colors")]
|
||||
Accurate = 3
|
||||
}
|
||||
|
||||
public static T GetEnumValueFromDescription<T>(string description)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (!type.IsEnum) { throw new ArgumentException("Enum type is null, bruh"); }
|
||||
FieldInfo[] fields = type.GetFields();
|
||||
var field = fields
|
||||
.SelectMany(f => f.GetCustomAttributes(
|
||||
typeof(DescriptionAttribute), false), (
|
||||
f, a) => new { Field = f, Att = a })
|
||||
.SingleOrDefault(a => ((DescriptionAttribute)a.Att)
|
||||
.Description == description);
|
||||
return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public ObservableCollection<AssetProperties> Assets { get; set; }
|
||||
public static Dictionary<string, Dictionary<string, string>> AssetsEntriesDict { get; set; }
|
||||
|
||||
public FModel_UpdateMode()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FoldersUtility.CheckWatermark();
|
||||
|
||||
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;
|
||||
|
||||
AssetsEntriesDict = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(FProp.Default.FUM_AssetsType);
|
||||
Assets = new ObservableCollection<AssetProperties>();
|
||||
foreach (KeyValuePair<string, Dictionary<string, string>> a in AssetsEntriesDict)
|
||||
{
|
||||
Assets.Add(new AssetProperties
|
||||
{
|
||||
Name = a.Key,
|
||||
Path = a.Value["Path"],
|
||||
IsChecked = bool.Parse(a.Value["isChecked"])
|
||||
});
|
||||
}
|
||||
|
||||
DataContext = this;
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
|
||||
private async void UpdateImageBox(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
private async void UpdateImageWithWatermark(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
private async Task UpdateImageWithWatermark()
|
||||
{
|
||||
bool watermarkEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
bool isFeatured = (bool)bFeaturedIcon.IsChecked;
|
||||
string rarityDesign = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
|
||||
int opacity = Convert.ToInt32(Opacity_Slider.Value);
|
||||
double scale = FProp.Default.FWatermarkScale;
|
||||
|
||||
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 ? RARITY_DEFAULT_FEATURED : RARITY_DEFAULT_NORMAL));
|
||||
break;
|
||||
case "Flat":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_FLAT_FEATURED : RARITY_FLAT_NORMAL));
|
||||
break;
|
||||
case "Minimalist":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_MINIMALIST_FEATURED : RARITY_MINIMALIST_NORMAL));
|
||||
break;
|
||||
case "Accurate Colors":
|
||||
source = new BitmapImage(new Uri(isFeatured ? RARITY_ACCURATECOLORS_FEATURED : RARITY_ACCURATECOLORS_NORMAL));
|
||||
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))
|
||||
{
|
||||
BitmapImage bmp = new BitmapImage();
|
||||
bmp.BeginInit();
|
||||
bmp.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bmp.StreamSource = image.BaseStream;
|
||||
bmp.EndInit();
|
||||
|
||||
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(FProp.Default.FWatermarkXPos, FProp.Default.FWatermarkYPos, scale, scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 async void EnableDisableWatermark(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OpenFile_Button.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
Opacity_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
|
||||
|
||||
await UpdateImageWithWatermark();
|
||||
}
|
||||
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 Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AssetsEntriesDict = new Dictionary<string, Dictionary<string, string>>();
|
||||
foreach (AssetProperties a in Assets)
|
||||
{
|
||||
AssetsEntriesDict[a.Name] = new Dictionary<string, string>();
|
||||
AssetsEntriesDict[a.Name]["Path"] = a.Path;
|
||||
AssetsEntriesDict[a.Name]["isChecked"] = a.IsChecked.ToString();
|
||||
|
||||
if (a.IsChecked)
|
||||
DebugHelper.WriteLine("UpdateMode: User is about to extract everything in " + a.Path);
|
||||
}
|
||||
|
||||
string selectedLang = ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString();
|
||||
if (AssetEntries.AssetEntriesDict != null && !string.Equals(FProp.Default.FLanguage, selectedLang))
|
||||
{
|
||||
AssetTranslations.SetAssetTranslation(selectedLang);
|
||||
}
|
||||
FProp.Default.FLanguage = selectedLang;
|
||||
|
||||
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.FUM_AssetsType = JsonConvert.SerializeObject(AssetsEntriesDict, Formatting.Indented);
|
||||
FProp.Default.Save();
|
||||
|
||||
DebugHelper.WriteLine("=============== UPDATE MODE ===============");
|
||||
DebugHelper.WriteLine("FRarity_Design > " + FProp.Default.FRarity_Design);
|
||||
DebugHelper.WriteLine("FLanguage > " + FProp.Default.FLanguage);
|
||||
DebugHelper.WriteLine("FIsFeatured > " + FProp.Default.FIsFeatured);
|
||||
DebugHelper.WriteLine("FUseWatermark > " + FProp.Default.FUseWatermark);
|
||||
DebugHelper.WriteLine("FWatermarkFilePath > " + FProp.Default.FWatermarkFilePath);
|
||||
DebugHelper.WriteLine("FWatermarkOpacity > " + FProp.Default.FWatermarkOpacity);
|
||||
DebugHelper.WriteLine("FWatermarkScale > " + FProp.Default.FWatermarkScale);
|
||||
DebugHelper.WriteLine("FWatermarkXPos > " + FProp.Default.FWatermarkXPos);
|
||||
DebugHelper.WriteLine("FWatermarkYPos > " + FProp.Default.FWatermarkYPos);
|
||||
DebugHelper.WriteLine("FOpenSounds > " + FProp.Default.FOpenSounds);
|
||||
DebugHelper.WriteLine("FAutoExtractRaw > " + FProp.Default.FAutoExtractRaw);
|
||||
DebugHelper.WriteLine("FAutoSaveJson > " + FProp.Default.FAutoSaveJson);
|
||||
DebugHelper.WriteLine("FAutoSaveImg > " + FProp.Default.FAutoSaveImg);
|
||||
DebugHelper.WriteLine("=============================================");
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void AssetsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0) { ((ListBox)sender).ScrollIntoView(e.AddedItems[0]); }
|
||||
Button_RemoveAssetType.IsEnabled = AssetsListBox.SelectedIndex >= 0;
|
||||
}
|
||||
|
||||
private void Button_RemoveAssetType_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AssetsListBox.Items.Count > 0 && AssetsListBox.SelectedItems.Count > 0)
|
||||
{
|
||||
DebugHelper.WriteLine("UpdateMode: Removing " + (AssetsListBox.SelectedItem as AssetProperties).Path + " to the list of assets type");
|
||||
Assets.Remove(AssetsListBox.SelectedItem as AssetProperties);
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_AddAssetType_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string path = PathTextBox.Text.Trim();
|
||||
if (!path.StartsWith("/"))
|
||||
path = path.Insert(0, "/");
|
||||
if (!path.EndsWith("/"))
|
||||
path += "/";
|
||||
|
||||
DebugHelper.WriteLine("UpdateMode: Adding " + path + " to the list of assets type");
|
||||
Assets.Add(new AssetProperties
|
||||
{
|
||||
Name = NameTextBox.Text,
|
||||
Path = path,
|
||||
IsSelected = true
|
||||
});
|
||||
}
|
||||
|
||||
private void RC_Properties_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AssetsListBox.SelectedIndex >= 0)
|
||||
{
|
||||
AssetProperties a = AssetsListBox.SelectedItem as AssetProperties;
|
||||
string infos = GetAssetInfos(a);
|
||||
if (DarkMessageBox.ShowYesNo(infos, a.Name, "Copy Properties", "OK") == MessageBoxResult.Yes)
|
||||
{
|
||||
Clipboard.SetText(infos);
|
||||
|
||||
new UpdateMyConsole(a.Name, CColors.Blue).Append();
|
||||
new UpdateMyConsole("'s properties successfully copied", CColors.White, true).Append();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetAssetInfos(AssetProperties a)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(
|
||||
"\n- Name:\t\t" + a.Name +
|
||||
"\n- Path:\t\t" + a.Path +
|
||||
"\n- Checked:\t" + a.IsChecked +
|
||||
"\n- Selected:\tTrue" +
|
||||
"\n"
|
||||
);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,559 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<!--
|
||||
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>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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}";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,255 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
|
@ -1,277 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,406 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
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>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
<?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>
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
<!--
|
||||
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>
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
<!--
|
||||
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>
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
<!--
|
||||
Apache 2.0 - 2016-2018
|
||||
Author : Derek Tremblay (derektremblay666@gmail.com)
|
||||
-->
|
||||
|
||||
<UserControl
|
||||
x:Class="WpfHexaEditor.HexBox"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p="clr-namespace:FModel.Properties"
|
||||
Width="100"
|
||||
Height="24"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="13" />
|
||||
<ColumnDefinition Width="65*" />
|
||||
<ColumnDefinition Width="22" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RepeatButton
|
||||
Grid.Column="2"
|
||||
Padding="0"
|
||||
BorderBrush="#FFCDCBCB"
|
||||
Click="UpButton_Click">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Margin="0,-1,0,0"
|
||||
FontSize="8"
|
||||
Text="▲" />
|
||||
</Grid>
|
||||
</RepeatButton>
|
||||
|
||||
<RepeatButton
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Padding="0"
|
||||
BorderBrush="#FFCDCBCB"
|
||||
Click="DownButton_Click">
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Margin="0,-1,0,0"
|
||||
FontSize="8"
|
||||
Text="▼" />
|
||||
</Grid>
|
||||
</RepeatButton>
|
||||
|
||||
<TextBox
|
||||
x:Name="HexTextBox"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
VerticalContentAlignment="Center"
|
||||
BorderBrush="{x:Null}"
|
||||
Focusable="True"
|
||||
IsUndoEnabled="False"
|
||||
KeyDown="HexTextBox_KeyDown"
|
||||
MaxLength="15"
|
||||
MaxLines="1"
|
||||
PreviewKeyDown="HexTextBox_PreviewKeyDown"
|
||||
TabIndex="1"
|
||||
Text="0"
|
||||
TextChanged="HexTextBox_TextChanged" Padding="0" Foreground="White">
|
||||
<TextBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Click="CopyHexaMenuItem_Click" Header="Copy as hexadecimal" />
|
||||
<MenuItem Click="CopyLongMenuItem_Click" Header="Copy as decimal" />
|
||||
</ContextMenu>
|
||||
</TextBox.ContextMenu>
|
||||
</TextBox>
|
||||
|
||||
<Label
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Padding="0"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="0x" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
//////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,425 +0,0 @@
|
|||
<!--
|
||||
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
|
|
@ -1,286 +0,0 @@
|
|||
<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>
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<!--
|
||||
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>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user