#nullable enable
namespace Terminal.Gui;
public partial class View // Text Property APIs
{
private string _text = string.Empty;
///
/// Called when the has changed. Fires the event.
///
public void OnTextChanged () { TextChanged?.Invoke (this, EventArgs.Empty); }
///
/// Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved
/// or not when is enabled.
/// If trailing spaces at the end of wrapped lines will be removed when
/// is formatted for display. The default is .
///
public bool PreserveTrailingSpaces
{
get => TextFormatter.PreserveTrailingSpaces;
set
{
if (TextFormatter.PreserveTrailingSpaces != value)
{
TextFormatter.PreserveTrailingSpaces = value;
TextFormatter.NeedsFormat = true;
SetLayoutNeeded ();
}
}
}
///
/// The text displayed by the .
///
///
///
/// The text will be drawn before any subviews are drawn.
///
///
/// The text will be drawn starting at the view origin (0, 0) and will be formatted according
/// to and .
///
///
/// The text will word-wrap to additional lines if it does not fit horizontally. If
/// 's height
/// is 1, the text will be clipped.
///
///
/// If or are using ,
/// the will be adjusted to fit the text.
///
/// When the text changes, the is fired.
///
public virtual string Text
{
get => _text;
set
{
if (_text == value)
{
return;
}
string old = _text;
_text = value;
UpdateTextFormatterText ();
SetLayoutNeeded ();
#if DEBUG
if (_text is { } && string.IsNullOrEmpty (Id))
{
Id = _text;
}
#endif
OnTextChanged ();
}
}
// TODO: Make this non-virtual. Nobody overrides it.
///
/// Gets or sets how the View's is aligned horizontally when drawn. Changing this property will
/// redisplay the .
///
///
///
/// or are using , the
/// will be adjusted to fit the text.
///
///
/// The text alignment.
public virtual Alignment TextAlignment
{
get => TextFormatter.Alignment;
set
{
TextFormatter.Alignment = value;
UpdateTextFormatterText ();
SetLayoutNeeded ();
}
}
///
/// Text changed event, raised when the text has changed.
///
public event EventHandler? TextChanged;
// TODO: Make this non-virtual. Nobody overrides it.
///
/// Gets or sets the direction of the View's . Changing this property will redisplay the
/// .
///
///
///
/// or are using , the
/// will be adjusted to fit the text.
///
///
/// The text direction.
public virtual TextDirection TextDirection
{
get => TextFormatter.Direction;
set => UpdateTextDirection (value);
}
///
/// Gets or sets the used to format .
///
public TextFormatter TextFormatter { get; init; } = new ();
// TODO: Make this non-virtual. Nobody overrides it.
///
/// Gets or sets how the View's is aligned vertically when drawn. Changing this property will
/// redisplay
/// the .
///
///
///
/// or are using , the
/// will be adjusted to fit the text.
///
///
/// The vertical text alignment.
public virtual Alignment VerticalTextAlignment
{
get => TextFormatter.VerticalAlignment;
set
{
TextFormatter.VerticalAlignment = value;
SetNeedsDisplay ();
}
}
// TODO: Add a OnUpdateTextFormatterText method that invokes UpdateTextFormatterText so that overrides don't have to call base.
///
/// Can be overridden if the has
/// different format than the default.
///
///
/// Overrides must call base.UpdateTextFormatterText before updating .
///
protected virtual void UpdateTextFormatterText ()
{
TextFormatter.Text = _text;
TextFormatter.ConstrainToWidth = null;
TextFormatter.ConstrainToHeight = null;
}
///
/// Internal API. Sets .Width/Height.
///
///
/// Use this API to set /Height when the view has changed such that the
/// size required to fit the text has changed.
/// changes.
///
///
internal void SetTextFormatterSize ()
{
// View subclasses can override UpdateTextFormatterText to modify the Text it holds (e.g. Checkbox and Button).
// We need to ensure TextFormatter is accurate by calling it here.
UpdateTextFormatterText ();
// Default is to use GetContentSize ().
Size? size = _contentSize;
// Use _width & _height instead of Width & Height to avoid debug spew
var widthAuto = _width as DimAuto;
var heightAuto = _height as DimAuto;
if (widthAuto is { } && widthAuto.Style.FastHasFlags (DimAutoStyle.Text))
{
TextFormatter.ConstrainToWidth = null;
}
else
{
if (size is { })
{
TextFormatter.ConstrainToWidth = size?.Width;
}
}
if (heightAuto is { } && heightAuto.Style.FastHasFlags (DimAutoStyle.Text))
{
TextFormatter.ConstrainToHeight = null;
}
else
{
if (size is { })
{
TextFormatter.ConstrainToHeight = size?.Height;
}
}
}
///
/// Initializes the Text of the View. Called by the constructor.
///
private void SetupText ()
{
Text = string.Empty;
TextDirection = TextDirection.LeftRight_TopBottom;
}
private void UpdateTextDirection (TextDirection newDirection)
{
bool directionChanged = TextFormatter.IsHorizontalDirection (TextFormatter.Direction) != TextFormatter.IsHorizontalDirection (newDirection);
TextFormatter.Direction = newDirection;
UpdateTextFormatterText ();
if (directionChanged)
{
TextFormatter.ConstrainToWidth = null;
TextFormatter.ConstrainToHeight = null;
SetLayoutNeeded ();
}
SetNeedsDisplay ();
}
}