diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index e56e9d97..665cc805 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -2,6 +2,7 @@ name: package on: workflow_dispatch: + pull_request: jobs: package: diff --git a/src/TF2HUD.Editor/App.config b/src/TF2HUD.Editor/App.config index 52fcb6a9..ad90766a 100644 --- a/src/TF2HUD.Editor/App.config +++ b/src/TF2HUD.Editor/App.config @@ -1,70 +1,70 @@  - - -
- - -
- - - - - - - - - - - - en-US - - - True - - - False - - - False - - - $ - - - - - - 0 - - - https://user-images.githubusercontent.com/6818236/220803776-12f85855-a409-4555-8f76-e3877d04bab9.png - - - - - - - https://criticalflaw.ca/TF2HUD.Editor/ - - - https://raw.githubusercontent.com/CriticalFlaw/TF2HUD.Editor/master/src/TF2HUD.Editor/JSON/{0} - - - https://api.github.com/repos/CriticalFlaw/TF2HUD.Editor/contents/src/TF2HUD.Editor/JSON - - - https://github.com/CriticalFlaw/TF2HUD.Editor/issues - - - https://github.com/CriticalFlaw/TF2HUD.Editor/releases/latest - - - https://github.com/mastercomfig/mastercomfig/releases/download/9.5.2/mastercomfig-transparent-viewmodels-addon.vpk - - - https://github.com/Hypnootize/TF2-HUD-Crosshairs/archive/refs/heads/master.zip - - - + + +
+ + +
+ + + + + + + + + + + + en-US + + + True + + + False + + + False + + + $ + + + + + + 0 + + + https://user-images.githubusercontent.com/6818236/220803776-12f85855-a409-4555-8f76-e3877d04bab9.png + + + + + + + https://criticalflaw.ca/TF2HUD.Editor/ + + + https://raw.githubusercontent.com/CriticalFlaw/TF2HUD.Editor/master/src/TF2HUD.Editor/JSON/{0} + + + https://api.github.com/repos/CriticalFlaw/TF2HUD.Editor/contents/src/TF2HUD.Editor/JSON + + + https://github.com/CriticalFlaw/TF2HUD.Editor/issues + + + https://github.com/CriticalFlaw/TF2HUD.Editor/releases/latest + + + https://github.com/mastercomfig/mastercomfig/releases/download/9.5.2/mastercomfig-transparent-viewmodels-addon.vpk + + + https://github.com/Hypnootize/TF2-HUD-Crosshairs/archive/refs/heads/master.zip + + + \ No newline at end of file diff --git a/src/TF2HUD.Editor/Classes/Converters.cs b/src/TF2HUD.Editor/Classes/Converters.cs index 47497a8d..6d6e14a8 100644 --- a/src/TF2HUD.Editor/Classes/Converters.cs +++ b/src/TF2HUD.Editor/Classes/Converters.cs @@ -14,7 +14,7 @@ namespace HUDEditor.Classes public class NullCheckConverter : IValueConverter { /// - /// Returns true if the provided value is not null or empty. + /// Returns true if the provided value is not null or empty. /// public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { @@ -36,7 +36,7 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu public class NotNullCheckConverter : IValueConverter { /// - /// Returns true if the provided value is null. + /// Returns true if the provided value is null. /// public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { @@ -144,18 +144,18 @@ public object Convert(object value, Type targetType, object parameter, CultureIn var hud = (HUD)value; if (hud is not null) { - MainWindow.Logger.Info($"User selected {hud.Name}"); + MainWindow.Logger.Info($"User selected: {hud.Name}"); if (Directory.Exists($"{Settings.Default.hud_directory}\\{hud.Name}")) { MainWindow.Logger.Info($"{hud.Name} is installed"); return Utilities.GetLocalizedString("ui_reinstall") ?? "Reinstall"; } - MainWindow.Logger.Info($"{hud.Name} is not installed"); + MainWindow.Logger.Warn($"{hud.Name} is not installed"); return Utilities.GetLocalizedString("ui_install") ?? "Install"; } - MainWindow.Logger.Warn("User selected HUD is null"); + MainWindow.Logger.Warn("User selected HUD is null. Returning to the main menu"); return Utilities.GetLocalizedString("ui_install") ?? "Install"; } diff --git a/src/TF2HUD.Editor/Classes/HUD/HUD.cs b/src/TF2HUD.Editor/Classes/HUD/HUD.cs index 2e2d997b..58c0a1a8 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUD.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUD.cs @@ -12,18 +12,44 @@ public partial class HUD { private Grid Controls = new(); private HUDBackground HudBackground; - private bool isRendered; + private bool IsRendered; private string[][] Layout; + #region HUD PROPERTIES + + public string Name { get; set; } + public HUDSettings Settings { get; set; } + public double Opacity { get; set; } + public bool Maximize { get; set; } + public string Thumbnail { get; set; } + public string Background { get; set; } + public string Description { get; set; } + public string Author { get; set; } + public string CustomizationsFolder { get; set; } + public string EnabledFolder { get; set; } + public Download[] Download; + public string GitHubUrl { get; set; } + public string TF2HudsUrl { get; set; } + public string ComfigHudsUrl { get; set; } + public string SteamUrl { get; set; } + public string DiscordUrl { get; set; } + public Dictionary ControlOptions; + public readonly string[] LayoutOptions; + public List DirtyControls; + public bool Unique; + public readonly bool InstallCrosshairs; + public string[] Screenshots { get; set; } + + #endregion HUD PROPERTIES + /// - /// Initialize the HUD object with values from the JSON schema. + /// Initializes the HUD object with values from the schema. /// - /// Name of the HUD object. - /// Contents of the HUD's schema file. - /// Flags the HUD as having unique customizations. - public HUD(string name, HudJson schema, bool unique) + /// HUD object name. + /// HUD schema contents. + /// Marks the HUD as having unique customizations. + public HUD(string name, HudJson schema, bool isUnique) { - // Basic Schema Properties. Name = schema.Name ?? name; Settings = new HUDSettings(Name); Opacity = schema.Opacity; @@ -43,21 +69,25 @@ public HUD(string name, HudJson schema, bool unique) ControlOptions = schema.Controls; LayoutOptions = schema.Layout; DirtyControls = new List(); - Unique = unique; + Unique = isUnique; InstallCrosshairs = schema.InstallCrosshairs; Screenshots = schema.Screenshots; } + /// + /// Changes the preset on a given HUD. + /// + /// public void SetPreset(Preset preset) { Settings.Preset = preset; - isRendered = false; + IsRendered = false; Controls = new Grid(); - MainWindow.Logger.Info($"Changed preset for {Name} to HUDSettingsPreset.{Settings.Preset}"); + MainWindow.Logger.Info($"Changing {Name} to Preset-{Settings.Preset}"); } /// - /// Reset all user-settings to the default values defined in the HUD schema. + /// Resets all user settings to their default values as defined in the schema. /// public void ResetAll() { @@ -67,7 +97,7 @@ public void ResetAll() } /// - /// Reset selected group of user-settings to the default values defined in the HUD schema. + /// Resets a group of user settings to their default values as defined in the schema. /// private void ResetSection(string selection) { @@ -76,7 +106,7 @@ private void ResetSection(string selection) } /// - /// Reset user-settings to the default values defined in the HUD schema. + /// Resets a user setting to its default value as defined in the schema. /// private void ResetControl(Controls control) { @@ -90,11 +120,6 @@ private void ResetControl(Controls control) Logger.Info($"Reset {control.Name} to {value}"); break; - case TextBox text: - text.Text = control.Value; - Logger.Info($"Reset {control.Name} to \"{control.Value}\""); - break; - case ColorPicker color: color.SelectedColor = Utilities.ConvertToColor(control.Value); Logger.Info($"Reset {control.Name} to {color.SelectedColor}"); @@ -110,6 +135,12 @@ private void ResetControl(Controls control) case IntegerUpDown integer: integer.Text = control.Value; + Logger.Info($"Reset {control.Name} to \"{control.Value}\""); + break; + + case TextBox text: + text.Text = control.Value; + Logger.Info($"Reset {control.Name} to \"{control.Value}\""); break; } } @@ -120,32 +151,5 @@ private void ResetControl(Controls control) throw; } } - - #region HUD PROPERTIES - - public string Name { get; set; } - public HUDSettings Settings { get; set; } - public double Opacity { get; set; } - public bool Maximize { get; set; } - public string Thumbnail { get; set; } - public string Background { get; set; } - public string Description { get; set; } - public string Author { get; set; } - public string CustomizationsFolder { get; set; } - public string EnabledFolder { get; set; } - public Download[] Download; - public string GitHubUrl { get; set; } - public string TF2HudsUrl { get; set; } - public string ComfigHudsUrl { get; set; } - public string SteamUrl { get; set; } - public string DiscordUrl { get; set; } - public Dictionary ControlOptions; - public readonly string[] LayoutOptions; - public List DirtyControls; - public string[] Screenshots { get; set; } - public bool Unique; - public readonly bool InstallCrosshairs; - - #endregion HUD PROPERTIES } } \ No newline at end of file diff --git a/src/TF2HUD.Editor/Classes/HUD/HUDAnimations.cs b/src/TF2HUD.Editor/Classes/HUD/HUDAnimations.cs index 114f98c6..e969fb41 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUDAnimations.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUDAnimations.cs @@ -5,45 +5,42 @@ namespace HUDEditor.Classes { /// - /// Sample Animation Script - /// Commands: + /// Sample Animation Script + /// Commands: /// Animate (panel name) (variable) (target value) (interpolator) (start time) (duration) /// Variables: - /// FgColor - /// BgColor - /// Position - /// Size - /// Blur (HUD panels only) - /// TextColor (HUD panels only) - /// Ammo2Color (HUD panels only) - /// Alpha (HUD weapon selection only) - /// SelectionAlpha (HUD weapon selection only) - /// TextScan (HUD weapon selection only) + /// FgColor + /// BgColor + /// Position + /// Size + /// Blur - HUD panels only + /// TextColor - HUD panels only + /// Ammo2Color - HUD panels only + /// Alpha - HUD weapon selection only + /// SelectionAlpha - HUD weapon selection only + /// TextScan - HUD weapon selection only /// Interpolator: - /// Linear - /// Accel - starts moving slow, ends fast - /// Deaccel - starts moving fast, ends slow - /// Spline - simple ease in/out curve - /// Pulse - ( freq ) over the duration, the value is pulsed (cosine) freq times ending at the dest value (assuming freq - /// is integral) - /// Flicker - ( randomness factor 0.0 to 1.0 ) over duration, each frame if random # is less than factor, use end - /// value, otherwise use prev value - /// Gain - ( bias ) Lower bias values bias towards 0.5 and higher bias values bias away from it. - /// Bias - ( bias ) Lower values bias the curve towards 0 and higher values bias it towards 1. - /// RunEvent (event name) (start time) - starts another even running at the specified time - /// StopEvent (event name) (start time) - stops another event that is current running at the specified time - /// StopAnimation (panel name) (variable) (start time) - stops all animations referring to the specified variable in - /// the specified panel - /// StopPanelAnimations (panel name) (start time) - stops all active animations operating on the specified panel - /// SetFont (panel name) (fontparameter) (fontname from scheme) (set time) - /// SetTexture (panel name) (textureidname) (texturefilename) (set time) - /// SetString (panel name) (string varname) (stringvalue) (set time) + /// Linear + /// Accel - starts moving slow, ends fast + /// Deaccel - starts moving fast, ends slow + /// Spline - simple ease in/out curve + /// Pulse - freq over the duration, the value is pulsed (cosine) freq times ending at the dest value (assuming freq is integral) + /// Flicker - randomness factor 0.0 to 1.0 over duration, each frame if random # is less than factor, use end value, otherwise use prev value + /// Gain - (bias) Lower bias values bias towards 0.5 and higher bias values bias away from it + /// Bias - (bias) Lower values bias the curve towards 0 and higher values bias it towards 1 + /// RunEvent (event name) (start time) - starts another even running at the specified time + /// StopEvent (event name) (start time) - stops another event that is current running at the specified time + /// StopAnimation (panel name) (variable) (start time) - stops all animations referring to the specified variable in the specified panel + /// StopPanelAnimations (panel name) (start time) - stops all active animations operating on the specified panel + /// SetFont (panel name) (fontparameter) (fontname from scheme) (set time) + /// SetTexture (panel name) (textureidname) (texturefilename) (set time) + /// SetString (panel name) (string varname) (stringvalue) (set time) /// internal static class HUDAnimations { public static Dictionary> Parse(string text) { - VDFTokeniser tokeniser = new VDFTokeniser(text); + VDFTokenizer tokenizer = new VDFTokenizer(text); Dictionary> ParseFile() { @@ -51,7 +48,7 @@ Dictionary> ParseFile() while (true) { - var token = tokeniser.Next(); + var token = tokenizer.Next(); if (token == null) break; switch (token.Value.Type) { @@ -59,16 +56,16 @@ Dictionary> ParseFile() { if (string.Equals(token.Value.Value, "event", StringComparison.CurrentCultureIgnoreCase)) { - var eventName = tokeniser.Next(); - if (eventName == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "event name" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + var eventName = tokenizer.Next(); + if (eventName == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["event name"], tokenizer.Index, tokenizer.Line, tokenizer.Character); if (eventName.Value.Type == VDFTokenType.String) animations[eventName.Value.Value] = ParseEvent(); - else throw new VDFSyntaxException(eventName.Value.Type, eventName.Value.Value, new[] { "event name" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + else throw new VDFSyntaxException(eventName.Value.Type, eventName.Value.Value, ["event name"], tokenizer.Index, tokenizer.Line, tokenizer.Character); } - else throw new VDFSyntaxException(token.Value.Type, token.Value.Value, new[] { "\"event\"", "EOF" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + else throw new VDFSyntaxException(token.Value.Type, token.Value.Value, ["\"event\"", "EOF"], tokenizer.Index, tokenizer.Line, tokenizer.Character); break; } default: - throw new VDFSyntaxException(token.Value.Type, token.Value.Value, new[] { "\"event\"", "EOF" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + throw new VDFSyntaxException(token.Value.Type, token.Value.Value, ["\"event\"", "EOF"], tokenizer.Index, tokenizer.Line, tokenizer.Character); } } @@ -78,15 +75,15 @@ Dictionary> ParseFile() List ParseEvent() { List events = new(); - var token = tokeniser.Next(); - if (token == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "{" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); - if (token.Value.Type != VDFTokenType.ControlCharacter || token.Value.Value != "{") throw new VDFSyntaxException(token.Value.Type, token.Value.Value, new[] { "{" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + var token = tokenizer.Next(); + if (token == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["{"], tokenizer.Index, tokenizer.Line, tokenizer.Character); + if (token.Value.Type != VDFTokenType.ControlCharacter || token.Value.Value != "{") throw new VDFSyntaxException(token.Value.Type, token.Value.Value, ["{"], tokenizer.Index, tokenizer.Line, tokenizer.Character); while (true) { - var animationCommandToken = tokeniser.Next(); - if (animationCommandToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "animation command", "}" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); - if (animationCommandToken.Value.Type != VDFTokenType.String) throw new VDFSyntaxException(animationCommandToken.Value.Type, animationCommandToken.Value.Value, new[] { "animation command", "}" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + var animationCommandToken = tokenizer.Next(); + if (animationCommandToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["animation command", "}"], tokenizer.Index, tokenizer.Line, tokenizer.Character); + if (animationCommandToken.Value.Type != VDFTokenType.String) throw new VDFSyntaxException(animationCommandToken.Value.Type, animationCommandToken.Value.Value, ["animation command", "}"], tokenizer.Index, tokenizer.Line, tokenizer.Character); if (animationCommandToken.Value.Value == "}") break; events.Add(ParseAnimation(animationCommandToken.Value.Value)); @@ -97,9 +94,9 @@ List ParseEvent() string ReadString() { - var token = tokeniser.Next(); - if (token == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "string" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); - if (token.Value.Type != VDFTokenType.String) throw new VDFSyntaxException(token.Value.Type, token.Value.Value, new[] { "string" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + var token = tokenizer.Next(); + if (token == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["string"], tokenizer.Index, tokenizer.Line, tokenizer.Character); + if (token.Value.Type != VDFTokenType.String) throw new VDFSyntaxException(token.Value.Type, token.Value.Value, ["string"], tokenizer.Index, tokenizer.Line, tokenizer.Character); return token.Value.Value; } @@ -111,115 +108,84 @@ string ReadNumber() string ReadBool() { var token = ReadString(); - if (token != "0" || token != "1") throw new VDFSyntaxException(VDFTokenType.String, token, new[] { "0", "1" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + if (token != "0" || token != "1") throw new VDFSyntaxException(VDFTokenType.String, token, ["0", "1"], tokenizer.Index, tokenizer.Line, tokenizer.Character); return token; } HUDAnimation ParseAnimation(string type) { - HUDAnimation animation; - - switch (type.ToLower()) + HUDAnimation animation = type.ToLower() switch { - case "animate": - animation = new Animate - { - Element = ReadString(), - Property = ReadString(), - Value = ReadString(), - Interpolator = ReadString().ToLower() switch - { - "linear" => new LinearInterpolator(), - "accel" => new AccelInterpolator(), - "deaccel" => new DeAccelInterpolator(), - "spline" => new SplineInterpolator(), - "pulse" => new PulseInterpolator { Frequency = ReadString() }, - "flicker" => new FlickerInterpolator { Randomness = ReadString() }, - "bias" => new BiasInterpolator { Bias = ReadString() }, - "gain" => new GainInterpolator { Bias = ReadString() }, - var interpolator => throw new VDFSyntaxException(VDFTokenType.String, interpolator, new[] { "interpolator" }, tokeniser.Index, tokeniser.Line, tokeniser.Character), - }, - Delay = ReadNumber(), - Duration = ReadNumber(), - }; - break; - - case "runevent": - animation = new RunEvent - { - Event = ReadString(), - Delay = ReadNumber(), - }; - break; - - case "stopevent": - animation = new StopEvent - { - Event = ReadString(), - Delay = ReadNumber(), - }; - break; - - case "setvisible": - animation = new SetVisible - { - Element = ReadString(), - Visible = ReadString(), - Delay = ReadNumber(), - }; - break; - - case "firecommand": - animation = new FireCommand - { - Delay = ReadNumber(), - Command = ReadString(), - }; - break; - - case "runeventchild": - animation = new RunEventChild - { - Element = ReadString(), - Event = ReadString(), - Delay = ReadNumber(), - }; - break; - - case "setinputenabled": - animation = new SetInputEnabled - { - Element = ReadString(), - Enabled = ReadBool(), - Delay = ReadNumber(), - }; - break; - - case "playsound": - animation = new PlaySound - { - Delay = ReadNumber(), - Sound = ReadString(), - }; - break; - - case "stoppanelanimations": - animation = new StopPanelAnimations + "animate" => new Animate + { + Element = ReadString(), + Property = ReadString(), + Value = ReadString(), + Interpolator = ReadString().ToLower() switch { - Element = ReadString(), - Delay = ReadNumber(), - }; - break; - - default: - throw new VDFSyntaxException(VDFTokenType.String, type, new[] { "animation command" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); - } - - var conditionalToken = tokeniser.Next(true); + "linear" => new LinearInterpolator(), + "accel" => new AccelInterpolator(), + "deaccel" => new DeAccelInterpolator(), + "spline" => new SplineInterpolator(), + "pulse" => new PulseInterpolator { Frequency = ReadString() }, + "flicker" => new FlickerInterpolator { Randomness = ReadString() }, + "bias" => new BiasInterpolator { Bias = ReadString() }, + "gain" => new GainInterpolator { Bias = ReadString() }, + var interpolator => throw new VDFSyntaxException(VDFTokenType.String, interpolator, ["interpolator"], tokenizer.Index, tokenizer.Line, tokenizer.Character), + }, + Delay = ReadNumber(), + Duration = ReadNumber(), + }, + "runevent" => new RunEvent + { + Event = ReadString(), + Delay = ReadNumber(), + }, + "stopevent" => new StopEvent + { + Event = ReadString(), + Delay = ReadNumber(), + }, + "setvisible" => new SetVisible + { + Element = ReadString(), + Visible = ReadString(), + Delay = ReadNumber(), + }, + "firecommand" => new FireCommand + { + Delay = ReadNumber(), + Command = ReadString(), + }, + "runeventchild" => new RunEventChild + { + Element = ReadString(), + Event = ReadString(), + Delay = ReadNumber(), + }, + "setinputenabled" => new SetInputEnabled + { + Element = ReadString(), + Enabled = ReadBool(), + Delay = ReadNumber(), + }, + "playsound" => new PlaySound + { + Delay = ReadNumber(), + Sound = ReadString(), + }, + "stoppanelanimations" => new StopPanelAnimations + { + Element = ReadString(), + Delay = ReadNumber(), + }, + _ => throw new VDFSyntaxException(VDFTokenType.String, type, ["animation command"], tokenizer.Index, tokenizer.Line, tokenizer.Character), + }; + var conditionalToken = tokenizer.Next(true); if (conditionalToken != null && conditionalToken.Value.Type == VDFTokenType.Conditional) { animation.Conditional = conditionalToken.Value.Value; - tokeniser.Next(); + tokenizer.Next(); } return animation; @@ -228,10 +194,16 @@ HUDAnimation ParseAnimation(string type) return ParseFile(); } + /// + /// Converts animation events into a string value to be written into HUD animations. + /// + /// + /// public static string Stringify(Dictionary> animations) { var stringValue = ""; const string newLine = "\r\n"; + foreach (var key in animations.Keys) { stringValue += $"event {key}{newLine}{{{newLine}"; diff --git a/src/TF2HUD.Editor/Classes/HUD/HUDBackground.cs b/src/TF2HUD.Editor/Classes/HUD/HUDBackground.cs index a350615f..a56a91c5 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUDBackground.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUDBackground.cs @@ -17,44 +17,44 @@ namespace HUDEditor.Classes /// internal class HUDBackground { - private readonly string HUDFolderPath; + private readonly string hudFolderPath; + private string hudImagePath; private string customImagePath; - private string HUDImagePath; private bool useCustomBackground; private bool useHUDBackground; private bool useStockBackgrounds; public HUDBackground(string hudPath) { - HUDFolderPath = hudPath; + hudFolderPath = hudPath; } - public void SetStockBackgrounds(bool enable) + public void SetStockBackground(bool enable) { - MainWindow.Logger.Info("Changing HUD background to: stock."); + MainWindow.Logger.Info("Changing HUD background to: stock"); useStockBackgrounds = enable; } public void SetHUDBackground(string imagePath) { MainWindow.Logger.Info($"Changing HUD background to: {imagePath}"); + hudImagePath = imagePath; useHUDBackground = true; - HUDImagePath = imagePath; } public void SetCustomBackground(string imagePath) { if (imagePath == "") return; MainWindow.Logger.Info($"Setting custom background to: {imagePath}"); - useCustomBackground = true; customImagePath = imagePath; + useCustomBackground = true; } - public void Apply() + public void ApplyBackground() { try { - var consoleFolder = HUDFolderPath + "materials\\console\\"; + var consoleFolder = hudFolderPath + "materials\\console\\"; var disabledFolder = consoleFolder + "_disabled"; if (!Directory.Exists(consoleFolder)) @@ -66,60 +66,63 @@ public void Apply() if (useCustomBackground && !string.IsNullOrWhiteSpace(customImagePath)) { // Check that the supplied image path is valid - MainWindow.Logger.Info($"Validating image path: {customImagePath}"); + MainWindow.Logger.Info($"Validating {customImagePath}"); if (!Uri.TryCreate(customImagePath, UriKind.Absolute, out _)) return; // Move all existing files to the disabled folder. foreach (var filePath in Directory.GetFiles(consoleFolder)) { - MainWindow.Logger.Info($"Moving {filePath} to {disabledFolder}"); + MainWindow.Logger.Info($"Moving \"{filePath}\" to \"{disabledFolder}\""); File.Move(filePath, $"{disabledFolder}\\{filePath.Split("\\")[^1]}", true); } // Convert the provided image into a VTF format. var converter = new VTF(MainWindow.HudPath.Replace("\\tf\\custom\\", string.Empty)); var output = $"{consoleFolder}\\background_upward.vtf"; - MainWindow.Logger.Info($"Converting image to VTF: {output}"); + MainWindow.Logger.Info($"Converting \"{customImagePath}\" to \"{output}\""); converter.Convert(customImagePath, output); // Copy the generated file to the backgrounds folder. - MainWindow.Logger.Info($"Copying {output} to {HUDFolderPath}"); + MainWindow.Logger.Info($"Copying \"{output}\" to \"{hudFolderPath}\""); File.Copy(output, output.Replace("background_upward", "background_upward_widescreen"), true); - File.Copy("Resources\\chapterbackgrounds.txt", $"{HUDFolderPath}\\scripts\\chapterbackgrounds.txt", true); + File.Copy("Resources\\chapterbackgrounds.txt", $"{hudFolderPath}\\scripts\\chapterbackgrounds.txt", true); } else { if (useHUDBackground) { // Copy enabled background to console folder - if (File.Exists($"{disabledFolder}\\{HUDImagePath}.vtf")) + if (File.Exists($"{disabledFolder}\\{hudImagePath}.vtf")) { - MainWindow.Logger.Info($"Copying {disabledFolder}\\{HUDImagePath} to {consoleFolder}"); - File.Copy($"{disabledFolder}\\{HUDImagePath}.vtf", $"{consoleFolder}\\background_upward.vtf", true); + MainWindow.Logger.Info($"Copying \"{disabledFolder}\\{hudImagePath}\" to \"{consoleFolder}\""); + File.Copy($"{disabledFolder}\\{hudImagePath}.vtf", $"{consoleFolder}\\background_upward.vtf", true); } - if (File.Exists($"{disabledFolder}\\{HUDImagePath}_widescreen.vtf")) + if (File.Exists($"{disabledFolder}\\{hudImagePath}_widescreen.vtf")) { - MainWindow.Logger.Info($"Copying {disabledFolder}\\{HUDImagePath} to {consoleFolder}"); - File.Copy($"{disabledFolder}\\{HUDImagePath}.vtf", $"{consoleFolder}\\background_upward_widescreen.vtf", true); + MainWindow.Logger.Info($"Copying \"{disabledFolder}\\{hudImagePath}\" to \"{consoleFolder}\""); + File.Copy($"{disabledFolder}\\{hudImagePath}.vtf", $"{consoleFolder}\\background_upward_widescreen.vtf", true); } - MainWindow.Logger.Info($"Copying chapterbackgrounds.txt to {HUDFolderPath}\\scripts"); - File.Copy("Resources\\chapterbackgrounds.txt", $"{HUDFolderPath}\\scripts\\chapterbackgrounds.txt", true); + MainWindow.Logger.Info($"Copying \"chapterbackgrounds.txt\" to \"{hudFolderPath}\\scripts\""); + File.Copy("Resources\\chapterbackgrounds.txt", $"{hudFolderPath}\\scripts\\chapterbackgrounds.txt", true); } else if (useStockBackgrounds) { + MainWindow.Logger.Info($"Disable VTF/VMT files"); foreach (var filePath in Directory.GetFiles(consoleFolder)) + { if (filePath.EndsWith(".vtf")) { - MainWindow.Logger.Info($"Disabling {filePath} (.VTF => .BAK)"); + MainWindow.Logger.Info($"Converting {filePath} to BAK format"); File.Move(filePath, filePath.Replace(".vtf", ".bak"), true); } else if (filePath.EndsWith(".vmt")) { - MainWindow.Logger.Info($"Disabling {filePath} (.VMT => .TEMP)"); + MainWindow.Logger.Info($"Converting {filePath} to TEMP format"); File.Move(filePath, filePath.Replace(".vmt", ".temp"), true); } + } } else { @@ -127,23 +130,26 @@ public void Apply() if (!Directory.Exists(disabledFolder)) return; foreach (var filePath in Directory.GetFiles(disabledFolder)) { - MainWindow.Logger.Info($"Copying {filePath} to {consoleFolder}"); + MainWindow.Logger.Info($"Copying \"{filePath}\" to \"{consoleFolder}\""); File.Move(filePath, $"{consoleFolder}\\{filePath.Split("\\")[^1]}", true); } Directory.Delete(disabledFolder); + MainWindow.Logger.Info($"Enable VTF/VMT files"); foreach (var filePath in Directory.GetFiles(consoleFolder)) + { if (filePath.EndsWith(".bak")) { - MainWindow.Logger.Info($"Enabling {filePath} (.BAK => .VTF)"); + MainWindow.Logger.Info($"Converting {filePath} to VTF format"); File.Move(filePath, filePath.Replace(".bak", ".vtf"), true); } else if (filePath.EndsWith(".temp")) { - MainWindow.Logger.Info($"Enabling {filePath} (.TEMP => .VMT)"); + MainWindow.Logger.Info($"Converting {filePath} to VMT format"); File.Move(filePath, filePath.Replace(".temp", ".vmt"), true); } + } } } } diff --git a/src/TF2HUD.Editor/Classes/HUD/HUDCustomizations.cs b/src/TF2HUD.Editor/Classes/HUD/HUDCustomizations.cs index d5c2c67a..1366458f 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUDCustomizations.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUDCustomizations.cs @@ -14,25 +14,23 @@ namespace HUDEditor.Classes public partial class HUD { /// - /// Apply user selected customizations to the HUD files. + /// Applies user selected customizations to the HUD files. /// public bool ApplyCustomizations() { try { // HUD Background Image. - // Set the HUD Background image path when applying, because it's possible - // the user did not have their tf/custom folder set up when this HUD constructor was called. + // Set the HUD Background image path when applying, because it's possible the user did not have their tf/custom folder set up when this HUD constructor was called. HudBackground = new HUDBackground($"{MainWindow.HudPath}\\{Name}\\"); var hudSettings = ControlOptions.Values; - // var hudSettings = JsonConvert.DeserializeObject(File.ReadAllText($"JSON//{Name}.json")).Controls.Values; // If the developer defined customization folders for their HUD, then copy those files. if (!string.IsNullOrWhiteSpace(CustomizationsFolder)) MoveCustomizationFiles(hudSettings); - // This Dictionary contains folders/files/properties as they should be written to the hud. + // This Dictionary contains folders/files/properties as they should be written to the HUD. // 'IterateFolder' and 'IterateHUDFileProperties' will write the properties to this. var hudFolders = new Dictionary(); @@ -99,8 +97,7 @@ static void IterateProperties(Dictionary folder, string folderP // Initialize to null to check whether matching element has been found const string pattern = "(Resource/UI/)*.res"; - KeyValuePair hudContainer = obj.FirstOrDefault(kv => Regex.IsMatch(kv.Key, pattern) && - kv.Value.GetType() == typeof(Dictionary)); + KeyValuePair hudContainer = obj.FirstOrDefault(kv => Regex.IsMatch(kv.Key, pattern) && kv.Value.GetType() == typeof(Dictionary)); if (hudContainer.Key is not null) { @@ -128,9 +125,8 @@ static void IterateProperties(Dictionary folder, string folderP } // Write hudFolders to the HUD once instead of each WriteToFile call reading and writing - var hudPath = MainWindow.HudPath + "\\" + Name; - IterateProperties(hudFolders, hudPath); - HudBackground.Apply(); + IterateProperties(hudFolders, MainWindow.HudPath + "\\" + Name); + HudBackground.ApplyBackground(); return true; } catch (Exception e) @@ -142,7 +138,7 @@ static void IterateProperties(Dictionary folder, string folderP } /// - /// Copy files used for folder-based customizations. + /// Copies files used for folder-based customizations. /// private void MoveCustomizationFiles(Dictionary.ValueCollection hudSettings) { @@ -179,12 +175,10 @@ private void MoveCustomizationFiles(Dictionary.ValueCollecti if (control.RenameFile.OldName.EndsWith('/')) { if (Directory.Exists(path + control.RenameFile.NewName)) - Directory.Move(path + control.RenameFile.NewName, - path + control.RenameFile.OldName); + Directory.Move(path + control.RenameFile.NewName, path + control.RenameFile.OldName); if (string.Equals(setting.Value, "true", StringComparison.CurrentCultureIgnoreCase)) - Directory.Move(path + control.RenameFile.OldName, - path + control.RenameFile.NewName); + Directory.Move(path + control.RenameFile.OldName, path + control.RenameFile.NewName); } else { @@ -282,7 +276,7 @@ private void MoveCustomizationFiles(Dictionary.ValueCollecti } /// - /// Write user selected options to HUD files. + /// Writes user selected options to HUD files. /// /// Settings as defined for the HUD /// Settings as selected by the user @@ -291,6 +285,7 @@ private void WriteToFile(Controls hudSetting, Setting userSetting, Dictionary CompileHudElement(JObject element, - string absolutePath, string relativePath, Dictionary hudElementRef, - string objectPath) + Dictionary CompileHudElement(JObject element, string absolutePath, string relativePath, Dictionary hudElementRef, string objectPath) { var hudElement = new Dictionary(); foreach (var property in element) + { if (string.Equals(property.Key, "replace", StringComparison.CurrentCultureIgnoreCase)) { var values = property.Value.ToArray(); @@ -362,7 +356,7 @@ Dictionary CompileHudElement(JObject element, replace = values[0].ToString(); } - MainWindow.Logger.Info($"Replace value \"{find}\" with \"{replace}\"."); + MainWindow.Logger.Info($"Replace \"{find}\" with \"{replace}\""); File.WriteAllText(absolutePath, File.ReadAllText(absolutePath).Replace(find, replace)); } else if (string.Equals(property.Key, "#base", StringComparison.OrdinalIgnoreCase)) @@ -385,23 +379,22 @@ Dictionary CompileHudElement(JObject element, if (currentObj.ContainsKey("true") && currentObj.ContainsKey("false")) { hudElement[property.Key] = currentObj[userSetting.Value.ToLowerInvariant()]; - MainWindow.Logger.Info($"Set \"{property.Key}\" to \"{hudElement[property.Key]}\"."); + MainWindow.Logger.Info($"Set \"{property.Key}\" to \"{hudElement[property.Key]}\""); } else { - MainWindow.Logger.Info(property.Key); - var newhudElementRef = hudElementRef.ContainsKey(property.Key) + MainWindow.Logger.Info($"Go to \"{property.Key}\""); + var newHudElementRef = hudElementRef.ContainsKey(property.Key) ? (Dictionary)hudElementRef[property.Key] : new Dictionary(); hudElement[property.Key] = CompileHudElement(currentObj, - absolutePath, relativePath, newhudElementRef, + absolutePath, relativePath, newHudElementRef, $"{objectPath}{property.Key}/"); } } else { - if (string.Equals(userSetting.Type, "ColorPicker", - StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(userSetting.Type, "ColorPicker", StringComparison.CurrentCultureIgnoreCase)) { // If the color is supposed to have a pulse, set the pulse value in the schema. if (hudSetting.Pulse) @@ -427,40 +420,30 @@ Dictionary CompileHudElement(JObject element, // Check for already existing keys and warn user if (hudElementRef.ContainsKey(property.Key)) - MainWindow.Logger.Warn( - $"{relativePath} => {objectPath} already contains key {property.Key}!"); + MainWindow.Logger.Warn($"{relativePath} -> {objectPath} already contains key {property.Key}!"); hudElement[property.Key] = EvaluateValue(property.Value.ToString()); - MainWindow.Logger.Info($"Set \"{property.Key}\" to \"{userSetting.Value}\"."); + MainWindow.Logger.Info($"Set \"{property.Key}\" to \"{userSetting.Value}\""); } + } return hudElement; } // # Applies animation options to .txt file and handles keywords where applicable. // - // This method takes a JObject of type and applies - // each keyword to the provided .txt file + // This method takes a JObject of type and applies each keyword to the provided .txt file // // keywords: - // replace takes a tuple of [true, false] values, evaluates $value and - // replaces text in the file - // - // comment takes an array of strings, and adds two forward slashes before - // each line that contains the any of the strings - // - // uncomment takes an array of strings, and removes te two forward slashes - // before each line that contains the any of the strings + // replace takes a tuple of [true, false] values, evaluates $value and replaces text in the file + // comment takes an array of strings, and adds two forward slashes before each line that contains the any of the strings + // uncomment takes an array of strings, and removes te two forward slashes before each line that contains the any of the strings // - // If the JObject property does not match a keyword, it is assumed to be an event - // name and List of HUD Animations, in which case the method will parse the animation - // file and overwrite the provided event animations with the JObject property's event - // animations + // If the JObject property does not match a keyword, it is assumed to be an event name and List of HUD Animations, in which case the method will parse the animation file and overwrite the provided event animations with the JObject property's event animations // void WriteAnimationCustomizations(string filePath, JObject animationOptions) { - HUDAnimation CreateAnimation(Dictionary animation, - KeyValuePair animationOption) + HUDAnimation CreateAnimation(Dictionary animation, KeyValuePair animationOption) { return animation?["Type"].ToString().ToLower() switch { @@ -527,16 +510,13 @@ HUDAnimation CreateAnimation(Dictionary animation, Element = EvaluateValue(animation["Element"]), Delay = EvaluateValue(animation["Delay"]) }, - _ => throw new Exception( - $"Unexpected animation type '{animation?["Type"]}' in {animationOption.Key}!") + _ => throw new Exception($"Unexpected animation type '{animation?["Type"]}' in {animationOption.Key}!") }; } - // Don't read animations file unless the user requests a new event - // the majority of the animation customizations are for enabling/disabling - // events, which use the 'replace' keyword + // Don't read animations file unless the user requests a new event the majority of the animation customizations are for enabling/disabling events, which use the 'replace' keyword Dictionary> animations = null; - MainWindow.Logger.Info($"Processing: {filePath}"); + MainWindow.Logger.Info($"Processing \"{filePath}\""); foreach (var animationOption in animationOptions) switch (animationOption.Key.ToLowerInvariant()) @@ -649,17 +629,15 @@ HUDAnimation CreateAnimation(Dictionary animation, // Create new event or animation statements could stack over multiple 'apply customizations'. animations[animationOption.Key] = new List(); - JToken[] animationevents; + JToken[] animationEvents; if (animationOption.Value.Type == JTokenType.Object) { - var animationsContainer = - animationOption.Value.ToObject>(); - if (animationsContainer.ContainsKey("true") && - animationsContainer.ContainsKey("false")) + var animationsContainer = animationOption.Value.ToObject>(); + if (animationsContainer.ContainsKey("true") && animationsContainer.ContainsKey("false")) { var selection = animationsContainer[userSetting.Value.ToLower()]; - animationevents = selection.ToArray(); + animationEvents = selection.ToArray(); } else { @@ -668,10 +646,10 @@ HUDAnimation CreateAnimation(Dictionary animation, } else { - animationevents = animationOption.Value.ToArray(); + animationEvents = animationOption.Value.ToArray(); } - foreach (var option in animationevents) + foreach (var option in animationEvents) { var animation = option.ToObject>(); @@ -680,14 +658,10 @@ HUDAnimation CreateAnimation(Dictionary animation, // Animate statements can have an extra argument make sure to account for them if (current.GetType() == typeof(Animate)) { - if (string.Equals(current.Interpolator, "pulse", - StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(current.Interpolator, "pulse", StringComparison.CurrentCultureIgnoreCase)) current.Frequency = EvaluateValue(animation["Frequency"]); - if (string.Equals(current.Interpolator, "gain", - StringComparison.CurrentCultureIgnoreCase) || - string.Equals(current.Interpolator, "bias", - StringComparison.CurrentCultureIgnoreCase)) + if (string.Equals(current.Interpolator, "gain", StringComparison.CurrentCultureIgnoreCase) || string.Equals(current.Interpolator, "bias", StringComparison.CurrentCultureIgnoreCase)) current.Bias = EvaluateValue(animation["Bias"]); } @@ -706,17 +680,14 @@ HUDAnimation CreateAnimation(Dictionary animation, foreach (var filePath in files) { var relativePath = string.Join('/', Regex.Split(filePath.Key, @"[\/]+")); - var absolutePath = MainWindow.HudPath + "\\" + Name + "\\" + - string.Join('\\', relativePath.Split('/')); + var absolutePath = MainWindow.HudPath + "\\" + Name + "\\" + string.Join('\\', relativePath.Split('/')); var extension = filePath.Key.Split(".")[^1]; if (resFileExtensions.Contains(extension)) { var hudFile = Utilities.CreateNestedObject(hudFolders, relativePath.Split('/')); - MainWindow.Logger.Info($"Go to => {relativePath}"); - - Utilities.Merge(hudFile, CompileHudElement(filePath.Value?.ToObject(), - absolutePath, relativePath, hudFile, "")); + MainWindow.Logger.Info($"Open \"{relativePath}\""); + Utilities.Merge(hudFile, CompileHudElement(filePath.Value?.ToObject(), absolutePath, relativePath, hudFile, "")); } else if (string.Equals(extension, "txt")) { @@ -740,6 +711,7 @@ private static (JObject, string, string[]) GetControlInfo(Controls hudSetting, S { if (!string.Equals(hudSetting.Type, "ComboBox", StringComparison.CurrentCultureIgnoreCase)) return (hudSetting.Files, hudSetting.Special, hudSetting.SpecialParameters); + // Determine files using the files of the selected item's label or value // Could cause issues if label and value are both numbers but numbered differently var selected = hudSetting.Options.First(x => x.Label == userSetting.Value || x.Value == userSetting.Value); @@ -750,7 +722,7 @@ private void EvaluateSpecial(string special, Setting userSetting, bool enable, s { // Check for special conditions, namely if we should enable stock backgrounds. if (string.Equals(special, "StockBackgrounds", StringComparison.CurrentCultureIgnoreCase)) - HudBackground.SetStockBackgrounds(enable); + HudBackground.SetStockBackground(enable); if (string.Equals(special, "HUDBackground", StringComparison.CurrentCultureIgnoreCase)) HudBackground.SetHUDBackground(parameters[0]); @@ -761,10 +733,12 @@ private void EvaluateSpecial(string special, Setting userSetting, bool enable, s if (string.Equals(special, "TransparentViewmodels", StringComparison.CurrentCultureIgnoreCase)) CopyTransparentViewmodelAddon(enable); + + MainWindow.Logger.Info("Option not selected"); } /// - /// Copy configuration file for transparent viewmodels into the HUD's cfg folder. + /// Copies configuration file for transparent viewmodels into the HUD's cfg folder. /// private async void CopyTransparentViewmodelAddon(bool enable = false) { @@ -789,7 +763,7 @@ private async void CopyTransparentViewmodelAddon(bool enable = false) } /// - /// Function for copying multiple files and subdirectories, recursively. + /// Copies multiple files and subdirectories, recursively. /// static void CopyDirectory(string source, string destination) { diff --git a/src/TF2HUD.Editor/Classes/HUD/HUDPage.cs b/src/TF2HUD.Editor/Classes/HUD/HUDPage.cs index 726d985b..c213a9ff 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUDPage.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUDPage.cs @@ -25,12 +25,12 @@ namespace HUDEditor.Classes public partial class HUD { /// - /// Generate the page layout using controls defined in the HUD schema. + /// Generates the page layout using controls defined in the HUD schema. /// public Grid GetControls() { // Skip this process if the controls have already been rendered. - if (isRendered) return Controls; + if (IsRendered) return Controls; // Define the container that will hold the title and content. var container = new Grid(); @@ -85,7 +85,6 @@ public Grid GetControls() } Grid.SetRow(sectionsContainer, 1); - var lastMargin = new Thickness(10, 2, 0, 0); var lastTop = lastMargin.Top; var groupBoxIndex = 0; @@ -126,7 +125,6 @@ public Grid GetControls() }; sectionContentContainer.Children.Add(resetInput); - Panel sectionContent = Layout is not null ? new WrapPanel() : new StackPanel(); sectionContent.Margin = new Thickness(3); @@ -176,7 +174,7 @@ public Grid GetControls() // Add to Page. sectionContent.Children.Add(checkBoxInput); controlItem.Control = checkBoxInput; - MainWindow.Logger.Info($"Added checkbox to the page ({checkBoxInput.Name})."); + MainWindow.Logger.Info($"Added {checkBoxInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); // Create a preview button if the control has a preview image. if (!string.IsNullOrWhiteSpace(controlItem.Preview)) @@ -194,7 +192,7 @@ public Grid GetControls() preview.Show(); }; sectionContent.Children.Add(previewBtn); - MainWindow.Logger.Info($"{checkBoxInput.Name} - Added preview: {controlItem.Preview}."); + MainWindow.Logger.Info($"Added a preview for {checkBoxInput.Name} ({controlItem.Preview})"); } break; @@ -243,14 +241,12 @@ public Grid GetControls() colorInput.SelectedColorChanged += (sender, _) => { var input = sender as ColorPicker; - Settings.SetSetting(input?.Name, - Utilities.ConvertToRgba(input?.SelectedColor.ToString())); + Settings.SetSetting(input?.Name, Utilities.ConvertToRgba(input?.SelectedColor.ToString())); }; colorInput.Closed += (sender, _) => { var input = sender as ColorPicker; - Settings.SetSetting(input?.Name, - Utilities.ConvertToRgba(input?.SelectedColor.ToString())); + Settings.SetSetting(input?.Name, Utilities.ConvertToRgba(input?.SelectedColor.ToString())); CheckIsDirty(controlItem); }; @@ -259,7 +255,7 @@ public Grid GetControls() colorContainer.Children.Add(colorInput); sectionContent.Children.Add(colorContainer); controlItem.Control = colorInput; - MainWindow.Logger.Info($"Added color picker to the page ({colorInput.Name})."); + MainWindow.Logger.Info($"Added {colorInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); // Create a preview button if the control has a preview image. if (!string.IsNullOrWhiteSpace(controlItem.Preview)) @@ -278,7 +274,7 @@ public Grid GetControls() preview.Show(); }; sectionContent.Children.Add(previewBtn); - MainWindow.Logger.Info($"{colorInput.Name} - Added preview: {controlItem.Preview}."); + MainWindow.Logger.Info($"Added a preview for {colorInput.Name} ({controlItem.Preview})"); } break; @@ -345,7 +341,7 @@ public Grid GetControls() comboBoxContainer.Children.Add(comboBoxInput); sectionContent.Children.Add(comboBoxContainer); controlItem.Control = comboBoxInput; - MainWindow.Logger.Info($"Added combo-box to the page ({comboBoxInput.Name})."); + MainWindow.Logger.Info($"Added {comboBoxInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); // Create a preview button if the control has a preview image. if (!string.IsNullOrWhiteSpace(controlItem.Preview)) @@ -364,7 +360,7 @@ public Grid GetControls() preview.Show(); }; sectionContent.Children.Add(previewBtn); - MainWindow.Logger.Info($"{comboBoxInput.Name} - Added preview: {controlItem.Preview}."); + MainWindow.Logger.Info($"Added a preview for {comboBoxInput.Name} ({controlItem.Preview})"); } break; @@ -415,7 +411,7 @@ public Grid GetControls() integerContainer.Children.Add(integerInput); sectionContent.Children.Add(integerContainer); controlItem.Control = integerInput; - MainWindow.Logger.Info($"Added num. counter to the page ({integerInput.Name})."); + MainWindow.Logger.Info($"Added {integerInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); // Create a preview button if the control has a preview image. if (!string.IsNullOrWhiteSpace(controlItem.Preview)) @@ -434,7 +430,7 @@ public Grid GetControls() preview.Show(); }; sectionContent.Children.Add(previewBtn); - MainWindow.Logger.Info($"{integerInput.Name} - Added preview: {controlItem.Preview}."); + MainWindow.Logger.Info($"Added a preview for {integerInput.Name} ({controlItem.Preview})"); } break; @@ -490,7 +486,7 @@ public Grid GetControls() xhairContainer.Children.Add(xhairInput); sectionContent.Children.Add(xhairContainer); controlItem.Control = xhairInput; - MainWindow.Logger.Info($"Added xhair picker to the page ({xhairInput.Name})."); + MainWindow.Logger.Info($"Added {xhairInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); // Create a preview button if the control has a preview image. if (!string.IsNullOrWhiteSpace(controlItem.Preview)) @@ -509,7 +505,7 @@ public Grid GetControls() preview.Show(); }; sectionContent.Children.Add(previewBtn); - MainWindow.Logger.Info($"{xhairInput.Name} - Added preview: {controlItem.Preview}."); + MainWindow.Logger.Info($"Added a preview for {xhairInput.Name} ({controlItem.Preview})"); } break; @@ -543,7 +539,6 @@ public Grid GetControls() { Name = id, Content = Resources.ui_browse, - // Width = 100, Height = 32, Padding = new Thickness(5, 2, 5, 0), HorizontalAlignment = HorizontalAlignment.Stretch @@ -555,7 +550,6 @@ public Grid GetControls() var clearInput = new Button { Content = Resources.ui_clear, - // Width = 100, Height = 32, Padding = new Thickness(5, 2, 5, 0), HorizontalAlignment = HorizontalAlignment.Stretch @@ -594,7 +588,7 @@ public Grid GetControls() if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); - MainWindow.Logger.Info($"Copying {browser.FileName} to {path}"); + MainWindow.Logger.Info($"Copying \"{browser.FileName}\" to \"{path}\""); File.Copy(browser.FileName, path, true); } @@ -620,7 +614,7 @@ public Grid GetControls() bgContainer.Children.Add(bgImage); sectionContent.Children.Add(bgContainer); controlItem.Control = bgInput; - MainWindow.Logger.Info($"Added background selector to the page ({bgInput.Name})."); + MainWindow.Logger.Info($"Added {bgInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); break; case "text": @@ -662,11 +656,11 @@ public Grid GetControls() textContainer.Children.Add(textInput); sectionContent.Children.Add(textContainer); controlItem.Control = textInput; - MainWindow.Logger.Info($"Added textbox to the page ({textInput.Name})."); + MainWindow.Logger.Info($"Added {textInput.Name} ({controlItem.Type.ToLowerInvariant()}) to the page"); break; default: - throw new Exception($"Entered type {controlItem.Type} is invalid."); + throw new Exception($"Entered type {controlItem.Type} is invalid"); } } @@ -692,6 +686,7 @@ public Grid GetControls() // These are not optimal speed but the code should be easier to understand: // Counts the occurrences of the current item id/index var columnSpan = 0; + // Iterate current row for (var index = 0; index < Layout[i].Length; index++) if (groupBoxIndex.ToString() == Layout[i][index] || section == Layout[i][index]) @@ -738,17 +733,16 @@ public Grid GetControls() container.Children.Add(scrollView); Controls.Children.Add(container); - isRendered = true; + IsRendered = true; return Controls; } /// - /// Check whether a control change requires a game restart. + /// Checks whether a control change requires a game restart. /// private void CheckIsDirty(Controls control) { - if (control.Restart && !string.Equals(control.Value, Settings.GetSetting(control.Name).Value) && - !DirtyControls.Contains(control.Label)) + if (control.Restart && !string.Equals(control.Value, Settings.GetSetting(control.Name).Value) && !DirtyControls.Contains(control.Label)) DirtyControls.Add(control.Label); else DirtyControls.Remove(control.Label); diff --git a/src/TF2HUD.Editor/Classes/HUD/HUDSettings.cs b/src/TF2HUD.Editor/Classes/HUD/HUDSettings.cs index 67bbf9ad..274acbc7 100644 --- a/src/TF2HUD.Editor/Classes/HUD/HUDSettings.cs +++ b/src/TF2HUD.Editor/Classes/HUD/HUDSettings.cs @@ -7,29 +7,17 @@ namespace HUDEditor.Classes { - public enum Preset - { - A, - B, - C, - D - } - public class HUDSettings { - public static readonly string UserFile = - $"{Directory.CreateDirectory($"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\TF2HUD.Editor").FullName}\\settings.json"; + public static readonly string UserFile = $"{Directory.CreateDirectory($"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\TF2HUD.Editor").FullName}\\settings.json"; private static readonly UserJson Json = File.Exists(UserFile) ? JsonConvert.DeserializeObject(File.ReadAllText(UserFile)) : new UserJson(); private static readonly Dictionary Presets = Json.Presets; - private static readonly List UserSettings = Json.Settings; - private Preset _Preset; - public string HUDName; public HUDSettings(string name) @@ -46,7 +34,7 @@ public Preset Preset } /// - /// Add a new setting to user settings. + /// Adds a new user setting. /// public void AddSetting(string name, Controls control) { @@ -62,7 +50,7 @@ public void AddSetting(string name, Controls control) } /// - /// Retrieve a specific user setting by name. + /// Retrieves a user setting by name. /// /// Name of the setting to retrieve. public Setting GetSetting(string name) @@ -71,7 +59,7 @@ public Setting GetSetting(string name) } /// - /// Retrieve a specific user setting or just the value, by name. + /// Retrieves a user setting or just the value, by name. /// /// Name of the setting to retrieve. public T GetSetting(string name) @@ -99,7 +87,7 @@ public T GetSetting(string name) } /// - /// Set a new user setting value. + /// Sets a new user setting value. /// /// Name of the setting to update. /// New value for updating setting. @@ -109,7 +97,7 @@ public void SetSetting(string name, string value) } /// - /// Save a user setting value to file. + /// Saves a user setting value to file. /// public void SaveSettings() { @@ -119,7 +107,7 @@ public void SaveSettings() Settings = UserSettings }; File.WriteAllText(UserFile, JsonConvert.SerializeObject(settings, Formatting.Indented)); - MainWindow.Logger.Info($"Saved user settings to: {UserFile}"); + MainWindow.Logger.Info($"Saving user settings to: {UserFile}"); } } } \ No newline at end of file diff --git a/src/TF2HUD.Editor/Classes/Utilities.cs b/src/TF2HUD.Editor/Classes/Utilities.cs index bcba87cc..75780236 100644 --- a/src/TF2HUD.Editor/Classes/Utilities.cs +++ b/src/TF2HUD.Editor/Classes/Utilities.cs @@ -21,72 +21,58 @@ namespace HUDEditor.Classes { public static class Utilities { - public static readonly List> ItemRarities = new() - { - new Tuple("QualityColorNormal", "DimmQualityColorNormal", - "QualityColorNormal_GreyedOut"), - new Tuple("QualityColorUnique", "DimmQualityColorUnique", - "QualityColorUnique_GreyedOut"), - new Tuple("QualityColorStrange", "DimmQualityColorStrange", - "QualityColorStrange_GreyedOut"), - new Tuple("QualityColorVintage", "DimmQualityColorVintage", - "QualityColorVintage_GreyedOut"), - new Tuple("QualityColorHaunted", "DimmQualityColorHaunted", - "QualityColorHaunted_GreyedOut"), - new Tuple("QualityColorrarity1", "DimmQualityColorrarity1", - "QualityColorrarity1_GreyedOut"), - new Tuple("QualityColorCollectors", "DimmQualityColorCollectors", - "QualityColorCollectors_GreyedOut"), - new Tuple("QualityColorrarity4", "DimmQualityColorrarity4", - "QualityColorrarity4_GreyedOut"), - new Tuple("QualityColorCommunity", "DimmQualityColorCommunity", - "QualityColorCommunity_GreyedOut"), - new Tuple("QualityColorDeveloper", "DimmQualityColorDeveloper", - "QualityColorDeveloper_GreyedOut"), + public static readonly List> ItemRarities = + [ + new Tuple("QualityColorNormal", "DimmQualityColorNormal", "QualityColorNormal_GreyedOut"), + new Tuple("QualityColorUnique", "DimmQualityColorUnique", "QualityColorUnique_GreyedOut"), + new Tuple("QualityColorStrange", "DimmQualityColorStrange", "QualityColorStrange_GreyedOut"), + new Tuple("QualityColorVintage", "DimmQualityColorVintage", "QualityColorVintage_GreyedOut"), + new Tuple("QualityColorHaunted", "DimmQualityColorHaunted", "QualityColorHaunted_GreyedOut"), + new Tuple("QualityColorrarity1", "DimmQualityColorrarity1", "QualityColorrarity1_GreyedOut"), + new Tuple("QualityColorCollectors", "DimmQualityColorCollectors", "QualityColorCollectors_GreyedOut"), + new Tuple("QualityColorrarity4", "DimmQualityColorrarity4", "QualityColorrarity4_GreyedOut"), + new Tuple("QualityColorCommunity", "DimmQualityColorCommunity", "QualityColorCommunity_GreyedOut"), + new Tuple("QualityColorDeveloper", "DimmQualityColorDeveloper", "QualityColorDeveloper_GreyedOut"), new Tuple("ItemRarityCommon", "DimmItemRarityCommon", "ItemRarityCommon_GreyedOut"), - new Tuple("ItemRarityUncommon", "DimmItemRarityUncommon", - "ItemRarityUncommon_GreyedOut"), + new Tuple("ItemRarityUncommon", "DimmItemRarityUncommon", "ItemRarityUncommon_GreyedOut"), new Tuple("ItemRarityRare", "DimmItemRarityRare", "ItemRarityRare_GreyedOut"), - new Tuple("ItemRarityMythical", "DimmItemRarityMythical", - "ItemRarityMythical_GreyedOut"), - new Tuple("ItemRarityLegendary", "DimmItemRarityLegendary", - "ItemRarityLegendary_GreyedOut"), - new Tuple("ItemRarityAncient", "DimmItemRarityAncient", - "ItemRarityAncient_GreyedOut") - }; - - public static readonly List CrosshairStyles = new() - { + new Tuple("ItemRarityMythical", "DimmItemRarityMythical", "ItemRarityMythical_GreyedOut"), + new Tuple("ItemRarityLegendary", "DimmItemRarityLegendary", "ItemRarityLegendary_GreyedOut"), + new Tuple("ItemRarityAncient", "DimmItemRarityAncient", "ItemRarityAncient_GreyedOut") + ]; + + public static readonly List CrosshairStyles = + [ "!", "#", "$", "%", "'", "(", ")", "*", "+", ",", ".", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "=", "<", ">", "?", "@", "|", "}", "`", "_", "^", "]", "[", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" - }; + ]; /// - /// Add a comment tag (//) to the beginning of a text line. + /// Adds a comment tag (//) to the beginning of a text line. /// /// Text lines from a file to process. /// Line number to which to add a comment tag. public static string CommentTextLine(string[] lines, int index) { - MainWindow.Logger.Info($"Commenting line: {index}"); + MainWindow.Logger.Info($"Commenting line {index}"); return string.Concat("//", lines[index].Replace("//", string.Empty)); } /// - /// Remove all comment tags (//) from a text line. + /// Removes all comment tags (//) from a text line. /// /// Text lines from a file to process. /// Line number from which to remove a comment tag. public static string UncommentTextLine(string[] lines, int index) { - MainWindow.Logger.Info($"Uncommenting line: {index}"); + MainWindow.Logger.Info($"Uncommenting line {index}"); return lines[index].Replace("//", string.Empty); } /// - /// Get a list of line numbers containing a given string. + /// Gets a list of line numbers containing a given string. /// /// An array of lines to loop through. /// String value to look for in the list of lines. @@ -101,18 +87,18 @@ public static List GetLineNumbersContainingString(string[] lines, string va } /// - /// Convert a HEX color code to RGBA. + /// Converts a HEX color code to RGBA. /// /// HEX color code to be convert to RGBA. public static string ConvertToRgba(string hex) { var color = ColorTranslator.FromHtml(hex); - MainWindow.Logger.Info($"Converting {hex} to {color}."); + MainWindow.Logger.Info($"Converting {hex} to {color}"); return $"{color.R} {color.G} {color.B} {color.A}"; } /// - /// Get a pulsed color by reducing a color channel value by 50. + /// Gets a pulsed color by reducing a color channel value by 50. /// /// RGBA color code to process. public static string GetPulsedColor(string rgba) @@ -124,7 +110,7 @@ public static string GetPulsedColor(string rgba) } /// - /// Get a darkened color by reducing each color channel by 40%. + /// Gets a darkened color by reducing each color channel by 40%. /// /// RGBA color code to process. public static string GetShadowColor(string rgba) @@ -137,7 +123,7 @@ public static string GetShadowColor(string rgba) } /// - /// Get a dimmed color by setting the alpha channel to 100. + /// Gets a dimmed color by setting the alpha channel to 100. /// /// RGBA color code to process. public static string GetDimmedColor(string rgba) @@ -148,7 +134,7 @@ public static string GetDimmedColor(string rgba) } /// - /// Get a grayed color by reducing each color channel by 75%. + /// Gets a grayed color by reducing each color channel by 75%. /// /// RGBA color code to process. public static string GetGrayedColor(string rgba) @@ -161,7 +147,7 @@ public static string GetGrayedColor(string rgba) } /// - /// Convert an RGBA color code to Color object. + /// Converts an RGBA color code to Color object. /// /// RGBA color code to process. public static Color ConvertToColor(string rgba) @@ -171,7 +157,7 @@ public static Color ConvertToColor(string rgba) } /// - /// Convert an RGBA color code to ColorBrush object. + /// Converts an RGBA color code to ColorBrush object. /// /// RGBA color code to process. public static SolidColorBrush ConvertToColorBrush(string rgba) @@ -181,7 +167,7 @@ public static SolidColorBrush ConvertToColorBrush(string rgba) } /// - /// Open the provided path in browser or Windows Explorer. + /// Opens the provided path in browser or Windows Explorer. /// /// URL link to open. public static void OpenWebpage(string url) @@ -192,7 +178,7 @@ public static void OpenWebpage(string url) } /// - /// Get the filename from the HUD schema control using a string value. + /// Gets the filename from the HUD schema control using a string value. /// /// Schema control to retrieve file names from. internal static dynamic GetFileNames(Controls control) @@ -203,7 +189,7 @@ internal static dynamic GetFileNames(Controls control) } /// - /// Check if Team Fortress 2 is currently running. + /// Checks if Team Fortress 2 is currently running. /// /// False if there's no active process named hl2, tf, or tf_win64, otherwise return true and a warning message. public static bool CheckIsGameRunning() @@ -214,7 +200,7 @@ public static bool CheckIsGameRunning() } /// - /// Search registry for the Team Fortress 2 installation directory. + /// Searchs registry for the Team Fortress 2 installation directory. /// /// True if the TF2 directory was found through the registry, otherwise return False. public static bool SearchRegistry() @@ -239,7 +225,7 @@ public static bool SearchRegistry() var pathTF = path + "\\steamapps\\common\\Team Fortress 2\\tf\\custom"; if (Directory.Exists(pathTF)) { - MainWindow.Logger.Info($"tf/custom directory found in the registry: {pathTF}"); + MainWindow.Logger.Info($"Set target directory to: {pathTF.Replace("\\\\", "\\")}"); Settings.Default.hud_directory = pathTF; Settings.Default.Save(); return true; @@ -249,16 +235,16 @@ public static bool SearchRegistry() } /// - /// Check if the set tf/custom directory is valid. + /// Checks if the target directory is valid. /// - /// True if the set tf/custom directory is valid. + /// True if the set target directory is valid. public static bool CheckUserPath(string hudPath) { return !string.IsNullOrWhiteSpace(hudPath) && hudPath.EndsWith("tf\\custom"); } /// - /// Get a localized string from the resource file. + /// Gets a localized string from the resource file. /// public static string GetLocalizedString(string key) { @@ -267,7 +253,7 @@ public static string GetLocalizedString(string key) } /// - /// Converts a HUD/control name into a WPF usable ID + /// Converts a HUD/control name into a WPF usable ID /// /// ID to sanitize. /// @@ -280,7 +266,7 @@ public static string EncodeId(string id) } /// - /// Deep merge keys from one object to another + /// Deep merges keys from one object to another /// /// /// @@ -312,7 +298,7 @@ public static void Merge(Dictionary object1, Dictionary - /// Adds the structure for empty nested objects inside a given object + /// Adds the structure for empty nested objects inside a given object /// /// Object to add nested objects to. /// Keys to add. @@ -339,7 +325,7 @@ public static Dictionary CreateNestedObject(Dictionary - /// Fetch JSON from specified URL. + /// Fetches JSON from specified URL. /// /// URL to request resource from. public static async Task Fetch(string url) @@ -350,7 +336,7 @@ public static async Task Fetch(string url) } /// - /// Downloads a file from URL to the specified file path. + /// Downloads a file from URL to the specified file path. /// /// URL to request resource from. /// Relative path to file to save resource to. @@ -362,7 +348,7 @@ public static async Task DownloadFile(string url, string filePath) } /// - /// Calculates a file hash identical to the output of git hash-object <file> + /// Calculates a file hash identical to the output of git hash-object <file> /// /// Path to file to calculate hash of. public static string GitHash(string filePath) @@ -375,7 +361,7 @@ public static string GitHash(string filePath) } /// - /// Install the Hypnotize TF2 HUD Crosshairs to a given HUD folder + /// Installs Hypnotize's TF2 HUD Crosshairs to a given HUD folder /// /// Absolute folder path to HUD to install crosshairs to public static async Task InstallCrosshairs(string folderPath) @@ -384,7 +370,7 @@ public static async Task InstallCrosshairs(string folderPath) var crosshairsZipFileName = $"{crosshairsName}.zip"; // Download TF2 HUD Crosshairs - await Utilities.DownloadFile(Settings.Default.tf2_hud_crosshairs_zip, crosshairsZipFileName); + await DownloadFile(Settings.Default.tf2_hud_crosshairs_zip, crosshairsZipFileName); if (Directory.Exists(crosshairsName)) Directory.Delete(crosshairsName, true); ZipFile.ExtractToDirectory(crosshairsZipFileName, folderPath); @@ -435,8 +421,7 @@ await Task.WhenAll( { var filePath = Path.Join(folderPath, "scripts\\hudanimations_manifest.txt"); - // If the HUD does not contain a hudanimations_manifest.txt, - // use the string from tf2_misc_dir.vpk scripts/hudanimations_manifest.txt + // If the HUD does not contain a hudanimations_manifest.txt, use the string from tf2_misc_dir.vpk scripts/hudanimations_manifest.txt var fileContents = File.Exists(filePath) ? await File.ReadAllTextAsync(filePath) : @" diff --git a/src/TF2HUD.Editor/Classes/VDF.cs b/src/TF2HUD.Editor/Classes/VDF.cs index 96c69c95..9ac3fb0e 100644 --- a/src/TF2HUD.Editor/Classes/VDF.cs +++ b/src/TF2HUD.Editor/Classes/VDF.cs @@ -5,18 +5,17 @@ namespace HUDEditor.Classes { - internal class VDFTokeniser + internal class VDFTokenizer { public static readonly char[] IgnoredChars = { ' ', '\t', '\r', '\n' }; public static readonly char[] TokenTerminate = { '"', '{', '}' }; - private readonly string Text; public int Index { get; private set; } = 0; public int Line { get; private set; } = 1; public int Character { get; private set; } = 1; private bool EOFRead = false; - public VDFTokeniser(string text) + public VDFTokenizer(string text) { Text = text; } @@ -86,7 +85,6 @@ public VDFTokeniser(string text) case '"': { // If we encounter a quote, read the enclosed text until the next quotation mark. - // Skip the opening quotation mark. index++; character++; @@ -97,7 +95,7 @@ public VDFTokeniser(string text) { if (index >= Text.Length) { - throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "closing double quote" }, index, line, character); + throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["closing double quote"], index, line, character); } index++; character++; @@ -132,7 +130,6 @@ public VDFTokeniser(string text) } var end = index; - var str = Text[start..end]; token = new VDFToken @@ -173,6 +170,7 @@ internal class VDFSyntaxException : Exception { public VDFSyntaxException(VDFTokenType type, string unexpected, string[] expected, int index, int line, int character) : base($"Unexpected {type} '{unexpected}' at position {index} (line {line}, character {character}). Expected {string.Join(" | ", expected)}") { + } } @@ -182,12 +180,11 @@ internal static class VDF public static Dictionary Parse(string text) { - var tokeniser = new VDFTokeniser(text); + var tokeniser = new VDFTokenizer(text); Dictionary ParseObject(bool isObject) { Dictionary objectRef = new(); - VDFToken? objectTerminator = isObject ? new VDFToken { Type = VDFTokenType.ControlCharacter, Value = "}" } : null; while (true) @@ -195,11 +192,10 @@ Dictionary ParseObject(bool isObject) string key; dynamic value; string conditional; - var keyToken = tokeniser.Next(); if (keyToken == objectTerminator) break; - if (keyToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "key" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + if (keyToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["key"], tokeniser.Index, tokeniser.Line, tokeniser.Character); switch (keyToken.Value.Type) { @@ -208,13 +204,13 @@ Dictionary ParseObject(bool isObject) key = keyToken.Value.Value; var valueToken = tokeniser.Next(); - if (valueToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "value", "{", "conditional" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + if (valueToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["value", "{", "conditional"], tokeniser.Index, tokeniser.Line, tokeniser.Character); if (valueToken.Value.Type == VDFTokenType.Conditional) { conditional = valueToken.Value.Value; valueToken = tokeniser.Next(); - if (valueToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", new[] { "value", "{" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + if (valueToken == null) throw new VDFSyntaxException(VDFTokenType.String, "EOF", ["value", "{"], tokeniser.Index, tokeniser.Line, tokeniser.Character); } switch (valueToken.Value.Type) @@ -249,16 +245,16 @@ Dictionary ParseObject(bool isObject) break; } case VDFTokenType.Conditional: - throw new VDFSyntaxException(VDFTokenType.Conditional, valueToken.Value.Value, new[] { "value", "{" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + throw new VDFSyntaxException(VDFTokenType.Conditional, valueToken.Value.Value, ["value", "{"], tokeniser.Index, tokeniser.Line, tokeniser.Character); default: throw new Exception(); } break; } case VDFTokenType.ControlCharacter: - throw new VDFSyntaxException(VDFTokenType.ControlCharacter, keyToken.Value.Value, new[] { "key" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + throw new VDFSyntaxException(VDFTokenType.ControlCharacter, keyToken.Value.Value, ["key"], tokeniser.Index, tokeniser.Line, tokeniser.Character); case VDFTokenType.Conditional: - throw new VDFSyntaxException(VDFTokenType.Conditional, keyToken.Value.Value, new[] { "key" }, tokeniser.Index, tokeniser.Line, tokeniser.Character); + throw new VDFSyntaxException(VDFTokenType.Conditional, keyToken.Value.Value, ["key"], tokeniser.Index, tokeniser.Line, tokeniser.Character); default: throw new Exception(); } @@ -352,8 +348,7 @@ public static string Stringify(Dictionary obj, int tabs = 0) // Check for an conditional. var keyTokens = key.Split('^'); if (keyTokens.Length > 1) - stringValue += - $"{new string(tab, tabs)}\"{keyTokens[0]}\"\t\"{obj[key]}\" {keyTokens[1]}{newLine}"; + stringValue += $"{new string(tab, tabs)}\"{keyTokens[0]}\"\t\"{obj[key]}\" {keyTokens[1]}{newLine}"; else stringValue += $"{new string(tab, tabs)}\"{key}\"\t\"{obj[key]}\"{newLine}"; } diff --git a/src/TF2HUD.Editor/Classes/VTF.cs b/src/TF2HUD.Editor/Classes/VTF.cs index 6027e9f3..5c227a41 100644 --- a/src/TF2HUD.Editor/Classes/VTF.cs +++ b/src/TF2HUD.Editor/Classes/VTF.cs @@ -16,7 +16,7 @@ public VTF(string path) } /// - /// Convert an image file into a VTF texture file to be used in-game. + /// Converts an image file into a VTF texture file to be used in-game. /// /// Path and file name of the image to be converted. /// Output path and file name for the VTF. @@ -30,7 +30,7 @@ public void Convert(string inFile, string outFile) if (!Directory.Exists(materialSrc)) Directory.CreateDirectory(materialSrc); - // Save image as .tga (cast using TGASharpLib) + // Save image as .TGA (cast using TGASharpLib) var tgaSquareImage = (TGA)ResizeImage(image); tgaSquareImage.Save($"{materialSrc}\\temp.tga"); @@ -62,18 +62,14 @@ public void Convert(string inFile, string outFile) } /// - /// Resize the image file so it can be saved into Targa file. + /// Resizes the image file so it can be saved into Targa file. /// /// Bitmap of the input image file. /// Bitmap of the resized image file. private static Bitmap ResizeImage(Bitmap image) { - // Image size is the greater of both the width and height rounded - // up to the nearest power of 2 - var size = (int)Math.Max( - Math.Pow(2, Math.Ceiling(Math.Log(image.Width) / Math.Log(2))), - Math.Pow(2, Math.Ceiling(Math.Log(image.Height) / Math.Log(2))) - ); + // Image size is the greater of both the width and height rounded up to the nearest power of 2 + var size = (int)Math.Max(Math.Pow(2, Math.Ceiling(Math.Log(image.Width) / Math.Log(2))), Math.Pow(2, Math.Ceiling(Math.Log(image.Height) / Math.Log(2)))); // Paint graphics onto the SquareImage Bitmap var squareImage = new Bitmap(size, size); @@ -83,7 +79,7 @@ private static Bitmap ResizeImage(Bitmap image) } /// - /// Use the Valve Texture Tool (Vtex) to convert a Targa file (tga) into a Valve Texture File (vtf). + /// Uses the Valve Texture Tool (Vtex) to convert a Targa file (TGA) into a Valve Texture File (VTF). /// /// Input image file path. /// Name of the image to be converted. @@ -91,19 +87,19 @@ private static Bitmap ResizeImage(Bitmap image) private void VtexConvert(string folderPath, string fileName) { // Set the VTEX Args - File.WriteAllLines($"{folderPath}\\{fileName}.txt", new[] - { + File.WriteAllLines($"{folderPath}\\{fileName}.txt", + [ "pointsample 1", "nolod 1", "nomip 1" - }); + ]); // Set the VTEX CLI Args string[] args = - { + [ "-quiet", $"\"{folderPath}\\{fileName}.tga\"" - }; + ]; // Call Vtex and pass the parameters. var processInfo = new ProcessStartInfo($"{_tf2Path}\\bin\\vtex.exe") @@ -112,8 +108,7 @@ private void VtexConvert(string folderPath, string fileName) RedirectStandardOutput = true }; var process = Process.Start(processInfo); - while (!process.StandardOutput.EndOfStream) - MainWindow.Logger.Info($"[VTEX] {process.StandardOutput.ReadLine()}"); + while (!process.StandardOutput.EndOfStream) MainWindow.Logger.Info(process.StandardOutput.ReadLine()); process.WaitForExit(); process.Close(); process.Dispose(); diff --git a/src/TF2HUD.Editor/HUDEditor.csproj b/src/TF2HUD.Editor/HUDEditor.csproj index 1633392f..faacff7b 100644 --- a/src/TF2HUD.Editor/HUDEditor.csproj +++ b/src/TF2HUD.Editor/HUDEditor.csproj @@ -11,9 +11,9 @@ CriticalFlaw CriticalFlaw http://criticalflaw.ca/TF2HUD.Editor/ - 3.2.0.0 - 3.2.0.0 - 3.2.0 + 3.2.2 + 3.2.2 + 3.2.2 https://github.com/CriticalFlaw/TF2HUD.Editor logo.png LICENSE @@ -69,41 +69,26 @@ Always - - + Always - - - PreserveNewest + + Always - - - - - - - - - - - - - - - - - - + + + + + @@ -126,19 +111,6 @@ - - - Always - - - Always - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - diff --git a/src/TF2HUD.Editor/MainWindow.xaml.cs b/src/TF2HUD.Editor/MainWindow.xaml.cs index 004381df..5ac1662e 100644 --- a/src/TF2HUD.Editor/MainWindow.xaml.cs +++ b/src/TF2HUD.Editor/MainWindow.xaml.cs @@ -22,7 +22,7 @@ namespace HUDEditor { /// - /// Interaction logic for MainWindow.xaml + /// Interaction logic for MainWindow.xaml /// public partial class MainWindow { @@ -47,7 +47,7 @@ public MainWindow() SetupDirectory(); // Check for updates - if (Settings.Default.app_update_auto == true) UpdateAppSchema(); + UpdateAppSchema(true); } private void MainWindowViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -59,7 +59,7 @@ private void MainWindowViewModelPropertyChanged(object sender, PropertyChangedEv } /// - /// Setup the tf/custom directory. + /// Setups the target directory (tf/custom). /// /// If true, prompts the user to select the tf/custom using the folder browser. public static void SetupDirectory(bool userSet = false) @@ -67,7 +67,7 @@ public static void SetupDirectory(bool userSet = false) if ((Utilities.SearchRegistry() || Utilities.CheckUserPath(HudPath)) && !userSet) return; // Display a folder browser, ask the user to provide the tf/custom directory. - Logger.Info("tf/custom directory is not set. Asking the user..."); + Logger.Info("Target directory not set. Asking user to provide it."); using (var browser = new FolderBrowserDialog { Description = Properties.Resources.info_path_browser, @@ -77,6 +77,7 @@ public static void SetupDirectory(bool userSet = false) { // Loop until the user provides a valid tf/custom directory, unless they cancel out. while (!browser.SelectedPath.EndsWith("tf\\custom")) + { if (browser.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (browser.SelectedPath.EndsWith("tf\\custom")) @@ -84,7 +85,7 @@ public static void SetupDirectory(bool userSet = false) Settings.Default.hud_directory = browser.SelectedPath; Settings.Default.Save(); HudPath = Settings.Default.hud_directory; - Logger.Info("tf/custom directory is set to: " + Settings.Default.hud_directory); + Logger.Info("Target directory set to: " + Settings.Default.hud_directory); } else { @@ -95,11 +96,12 @@ public static void SetupDirectory(bool userSet = false) { break; } + } } // Check one more time if a valid directory has been set. if (Utilities.CheckUserPath(HudPath)) return; - Logger.Info("tf/custom directory still not set. Exiting..."); + Logger.Info("Target directory still not set. Closing."); ShowMessageBox(MessageBoxImage.Warning, Utilities.GetLocalizedString("error_app_directory")); Application.Current.Shutdown(); } @@ -137,13 +139,16 @@ public static bool CheckHudInstallation(HUD hud) } /// - /// Synchronize the local HUD schema files with the latest versions on GitHub. + /// Synchronizes the local HUD schema files with the latest versions on GitHub. /// /// If true, the user will not be notified if there are no updates on startup. public static async void UpdateAppSchema(bool silent = true) { try { + // Create the schema folder if it does not exist. + if (!Directory.Exists("JSON")) Directory.CreateDirectory("JSON"); + var downloads = new List(); var remoteFiles = (await Utilities.Fetch(Settings.Default.json_list)).Where((x) => x.Name.EndsWith(".json") && x.Type == "file").ToArray(); @@ -175,7 +180,7 @@ public static async void UpdateAppSchema(bool silent = true) await Task.WhenAll(downloads); if (Convert.ToBoolean(downloads.Count)) { - if (ShowMessageBox(MessageBoxImage.Information, Properties.Resources.info_hud_update, MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; + if (!silent) if (ShowMessageBox(MessageBoxImage.Information, Properties.Resources.info_hud_update, MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; Debug.WriteLine(Assembly.GetExecutingAssembly().Location); Process.Start(Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe")); Environment.Exit(0); @@ -197,17 +202,18 @@ public static async void UpdateAppSchema(bool silent = true) } /// - /// Check if there's a new version of the app available. + /// Checks if there's a new version of the app available. /// public static async void UpdateAppVersion() { try { - string appVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0,3); + string appVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 3); var latestVersion = await new GitHubClient(new ProductHeaderValue("TF2HUD.Editor")).Repository.Release.GetLatest("CriticalFlaw", "TF2HUD.Editor"); - Logger.Info($"Comparing version numbers: Local version {appVersion} | Live version {latestVersion.TagName}"); + Logger.Info($"Checking for app update. Latest version is {latestVersion.TagName}"); if (appVersion.Equals(latestVersion.TagName)) return; + Logger.Info($"Update available from {appVersion} -> {latestVersion.TagName}"); if (ShowMessageBox(MessageBoxImage.Information, Properties.Resources.info_app_update, MessageBoxButton.YesNo) != MessageBoxResult.Yes) return; Utilities.OpenWebpage(Settings.Default.app_update); diff --git a/src/TF2HUD.Editor/Models/Controls.cs b/src/TF2HUD.Editor/Models/Controls.cs index 7c5a2b26..363e84c6 100644 --- a/src/TF2HUD.Editor/Models/Controls.cs +++ b/src/TF2HUD.Editor/Models/Controls.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using System.Windows; using Newtonsoft.Json.Linq; diff --git a/src/TF2HUD.Editor/Models/Download.cs b/src/TF2HUD.Editor/Models/Download.cs index 68fe1c2f..f1439ce1 100644 --- a/src/TF2HUD.Editor/Models/Download.cs +++ b/src/TF2HUD.Editor/Models/Download.cs @@ -1,9 +1,4 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; -using System.Windows; -using Newtonsoft.Json.Linq; - -namespace HUDEditor.Models +namespace HUDEditor.Models { public class Download { diff --git a/src/TF2HUD.Editor/Models/HudAnimation.cs b/src/TF2HUD.Editor/Models/HudAnimation.cs index 759c2e8e..76921db2 100644 --- a/src/TF2HUD.Editor/Models/HudAnimation.cs +++ b/src/TF2HUD.Editor/Models/HudAnimation.cs @@ -1,5 +1,4 @@ -using System; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace HUDEditor.Models { diff --git a/src/TF2HUD.Editor/Models/HudJson.cs b/src/TF2HUD.Editor/Models/HudJson.cs index 1745165d..0e842078 100644 --- a/src/TF2HUD.Editor/Models/HudJson.cs +++ b/src/TF2HUD.Editor/Models/HudJson.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -using System.Windows; -using Newtonsoft.Json.Linq; namespace HUDEditor.Models { diff --git a/src/TF2HUD.Editor/Models/Links.cs b/src/TF2HUD.Editor/Models/Links.cs index eea2b882..8e4b5a5a 100644 --- a/src/TF2HUD.Editor/Models/Links.cs +++ b/src/TF2HUD.Editor/Models/Links.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; -using System.Windows; -using Newtonsoft.Json.Linq; +using System.Text.Json.Serialization; namespace HUDEditor.Models { diff --git a/src/TF2HUD.Editor/Models/Option.cs b/src/TF2HUD.Editor/Models/Option.cs index 96116bec..66355675 100644 --- a/src/TF2HUD.Editor/Models/Option.cs +++ b/src/TF2HUD.Editor/Models/Option.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; -using System.Windows; +using System.Text.Json.Serialization; using Newtonsoft.Json.Linq; namespace HUDEditor.Models diff --git a/src/TF2HUD.Editor/Models/Preset.cs b/src/TF2HUD.Editor/Models/Preset.cs new file mode 100644 index 00000000..f6faebd8 --- /dev/null +++ b/src/TF2HUD.Editor/Models/Preset.cs @@ -0,0 +1,10 @@ +namespace HUDEditor.Models +{ + public enum Preset + { + A, + B, + C, + D + } +} \ No newline at end of file diff --git a/src/TF2HUD.Editor/Models/RenameFile.cs b/src/TF2HUD.Editor/Models/RenameFile.cs index fad44bae..7c20ef9b 100644 --- a/src/TF2HUD.Editor/Models/RenameFile.cs +++ b/src/TF2HUD.Editor/Models/RenameFile.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; -using System.Windows; -using Newtonsoft.Json.Linq; +using System.Text.Json.Serialization; namespace HUDEditor.Models { diff --git a/src/TF2HUD.Editor/Models/Setting.cs b/src/TF2HUD.Editor/Models/Setting.cs index 57da9432..c8c5ccb2 100644 --- a/src/TF2HUD.Editor/Models/Setting.cs +++ b/src/TF2HUD.Editor/Models/Setting.cs @@ -1,6 +1,4 @@ -using HUDEditor.Classes; -using System.Collections.Generic; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace HUDEditor.Models { diff --git a/src/TF2HUD.Editor/Models/SteamModel.cs b/src/TF2HUD.Editor/Models/SteamModel.cs deleted file mode 100644 index bed3bd77..00000000 --- a/src/TF2HUD.Editor/Models/SteamModel.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Text.Json.Serialization; - -namespace HUDEditor.Models -{ - public class SteamModel - { - [JsonPropertyName("path")] public string Path { get; set; } - [JsonPropertyName("label")] public string Label { get; set; } - } -} \ No newline at end of file diff --git a/src/TF2HUD.Editor/Models/UserJson.cs b/src/TF2HUD.Editor/Models/UserJson.cs index 4ac304a8..816ef088 100644 --- a/src/TF2HUD.Editor/Models/UserJson.cs +++ b/src/TF2HUD.Editor/Models/UserJson.cs @@ -1,12 +1,11 @@ -using HUDEditor.Classes; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace HUDEditor.Models { public class UserJson { - [JsonPropertyName("Presets")] public Dictionary Presets { get; set; } = new(); - [JsonPropertyName("Settings")] public List Settings { get; set; } = new(); + [JsonPropertyName("Presets")] public Dictionary Presets { get; set; } = []; + [JsonPropertyName("Settings")] public List Settings { get; set; } = []; } } \ No newline at end of file diff --git a/src/TF2HUD.Editor/Properties/Resources.Designer.cs b/src/TF2HUD.Editor/Properties/Resources.Designer.cs index d7c5e53a..caf8912a 100644 --- a/src/TF2HUD.Editor/Properties/Resources.Designer.cs +++ b/src/TF2HUD.Editor/Properties/Resources.Designer.cs @@ -159,6 +159,15 @@ public static string info_background_override { } } + /// + /// Looks up a localized string similar to This option will delete all local schema and editor data files then restart the app. Would you like to continue?. + /// + public static string info_clear_cache { + get { + return ResourceManager.GetString("info_clear_cache", resourceCulture); + } + } + /// /// Looks up a localized string similar to Following changes require the game to be restarted:. /// @@ -411,6 +420,15 @@ public static string ui_clear { } } + /// + /// Looks up a localized string similar to Clear Cache. + /// + public static string ui_clear_cache { + get { + return ResourceManager.GetString("ui_clear_cache", resourceCulture); + } + } + /// /// Looks up a localized string similar to Customize. /// @@ -448,8 +466,7 @@ public static string ui_install { } /// - /// Looks up a localized string similar to Options - ///. + /// Looks up a localized string similar to Options. /// public static string ui_options { get { diff --git a/src/TF2HUD.Editor/Properties/Resources.resx b/src/TF2HUD.Editor/Properties/Resources.resx index a138db71..151b150e 100644 --- a/src/TF2HUD.Editor/Properties/Resources.resx +++ b/src/TF2HUD.Editor/Properties/Resources.resx @@ -279,4 +279,10 @@ Options + + Clear Cache + + + This option will delete all local schema and editor data files then restart the app. Would you like to continue? + \ No newline at end of file diff --git a/src/TF2HUD.Editor/SettingsWindow.xaml b/src/TF2HUD.Editor/SettingsWindow.xaml index bcf288cd..71ddb53e 100644 --- a/src/TF2HUD.Editor/SettingsWindow.xaml +++ b/src/TF2HUD.Editor/SettingsWindow.xaml @@ -69,23 +69,22 @@