180 lines
6.7 KiB
C#
180 lines
6.7 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using Ooui.Forms.Extensions;
|
|
using Xamarin.Forms;
|
|
|
|
using NativeLabel = Ooui.Span;
|
|
|
|
namespace Ooui.Forms.Renderers
|
|
{
|
|
public class LabelRenderer : ViewRenderer<Xamarin.Forms.Label, NativeLabel>
|
|
{
|
|
SizeRequest _perfectSize;
|
|
|
|
bool _perfectSizeValid;
|
|
|
|
public override SizeRequest GetDesiredSize (double widthConstraint, double heightConstraint)
|
|
{
|
|
// System.Console.WriteLine($"Label.GetDesiredSize ({widthConstraint}, {heightConstraint})");
|
|
if (!_perfectSizeValid) {
|
|
var size = Element.Text.MeasureSize (Element.FontFamily, Element.FontSize, Element.FontAttributes, double.PositiveInfinity, double.PositiveInfinity);
|
|
size.Width = Math.Ceiling (size.Width);
|
|
size.Height = Math.Ceiling (size.Height);
|
|
_perfectSize = new SizeRequest (size, new Size (Element.FontSize, Element.FontSize));
|
|
_perfectSizeValid = true;
|
|
}
|
|
|
|
var widthFits = widthConstraint >= _perfectSize.Request.Width;
|
|
var heightFits = heightConstraint >= _perfectSize.Request.Height;
|
|
|
|
if (widthFits && heightFits)
|
|
return _perfectSize;
|
|
|
|
var resultRequestSize = Element.Text.MeasureSize (Element.FontFamily, Element.FontSize, Element.FontAttributes, widthConstraint, heightConstraint);
|
|
var result = new SizeRequest (resultRequestSize, resultRequestSize);
|
|
var tinyWidth = Math.Min (10, result.Request.Width);
|
|
result.Minimum = new Size (tinyWidth, result.Request.Height);
|
|
|
|
if (widthFits || Element.LineBreakMode == LineBreakMode.NoWrap)
|
|
return result;
|
|
|
|
bool containerIsNotInfinitelyWide = !double.IsInfinity (widthConstraint);
|
|
|
|
if (containerIsNotInfinitelyWide) {
|
|
bool textCouldHaveWrapped = Element.LineBreakMode == LineBreakMode.WordWrap || Element.LineBreakMode == LineBreakMode.CharacterWrap;
|
|
bool textExceedsContainer = result.Request.Width > widthConstraint;
|
|
|
|
if (textExceedsContainer || textCouldHaveWrapped) {
|
|
var expandedWidth = Math.Max (tinyWidth, widthConstraint);
|
|
result.Request = new Size (expandedWidth, result.Request.Height);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Label> e)
|
|
{
|
|
if (e.NewElement != null) {
|
|
if (Control == null) {
|
|
SetNativeControl (new NativeLabel ());
|
|
}
|
|
|
|
UpdateText ();
|
|
UpdateTextColor ();
|
|
UpdateFont ();
|
|
|
|
UpdateLineBreakMode ();
|
|
UpdateAlignment ();
|
|
}
|
|
|
|
base.OnElementChanged (e);
|
|
}
|
|
|
|
protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
|
|
{
|
|
base.OnElementPropertyChanged (sender, e);
|
|
|
|
if (Control == null)
|
|
return;
|
|
|
|
if (e.PropertyName == Xamarin.Forms.Label.HorizontalTextAlignmentProperty.PropertyName)
|
|
UpdateAlignment ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.VerticalTextAlignmentProperty.PropertyName)
|
|
UpdateAlignment ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.TextColorProperty.PropertyName)
|
|
UpdateTextColor ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.FontProperty.PropertyName)
|
|
UpdateFont ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.TextProperty.PropertyName)
|
|
UpdateText ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.FormattedTextProperty.PropertyName)
|
|
UpdateText ();
|
|
else if (e.PropertyName == Xamarin.Forms.Label.LineBreakModeProperty.PropertyName)
|
|
UpdateLineBreakMode ();
|
|
}
|
|
|
|
protected override void SetBackgroundColor (Xamarin.Forms.Color color)
|
|
{
|
|
Style.BackgroundColor = color.ToOouiColor (Colors.Clear);
|
|
}
|
|
|
|
void UpdateAlignment ()
|
|
{
|
|
this.Style.Display = "table";
|
|
Control.Style.Display = "table-cell";
|
|
this.Style.TextAlign = Element.HorizontalTextAlignment.ToOouiTextAlign ();
|
|
Control.Style.VerticalAlign = Element.VerticalTextAlignment.ToOouiVerticalAlign ();
|
|
}
|
|
|
|
void UpdateLineBreakMode ()
|
|
{
|
|
_perfectSizeValid = false;
|
|
//switch (Element.LineBreakMode)
|
|
//{
|
|
// case LineBreakMode.NoWrap:
|
|
// Control.LineBreakMode = UILineBreakMode.Clip;
|
|
// Control.Lines = 1;
|
|
// break;
|
|
// case LineBreakMode.WordWrap:
|
|
// Control.LineBreakMode = UILineBreakMode.WordWrap;
|
|
// Control.Lines = 0;
|
|
// break;
|
|
// case LineBreakMode.CharacterWrap:
|
|
// Control.LineBreakMode = UILineBreakMode.CharacterWrap;
|
|
// Control.Lines = 0;
|
|
// break;
|
|
// case LineBreakMode.HeadTruncation:
|
|
// Control.LineBreakMode = UILineBreakMode.HeadTruncation;
|
|
// Control.Lines = 1;
|
|
// break;
|
|
// case LineBreakMode.MiddleTruncation:
|
|
// Control.LineBreakMode = UILineBreakMode.MiddleTruncation;
|
|
// Control.Lines = 1;
|
|
// break;
|
|
// case LineBreakMode.TailTruncation:
|
|
// Control.LineBreakMode = UILineBreakMode.TailTruncation;
|
|
// Control.Lines = 1;
|
|
// break;
|
|
//}
|
|
}
|
|
|
|
bool isTextFormatted;
|
|
void UpdateText ()
|
|
{
|
|
_perfectSizeValid = false;
|
|
|
|
if (Element.FormattedText != null) {
|
|
Control.Text = Element.Text;
|
|
isTextFormatted = true;
|
|
}
|
|
else {
|
|
Control.Text = Element.Text;
|
|
isTextFormatted = false;
|
|
}
|
|
}
|
|
|
|
void UpdateFont ()
|
|
{
|
|
if (isTextFormatted)
|
|
return;
|
|
_perfectSizeValid = false;
|
|
|
|
Element.SetStyleFont (Element.FontFamily, Element.FontSize, Element.FontAttributes, Control.Style);
|
|
}
|
|
|
|
void UpdateTextColor ()
|
|
{
|
|
if (isTextFormatted)
|
|
return;
|
|
|
|
_perfectSizeValid = false;
|
|
|
|
var textColor = (Xamarin.Forms.Color)Element.GetValue (Xamarin.Forms.Label.TextColorProperty);
|
|
|
|
Control.Style.Color = textColor.ToOouiColor(Xamarin.Forms.Color.Black);
|
|
}
|
|
}
|
|
}
|