All working but codex.
This commit is contained in:
144
Assets/Scripts/UI/Menus/Components/ScrollableTextBox.cs
Normal file
144
Assets/Scripts/UI/Menus/Components/ScrollableTextBox.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.UI.Components
|
||||
{
|
||||
[ExecuteAlways]
|
||||
public class ScrollableTextBox : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TextMeshProUGUI _text;
|
||||
[SerializeField] private RectTransform _content;
|
||||
[SerializeField] private BriarQueen.UI.Menus.VerticalScrollbar _scrollbar;
|
||||
|
||||
private RectTransform _textRect;
|
||||
private LayoutElement _layoutElement;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (this == null) return;
|
||||
Init();
|
||||
if (_text != null && !string.IsNullOrEmpty(_text.text))
|
||||
ApplyTextHeight();
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (_text != null)
|
||||
{
|
||||
_textRect = _text.GetComponent<RectTransform>();
|
||||
_layoutElement = _text.GetComponent<LayoutElement>();
|
||||
|
||||
if (_layoutElement == null)
|
||||
_layoutElement = _text.gameObject.AddComponent<LayoutElement>();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyTextHeight()
|
||||
{
|
||||
_text.ForceMeshUpdate();
|
||||
var height = _text.preferredHeight;
|
||||
|
||||
if (_layoutElement != null)
|
||||
_layoutElement.preferredHeight = height;
|
||||
|
||||
if (_textRect != null)
|
||||
{
|
||||
var delta = _textRect.sizeDelta;
|
||||
delta.y = height;
|
||||
_textRect.sizeDelta = delta;
|
||||
}
|
||||
|
||||
if (_content != null)
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(_content);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetText(string content)
|
||||
{
|
||||
if (_text == null) return;
|
||||
|
||||
_text.text = content;
|
||||
_text.ForceMeshUpdate();
|
||||
|
||||
var height = _text.preferredHeight;
|
||||
|
||||
if (_layoutElement != null)
|
||||
_layoutElement.preferredHeight = height;
|
||||
|
||||
if (_textRect != null)
|
||||
{
|
||||
var delta = _textRect.sizeDelta;
|
||||
delta.y = height;
|
||||
_textRect.sizeDelta = delta;
|
||||
}
|
||||
|
||||
// Also resize Content to match so scrollbar measures correctly
|
||||
if (_content != null)
|
||||
{
|
||||
var delta = _content.sizeDelta;
|
||||
delta.y = height;
|
||||
_content.sizeDelta = delta;
|
||||
|
||||
var pos = _content.anchoredPosition;
|
||||
pos.y = 0f;
|
||||
_content.anchoredPosition = pos;
|
||||
}
|
||||
|
||||
if (Application.isPlaying)
|
||||
StartCoroutine(RebuildNextFrame());
|
||||
else
|
||||
_scrollbar?.Rebuild();
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator RebuildNextFrame()
|
||||
{
|
||||
yield return null;
|
||||
Canvas.ForceUpdateCanvases();
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(_content);
|
||||
yield return null;
|
||||
_scrollbar?.Rebuild();
|
||||
_scrollbar?.SetNormalized(1f);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_text == null) return;
|
||||
_text.text = string.Empty;
|
||||
|
||||
if (_layoutElement != null)
|
||||
_layoutElement.preferredHeight = 0f;
|
||||
|
||||
if (_textRect != null)
|
||||
{
|
||||
var sd = _textRect.sizeDelta;
|
||||
sd.y = 0f;
|
||||
_textRect.sizeDelta = sd;
|
||||
}
|
||||
|
||||
if (_content != null)
|
||||
{
|
||||
var pos = _content.anchoredPosition;
|
||||
pos.y = 0f;
|
||||
_content.anchoredPosition = pos;
|
||||
}
|
||||
|
||||
_scrollbar?.Rebuild();
|
||||
}
|
||||
|
||||
public void ScrollToTop() => _scrollbar?.SetNormalized(1f);
|
||||
public void ScrollToBottom() => _scrollbar?.SetNormalized(0f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3727dc2fa2f418f82fcfae0993856cb
|
||||
timeCreated: 1778584851
|
||||
@@ -15,11 +15,17 @@ namespace BriarQueen.UI.Menus.Components
|
||||
IDeselectHandler
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private TextMeshProUGUI _label;
|
||||
[SerializeField] protected TextMeshProUGUI _label;
|
||||
|
||||
private Button _button;
|
||||
private UnderlineButtonGroup _group;
|
||||
private bool _isHovered;
|
||||
[SerializeField]
|
||||
protected TextMeshProUGUI _contextLabel;
|
||||
|
||||
[SerializeField]
|
||||
protected string _contextText;
|
||||
|
||||
protected Button _button;
|
||||
protected UnderlineButtonGroup _group;
|
||||
protected bool _isHovered;
|
||||
|
||||
public event Action<UnderlineButton> SelectionRequested;
|
||||
public event Action<UnderlineButton> HoverEntered;
|
||||
@@ -29,14 +35,15 @@ namespace BriarQueen.UI.Menus.Components
|
||||
|
||||
// True when this button is registered with a group
|
||||
public bool IsGrouped => _group != null;
|
||||
|
||||
|
||||
private void Awake()
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_button = GetComponent<Button>();
|
||||
SetUnderline(false);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
_isHovered = false;
|
||||
SetUnderline(false);
|
||||
@@ -68,6 +75,8 @@ namespace BriarQueen.UI.Menus.Components
|
||||
HoverEntered?.Invoke(this);
|
||||
else
|
||||
RefreshStandaloneState();
|
||||
|
||||
UpdateContextText();
|
||||
}
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
@@ -78,10 +87,13 @@ namespace BriarQueen.UI.Menus.Components
|
||||
HoverExited?.Invoke(this);
|
||||
else
|
||||
RefreshStandaloneState();
|
||||
|
||||
UpdateContextText();
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
Debug.Log($"[UnderlineButton] OnPointerClick {gameObject.name}");
|
||||
if (_button != null && !_button.interactable) return;
|
||||
SelectionRequested?.Invoke(this);
|
||||
}
|
||||
@@ -102,6 +114,8 @@ namespace BriarQueen.UI.Menus.Components
|
||||
IsSelected = true;
|
||||
RefreshStandaloneState();
|
||||
}
|
||||
|
||||
UpdateContextText();
|
||||
}
|
||||
|
||||
public void OnDeselect(BaseEventData eventData)
|
||||
@@ -115,6 +129,8 @@ namespace BriarQueen.UI.Menus.Components
|
||||
IsSelected = false;
|
||||
RefreshStandaloneState();
|
||||
}
|
||||
|
||||
UpdateContextText();
|
||||
}
|
||||
|
||||
// ── Public API ────────────────────────────────────────────────
|
||||
@@ -154,5 +170,16 @@ namespace BriarQueen.UI.Menus.Components
|
||||
|
||||
SetUnderline(IsSelected || _isHovered);
|
||||
}
|
||||
|
||||
private void UpdateContextText()
|
||||
{
|
||||
if (_contextLabel == null)
|
||||
return;
|
||||
|
||||
if(IsSelected || _isHovered)
|
||||
_contextLabel.text = _contextText;
|
||||
else
|
||||
_contextLabel.text = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user