KSP-Conformal-Decals/Source/ConformalDecals/ModuleConformalText.cs

314 lines
13 KiB
C#
Raw Normal View History

using System.Collections;
2020-11-13 09:42:55 +00:00
using System.Net;
2020-07-27 23:16:15 +00:00
using ConformalDecals.MaterialProperties;
2020-06-19 08:01:46 +00:00
using ConformalDecals.Text;
2020-07-13 03:27:19 +00:00
using ConformalDecals.UI;
2020-09-30 02:46:14 +00:00
using ConformalDecals.Util;
2020-07-27 02:32:58 +00:00
using TMPro;
using UnityEngine;
namespace ConformalDecals {
public class ModuleConformalText : ModuleConformalDecal {
2020-09-27 02:33:12 +00:00
[KSPField] public Vector2 lineSpacingRange = new Vector2(-50, 50);
[KSPField] public Vector2 charSpacingRange = new Vector2(-50, 50);
2020-08-22 06:45:10 +00:00
[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;
2020-07-27 02:32:58 +00:00
// 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, vertical, lineSpacing, charSpacing, lineSpacingRange, charSpacingRange, OnTextUpdate);
2020-07-27 02:32:58 +00:00
}
else {
2020-08-22 06:45:10 +00:00
_textEntryController.Close();
}
2020-07-27 02:32:58 +00:00
}
// FILL
[KSPField(guiName = "#LOC_ConformalDecals_gui-fill", groupName = "decal-fill", groupDisplayName = "#LOC_ConformalDecals_gui-group-fill",
guiActive = false, guiActiveEditor = true, isPersistant = true),
UI_Toggle()]
public bool fillEnabled = true;
2020-09-26 07:02:34 +00:00
[KSPEvent(guiName = "#LOC_ConformalDecals_gui-set-fill-color", groupName = "decal-fill", groupDisplayName = "#LOC_ConformalDecals_gui-group-fill",
2020-07-27 02:32:58 +00:00
guiActive = false, guiActiveEditor = true)]
public void SetFillColor() {
if (_fillColorPickerController == null) {
_fillColorPickerController = ColorPickerController.Create(fillColor, OnFillColorUpdate);
2020-07-27 02:32:58 +00:00
}
else {
2020-08-22 06:45:10 +00:00
_fillColorPickerController.Close();
}
2020-07-27 02:32:58 +00:00
}
// OUTLINE
[KSPField(guiName = "#LOC_ConformalDecals_gui-outline", groupName = "decal-outline", groupDisplayName = "#LOC_ConformalDecals_gui-group-outline",
guiActive = false, guiActiveEditor = true, isPersistant = true),
UI_Toggle()]
public bool outlineEnabled;
[KSPField(guiName = "#LOC_ConformalDecals_gui-outline-width", groupName = "decal-outline", groupDisplayName = "#LOC_ConformalDecals_gui-group-outline",
guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F2"),
UI_FloatRange(stepIncrement = 0.05f)]
public float outlineWidth = 0.1f;
[KSPEvent(guiName = "#LOC_ConformalDecals_gui-set-outline-color", groupName = "decal-outline", groupDisplayName = "#LOC_ConformalDecals_gui-group-outline",
guiActive = false, guiActiveEditor = true)]
public void SetOutlineColor() {
if (_outlineColorPickerController == null) {
_outlineColorPickerController = ColorPickerController.Create(outlineColor, OnOutlineColorUpdate);
}
else {
2020-08-22 06:45:10 +00:00
_outlineColorPickerController.Close();
2020-07-27 02:32:58 +00:00
}
}
2020-07-27 02:32:58 +00:00
2020-07-23 05:37:16 +00:00
private TextEntryController _textEntryController;
private ColorPickerController _fillColorPickerController;
private ColorPickerController _outlineColorPickerController;
private MaterialTextureProperty _decalTextureProperty;
private MaterialKeywordProperty _fillEnabledProperty;
private MaterialColorProperty _fillColorProperty;
private MaterialKeywordProperty _outlineEnabledProperty;
private MaterialColorProperty _outlineColorProperty;
private MaterialFloatProperty _outlineWidthProperty;
2020-07-27 23:16:15 +00:00
private DecalText _currentText;
2020-07-27 02:32:58 +00:00
public override void OnLoad(ConfigNode node) {
base.OnLoad(node);
2020-11-16 22:44:07 +00:00
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");
2020-11-16 22:44:07 +00:00
int styleInt = 0;
2020-11-16 22:44:07 +00:00
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 {
UpdateText();
}
2020-07-27 02:32:58 +00:00
}
public override void OnSave(ConfigNode node) {
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());
2020-07-27 02:32:58 +00:00
base.OnSave(node);
}
public override void OnAwake() {
base.OnAwake();
_decalTextureProperty = materialProperties.AddOrGetTextureProperty("_Decal", true);
_fillEnabledProperty = materialProperties.AddOrGetProperty<MaterialKeywordProperty>("DECAL_FILL");
_fillColorProperty = materialProperties.AddOrGetProperty<MaterialColorProperty>("_DecalColor");
_outlineEnabledProperty = materialProperties.AddOrGetProperty<MaterialKeywordProperty>("DECAL_OUTLINE");
_outlineColorProperty = materialProperties.AddOrGetProperty<MaterialColorProperty>("_OutlineColor");
_outlineWidthProperty = materialProperties.AddOrGetProperty<MaterialFloatProperty>("_OutlineWidth");
}
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;
2022-03-06 08:01:23 +00:00
UpdateText(true);
}
2020-07-23 05:37:16 +00:00
public void OnFillColorUpdate(Color rgb, Util.ColorHSV hsv) {
fillColor = rgb;
UpdateMaterials();
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.fillColor = fillColor;
decal.UpdateMaterials();
}
2020-07-23 05:37:16 +00:00
}
public void OnOutlineColorUpdate(Color rgb, Util.ColorHSV hsv) {
outlineColor = rgb;
UpdateMaterials();
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.outlineColor = outlineColor;
decal.UpdateMaterials();
}
2020-07-23 05:37:16 +00:00
}
public void OnFillToggle(BaseField field, object obj) {
// fill and outline cant both be disabled
outlineEnabled = outlineEnabled || (!outlineEnabled && !fillEnabled);
UpdateTweakables();
2020-09-26 07:02:34 +00:00
UpdateMaterials();
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.fillEnabled = fillEnabled;
decal.outlineEnabled = outlineEnabled;
decal.UpdateTweakables();
2020-09-26 07:02:34 +00:00
decal.UpdateMaterials();
}
}
2020-07-23 05:37:16 +00:00
public void OnOutlineToggle(BaseField field, object obj) {
// fill and outline cant both be disabled
fillEnabled = fillEnabled || (!fillEnabled && !outlineEnabled);
UpdateTweakables();
2020-09-26 07:02:34 +00:00
UpdateMaterials();
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.fillEnabled = fillEnabled;
decal.outlineEnabled = outlineEnabled;
decal.UpdateTweakables();
2020-09-26 07:02:34 +00:00
decal.UpdateMaterials();
}
}
public void OnOutlineWidthUpdate(BaseField field, object obj) {
UpdateMaterials();
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.outlineWidth = outlineWidth;
decal.UpdateMaterials();
2020-07-23 05:37:16 +00:00
}
}
public override void OnDestroy() {
2020-09-26 07:02:34 +00:00
if (HighLogic.LoadedSceneIsGame && _currentText != null) TextRenderer.UnregisterText(_currentText);
2020-11-16 22:44:07 +00:00
// close all UIs
if (_textEntryController != null) _textEntryController.Close();
if (_fillColorPickerController != null) _fillColorPickerController.Close();
if (_outlineColorPickerController != null) _outlineColorPickerController.Close();
2022-10-31 04:03:27 +00:00
base.OnDestroy();
2020-07-27 23:16:15 +00:00
}
protected override void OnDetach() {
// close all UIs
2020-08-22 06:44:58 +00:00
if (_textEntryController != null) _textEntryController.Close();
if (_fillColorPickerController != null) _fillColorPickerController.Close();
if (_outlineColorPickerController != null) _outlineColorPickerController.Close();
base.OnDetach();
}
private IEnumerator UpdateTextLate() {
yield return null;
UpdateText();
}
2022-03-06 08:01:23 +00:00
private void UpdateText(bool recursive = false) {
2020-07-27 23:16:15 +00:00
// Render text
var newText = new DecalText(text, font, style, vertical, lineSpacing, charSpacing);
var output = TextRenderer.UpdateText(_currentText, newText);
2022-03-06 08:01:23 +00:00
// update the _currentText state variable
// this is the ONLY place this variable should be set! otherwise the current state is lost
2020-07-27 23:16:15 +00:00
_currentText = newText;
2022-03-06 08:01:23 +00:00
// Update the texture with the new rendered output
2020-07-27 23:16:15 +00:00
UpdateTexture(output);
2022-03-06 08:01:23 +00:00
// If recursive, copy parameters to other parts and perform the same operation
if (recursive) {
foreach (var counterpart in part.symmetryCounterparts) {
var decal = counterpart.GetComponent<ModuleConformalText>();
decal.text = text;
decal.font = font;
decal.style = style;
decal.vertical = vertical;
decal.charSpacing = charSpacing;
decal.lineSpacing = lineSpacing;
decal.UpdateText();
}
}
2020-07-27 23:16:15 +00:00
}
public void UpdateTexture(TextRenderOutput output) {
_decalTextureProperty.Texture = output.Texture;
_decalTextureProperty.SetTile(output.Window);
2020-07-27 23:16:15 +00:00
UpdateMaterials();
UpdateScale();
2020-07-27 23:16:15 +00:00
}
protected override void UpdateMaterials() {
_fillEnabledProperty.value = fillEnabled;
_fillColorProperty.color = fillColor;
2020-07-27 23:16:15 +00:00
_outlineEnabledProperty.value = outlineEnabled;
_outlineColorProperty.color = outlineColor;
_outlineWidthProperty.value = outlineWidth;
2020-07-27 23:16:15 +00:00
base.UpdateMaterials();
}
protected override void UpdateTweakables() {
var fillEnabledField = Fields[nameof(fillEnabled)];
var fillColorEvent = Events["SetFillColor"];
var outlineEnabledField = Fields[nameof(outlineEnabled)];
var outlineWidthField = Fields[nameof(outlineWidth)];
var outlineColorEvent = Events["SetOutlineColor"];
fillColorEvent.guiActiveEditor = fillEnabled;
outlineWidthField.guiActiveEditor = outlineEnabled;
outlineColorEvent.guiActiveEditor = outlineEnabled;
((UI_Toggle) fillEnabledField.uiControlEditor).onFieldChanged = OnFillToggle;
((UI_Toggle) outlineEnabledField.uiControlEditor).onFieldChanged = OnOutlineToggle;
((UI_FloatRange) outlineWidthField.uiControlEditor).onFieldChanged = OnOutlineWidthUpdate;
base.UpdateTweakables();
}
}
}