| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- // Copyright (c) The Avalonia Project. All rights reserved.
- // Licensed under the MIT license. See licence.md file in the project root for full license information.
- using System;
- using System.Reactive;
- using System.Reactive.Linq;
- using Avalonia.Data;
- using Avalonia.LogicalTree;
- using Avalonia.Media;
- using Avalonia.Metadata;
- namespace Avalonia.Controls
- {
- /// <summary>
- /// A control that displays a block of text.
- /// </summary>
- public class TextBlock : Control
- {
- /// <summary>
- /// Defines the <see cref="Background"/> property.
- /// </summary>
- public static readonly StyledProperty<IBrush> BackgroundProperty =
- Border.BackgroundProperty.AddOwner<TextBlock>();
- // TODO: Define these attached properties elswhere (e.g. on a Text class) and AddOwner
- // them into TextBlock.
- /// <summary>
- /// Defines the <see cref="FontFamily"/> property.
- /// </summary>
- public static readonly AttachedProperty<string> FontFamilyProperty =
- AvaloniaProperty.RegisterAttached<TextBlock, Control, string>(
- nameof(FontFamily),
- defaultValue: "Courier New",
- inherits: true);
- /// <summary>
- /// Defines the <see cref="FontSize"/> property.
- /// </summary>
- public static readonly AttachedProperty<double> FontSizeProperty =
- AvaloniaProperty.RegisterAttached<TextBlock, Control, double>(
- nameof(FontSize),
- defaultValue: 12,
- inherits: true);
- /// <summary>
- /// Defines the <see cref="FontStyle"/> property.
- /// </summary>
- public static readonly AttachedProperty<FontStyle> FontStyleProperty =
- AvaloniaProperty.RegisterAttached<TextBlock, Control, FontStyle>(
- nameof(FontStyle),
- inherits: true);
- /// <summary>
- /// Defines the <see cref="FontWeight"/> property.
- /// </summary>
- public static readonly AttachedProperty<FontWeight> FontWeightProperty =
- AvaloniaProperty.RegisterAttached<TextBlock, Control, FontWeight>(
- nameof(FontWeight),
- inherits: true,
- defaultValue: FontWeight.Normal);
- /// <summary>
- /// Defines the <see cref="Foreground"/> property.
- /// </summary>
- public static readonly AttachedProperty<IBrush> ForegroundProperty =
- AvaloniaProperty.RegisterAttached<TextBlock, Control, IBrush>(
- nameof(Foreground),
- new SolidColorBrush(0xff000000),
- inherits: true);
- /// <summary>
- /// Defines the <see cref="Text"/> property.
- /// </summary>
- public static readonly DirectProperty<TextBlock, string> TextProperty =
- AvaloniaProperty.RegisterDirect<TextBlock, string>(
- nameof(Text),
- o => o.Text,
- (o, v) => o.Text = v);
- /// <summary>
- /// Defines the <see cref="TextAlignment"/> property.
- /// </summary>
- public static readonly StyledProperty<TextAlignment> TextAlignmentProperty =
- AvaloniaProperty.Register<TextBlock, TextAlignment>(nameof(TextAlignment));
- /// <summary>
- /// Defines the <see cref="TextWrapping"/> property.
- /// </summary>
- public static readonly StyledProperty<TextWrapping> TextWrappingProperty =
- AvaloniaProperty.Register<TextBlock, TextWrapping>(nameof(TextWrapping));
- private string _text;
- private FormattedText _formattedText;
- private Size _constraint;
- /// <summary>
- /// Initializes static members of the <see cref="TextBlock"/> class.
- /// </summary>
- static TextBlock()
- {
- ClipToBoundsProperty.OverrideDefaultValue<TextBlock>(true);
- AffectsRender(ForegroundProperty);
- AffectsRender(FontWeightProperty);
- AffectsRender(FontSizeProperty);
- AffectsRender(FontStyleProperty);
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="TextBlock"/> class.
- /// </summary>
- public TextBlock()
- {
- Observable.Merge(
- this.GetObservable(TextProperty).Select(_ => Unit.Default),
- this.GetObservable(TextAlignmentProperty).Select(_ => Unit.Default),
- this.GetObservable(FontSizeProperty).Select(_ => Unit.Default),
- this.GetObservable(FontStyleProperty).Select(_ => Unit.Default),
- this.GetObservable(FontWeightProperty).Select(_ => Unit.Default))
- .Subscribe(_ =>
- {
- InvalidateFormattedText();
- InvalidateMeasure();
- });
- }
- /// <summary>
- /// Gets or sets a brush used to paint the control's background.
- /// </summary>
- public IBrush Background
- {
- get { return GetValue(BackgroundProperty); }
- set { SetValue(BackgroundProperty, value); }
- }
- /// <summary>
- /// Gets or sets the text.
- /// </summary>
- [Content]
- public string Text
- {
- get { return _text; }
- set { SetAndRaise(TextProperty, ref _text, value); }
- }
- /// <summary>
- /// Gets or sets the font family.
- /// </summary>
- public string FontFamily
- {
- get { return GetValue(FontFamilyProperty); }
- set { SetValue(FontFamilyProperty, value); }
- }
- /// <summary>
- /// Gets or sets the font size.
- /// </summary>
- public double FontSize
- {
- get { return GetValue(FontSizeProperty); }
- set { SetValue(FontSizeProperty, value); }
- }
- /// <summary>
- /// Gets or sets the font style.
- /// </summary>
- public FontStyle FontStyle
- {
- get { return GetValue(FontStyleProperty); }
- set { SetValue(FontStyleProperty, value); }
- }
- /// <summary>
- /// Gets or sets the font weight.
- /// </summary>
- public FontWeight FontWeight
- {
- get { return GetValue(FontWeightProperty); }
- set { SetValue(FontWeightProperty, value); }
- }
- /// <summary>
- /// Gets or sets a brush used to paint the text.
- /// </summary>
- public IBrush Foreground
- {
- get { return GetValue(ForegroundProperty); }
- set { SetValue(ForegroundProperty, value); }
- }
- /// <summary>
- /// Gets the <see cref="FormattedText"/> used to render the text.
- /// </summary>
- public FormattedText FormattedText
- {
- get
- {
- if (_formattedText == null)
- {
- _formattedText = CreateFormattedText(_constraint);
- }
- return _formattedText;
- }
- }
- /// <summary>
- /// Gets or sets the control's text wrapping mode.
- /// </summary>
- public TextWrapping TextWrapping
- {
- get { return GetValue(TextWrappingProperty); }
- set { SetValue(TextWrappingProperty, value); }
- }
- /// <summary>
- /// Gets or sets the text alignment.
- /// </summary>
- public TextAlignment TextAlignment
- {
- get { return GetValue(TextAlignmentProperty); }
- set { SetValue(TextAlignmentProperty, value); }
- }
- /// <summary>
- /// Gets the value of the attached <see cref="FontFamilyProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <returns>The font family.</returns>
- public static string GetFontFamily(Control control)
- {
- return control.GetValue(FontFamilyProperty);
- }
- /// <summary>
- /// Gets the value of the attached <see cref="FontSizeProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <returns>The font family.</returns>
- public static double GetFontSize(Control control)
- {
- return control.GetValue(FontSizeProperty);
- }
- /// <summary>
- /// Gets the value of the attached <see cref="FontStyleProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <returns>The font family.</returns>
- public static FontStyle GetFontStyle(Control control)
- {
- return control.GetValue(FontStyleProperty);
- }
- /// <summary>
- /// Gets the value of the attached <see cref="FontWeightProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <returns>The font family.</returns>
- public static FontWeight GetFontWeight(Control control)
- {
- return control.GetValue(FontWeightProperty);
- }
- /// <summary>
- /// Gets the value of the attached <see cref="ForegroundProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <returns>The foreground.</returns>
- public static IBrush GetForeground(Control control)
- {
- return control.GetValue(ForegroundProperty);
- }
- /// <summary>
- /// Sets the value of the attached <see cref="FontFamilyProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <param name="value">The property value to set.</param>
- /// <returns>The font family.</returns>
- public static void SetFontFamily(Control control, string value)
- {
- control.SetValue(FontFamilyProperty, value);
- }
- /// <summary>
- /// Sets the value of the attached <see cref="FontSizeProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <param name="value">The property value to set.</param>
- /// <returns>The font family.</returns>
- public static void SetFontSize(Control control, double value)
- {
- control.SetValue(FontSizeProperty, value);
- }
- /// <summary>
- /// Sets the value of the attached <see cref="FontStyleProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <param name="value">The property value to set.</param>
- /// <returns>The font family.</returns>
- public static void SetFontStyle(Control control, FontStyle value)
- {
- control.SetValue(FontStyleProperty, value);
- }
- /// <summary>
- /// Sets the value of the attached <see cref="FontWeightProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <param name="value">The property value to set.</param>
- /// <returns>The font family.</returns>
- public static void SetFontWeight(Control control, FontWeight value)
- {
- control.SetValue(FontWeightProperty, value);
- }
- /// <summary>
- /// Sets the value of the attached <see cref="ForegroundProperty"/> on a control.
- /// </summary>
- /// <param name="control">The control.</param>
- /// <param name="value">The property value to set.</param>
- /// <returns>The font family.</returns>
- public static void SetForeground(Control control, IBrush value)
- {
- control.SetValue(ForegroundProperty, value);
- }
- /// <summary>
- /// Renders the <see cref="TextBlock"/> to a drawing context.
- /// </summary>
- /// <param name="context">The drawing context.</param>
- public override void Render(DrawingContext context)
- {
- var background = Background;
- if (background != null)
- {
- context.FillRectangle(background, new Rect(Bounds.Size));
- }
- FormattedText.Constraint = Bounds.Size;
- context.DrawText(Foreground, new Point(), FormattedText);
- }
- /// <summary>
- /// Creates the <see cref="FormattedText"/> used to render the text.
- /// </summary>
- /// <param name="constraint">The constraint of the text.</param>
- /// <returns>A <see cref="FormattedText"/> object.</returns>
- protected virtual FormattedText CreateFormattedText(Size constraint)
- {
- return new FormattedText
- {
- Constraint = constraint,
- Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight),
- Text = Text ?? string.Empty,
- TextAlignment = TextAlignment,
- Wrapping = TextWrapping,
- };
- }
- /// <summary>
- /// Invalidates <see cref="FormattedText"/>.
- /// </summary>
- protected void InvalidateFormattedText()
- {
- if (_formattedText != null)
- {
- _constraint = _formattedText.Constraint;
- _formattedText = null;
- }
- }
- /// <summary>
- /// Measures the control.
- /// </summary>
- /// <param name="availableSize">The available size for the control.</param>
- /// <returns>The desired size.</returns>
- protected override Size MeasureOverride(Size availableSize)
- {
- if (!string.IsNullOrEmpty(Text))
- {
- if (TextWrapping == TextWrapping.Wrap)
- {
- FormattedText.Constraint = new Size(availableSize.Width, double.PositiveInfinity);
- }
- else
- {
- FormattedText.Constraint = Size.Infinity;
- }
- return FormattedText.Measure();
- }
- return new Size();
- }
- protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
- {
- base.OnAttachedToLogicalTree(e);
- InvalidateFormattedText();
- InvalidateMeasure();
- }
- }
- }
|