KSP-Conformal-Decals/Source/ConformalDecals/UI/TextEntryController.cs

317 lines
11 KiB
C#
Raw Normal View History

2020-07-21 07:07:18 +00:00
using System;
2020-07-16 01:12:50 +00:00
using ConformalDecals.Text;
2020-09-28 08:02:17 +00:00
using ConformalDecals.Util;
2020-07-16 01:12:50 +00:00
using TMPro;
2020-07-13 05:38:37 +00:00
using UnityEngine;
2020-07-16 01:12:50 +00:00
using UnityEngine.UI;
2020-07-13 05:38:37 +00:00
namespace ConformalDecals.UI {
public class TextEntryController : MonoBehaviour {
2020-07-21 07:07:18 +00:00
[Serializable]
public delegate void TextUpdateDelegate(string newText, DecalFont newFont, FontStyles style, bool vertical, float linespacing, float charspacing);
2020-07-20 04:12:48 +00:00
2020-07-16 01:12:50 +00:00
[SerializeField] private Selectable _textBox;
2020-07-20 04:12:48 +00:00
[SerializeField] private Button _fontButton;
2020-07-16 01:12:50 +00:00
2020-08-22 06:45:10 +00:00
[SerializeField] private Slider _lineSpacingSlider;
[SerializeField] private Selectable _lineSpacingTextBox;
[SerializeField] private Slider _charSpacingSlider;
[SerializeField] private Selectable _charSpacingTextBox;
2020-07-16 01:12:50 +00:00
[SerializeField] private Toggle _boldButton;
[SerializeField] private Toggle _italicButton;
[SerializeField] private Toggle _underlineButton;
[SerializeField] private Toggle _smallCapsButton;
[SerializeField] private Toggle _verticalButton;
2020-07-24 21:39:35 +00:00
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 FontMenuController _fontMenu;
private TextUpdateDelegate _onValueChanged;
2020-07-24 21:39:35 +00:00
private static int _lockCounter;
2020-07-16 01:12:50 +00:00
2020-11-16 23:34:10 +00:00
private bool _isLocked;
private string _lockString;
private bool _ignoreUpdates;
private bool _textUpdated;
2020-07-27 02:30:19 +00:00
2020-08-22 06:45:10 +00:00
public static TextEntryController Create(
string text, DecalFont font, FontStyles style, bool vertical, float linespacing, float charspacing,
2020-08-22 06:45:10 +00:00
Vector2 lineSpacingRange, Vector2 charSpacingRange,
TextUpdateDelegate textUpdateCallback) {
2020-07-24 21:39:35 +00:00
2020-07-20 04:12:48 +00:00
var window = Instantiate(UILoader.TextEntryPrefab, MainCanvasUtil.MainCanvas.transform, true);
window.AddComponent<DragPanel>();
MenuNavigation.SpawnMenuNavigation(window, Navigation.Mode.Automatic, true);
2020-07-16 01:12:50 +00:00
2020-07-20 04:12:48 +00:00
var controller = window.GetComponent<TextEntryController>();
2020-07-24 21:39:35 +00:00
controller._text = text;
controller._font = font;
controller._style = style;
controller._vertical = vertical;
controller._lineSpacing = linespacing;
controller._charSpacing = charspacing;
2020-08-22 06:45:10 +00:00
controller._lineSpacingRange = lineSpacingRange;
controller._charSpacingRange = charSpacingRange;
controller._onValueChanged = textUpdateCallback;
2020-07-16 01:12:50 +00:00
2020-07-20 04:12:48 +00:00
return controller;
}
2020-07-16 01:12:50 +00:00
2020-08-22 06:45:10 +00:00
public void Close() {
if (_fontMenu != null) _fontMenu.Close();
2020-07-16 01:12:50 +00:00
Destroy(gameObject);
}
2020-11-16 23:34:10 +00:00
public void SetControlLock(string value = null) {
if (_isLocked) return;
InputLockManager.SetControlLock(ControlTypes.EDITOR_UI, _lockString);
2020-11-16 23:34:10 +00:00
_isLocked = true;
}
public void RemoveControlLock(string value = null) {
if (!_isLocked) return;
InputLockManager.RemoveControlLock(_lockString);
_isLocked = false;
}
2020-07-20 04:12:48 +00:00
public void OnTextUpdate(string newText) {
2020-07-24 21:39:35 +00:00
this._text = newText;
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
2020-07-20 04:12:48 +00:00
public void OnFontMenu() {
2020-07-24 21:39:35 +00:00
if (_fontMenu == null) _fontMenu = FontMenuController.Create(DecalConfig.Fonts, _font, OnFontUpdate);
2020-07-20 04:12:48 +00:00
}
public void OnFontUpdate(DecalFont font) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
2020-07-24 21:39:35 +00:00
_font = font;
2020-07-20 04:12:48 +00:00
font.SetupSample(_fontButton.GetComponentInChildren<TextMeshProUGUI>());
2020-09-30 06:34:47 +00:00
_textBoxTMP.text = _text;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
2020-09-30 06:34:47 +00:00
_textBoxTMP.fontAsset = _font.FontAsset;
2020-07-16 01:12:50 +00:00
UpdateStyleButtons();
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
2020-08-22 06:45:10 +00:00
public void OnLineSpacingUpdate(float value) {
if (_ignoreUpdates) return;
_lineSpacing = Mathf.Lerp(_lineSpacingRange.x, _lineSpacingRange.y, value);
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
UpdateLineSpacing();
_textUpdated = true;
2020-08-22 06:45:10 +00:00
}
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
public void OnLineSpacingUpdate(string text) {
if (_ignoreUpdates) return;
if (float.TryParse(text, out var value)) {
_lineSpacing = Mathf.Clamp(value, _lineSpacingRange.x, _lineSpacingRange.y);
2020-08-22 06:45:10 +00:00
}
else {
2020-09-28 08:02:17 +00:00
Logging.LogWarning("Line spacing value '{text}' could not be parsed.");
2020-08-22 06:45:10 +00:00
}
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
UpdateLineSpacing();
_textUpdated = true;
2020-08-22 06:45:10 +00:00
}
public void OnCharSpacingUpdate(float value) {
if (_ignoreUpdates) return;
_charSpacing = Mathf.Lerp(_charSpacingRange.x, _charSpacingRange.y, value);
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
UpdateCharSpacing();
_textUpdated = true;
2020-08-22 06:45:10 +00:00
}
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
public void OnCharSpacingUpdate(string text) {
if (_ignoreUpdates) return;
if (float.TryParse(text, out var value)) {
_charSpacing = Mathf.Clamp(value, _charSpacingRange.x, _charSpacingRange.y);
2020-08-22 06:45:10 +00:00
}
else {
2020-09-28 08:02:17 +00:00
Logging.LogWarning("Char spacing value '{text}' could not be parsed.");
2020-08-22 06:45:10 +00:00
}
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
UpdateCharSpacing();
_textUpdated = true;
2020-08-22 06:45:10 +00:00
}
2020-07-16 01:12:50 +00:00
public void OnBoldUpdate(bool state) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
2020-07-16 01:12:50 +00:00
if (state)
_style |= FontStyles.Bold;
else
_style &= ~FontStyles.Bold;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
public void OnItalicUpdate(bool state) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
if (state)
_style |= FontStyles.Italic;
else
_style &= ~FontStyles.Italic;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
public void OnUnderlineUpdate(bool state) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
if (state)
_style |= FontStyles.Underline;
else
_style &= ~FontStyles.Underline;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
public void OnSmallCapsUpdate(bool state) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
if (state)
_style |= FontStyles.SmallCaps;
else
_style &= ~FontStyles.SmallCaps;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
_textUpdated = true;
2020-07-16 01:12:50 +00:00
}
public void OnVerticalUpdate(bool state) {
2020-07-27 02:30:19 +00:00
if (_ignoreUpdates) return;
_vertical = state;
_textUpdated = true;
2020-07-13 05:38:37 +00:00
}
2020-07-27 02:30:19 +00:00
private void Start() {
2020-11-16 23:34:10 +00:00
_lockString = $"ConformalDecals_TextEditor_{_lockCounter++}";
2020-09-30 06:34:47 +00:00
_textBoxTMP = ((TMP_InputField) _textBox);
_textBoxTMP.text = _text;
_textBoxTMP.textComponent.fontStyle = _style | _font.FontStyle & ~_font.FontStyleMask;
2020-09-30 06:34:47 +00:00
_textBoxTMP.fontAsset = _font.FontAsset;
2020-11-16 23:34:10 +00:00
_textBoxTMP.onSelect.AddListener(SetControlLock);
_textBoxTMP.onDeselect.AddListener(RemoveControlLock);
_font.SetupSample(_fontButton.GetComponentInChildren<TextMeshProUGUI>());
UpdateStyleButtons();
2020-08-22 06:45:10 +00:00
UpdateLineSpacing();
UpdateCharSpacing();
}
2020-11-16 23:34:10 +00:00
private void OnDestroy() {
RemoveControlLock();
}
private void LateUpdate() {
if (_textUpdated) {
_onValueChanged(_text, _font, _style, _vertical, _lineSpacing, _charSpacing);
_textUpdated = false;
}
}
private void UpdateStyleButtons() {
2020-07-27 02:30:19 +00:00
_ignoreUpdates = true;
if (_font.Bold) {
_boldButton.interactable = false;
_boldButton.isOn = true;
}
else if (_font.BoldMask) {
_boldButton.interactable = false;
_boldButton.isOn = false;
}
else {
_boldButton.interactable = true;
_boldButton.isOn = (_style & FontStyles.Bold) != 0;
2020-07-27 02:30:19 +00:00
}
if (_font.Italic) {
_italicButton.interactable = false;
_italicButton.isOn = true;
}
else if (_font.ItalicMask) {
_italicButton.interactable = false;
_italicButton.isOn = false;
}
else {
_italicButton.interactable = true;
_italicButton.isOn = (_style & FontStyles.Italic) != 0;
2020-07-27 02:30:19 +00:00
}
if (_font.Underline) {
_underlineButton.interactable = false;
_underlineButton.isOn = true;
}
else if (_font.UnderlineMask) {
_underlineButton.interactable = false;
_underlineButton.isOn = false;
}
else {
_underlineButton.interactable = true;
_underlineButton.isOn = (_style & FontStyles.Underline) != 0;
2020-07-27 02:30:19 +00:00
}
if (_font.SmallCaps) {
_smallCapsButton.interactable = false;
_smallCapsButton.isOn = true;
}
else if (_font.SmallCapsMask) {
_smallCapsButton.interactable = false;
_smallCapsButton.isOn = false;
}
else {
_smallCapsButton.interactable = true;
_smallCapsButton.isOn = (_style & FontStyles.SmallCaps) != 0;
2020-07-27 02:30:19 +00:00
}
_verticalButton.isOn = _vertical;
2020-07-27 02:30:19 +00:00
_ignoreUpdates = false;
}
2020-08-22 06:45:10 +00:00
private void UpdateLineSpacing() {
_ignoreUpdates = true;
2020-09-30 06:34:47 +00:00
_lineSpacingSlider.value = Mathf.InverseLerp(_lineSpacingRange.x, _lineSpacingRange.y, _lineSpacing);
((TMP_InputField) _lineSpacingTextBox).text = $"{_lineSpacing:F1}";
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
_ignoreUpdates = false;
}
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
private void UpdateCharSpacing() {
_ignoreUpdates = true;
2020-09-30 06:34:47 +00:00
_charSpacingSlider.value = Mathf.InverseLerp(_charSpacingRange.x, _charSpacingRange.y, _charSpacing);
((TMP_InputField) _charSpacingTextBox).text = $"{_charSpacing:F1}";
2020-09-30 06:34:47 +00:00
2020-08-22 06:45:10 +00:00
_ignoreUpdates = false;
}
2020-07-13 05:38:37 +00:00
}
}