From dbbc621181df143541691ad496e3b1eff5b1e716 Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Sat, 14 Nov 2020 21:11:16 -0800 Subject: [PATCH] Fix text decal saving and loading Closes #25 --- .../Plugins/ConformalDecals.dll | Bin 83968 -> 82432 bytes Source/ConformalDecals/ConformalDecals.csproj | 1 - Source/ConformalDecals/ModuleConformalText.cs | 103 +++++++----------- Source/ConformalDecals/Text/DecalFont.cs | 46 +++++--- Source/ConformalDecals/Text/DecalText.cs | 49 +++++++-- Source/ConformalDecals/Text/DecalTextStyle.cs | 101 ----------------- Source/ConformalDecals/Text/TextRenderer.cs | 6 +- .../ConformalDecals/UI/TextEntryController.cs | 98 ++++++++++------- Source/ConformalDecals/Util/ParseUtil.cs | 10 +- 9 files changed, 177 insertions(+), 237 deletions(-) delete mode 100644 Source/ConformalDecals/Text/DecalTextStyle.cs diff --git a/GameData/ConformalDecals/Plugins/ConformalDecals.dll b/GameData/ConformalDecals/Plugins/ConformalDecals.dll index 33734ea0ab608d75585b42c6c334aac40183206a..dad1a8ec0c213d725489578812e176e915567bb6 100644 GIT binary patch literal 82432 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 - diff --git a/Source/ConformalDecals/ModuleConformalText.cs b/Source/ConformalDecals/ModuleConformalText.cs index 03a3cb2..f6bf14a 100644 --- a/Source/ConformalDecals/ModuleConformalText.cs +++ b/Source/ConformalDecals/ModuleConformalText.cs @@ -8,27 +8,26 @@ using TMPro; 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(); @@ -46,7 +45,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(); @@ -69,18 +68,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 string _text; - private DecalTextStyle _style; - private DecalFont _font; - private Color32 _fillColor; - private Color32 _outlineColor; private TextEntryController _textEntryController; private ColorPickerController _fillColorPickerController; @@ -100,7 +94,12 @@ namespace ConformalDecals { public override void OnLoad(ConfigNode node) { base.OnLoad(node); - OnAfterDeserialize(); + text = WebUtility.UrlDecode(ParseUtil.ParseString(node, "text")); + font = DecalConfig.GetFont(ParseUtil.ParseString(node, "font", true, "Calibri SDF")); + int styleInt = 0; + if (ParseUtil.ParseIntIndirect(ref styleInt, node, "style")) style = (FontStyles) styleInt; + if (!ParseUtil.ParseColor32Indirect(ref fillColor, node, "fillColor")) fillColor = Color.magenta; + if (!ParseUtil.ParseColor32Indirect(ref outlineColor, node, "outlineColor")) outlineColor = Color.magenta; if (HighLogic.LoadedSceneIsGame) { // For some reason, rendering doesnt work right on the first frame a scene is loaded @@ -114,7 +113,11 @@ namespace ConformalDecals { } 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); } @@ -131,31 +134,34 @@ namespace ConformalDecals { _outlineWidthProperty = materialProperties.AddOrGetProperty("_OutlineWidth"); } - public void OnTextUpdate(string newText, DecalFont newFont, DecalTextStyle newStyle) { - _text = newText; - _font = newFont; - _style = newStyle; + public void OnTextUpdate(string newText, DecalFont newFont, FontStyles newStyle, bool newVertical, float newLineSpacing, float newCharSpacing) { + this.text = newText; + this.font = newFont; + this.style = newStyle; + this.vertical = newVertical; + this.lineSpacing = newLineSpacing; + this.charSpacing = newCharSpacing; UpdateTextRecursive(); } 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(); } } @@ -202,33 +208,6 @@ namespace ConformalDecals { } } - public void OnBeforeSerialize() { - text = WebUtility.UrlEncode(_text); - 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() { - _text = WebUtility.UrlDecode(text); - _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; - } - } - public override void OnDestroy() { if (HighLogic.LoadedSceneIsGame && _currentText != null) TextRenderer.UnregisterText(_currentText); @@ -249,9 +228,9 @@ namespace ConformalDecals { foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); - decal._text = _text; - decal._font = _font; - decal._style = _style; + decal.text = text; + decal.font = font; + decal.style = style; decal._currentJob = _currentJob; decal._currentText = _currentText; @@ -266,7 +245,7 @@ namespace ConformalDecals { private void UpdateText() { // 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; @@ -288,10 +267,10 @@ namespace ConformalDecals { 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/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..4de8081 100644 --- a/Source/ConformalDecals/Text/DecalText.cs +++ b/Source/ConformalDecals/Text/DecalText.cs @@ -1,21 +1,38 @@ 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 (Vertical) { return Regex.Replace(Text, @"(.)", "$1\n"); } else { @@ -24,17 +41,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 +68,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 8d210f1..5176c15 100644 --- a/Source/ConformalDecals/Text/TextRenderer.cs +++ b/Source/ConformalDecals/Text/TextRenderer.cs @@ -163,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; diff --git a/Source/ConformalDecals/UI/TextEntryController.cs b/Source/ConformalDecals/UI/TextEntryController.cs index 40d047d..aded7bf 100644 --- a/Source/ConformalDecals/UI/TextEntryController.cs +++ b/Source/ConformalDecals/UI/TextEntryController.cs @@ -9,9 +9,8 @@ using UnityEngine.UI; namespace ConformalDecals.UI { public class TextEntryController : MonoBehaviour { [Serializable] - public class TextUpdateEvent : UnityEvent { } + public delegate void TextUpdateDelegate(string newText, DecalFont newFont, FontStyles style, bool vertical, float linespacing, float charspacing); - [SerializeField] public TextUpdateEvent onValueChanged = new TextUpdateEvent(); [SerializeField] private Selectable _textBox; [SerializeField] private Button _fontButton; @@ -28,21 +27,25 @@ 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; 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 +55,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; } @@ -81,7 +87,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 +97,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 +107,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 +120,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 +130,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,39 +143,55 @@ 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(); } @@ -177,7 +199,7 @@ namespace ConformalDecals.UI { private void Start() { _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; _font.SetupSample(_fontButton.GetComponentInChildren()); @@ -188,7 +210,7 @@ namespace ConformalDecals.UI { } private void OnValueChanged() { - onValueChanged.Invoke(_text, _font, _style); + _onValueChanged(_text, _font, _style, _vertical, _lineSpacing, _charSpacing); } private void UpdateStyleButtons() { @@ -204,7 +226,7 @@ namespace ConformalDecals.UI { } else { _boldButton.interactable = true; - _boldButton.isOn = _style.Bold; + _boldButton.isOn = (_style & FontStyles.Bold) != 0; } if (_font.Italic) { @@ -217,7 +239,7 @@ namespace ConformalDecals.UI { } else { _italicButton.interactable = true; - _italicButton.isOn = _style.Italic; + _italicButton.isOn = (_style & FontStyles.Italic) != 0; } if (_font.Underline) { @@ -230,7 +252,7 @@ namespace ConformalDecals.UI { } else { _underlineButton.interactable = true; - _underlineButton.isOn = _style.Underline; + _underlineButton.isOn = (_style & FontStyles.Underline) != 0; } if (_font.SmallCaps) { @@ -243,10 +265,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 +276,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 +285,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 5a712c7..d600bf5 100644 --- a/Source/ConformalDecals/Util/ParseUtil.cs +++ b/Source/ConformalDecals/Util/ParseUtil.cs @@ -30,9 +30,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) {