diff --git a/.gitignore b/.gitignore index 45bb007..5b4dea1 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ Source/ConformalDecals/bin *.sublime* .idea obj +*.swp diff --git a/.travis.yml b/.travis.yml index c594017..33780f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,15 +3,13 @@ python: - 3.6 before_install: - echo -e "machine github.com\n login $GITHUB_OAUTH_TOKEN" > ~/.netrc - - git lfs pull - - git lfs fetch --all install: - pip install awscli boto3 requests branches: only: - release script: - - git clone https://github.com/post-kerbin-mining-corporation/build-deploy.git + - git clone https://github.com/post-kerbin-mining-corporation/build-deploy.git - cd build-deploy - git checkout master - cd .. @@ -24,4 +22,4 @@ deploy: script: python build-deploy/src/deploy.py --f ".mod_data.yml" # Deploy package to spacedock, curse, github skip_cleanup: true on: - branch: release \ No newline at end of file + branch: release diff --git a/GameData/ConformalDecals/Parts/decal-text.cfg b/GameData/ConformalDecals/Parts/decal-text.cfg index ed1edc1..1f92cb5 100644 --- a/GameData/ConformalDecals/Parts/decal-text.cfg +++ b/GameData/ConformalDecals/Parts/decal-text.cfg @@ -52,11 +52,17 @@ PART name = ModuleConformalText text = Text + fontName = Calibri SDF + fillColor = #000000FF + outlineColor = #FFFFFFFF + fillEnabled = true + outlineEnabled = false shader = ConformalDecals/Decal/Text useBaseNormal = true scaleMode = MINIMUM + defaultScale = 0.2 defaultDepth = 0.2 defaultCutoff = 0.5 } diff --git a/GameData/ConformalDecals/Patches/FAR.cfg b/GameData/ConformalDecals/Patches/FAR.cfg new file mode 100644 index 0000000..7aa2034 --- /dev/null +++ b/GameData/ConformalDecals/Patches/FAR.cfg @@ -0,0 +1,17 @@ +// Decals are just paint, so they shouldnt affect a vessel's aerodynamics at all + +@PART[*]:HAS[@MODULE[ModuleConformalDecal]]:After[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} + +@PART[*]:HAS[@MODULE[ModuleConformalFlag]]:After[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} + +@PART[*]:HAS[@MODULE[ModuleConformalText]]:After[FerramAerospaceResearch] +{ + + !MODULE[GeometryPartModule] {} +} \ No newline at end of file diff --git a/GameData/ConformalDecals/Versioning/ConformalDecals.version b/GameData/ConformalDecals/Versioning/ConformalDecals.version index 9da95d5..4dfbdd5 100644 --- a/GameData/ConformalDecals/Versioning/ConformalDecals.version +++ b/GameData/ConformalDecals/Versioning/ConformalDecals.version @@ -6,8 +6,8 @@ { "MAJOR":0, "MINOR":2, - "PATCH":1, - "BUILD":0 + "PATCH":6, + "BUILD":1 }, "KSP_VERSION": { diff --git a/README.md b/README.md index 285a4b3..febd796 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Conformal Decals v0.2.1 +# Conformal Decals v0.2.6 [![Build Status](https://travis-ci.org/drewcassidy/KSP-Conformal-Decals.svg?branch=release)](https://travis-ci.org/drewcassidy/KSP-Conformal-Decals) [![Art: CC BY-SA 4.0](https://img.shields.io/badge/Art%20License-CC%20BY--SA%204.0-orange.svg)](https://creativecommons.org/licenses/by-sa/4.0/) [![Code: GPL v3](https://img.shields.io/badge/Code%20License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ![Screenshot](http://pileof.rocks/KSP/images/ConformalDecalsHeader.png) diff --git a/Source/ConformalDecals.sln b/Source/ConformalDecals.sln index 5962f05..2e27ad0 100644 --- a/Source/ConformalDecals.sln +++ b/Source/ConformalDecals.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConformalDecals", "ConformalDecals/ConformalDecals.csproj", "{1ea983f9-42e5-494e-9683-fdac9c9121f4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConformalDecals", "ConformalDecals/ConformalDecals.csproj", "{1EA983F9-42E5-494E-9683-FDAC9C9121F4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -8,9 +8,9 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1ea983f9-42e5-494e-9683-fdac9c9121f4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1ea983f9-42e5-494e-9683-fdac9c9121f4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1ea983f9-42e5-494e-9683-fdac9c9121f4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1ea983f9-42e5-494e-9683-fdac9c9121f4}.Release|Any CPU.Build.0 = Release|Any CPU + {1EA983F9-42E5-494E-9683-FDAC9C9121F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1EA983F9-42E5-494E-9683-FDAC9C9121F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1EA983F9-42E5-494E-9683-FDAC9C9121F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1EA983F9-42E5-494E-9683-FDAC9C9121F4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Source/ConformalDecals/ConformalDecals.csproj b/Source/ConformalDecals/ConformalDecals.csproj index 8ab7fce..ab0a0dd 100644 --- a/Source/ConformalDecals/ConformalDecals.csproj +++ b/Source/ConformalDecals/ConformalDecals.csproj @@ -1,116 +1,55 @@ - - - + - Debug - AnyCPU - {1ea983f9-42e5-494e-9683-fdac9c9121f4} - Library - Properties - v4.6 - 512 - true + net48 8 - ConformalDecals - - - true - full - false - bin/Debug/ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin/Release/ - TRACE - prompt - 4 - bin/Release/ConformalDecals.xml - CS1591,CS0649 + false + x64 + 1701;1702;CS0649;CS1591 + - dlls/Assembly-CSharp.dll - - - dlls\KSPAssets.dll + dlls\Assembly-CSharp.dll - dlls/Shabby.dll + dlls\Shabby.dll - - dlls/UnityEngine.dll + dlls\UnityEngine.dll - dlls/UnityEngine.AssetBundleModule.dll + dlls\UnityEngine.AssetBundleModule.dll - dlls/UnityEngine.CoreModule.dll + dlls\UnityEngine.CoreModule.dll - dlls/UnityEngine.PhysicsModule.dll - - - dlls/UnityEngine.TextCoreModule.dll - - - dlls/UnityEngine.TextRenderingModule.dll + dlls\UnityEngine.PhysicsModule.dll - dlls/UnityEngine.UI.dll - - - dlls/UnityEngine.UIElementsModule.dll + dlls\UnityEngine.UI.dll - dlls/UnityEngine.UIModule.dll + dlls\UnityEngine.UIModule.dll + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - sh -e -c "cp -v '$(TargetPath)' '$(SolutionDir)/../GameData/ConformalDecals/Plugins'" - + + + + + + + + + + + + + + + diff --git a/Source/ConformalDecals/DecalConfig.cs b/Source/ConformalDecals/DecalConfig.cs index 7a3e730..15fe1fb 100644 --- a/Source/ConformalDecals/DecalConfig.cs +++ b/Source/ConformalDecals/DecalConfig.cs @@ -91,7 +91,7 @@ namespace ConformalDecals { _shaderBlacklist.Add(shaderName); } } - + var allFonts = Resources.FindObjectsOfTypeAll(); foreach (var fontNode in node.GetNodes("FONT")) { diff --git a/Source/ConformalDecals/MaterialProperties/MaterialTextureProperty.cs b/Source/ConformalDecals/MaterialProperties/MaterialTextureProperty.cs index cfd018b..9a096aa 100644 --- a/Source/ConformalDecals/MaterialProperties/MaterialTextureProperty.cs +++ b/Source/ConformalDecals/MaterialProperties/MaterialTextureProperty.cs @@ -41,7 +41,13 @@ namespace ConformalDecals.MaterialProperties { public Vector2 Dimensions => new Vector2(_texture.width, _texture.height); public Vector2 MaskedDimensions => _hasTile ? _tileRect.size : Dimensions; - public float AspectRatio => MaskedHeight / (float) MaskedWidth; + public float AspectRatio { + get { + if (_texture == null) return 1; + if (_textureUrl?.Contains("Squad/Flags") == true) return 0.625f; + return MaskedHeight / (float) MaskedWidth; + } + } public override void ParseNode(ConfigNode node) { base.ParseNode(node); diff --git a/Source/ConformalDecals/ModuleConformalDecal.cs b/Source/ConformalDecals/ModuleConformalDecal.cs index 36dfbf5..2fb883d 100644 --- a/Source/ConformalDecals/ModuleConformalDecal.cs +++ b/Source/ConformalDecals/ModuleConformalDecal.cs @@ -32,7 +32,7 @@ namespace ConformalDecals { [KSPField] public bool scaleAdjustable = true; [KSPField] public float defaultScale = 1; - [KSPField] public Vector2 scaleRange = new Vector2(0, 4); + [KSPField] public Vector2 scaleRange = new Vector2(0, 5); [KSPField] public DecalScaleMode scaleMode = DecalScaleMode.HEIGHT; @@ -61,19 +61,19 @@ namespace ConformalDecals { // INTERNAL VALUES [KSPField(guiName = "#LOC_ConformalDecals_gui-scale", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F2", guiUnits = "m"), - UI_FloatRange(stepIncrement = 0.05f)] + UI_FloatRange()] public float scale = 1.0f; [KSPField(guiName = "#LOC_ConformalDecals_gui-depth", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F2", guiUnits = "m"), - UI_FloatRange(stepIncrement = 0.02f)] + UI_FloatRange()] public float depth = 0.2f; [KSPField(guiName = "#LOC_ConformalDecals_gui-opacity", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "P0"), - UI_FloatRange(stepIncrement = 0.05f)] + UI_FloatRange()] public float opacity = 1.0f; [KSPField(guiName = "#LOC_ConformalDecals_gui-cutoff", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "P0"), - UI_FloatRange(stepIncrement = 0.05f)] + UI_FloatRange()] public float cutoff = 0.5f; [KSPField(guiName = "#LOC_ConformalDecals_gui-wear", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F0"), @@ -420,7 +420,7 @@ namespace ConformalDecals { // Update scale and depth scale = Mathf.Max(0.01f, scale); depth = Mathf.Max(0.01f, depth); - var aspectRatio = materialProperties.AspectRatio; + var aspectRatio = Mathf.Max(0.01f, materialProperties.AspectRatio); Vector2 size; switch (scaleMode) { @@ -541,7 +541,7 @@ namespace ConformalDecals { cutoffField.guiActiveEditor = cutoffAdjustable; wearField.guiActiveEditor = useBaseNormal; - var steps = 40; + var steps = 20; if (scaleAdjustable) { var minValue = Mathf.Max(Mathf.Epsilon, scaleRange.x); @@ -550,7 +550,7 @@ namespace ConformalDecals { var scaleEditor = (UI_FloatRange) scaleField.uiControlEditor; scaleEditor.minValue = minValue; scaleEditor.maxValue = maxValue; - scaleEditor.stepIncrement = (maxValue - minValue) / steps; + scaleEditor.stepIncrement = 0.01f; //1cm scaleEditor.onFieldChanged = OnProjectionTweakEvent; } @@ -561,7 +561,7 @@ namespace ConformalDecals { var depthEditor = (UI_FloatRange) depthField.uiControlEditor; depthEditor.minValue = minValue; depthEditor.maxValue = maxValue; - depthEditor.stepIncrement = (maxValue - minValue) / steps; + depthEditor.stepIncrement = 0.01f; //1cm depthEditor.onFieldChanged = OnProjectionTweakEvent; } diff --git a/Source/ConformalDecals/ModuleConformalText.cs b/Source/ConformalDecals/ModuleConformalText.cs index fdd9cb1..0b6145b 100644 --- a/Source/ConformalDecals/ModuleConformalText.cs +++ b/Source/ConformalDecals/ModuleConformalText.cs @@ -1,32 +1,34 @@ +using System.Collections; +using System.Net; using ConformalDecals.MaterialProperties; using ConformalDecals.Text; using ConformalDecals.UI; using ConformalDecals.Util; using TMPro; +using UniLinq; using UnityEngine; namespace ConformalDecals { - public class ModuleConformalText : ModuleConformalDecal, ISerializationCallbackReceiver { - [KSPField(isPersistant = true)] public string text = "Text"; - + public class ModuleConformalText : ModuleConformalDecal { [KSPField] public Vector2 lineSpacingRange = new Vector2(-50, 50); [KSPField] public Vector2 charSpacingRange = new Vector2(-50, 50); - // serialization-only fields. do not use except in serialization functions - [KSPField(isPersistant = true)] public string fontName = "Calibri SDF"; - [KSPField(isPersistant = true)] public int style; - [KSPField(isPersistant = true)] public bool vertical; - [KSPField(isPersistant = true)] public float lineSpacing; - [KSPField(isPersistant = true)] public float charSpacing; - [KSPField(isPersistant = true)] public string fillColor = "000000FF"; - [KSPField(isPersistant = true)] public string outlineColor = "FFFFFFFF"; + [KSPField(isPersistant = true)] public bool vertical; + [KSPField(isPersistant = true)] public float lineSpacing; + [KSPField(isPersistant = true)] public float charSpacing; + + [KSPField] public string text; + [KSPField] public DecalFont font; + [KSPField] public FontStyles style; + [KSPField] public Color32 fillColor = Color.black; + [KSPField] public Color32 outlineColor = Color.white; // KSP TWEAKABLES [KSPEvent(guiName = "#LOC_ConformalDecals_gui-set-text", guiActive = false, guiActiveEditor = true)] public void SetText() { if (_textEntryController == null) { - _textEntryController = TextEntryController.Create(text, _font, _style, lineSpacingRange, charSpacingRange, OnTextUpdate); + _textEntryController = TextEntryController.Create(text, font, style, vertical, lineSpacing, charSpacing, lineSpacingRange, charSpacingRange, OnTextUpdate); } else { _textEntryController.Close(); @@ -44,7 +46,7 @@ namespace ConformalDecals { guiActive = false, guiActiveEditor = true)] public void SetFillColor() { if (_fillColorPickerController == null) { - _fillColorPickerController = ColorPickerController.Create(_fillColor, OnFillColorUpdate); + _fillColorPickerController = ColorPickerController.Create(fillColor, OnFillColorUpdate); } else { _fillColorPickerController.Close(); @@ -67,17 +69,13 @@ namespace ConformalDecals { guiActive = false, guiActiveEditor = true)] public void SetOutlineColor() { if (_outlineColorPickerController == null) { - _outlineColorPickerController = ColorPickerController.Create(_outlineColor, OnOutlineColorUpdate); + _outlineColorPickerController = ColorPickerController.Create(outlineColor, OnOutlineColorUpdate); } else { _outlineColorPickerController.Close(); } } - private DecalTextStyle _style; - private DecalFont _font; - private Color32 _fillColor; - private Color32 _outlineColor; private TextEntryController _textEntryController; private ColorPickerController _fillColorPickerController; @@ -92,35 +90,56 @@ namespace ConformalDecals { private MaterialColorProperty _outlineColorProperty; private MaterialFloatProperty _outlineWidthProperty; - private TextRenderJob _currentJob; private DecalText _currentText; public override void OnLoad(ConfigNode node) { base.OnLoad(node); - OnAfterDeserialize(); + + string textRaw = ""; + if (ParseUtil.ParseStringIndirect(ref textRaw, node, "text")) { + text = WebUtility.UrlDecode(textRaw); + } + + string fontName = ""; + if (ParseUtil.ParseStringIndirect(ref fontName, node, "fontName")) { + font = DecalConfig.GetFont(fontName); + } + else if (font == null) font = DecalConfig.GetFont("Calibri SDF"); + + int styleInt = 0; + if (ParseUtil.ParseIntIndirect(ref styleInt, node, "style")) { + style = (FontStyles) styleInt; + } + + ParseUtil.ParseColor32Indirect(ref fillColor, node, "fillColor"); + ParseUtil.ParseColor32Indirect(ref outlineColor, node, "outlineColor"); + + if (HighLogic.LoadedSceneIsGame) { + // For some reason, rendering doesnt work right on the first frame a scene is loaded + // So delay any rendering until the next frame when called in OnLoad + // This is probably a problem with Unity, not KSP + StartCoroutine(UpdateTextLate()); + } + else { + UpdateTextures(); + UpdateMaterials(); + UpdateScale(); + UpdateTargets(); + } } public override void OnSave(ConfigNode node) { - OnBeforeSerialize(); + node.AddValue("text", WebUtility.UrlEncode(text)); + node.AddValue("fontName", font.Name); + node.AddValue("style", (int) style); + node.AddValue("fillColor", fillColor.ToHexString()); + node.AddValue("outlineColor", outlineColor.ToHexString()); base.OnSave(node); } public override void OnAwake() { base.OnAwake(); - _font = DecalConfig.GetFont(fontName); - _style = new DecalTextStyle((FontStyles) style, vertical, lineSpacing, charSpacing); - - if (!ParseUtil.TryParseColor32(fillColor, out _fillColor)) { - Logging.LogWarning($"Improperly formatted color value for fill: '{fillColor}'"); - _fillColor = Color.magenta; - } - - if (!ParseUtil.TryParseColor32(outlineColor, out _outlineColor)) { - Logging.LogWarning($"Improperly formatted color value for outline: '{outlineColor}'"); - _outlineColor = Color.magenta; - } - _decalTextureProperty = materialProperties.AddOrGetTextureProperty("_Decal", true); _fillEnabledProperty = materialProperties.AddOrGetProperty("DECAL_FILL"); @@ -131,46 +150,44 @@ namespace ConformalDecals { _outlineWidthProperty = materialProperties.AddOrGetProperty("_OutlineWidth"); } - public void OnTextUpdate(string newText, DecalFont newFont, DecalTextStyle newStyle) { + public void OnTextUpdate(string newText, DecalFont newFont, FontStyles newStyle, bool newVertical, float newLineSpacing, float newCharSpacing) { text = newText; - _font = newFont; - _style = newStyle; - UpdateTextures(); - UpdateScale(); - UpdateTargets(); - - foreach (var counterpart in part.symmetryCounterparts) { - var decal = counterpart.GetComponent(); - decal.text = text; - decal._font = _font; - decal._style = _style; - - decal._currentJob = _currentJob; - decal._currentText = _currentText; - decal.UpdateTextures(); - decal.UpdateScale(); - decal.UpdateTargets(); + font = newFont; + style = newStyle; + vertical = newVertical; + lineSpacing = newLineSpacing; + charSpacing = newCharSpacing; + UpdateText(); + + foreach (var decal in part.symmetryCounterparts.Select(o => o.GetComponent())) { + decal.text = newText; + decal.font = newFont; + decal.style = newStyle; + decal.vertical = newVertical; + decal.lineSpacing = newLineSpacing; + decal.charSpacing = newCharSpacing; + decal.UpdateText(); } } public void OnFillColorUpdate(Color rgb, Util.ColorHSV hsv) { - _fillColor = rgb; + fillColor = rgb; UpdateMaterials(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); - decal._fillColor = _fillColor; + decal.fillColor = fillColor; decal.UpdateMaterials(); } } public void OnOutlineColorUpdate(Color rgb, Util.ColorHSV hsv) { - _outlineColor = rgb; + outlineColor = rgb; UpdateMaterials(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); - decal._outlineColor = _outlineColor; + decal.outlineColor = outlineColor; decal.UpdateMaterials(); } } @@ -217,21 +234,14 @@ namespace ConformalDecals { } } - public void OnBeforeSerialize() { - fontName = _font.Name; - style = (int) _style.FontStyle; - vertical = _style.Vertical; - lineSpacing = _style.LineSpacing; - charSpacing = _style.CharSpacing; - fillColor = _fillColor.ToHexString(); - outlineColor = _outlineColor.ToHexString(); - } - - public void OnAfterDeserialize() {} - public override void OnDestroy() { if (HighLogic.LoadedSceneIsGame && _currentText != null) TextRenderer.UnregisterText(_currentText); + // close all UIs + if (_textEntryController != null) _textEntryController.Close(); + if (_fillColorPickerController != null) _fillColorPickerController.Close(); + if (_outlineColorPickerController != null) _outlineColorPickerController.Close(); + base.OnDestroy(); } @@ -244,24 +254,34 @@ namespace ConformalDecals { base.OnDetach(); } + protected void UpdateText() { + UpdateTextures(); + UpdateMaterials(); + UpdateScale(); + UpdateTargets(); + } + + private IEnumerator UpdateTextLate() { + yield return null; + UpdateText(); + } + protected override void UpdateTextures() { // Render text - var newText = new DecalText(text, _font, _style); + var newText = new DecalText(text, font, style, vertical, lineSpacing, charSpacing); var output = TextRenderer.UpdateTextNow(_currentText, newText); _currentText = newText; _decalTextureProperty.Texture = output.Texture; _decalTextureProperty.SetTile(output.Window); - - UpdateMaterials(); } protected override void UpdateMaterials() { _fillEnabledProperty.value = fillEnabled; - _fillColorProperty.color = _fillColor; + _fillColorProperty.color = fillColor; _outlineEnabledProperty.value = outlineEnabled; - _outlineColorProperty.color = _outlineColor; + _outlineColorProperty.color = outlineColor; _outlineWidthProperty.value = outlineWidth; base.UpdateMaterials(); diff --git a/Source/ConformalDecals/Properties/AssemblyInfo.cs b/Source/ConformalDecals/Properties/AssemblyInfo.cs index 3eab961..f2a1459 100644 --- a/Source/ConformalDecals/Properties/AssemblyInfo.cs +++ b/Source/ConformalDecals/Properties/AssemblyInfo.cs @@ -1,38 +1 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ConformalDecals")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Cineboxandrew")] -[assembly: AssemblyProduct("ConformalDecals")] -[assembly: AssemblyCopyright("Copyright © Andrew Cassidy 2020")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1ea983f9-42e5-494e-9683-fdac9c9121f4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] - -[assembly: KSPAssembly("ConformalDecals", 0, 1, 0)] +[assembly: KSPAssembly("ConformalDecals", 0, 2, 6)] \ No newline at end of file diff --git a/Source/ConformalDecals/Text/DecalFont.cs b/Source/ConformalDecals/Text/DecalFont.cs index efa0b6e..bf422ee 100644 --- a/Source/ConformalDecals/Text/DecalFont.cs +++ b/Source/ConformalDecals/Text/DecalFont.cs @@ -3,41 +3,47 @@ using System.Collections.Generic; using ConformalDecals.Util; using TMPro; using UniLinq; +using UnityEngine; namespace ConformalDecals.Text { - public class DecalFont : IEquatable { + public class DecalFont : ScriptableObject, ISerializationCallbackReceiver, IEquatable { + [SerializeField] private string _title; + [SerializeField] private TMP_FontAsset _fontAsset; + [SerializeField] private FontStyles _fontStyle; + [SerializeField] private FontStyles _fontStyleMask; + /// Human-readable name for the font - public string Title { get; } + public string Title => _title; /// Internal name for the font - public string Name => FontAsset.name; + public string Name => _fontAsset.name; /// The font asset itself - public TMP_FontAsset FontAsset { get; } + public TMP_FontAsset FontAsset => _fontAsset; /// Styles that are forced on for this font, /// e.g. smallcaps for a font without lower case characters - public FontStyles FontStyle { get; } + public FontStyles FontStyle => _fontStyle; - public bool Bold => (FontStyle & FontStyles.Bold) != 0; + public bool Bold => (_fontStyle & FontStyles.Bold) != 0; - public bool Italic => (FontStyle & FontStyles.Italic) != 0; + public bool Italic => (_fontStyle & FontStyles.Italic) != 0; - public bool Underline => (FontStyle & FontStyles.Underline) != 0; + public bool Underline => (_fontStyle & FontStyles.Underline) != 0; - public bool SmallCaps => (FontStyle & FontStyles.SmallCaps) != 0; + public bool SmallCaps => (_fontStyle & FontStyles.SmallCaps) != 0; /// Styles that are forced off for this font, /// e.g. underline for a font with no underscore character - public FontStyles FontStyleMask { get; } + public FontStyles FontStyleMask => _fontStyleMask; - public bool BoldMask => (FontStyleMask & FontStyles.Bold) != 0; + public bool BoldMask => (_fontStyleMask & FontStyles.Bold) != 0; - public bool ItalicMask => (FontStyleMask & FontStyles.Italic) != 0; + public bool ItalicMask => (_fontStyleMask & FontStyles.Italic) != 0; - public bool UnderlineMask => (FontStyleMask & FontStyles.Underline) != 0; + public bool UnderlineMask => (_fontStyleMask & FontStyles.Underline) != 0; - public bool SmallCapsMask => (FontStyleMask & FontStyles.SmallCaps) != 0; + public bool SmallCapsMask => (_fontStyleMask & FontStyles.SmallCaps) != 0; public DecalFont(ConfigNode node, IEnumerable fontAssets) { @@ -45,14 +51,14 @@ namespace ConformalDecals.Text { if (fontAssets == null) throw new ArgumentNullException(nameof(fontAssets)); var name = ParseUtil.ParseString(node, "name"); - FontAsset = fontAssets.First(o => o.name == name); + _fontAsset = fontAssets.First(o => o.name == name); if (FontAsset == null) { throw new FormatException($"Could not find font asset named {name}"); } - Title = ParseUtil.ParseString(node, "title", true, name); - FontStyle = (FontStyles) ParseUtil.ParseInt(node, "style", true); - FontStyleMask = (FontStyles) ParseUtil.ParseInt(node, "styleMask", true); + _title = ParseUtil.ParseString(node, "title", true, name); + _fontStyle = (FontStyles) ParseUtil.ParseInt(node, "style", true); + _fontStyleMask = (FontStyles) ParseUtil.ParseInt(node, "styleMask", true); } @@ -95,5 +101,9 @@ namespace ConformalDecals.Text { public static bool operator !=(DecalFont left, DecalFont right) { return !Equals(left, right); } + + public void OnBeforeSerialize() { } + + public void OnAfterDeserialize() { } } } \ No newline at end of file diff --git a/Source/ConformalDecals/Text/DecalText.cs b/Source/ConformalDecals/Text/DecalText.cs index c974292..d6af8d1 100644 --- a/Source/ConformalDecals/Text/DecalText.cs +++ b/Source/ConformalDecals/Text/DecalText.cs @@ -1,21 +1,39 @@ using System; using System.Text.RegularExpressions; +using TMPro; namespace ConformalDecals.Text { public class DecalText : IEquatable { + private readonly string _text; + private readonly DecalFont _font; + private readonly FontStyles _style; + private readonly bool _vertical; + private readonly float _lineSpacing; + private readonly float _charSpacing; + /// Raw text contents - public string Text { get; } + public string Text => _text; /// Font asset used by this text snippet - public DecalFont Font { get; } + public DecalFont Font => _font; /// Style used by this text snippet - public DecalTextStyle Style { get; } + public FontStyles Style => _style; + + /// If this text snippet is vertical + public bool Vertical => _vertical; + + /// The text snippet's line spacing + public float LineSpacing => _lineSpacing; + + /// The text snippet's character spacing + public float CharSpacing => _charSpacing; /// The text formatted with newlines for vertical text public string FormattedText { get { - if (Style.Vertical) { + if (string.IsNullOrWhiteSpace(Text)) return "•"; + if (Vertical) { return Regex.Replace(Text, @"(.)", "$1\n"); } else { @@ -24,17 +42,22 @@ namespace ConformalDecals.Text { } } - public DecalText(string text, DecalFont font, DecalTextStyle style) { + + public DecalText(string text, DecalFont font, FontStyles style, bool vertical, float linespacing, float charspacing) { if (font == null) throw new ArgumentNullException(nameof(font)); - Text = text; - Font = font; - Style = style; + _text = text; + _font = font; + _style = style; + _vertical = vertical; + _lineSpacing = linespacing; + _charSpacing = charspacing; } public bool Equals(DecalText other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return Text == other.Text && Equals(Font, other.Font) && Style.Equals(other.Style); + return _text == other._text && Equals(_font, other._font) && _style == other._style && _vertical == other._vertical && _lineSpacing.Equals(other._lineSpacing) && + _charSpacing.Equals(other._charSpacing); } public override bool Equals(object obj) { @@ -46,9 +69,12 @@ namespace ConformalDecals.Text { public override int GetHashCode() { unchecked { - var hashCode = (Text != null ? Text.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (Font != null ? Font.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ Style.GetHashCode(); + var hashCode = (_text != null ? _text.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (_font != null ? _font.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (int) _style; + hashCode = (hashCode * 397) ^ _vertical.GetHashCode(); + hashCode = (hashCode * 397) ^ _lineSpacing.GetHashCode(); + hashCode = (hashCode * 397) ^ _charSpacing.GetHashCode(); return hashCode; } } diff --git a/Source/ConformalDecals/Text/DecalTextStyle.cs b/Source/ConformalDecals/Text/DecalTextStyle.cs deleted file mode 100644 index ac55fc3..0000000 --- a/Source/ConformalDecals/Text/DecalTextStyle.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using TMPro; -using UnityEngine; - -// ReSharper disable NonReadonlyMemberInGetHashCode - -namespace ConformalDecals.Text { - public struct DecalTextStyle : IEquatable { - private FontStyles _fontStyle; - private bool _vertical; - private float _lineSpacing; - private float _charSpacing; - - public FontStyles FontStyle { - get => _fontStyle; - set => _fontStyle = value; - } - - public bool Bold { - get => (FontStyle & FontStyles.Bold) != 0; - set { - if (value) FontStyle |= FontStyles.Bold; - else FontStyle &= ~FontStyles.Bold; - } - } - - public bool Italic { - get => (FontStyle & FontStyles.Italic) != 0; - set { - if (value) FontStyle |= FontStyles.Italic; - else FontStyle &= ~FontStyles.Italic; - } - } - - public bool Underline { - get => (FontStyle & FontStyles.Underline) != 0; - set { - if (value) FontStyle |= FontStyles.Underline; - else FontStyle &= ~FontStyles.Underline; - } - } - - public bool SmallCaps { - get => (FontStyle & FontStyles.SmallCaps) != 0; - set { - if (value) FontStyle |= FontStyles.SmallCaps; - else FontStyle &= ~FontStyles.SmallCaps; - } - } - - public bool Vertical { - get => _vertical; - set => _vertical = value; - } - - public float LineSpacing { - get => _lineSpacing; - set => _lineSpacing = value; - } - - public float CharSpacing { - get => _charSpacing; - set => _charSpacing = value; - } - - public DecalTextStyle(FontStyles fontStyle, bool vertical, float lineSpacing, float charSpacing) { - _fontStyle = fontStyle; - _vertical = vertical; - _lineSpacing = lineSpacing; - _charSpacing = charSpacing; - } - - public bool Equals(DecalTextStyle other) { - return FontStyle == other.FontStyle && Vertical == other.Vertical && - Mathf.Approximately(LineSpacing, other.LineSpacing) && - Mathf.Approximately(CharSpacing, other.CharSpacing); - } - - public override bool Equals(object obj) { - return obj is DecalTextStyle other && Equals(other); - } - - public override int GetHashCode() { - unchecked { - var hashCode = (int) FontStyle; - hashCode = (hashCode * 397) ^ Vertical.GetHashCode(); - hashCode = (hashCode * 397) ^ LineSpacing.GetHashCode(); - hashCode = (hashCode * 397) ^ CharSpacing.GetHashCode(); - return hashCode; - } - } - - public static bool operator ==(DecalTextStyle left, DecalTextStyle right) { - return left.Equals(right); - } - - public static bool operator !=(DecalTextStyle left, DecalTextStyle right) { - return !left.Equals(right); - } - } -} \ No newline at end of file diff --git a/Source/ConformalDecals/Text/TextRenderer.cs b/Source/ConformalDecals/Text/TextRenderer.cs index 4aef069..6c1206a 100644 --- a/Source/ConformalDecals/Text/TextRenderer.cs +++ b/Source/ConformalDecals/Text/TextRenderer.cs @@ -89,9 +89,11 @@ namespace ConformalDecals.Text { if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12) { textRenderTextureFormat = RenderTextureFormat.ARGB32; // DirectX is dumb } + if (!SystemInfo.SupportsTextureFormat(textTextureFormat)) { Logging.LogError($"Text texture format {textTextureFormat} not supported on this platform."); } + if (!SystemInfo.SupportsRenderTextureFormat(textRenderTextureFormat)) { Logging.LogError($"Text texture format {textRenderTextureFormat} not supported on this platform."); } @@ -161,9 +163,9 @@ namespace ConformalDecals.Text { // SETUP TMP OBJECT FOR RENDERING _tmp.text = text.FormattedText; _tmp.font = text.Font.FontAsset; - _tmp.fontStyle = text.Style.FontStyle | text.Font.FontStyle; - _tmp.lineSpacing = text.Style.LineSpacing; - _tmp.characterSpacing = text.Style.CharSpacing; + _tmp.fontStyle = text.Style | text.Font.FontStyle; + _tmp.lineSpacing = text.LineSpacing; + _tmp.characterSpacing = text.CharSpacing; _tmp.extraPadding = true; _tmp.enableKerning = true; @@ -205,6 +207,9 @@ namespace ConformalDecals.Text { // CALCULATE SIZES var size = bounds.size * PixelDensity; + size.x = Mathf.Max(size.x, 0.1f); + size.y = Mathf.Max(size.y, 0.1f); + var textureSize = new Vector2Int { x = Mathf.NextPowerOfTwo((int) size.x), y = Mathf.NextPowerOfTwo((int) size.y) @@ -250,13 +255,13 @@ namespace ConformalDecals.Text { bounds.center.y - halfSize.y, bounds.center.y + halfSize.y, -1, 1); // GET RENDERTEX - var renderTex = RenderTexture.GetTemporary(textureSize.x, textureSize.y, 0, textRenderTextureFormat, RenderTextureReadWrite.Linear, 1); - renderTex.autoGenerateMips = false; + var renderTex = new RenderTexture(textureSize.x, textureSize.y, 0, textRenderTextureFormat, RenderTextureReadWrite.Linear) {autoGenerateMips = false}; // RENDER Graphics.SetRenderTarget(renderTex); GL.PushMatrix(); GL.LoadProjectionMatrix(matrix); + GL.LoadIdentity(); GL.Clear(false, true, Color.black); for (var i = 0; i < meshes.Length; i++) { @@ -266,19 +271,25 @@ namespace ConformalDecals.Text { } } - GL.PopMatrix(); - // COPY TEXTURE BACK INTO RAM + var prevRT = RenderTexture.active; RenderTexture.active = renderTex; texture.ReadPixels(new Rect(0, 0, textureSize.x, textureSize.y), 0, 0, true); texture.Apply(); + RenderTexture.active = prevRT; + GL.PopMatrix(); + // RELEASE RENDERTEX - RenderTexture.ReleaseTemporary(renderTex); + renderTex.Release(); + RenderTexture.Destroy(renderTex); // CLEAR SUBMESHES + _tmp.text = ""; + for (int i = 0; i < transform.childCount; i++) { - Destroy(transform.GetChild(i).gameObject); + var child = transform.GetChild(i); + Destroy(child.gameObject); } return new TextRenderOutput(texture, window); diff --git a/Source/ConformalDecals/UI/TextEntryController.cs b/Source/ConformalDecals/UI/TextEntryController.cs index 40d047d..8a783b0 100644 --- a/Source/ConformalDecals/UI/TextEntryController.cs +++ b/Source/ConformalDecals/UI/TextEntryController.cs @@ -9,9 +9,7 @@ using UnityEngine.UI; namespace ConformalDecals.UI { public class TextEntryController : MonoBehaviour { [Serializable] - public class TextUpdateEvent : UnityEvent { } - - [SerializeField] public TextUpdateEvent onValueChanged = new TextUpdateEvent(); + public delegate void TextUpdateDelegate(string newText, DecalFont newFont, FontStyles style, bool vertical, float linespacing, float charspacing); [SerializeField] private Selectable _textBox; [SerializeField] private Button _fontButton; @@ -28,21 +26,28 @@ namespace ConformalDecals.UI { [SerializeField] private Toggle _smallCapsButton; [SerializeField] private Toggle _verticalButton; - private string _text; - private DecalFont _font; - private DecalTextStyle _style; - private Vector2 _lineSpacingRange; - private Vector2 _charSpacingRange; - private TMP_InputField _textBoxTMP; + private string _text; + private DecalFont _font; + private FontStyles _style; + private bool _vertical; + private float _lineSpacing; + private float _charSpacing; + private Vector2 _lineSpacingRange; + private Vector2 _charSpacingRange; + private TMP_InputField _textBoxTMP; + private TextUpdateDelegate _onValueChanged; private FontMenuController _fontMenu; - private bool _ignoreUpdates; + private bool _ignoreUpdates; + private bool _isLocked; + private string _lockString; + private static int _lockCounter; public static TextEntryController Create( - string text, DecalFont font, DecalTextStyle style, + string text, DecalFont font, FontStyles style, bool vertical, float linespacing, float charspacing, Vector2 lineSpacingRange, Vector2 charSpacingRange, - UnityAction textUpdateCallback) { + TextUpdateDelegate textUpdateCallback) { var window = Instantiate(UILoader.TextEntryPrefab, MainCanvasUtil.MainCanvas.transform, true); window.AddComponent(); @@ -52,9 +57,12 @@ namespace ConformalDecals.UI { controller._text = text; controller._font = font; controller._style = style; + controller._vertical = vertical; + controller._lineSpacing = linespacing; + controller._charSpacing = charspacing; controller._lineSpacingRange = lineSpacingRange; controller._charSpacingRange = charSpacingRange; - controller.onValueChanged.AddListener(textUpdateCallback); + controller._onValueChanged = textUpdateCallback; return controller; } @@ -64,6 +72,18 @@ namespace ConformalDecals.UI { Destroy(gameObject); } + public void SetControlLock(string value = null) { + if (_isLocked) return; + InputLockManager.SetControlLock(_lockString); + _isLocked = true; + } + + public void RemoveControlLock(string value = null) { + if (!_isLocked) return; + InputLockManager.RemoveControlLock(_lockString); + _isLocked = false; + } + public void OnTextUpdate(string newText) { this._text = newText; @@ -81,7 +101,7 @@ namespace ConformalDecals.UI { font.SetupSample(_fontButton.GetComponentInChildren()); _textBoxTMP.text = _text; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; _textBoxTMP.fontAsset = _font.FontAsset; UpdateStyleButtons(); @@ -91,7 +111,7 @@ namespace ConformalDecals.UI { public void OnLineSpacingUpdate(float value) { if (_ignoreUpdates) return; - _style.LineSpacing = Mathf.Lerp(_lineSpacingRange.x, _lineSpacingRange.y, value); + _lineSpacing = Mathf.Lerp(_lineSpacingRange.x, _lineSpacingRange.y, value); UpdateLineSpacing(); OnValueChanged(); @@ -101,7 +121,7 @@ namespace ConformalDecals.UI { if (_ignoreUpdates) return; if (float.TryParse(text, out var value)) { - _style.LineSpacing = Mathf.Clamp(value, _lineSpacingRange.x, _lineSpacingRange.y); + _lineSpacing = Mathf.Clamp(value, _lineSpacingRange.x, _lineSpacingRange.y); } else { Logging.LogWarning("Line spacing value '{text}' could not be parsed."); @@ -114,7 +134,7 @@ namespace ConformalDecals.UI { public void OnCharSpacingUpdate(float value) { if (_ignoreUpdates) return; - _style.CharSpacing = Mathf.Lerp(_charSpacingRange.x, _charSpacingRange.y, value); + _charSpacing = Mathf.Lerp(_charSpacingRange.x, _charSpacingRange.y, value); UpdateCharSpacing(); OnValueChanged(); @@ -124,7 +144,7 @@ namespace ConformalDecals.UI { if (_ignoreUpdates) return; if (float.TryParse(text, out var value)) { - _style.CharSpacing = Mathf.Clamp(value, _charSpacingRange.x, _charSpacingRange.y); + _charSpacing = Mathf.Clamp(value, _charSpacingRange.x, _charSpacingRange.y); } else { Logging.LogWarning("Char spacing value '{text}' could not be parsed."); @@ -137,48 +157,67 @@ namespace ConformalDecals.UI { public void OnBoldUpdate(bool state) { if (_ignoreUpdates) return; - _style.Bold = state; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + if (state) + _style |= FontStyles.Bold; + else + _style &= ~FontStyles.Bold; + + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; OnValueChanged(); } public void OnItalicUpdate(bool state) { if (_ignoreUpdates) return; - _style.Italic = state; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + if (state) + _style |= FontStyles.Italic; + else + _style &= ~FontStyles.Italic; + + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; OnValueChanged(); } public void OnUnderlineUpdate(bool state) { if (_ignoreUpdates) return; - _style.Underline = state; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + if (state) + _style |= FontStyles.Underline; + else + _style &= ~FontStyles.Underline; + + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; OnValueChanged(); } public void OnSmallCapsUpdate(bool state) { if (_ignoreUpdates) return; - - _style.SmallCaps = state; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + + if (state) + _style |= FontStyles.SmallCaps; + else + _style &= ~FontStyles.SmallCaps; + + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; OnValueChanged(); } public void OnVerticalUpdate(bool state) { if (_ignoreUpdates) return; - - _style.Vertical = state; + + _vertical = state; OnValueChanged(); } - private void Start() { + _lockString = $"ConformalDecals_TextEditor_{_lockCounter++}"; + _textBoxTMP = ((TMP_InputField) _textBox); _textBoxTMP.text = _text; - _textBoxTMP.textComponent.fontStyle = _style.FontStyle | _font.FontStyle & ~_font.FontStyleMask; + _textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask; _textBoxTMP.fontAsset = _font.FontAsset; + _textBoxTMP.onSelect.AddListener(SetControlLock); + _textBoxTMP.onDeselect.AddListener(RemoveControlLock); _font.SetupSample(_fontButton.GetComponentInChildren()); @@ -187,8 +226,12 @@ namespace ConformalDecals.UI { UpdateCharSpacing(); } + private void OnDestroy() { + RemoveControlLock(); + } + private void OnValueChanged() { - onValueChanged.Invoke(_text, _font, _style); + _onValueChanged(_text, _font, _style, _vertical, _lineSpacing, _charSpacing); } private void UpdateStyleButtons() { @@ -204,7 +247,7 @@ namespace ConformalDecals.UI { } else { _boldButton.interactable = true; - _boldButton.isOn = _style.Bold; + _boldButton.isOn = (_style & FontStyles.Bold) != 0; } if (_font.Italic) { @@ -217,7 +260,7 @@ namespace ConformalDecals.UI { } else { _italicButton.interactable = true; - _italicButton.isOn = _style.Italic; + _italicButton.isOn = (_style & FontStyles.Italic) != 0; } if (_font.Underline) { @@ -230,7 +273,7 @@ namespace ConformalDecals.UI { } else { _underlineButton.interactable = true; - _underlineButton.isOn = _style.Underline; + _underlineButton.isOn = (_style & FontStyles.Underline) != 0; } if (_font.SmallCaps) { @@ -243,10 +286,10 @@ namespace ConformalDecals.UI { } else { _smallCapsButton.interactable = true; - _smallCapsButton.isOn = _style.SmallCaps; + _smallCapsButton.isOn = (_style & FontStyles.SmallCaps) != 0; } - _verticalButton.isOn = _style.Vertical; + _verticalButton.isOn = _vertical; _ignoreUpdates = false; } @@ -254,8 +297,8 @@ namespace ConformalDecals.UI { private void UpdateLineSpacing() { _ignoreUpdates = true; - _lineSpacingSlider.value = Mathf.InverseLerp(_lineSpacingRange.x, _lineSpacingRange.y, _style.LineSpacing); - ((TMP_InputField) _lineSpacingTextBox).text = $"{_style.LineSpacing:F1}"; + _lineSpacingSlider.value = Mathf.InverseLerp(_lineSpacingRange.x, _lineSpacingRange.y, _lineSpacing); + ((TMP_InputField) _lineSpacingTextBox).text = $"{_lineSpacing:F1}"; _ignoreUpdates = false; } @@ -263,8 +306,8 @@ namespace ConformalDecals.UI { private void UpdateCharSpacing() { _ignoreUpdates = true; - _charSpacingSlider.value = Mathf.InverseLerp(_charSpacingRange.x, _charSpacingRange.y, _style.CharSpacing); - ((TMP_InputField) _charSpacingTextBox).text = $"{_style.CharSpacing:F1}"; + _charSpacingSlider.value = Mathf.InverseLerp(_charSpacingRange.x, _charSpacingRange.y, _charSpacing); + ((TMP_InputField) _charSpacingTextBox).text = $"{_charSpacing:F1}"; _ignoreUpdates = false; } diff --git a/Source/ConformalDecals/Util/ParseUtil.cs b/Source/ConformalDecals/Util/ParseUtil.cs index 1a883d1..71be8f5 100644 --- a/Source/ConformalDecals/Util/ParseUtil.cs +++ b/Source/ConformalDecals/Util/ParseUtil.cs @@ -31,9 +31,15 @@ namespace ConformalDecals.Util { } public static string ParseString(ConfigNode node, string valueName, bool isOptional = false, string defaultValue = "") { - if (!node.HasValue(valueName)) throw new FormatException($"Missing value for {valueName}"); + if (node.HasValue(valueName)) return node.GetValue(valueName); + + if (isOptional) { + return defaultValue; + } + else { + throw new FormatException($"Missing value for {valueName}"); + } - return node.GetValue(valueName); } public static bool ParseStringIndirect(ref string value, ConfigNode node, string valueName) { diff --git a/changelog.txt b/changelog.txt index 71c69d1..dbaba71 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,8 +1,44 @@ +v0.2.6 +------ +- Fixes: + - Fixed stock flags appearing stretched by forcing their aspect ratio to be correct. + - Another attempted fix for the planet text glitch. + +v0.2.5 +------ +- Fixes: + - Fixed line spacing, character spacing, and vertical settings not applying to symmetry counterparts + +v0.2.4 +------ +- Fixes: + - Fixed red text appearing on planets due to KSP bug by clearing render textures afterwards. + - Fixed fonts not saving correctly. +- Changes: + - Lowered step size for decal size and depth to 1cm. + - Changed default max size to 5m. + - Changed default text decal size to 0.2m + - Text decals now show as a circle if they contain only whitespace. + +v0.2.3 +------ +- Fixes: + - Fixed TMP subobjects being deleted, causing fallback fonts to fail in some situations. + - Started using URL-style encoding for text decals behind the scenes to prevent issues with certain characters. + - Fixed text decals having zero size when they had only whitespace or an empty string. + - Fixed decals having drag and causing issues when using FAR. + - Fixed broken saving of text decals in certain circumstances. + +v0.2.2 +------ +- Fixes: + - Fixed corrupted text rendering when a vessel loads during a scene change. + v0.2.1 ------ -- Changes +- Changes: - Pressing enter in the text entry window now types a newline. -- Fixes +- Fixes: - Renamed font assetbundle. The old extension was causing the game to try to load it twice on Windows due to legacy compatability features. - Fixed text rendering on DirectX resulting in black boxes by using ARGB32 instead of RG16 for the render texture in DirectX.