зеркало из https://github.com/DeGsoft/maui-linux.git
[Enhancement] Allow underline and strikethrough text decorations on labels and spans (#2221)
* Fixes #1632 * Allow underline and strikethrought text decorations on labels and spans * revert some files * pr feedback adjustments * remove docs * rename interface * reorder enum * clean up whitespace * adjust tizen renderer * add gallery demo for setting both underline and strike * allow multiple values of enum to be set in xaml/css * use normal null check * use nameof * include paragraph style * tab alignment * rebase from upstream * pass control to update method on UWP * correct text decorations type converter * reset run text instead of label text on UWP when spans are used * add tests for text decoration converter
This commit is contained in:
Родитель
fd733037a4
Коммит
97d2f30f6b
|
@ -26,6 +26,14 @@ namespace Xamarin.Forms.Controls
|
|||
var namedSizeMediumItalicContainer = new ViewContainer<Label> (Test.Label.FontAttributesItalic, new Label { Text = "Medium Italic Font", Font = Font.SystemFontOfSize (NamedSize.Medium, FontAttributes.Italic) });
|
||||
#pragma warning restore 618
|
||||
|
||||
#pragma warning disable 618
|
||||
var namedSizeMediumUnderlineContainer = new ViewContainer<Label>(Test.Label.TextDecorationUnderline, new Label { Text = "Medium Underlined Font", Font = Font.SystemFontOfSize(NamedSize.Medium), TextDecorations = TextDecorations.Underline });
|
||||
#pragma warning restore 618
|
||||
|
||||
#pragma warning disable 618
|
||||
var namedSizeMediumStrikeContainer = new ViewContainer<Label>(Test.Label.TextDecorationStrike, new Label { Text = "Medium StrikeThrough Font", Font = Font.SystemFontOfSize(NamedSize.Medium), TextDecorations = TextDecorations.Strikethrough });
|
||||
#pragma warning restore 618
|
||||
|
||||
#pragma warning disable 618
|
||||
var namedSizeLargeContainer = new ViewContainer<Label> (Test.Label.FontNamedSizeLarge, new Label { Text = "Large Font", Font = Font.SystemFontOfSize (NamedSize.Large) });
|
||||
#pragma warning restore 618
|
||||
|
@ -151,6 +159,8 @@ namespace Xamarin.Forms.Controls
|
|||
|
||||
Add (namedSizeMediumBoldContainer);
|
||||
Add (namedSizeMediumItalicContainer);
|
||||
Add (namedSizeMediumUnderlineContainer);
|
||||
Add (namedSizeMediumStrikeContainer);
|
||||
Add (namedSizeLargeContainer);
|
||||
Add (namedSizeMediumContainer);
|
||||
Add (namedSizeMicroContainer);
|
||||
|
|
|
@ -29,6 +29,14 @@ namespace Xamarin.Forms.Controls
|
|||
var italicfont = new Label { Text = "Custom Italic Font" };
|
||||
var boldfont = new Label { Text = "Custom Bold Font" };
|
||||
var bolditalicfont = new Label { Text = "Custom Bold Italic Font" };
|
||||
var toggleUnderline = new Label { Text = "Tap to toggle Underline", TextDecorations = TextDecorations.Underline };
|
||||
toggleUnderline.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(()=> { toggleUnderline.TextDecorations ^= TextDecorations.Underline; }) });
|
||||
var toggleStrike = new Label { Text = "Tap to toggle StrikeThrough", TextDecorations = TextDecorations.Strikethrough };
|
||||
toggleStrike.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => { toggleStrike.TextDecorations ^= TextDecorations.Strikethrough; }) });
|
||||
var toggleBoth = new Label { Text = "Tap to toggle both", TextDecorations = TextDecorations.Strikethrough | TextDecorations.Underline };
|
||||
toggleBoth.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => { toggleBoth.TextDecorations ^= TextDecorations.Strikethrough;
|
||||
toggleBoth.TextDecorations ^= TextDecorations.Underline;
|
||||
}) });
|
||||
var huge = new Label {
|
||||
Text = "This is the label that never ends, yes it go on and on my friend. " +
|
||||
"Some people started catting it not knowing what it was, and they'll continue catting it forever just because...",
|
||||
|
@ -39,10 +47,13 @@ namespace Xamarin.Forms.Controls
|
|||
#pragma warning disable 618
|
||||
new Span {Text="FormattedStrings ", TextColor=Color.Blue, BackgroundColor = Color.Yellow, Font = Font.BoldSystemFontOfSize (NamedSize.Large)},
|
||||
#pragma warning restore 618
|
||||
new Span {Text="are ", TextColor=Color.Red, BackgroundColor = Color.Gray},
|
||||
new Span {Text="not pretty!", TextColor = Color.Green,},
|
||||
}
|
||||
} };
|
||||
var underlineSpan = new Span { Text = "are ", TextColor = Color.Red, BackgroundColor = Color.Gray, TextDecorations = TextDecorations.Underline };
|
||||
var strikeSpan = new Span { Text = "not pretty!", TextColor = Color.Green, TextDecorations = TextDecorations.Strikethrough };
|
||||
formatted.FormattedText.Spans.Add(underlineSpan);
|
||||
formatted.FormattedText.Spans.Add(strikeSpan);
|
||||
|
||||
var missingfont = new Label { Text = "Missing font: use default" };
|
||||
|
||||
#pragma warning disable 618
|
||||
|
@ -148,6 +159,9 @@ namespace Xamarin.Forms.Controls
|
|||
bold,
|
||||
italic,
|
||||
bolditalic,
|
||||
toggleUnderline,
|
||||
toggleStrike,
|
||||
toggleBoth,
|
||||
customFont,
|
||||
italicfont,
|
||||
boldfont,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
using System.Globalization;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace Xamarin.Forms.Core.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TextDecorationUnitTests : BaseTestFixture
|
||||
{
|
||||
[Test]
|
||||
public void TestTextDecorationConverter()
|
||||
{
|
||||
var converter = new TextDecorationConverter();
|
||||
TextDecorations both = TextDecorations.Strikethrough;
|
||||
both |= TextDecorations.Underline;
|
||||
Assert.True(converter.CanConvertFrom(typeof(string)));
|
||||
Assert.AreEqual(TextDecorations.Strikethrough, converter.ConvertFromInvariantString("strikethrough"));
|
||||
Assert.AreEqual(TextDecorations.Underline, converter.ConvertFromInvariantString("underline"));
|
||||
Assert.AreEqual(TextDecorations.Strikethrough, converter.ConvertFromInvariantString("line-through"));
|
||||
Assert.AreEqual(TextDecorations.None, converter.ConvertFromInvariantString("none"));
|
||||
Assert.AreEqual(both, converter.ConvertFromInvariantString("strikethrough underline"));
|
||||
Assert.AreEqual(both, converter.ConvertFromInvariantString("underline strikethrough"));
|
||||
Assert.AreEqual(both, converter.ConvertFromInvariantString("underline line-through"));
|
||||
Assert.AreEqual(both, converter.ConvertFromInvariantString("line-through underline"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
|
@ -149,6 +149,7 @@
|
|||
<Compile Include="TapGestureRecognizerTests.cs" />
|
||||
<Compile Include="TemplatedItemsListTests.cs" />
|
||||
<Compile Include="TextCellTests.cs" />
|
||||
<Compile Include="TextDecorationUnitTests.cs" />
|
||||
<Compile Include="ThicknessTests.cs" />
|
||||
<Compile Include="TimePickerUnitTest.cs" />
|
||||
<Compile Include="ToolbarItemTests.cs" />
|
||||
|
@ -228,4 +229,4 @@
|
|||
<LogicalName>Images/crimson.jpg</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
[Flags]
|
||||
[TypeConverter(typeof(TextDecorationConverter))]
|
||||
public enum TextDecorations
|
||||
{
|
||||
None = 0,
|
||||
Underline = 1 << 0,
|
||||
Strikethrough = 1 << 1,
|
||||
}
|
||||
static class DecorableTextElement
|
||||
{
|
||||
public static readonly BindableProperty TextDecorationsProperty = BindableProperty.Create(nameof(IDecorableTextElement.TextDecorations), typeof(TextDecorations), typeof(IDecorableTextElement), TextDecorations.None);
|
||||
}
|
||||
|
||||
[Xaml.TypeConversion(typeof(TextDecorations))]
|
||||
public class TextDecorationConverter : TypeConverter
|
||||
{
|
||||
public override object ConvertFromInvariantString(string value)
|
||||
{
|
||||
TextDecorations result = TextDecorations.None;
|
||||
if (value == null)
|
||||
throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(TextDecorations)));
|
||||
|
||||
var valueArr = value.Split(',');
|
||||
|
||||
if (valueArr.Length <= 1)
|
||||
valueArr = value.Split(' ');
|
||||
|
||||
foreach (var item in valueArr)
|
||||
{
|
||||
if (Enum.TryParse(item.Trim(), true, out TextDecorations textDecorations))
|
||||
result |= textDecorations;
|
||||
else if (item.Equals("line-through", StringComparison.OrdinalIgnoreCase))
|
||||
result |= TextDecorations.Strikethrough;
|
||||
else
|
||||
throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", item, typeof(TextDecorations)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public interface IDecorableTextElement
|
||||
{
|
||||
TextDecorations TextDecorations { get; set; }
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ namespace Xamarin.Forms
|
|||
{
|
||||
[ContentProperty("Text")]
|
||||
[RenderWith(typeof(_LabelRenderer))]
|
||||
public class Label : View, IFontElement, ITextElement, ITextAlignmentElement, ILineHeightElement, IElementConfiguration<Label>
|
||||
public class Label : View, IFontElement, ITextElement, ITextAlignmentElement, ILineHeightElement, IElementConfiguration<Label>, IDecorableTextElement
|
||||
{
|
||||
public static readonly BindableProperty HorizontalTextAlignmentProperty = TextAlignmentElement.HorizontalTextAlignmentProperty;
|
||||
|
||||
|
@ -36,6 +36,8 @@ namespace Xamarin.Forms
|
|||
|
||||
public static readonly BindableProperty FontAttributesProperty = FontElement.FontAttributesProperty;
|
||||
|
||||
public static readonly BindableProperty TextDecorationsProperty = DecorableTextElement.TextDecorationsProperty;
|
||||
|
||||
public static readonly BindableProperty FormattedTextProperty = BindableProperty.Create(nameof(FormattedText), typeof(FormattedString), typeof(Label), default(FormattedString),
|
||||
propertyChanging: (bindable, oldvalue, newvalue) =>
|
||||
{
|
||||
|
@ -155,6 +157,12 @@ namespace Xamarin.Forms
|
|||
set { SetValue(FontAttributesProperty, value); }
|
||||
}
|
||||
|
||||
public TextDecorations TextDecorations
|
||||
{
|
||||
get { return (TextDecorations)GetValue(TextDecorationsProperty); }
|
||||
set { SetValue(TextDecorationsProperty, value); }
|
||||
}
|
||||
|
||||
public string FontFamily
|
||||
{
|
||||
get { return (string)GetValue(FontFamilyProperty); }
|
||||
|
|
|
@ -60,6 +60,7 @@ using Xamarin.Forms.StyleSheets;
|
|||
[assembly: StyleProperty("padding-right", typeof(IPaddingElement), nameof(PaddingElement.PaddingRightProperty), PropertyOwnerType = typeof(PaddingElement))]
|
||||
[assembly: StyleProperty("padding-bottom", typeof(IPaddingElement), nameof(PaddingElement.PaddingBottomProperty), PropertyOwnerType = typeof(PaddingElement))]
|
||||
[assembly: StyleProperty("text-align", typeof(ITextAlignmentElement), nameof(TextAlignmentElement.HorizontalTextAlignmentProperty), Inherited = true)]
|
||||
[assembly: StyleProperty("text-decoration", typeof(IDecorableTextElement), nameof(DecorableTextElement.TextDecorationsProperty))]
|
||||
[assembly: StyleProperty("visibility", typeof(VisualElement), nameof(VisualElement.IsVisibleProperty), Inherited = true)]
|
||||
[assembly: StyleProperty("width", typeof(VisualElement), nameof(VisualElement.WidthRequestProperty))]
|
||||
[assembly: StyleProperty("line-height", typeof(ILineHeightElement), nameof(LineHeightElement.LineHeightProperty), Inherited = true)]
|
||||
|
|
|
@ -4,7 +4,7 @@ using Xamarin.Forms.Internals;
|
|||
namespace Xamarin.Forms
|
||||
{
|
||||
[ContentProperty("Text")]
|
||||
public sealed class Span : GestureElement, IFontElement, ITextElement, ILineHeightElement
|
||||
public sealed class Span : GestureElement, IFontElement, ITextElement, ILineHeightElement, IDecorableTextElement
|
||||
{
|
||||
internal readonly MergedStyle _mergedStyle;
|
||||
|
||||
|
@ -16,6 +16,8 @@ namespace Xamarin.Forms
|
|||
public static readonly BindableProperty StyleProperty = BindableProperty.Create(nameof(Style), typeof(Style), typeof(Span), default(Style),
|
||||
propertyChanged: (bindable, oldvalue, newvalue) => ((Span)bindable)._mergedStyle.Style = (Style)newvalue, defaultBindingMode: BindingMode.OneTime);
|
||||
|
||||
public static readonly BindableProperty TextDecorationsProperty = DecorableTextElement.TextDecorationsProperty;
|
||||
|
||||
public Style Style
|
||||
{
|
||||
get { return (Style)GetValue(StyleProperty); }
|
||||
|
@ -95,6 +97,12 @@ namespace Xamarin.Forms
|
|||
set { SetValue(FontElement.FontSizeProperty, value); }
|
||||
}
|
||||
|
||||
public TextDecorations TextDecorations
|
||||
{
|
||||
get { return (TextDecorations)GetValue(TextDecorationsProperty); }
|
||||
set { SetValue(TextDecorationsProperty, value); }
|
||||
}
|
||||
|
||||
public double LineHeight {
|
||||
get { return (double)GetValue(LineHeightElement.LineHeightProperty); }
|
||||
set { SetValue(LineHeightElement.LineHeightProperty, value); }
|
||||
|
|
|
@ -582,6 +582,8 @@ namespace Xamarin.Forms.CustomAttributes
|
|||
FormattedText,
|
||||
FontAttibutesBold,
|
||||
FontAttributesItalic,
|
||||
TextDecorationUnderline,
|
||||
TextDecorationStrike,
|
||||
FontNamedSizeMicro,
|
||||
FontNamedSizeSmall,
|
||||
FontNamedSizeMedium,
|
||||
|
|
|
@ -280,6 +280,24 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
var textDecorations = Element.TextDecorations;
|
||||
|
||||
if ((textDecorations & TextDecorations.Strikethrough) == 0)
|
||||
PaintFlags &= ~PaintFlags.StrikeThruText;
|
||||
else
|
||||
PaintFlags |= PaintFlags.StrikeThruText;
|
||||
|
||||
if ((textDecorations & TextDecorations.Underline) == 0)
|
||||
PaintFlags &= ~PaintFlags.UnderlineText;
|
||||
else
|
||||
PaintFlags |= PaintFlags.UnderlineText;
|
||||
}
|
||||
|
||||
void UpdateGravity()
|
||||
{
|
||||
Label label = Element;
|
||||
|
|
|
@ -62,6 +62,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
#pragma warning restore 618
|
||||
else
|
||||
spannable.SetSpan(new FontSpan(defaultFont, view), start, end, SpanTypes.InclusiveInclusive);
|
||||
if (span.IsSet(Span.TextDecorationsProperty))
|
||||
spannable.SetSpan(new TextDecorationSpan(span), start, end, SpanTypes.InclusiveInclusive);
|
||||
}
|
||||
return spannable;
|
||||
}
|
||||
|
@ -95,6 +97,34 @@ namespace Xamarin.Forms.Platform.Android
|
|||
paint.TextSize = TypedValue.ApplyDimension(ComplexUnitType.Sp, value, TextView.Resources.DisplayMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
class TextDecorationSpan : MetricAffectingSpan
|
||||
{
|
||||
public TextDecorationSpan(Span span)
|
||||
{
|
||||
Span = span;
|
||||
}
|
||||
|
||||
public Span Span { get; }
|
||||
|
||||
public override void UpdateDrawState(TextPaint tp)
|
||||
{
|
||||
Apply(tp);
|
||||
}
|
||||
|
||||
public override void UpdateMeasureState(TextPaint p)
|
||||
{
|
||||
Apply(p);
|
||||
}
|
||||
|
||||
void Apply(Paint paint)
|
||||
{
|
||||
var textDecorations = Span.TextDecorations;
|
||||
paint.UnderlineText = (textDecorations & TextDecorations.Underline) != 0;
|
||||
paint.StrikeThruText = (textDecorations & TextDecorations.Strikethrough) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
class LineHeightSpan : Java.Lang.Object, ILineHeightSpan
|
||||
{
|
||||
private double _lineHeight;
|
||||
|
@ -114,7 +144,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
fm.Ascent = (int) (_ascent * _lineHeight);
|
||||
fm.Descent = (int) (_descent * _lineHeight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -118,7 +118,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (e.OldElement.HorizontalTextAlignment != e.NewElement.HorizontalTextAlignment || e.OldElement.VerticalTextAlignment != e.NewElement.VerticalTextAlignment)
|
||||
UpdateGravity();
|
||||
}
|
||||
|
||||
UpdateTextDecorations();
|
||||
_motionEventHelper.UpdateElement(e.NewElement);
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateText();
|
||||
else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName)
|
||||
UpdateLineBreakMode();
|
||||
else if (e.PropertyName == Label.TextDecorationsProperty.PropertyName)
|
||||
UpdateTextDecorations();
|
||||
else if (e.PropertyName == Label.TextProperty.PropertyName || e.PropertyName == Label.FormattedTextProperty.PropertyName)
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.LineHeightProperty.PropertyName)
|
||||
|
@ -174,6 +176,24 @@ namespace Xamarin.Forms.Platform.Android
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
var textDecorations = Element.TextDecorations;
|
||||
|
||||
if ((textDecorations & TextDecorations.Strikethrough) == 0)
|
||||
_view.PaintFlags &= ~PaintFlags.StrikeThruText;
|
||||
else
|
||||
_view.PaintFlags |= PaintFlags.StrikeThruText;
|
||||
|
||||
if ((textDecorations & TextDecorations.Underline) == 0)
|
||||
_view.PaintFlags &= ~PaintFlags.UnderlineText;
|
||||
else
|
||||
_view.PaintFlags |= PaintFlags.UnderlineText;
|
||||
}
|
||||
|
||||
void UpdateGravity()
|
||||
{
|
||||
Label label = Element;
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
RegisterPropertyHandler(Label.FormattedTextProperty, UpdateFormattedText);
|
||||
RegisterPropertyHandler(Label.LineHeightProperty, UpdateLineHeight);
|
||||
RegisterPropertyHandler(Specific.FontWeightProperty, UpdateFontWeight);
|
||||
RegisterPropertyHandler(Label.TextDecorationsProperty, UpdateTextDecorations);
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||
|
@ -46,6 +47,8 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
|
||||
foreach (var span in formattedString.Spans)
|
||||
{
|
||||
var textDecorations = span.TextDecorations;
|
||||
|
||||
Native.Span nativeSpan = new Native.Span();
|
||||
nativeSpan.Text = span.Text;
|
||||
nativeSpan.FontAttributes = span.FontAttributes;
|
||||
|
@ -53,6 +56,8 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
nativeSpan.FontSize = span.FontSize;
|
||||
nativeSpan.ForegroundColor = span.TextColor.ToNative();
|
||||
nativeSpan.BackgroundColor = span.BackgroundColor.ToNative();
|
||||
nativeSpan.Underline = (textDecorations & TextDecorations.Underline) != 0;
|
||||
nativeSpan.Strikethrough = (textDecorations & TextDecorations.Strikethrough) != 0;
|
||||
nativeSpan.LineHeight = span.LineHeight;
|
||||
nativeString.Spans.Add(nativeSpan);
|
||||
}
|
||||
|
@ -60,6 +65,15 @@ namespace Xamarin.Forms.Platform.Tizen
|
|||
return nativeString;
|
||||
}
|
||||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
Control.BatchBegin();
|
||||
var textDecorations = Element.TextDecorations;
|
||||
Control.Strikethrough = (textDecorations & TextDecorations.Strikethrough) != 0;
|
||||
Control.Underline = (textDecorations & TextDecorations.Underline) != 0;
|
||||
Control.BatchCommit();
|
||||
}
|
||||
|
||||
void UpdateFormattedText()
|
||||
{
|
||||
if (Element.FormattedText != null)
|
||||
|
|
|
@ -25,6 +25,9 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
run.ApplyFont(span.Font);
|
||||
#pragma warning restore 618
|
||||
|
||||
if (span.IsSet(Span.TextDecorationsProperty))
|
||||
run.TextDecorations = (Windows.UI.Text.TextDecorations)span.TextDecorations;
|
||||
|
||||
return run;
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +135,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
_isInitiallyDefault = Element.IsDefault();
|
||||
|
||||
UpdateText(Control);
|
||||
UpdateTextDecorations(Control);
|
||||
UpdateColor(Control);
|
||||
UpdateAlign(Control);
|
||||
UpdateFont(Control);
|
||||
|
@ -150,6 +154,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateAlign(Control);
|
||||
else if (e.PropertyName == Label.FontProperty.PropertyName)
|
||||
UpdateFont(Control);
|
||||
else if (e.PropertyName == Label.TextDecorationsProperty.PropertyName)
|
||||
UpdateTextDecorations(Control);
|
||||
else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName)
|
||||
UpdateLineBreakMode(Control);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
|
@ -161,6 +167,39 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
||||
void UpdateTextDecorations(TextBlock textBlock)
|
||||
{
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
var elementTextDecorations = Element.TextDecorations;
|
||||
|
||||
if ((elementTextDecorations & TextDecorations.Underline) == 0)
|
||||
textBlock.TextDecorations &= ~Windows.UI.Text.TextDecorations.Underline;
|
||||
else
|
||||
textBlock.TextDecorations |= Windows.UI.Text.TextDecorations.Underline;
|
||||
|
||||
if ((elementTextDecorations & TextDecorations.Strikethrough) == 0)
|
||||
textBlock.TextDecorations &= ~Windows.UI.Text.TextDecorations.Strikethrough;
|
||||
else
|
||||
textBlock.TextDecorations |= Windows.UI.Text.TextDecorations.Strikethrough;
|
||||
|
||||
//TextDecorations are not updated in the UI until the text changes
|
||||
if (textBlock.Inlines != null && textBlock.Inlines.Count > 0)
|
||||
{
|
||||
for (var i = 0; i < textBlock.Inlines.Count; i++)
|
||||
{
|
||||
var run = (Run)textBlock.Inlines[i];
|
||||
run.Text = run.Text;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
textBlock.Text = textBlock.Text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UpdateAlign(TextBlock textBlock)
|
||||
{
|
||||
_perfectSizeValid = false;
|
||||
|
|
|
@ -29,7 +29,17 @@ namespace Xamarin.Forms.Platform.WPF
|
|||
#pragma warning disable 618
|
||||
run.ApplyFont(span.Font);
|
||||
#pragma warning restore 618
|
||||
if (!span.IsSet(Span.TextDecorationsProperty))
|
||||
return run;
|
||||
|
||||
var textDecorations = span.TextDecorations;
|
||||
|
||||
if ((textDecorations & TextDecorations.Underline) != 0)
|
||||
run.TextDecorations.Add(System.Windows.TextDecorations.Underline);
|
||||
|
||||
if ((textDecorations & TextDecorations.Strikethrough) != 0)
|
||||
run.TextDecorations.Add(System.Windows.TextDecorations.Strikethrough);
|
||||
|
||||
return run;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace Xamarin.Forms.Platform.WPF
|
|||
|
||||
// Update control property
|
||||
UpdateText();
|
||||
UpdateTextDecorations();
|
||||
UpdateColor();
|
||||
UpdateAlign();
|
||||
UpdateFont();
|
||||
|
@ -47,6 +48,8 @@ namespace Xamarin.Forms.Platform.WPF
|
|||
|
||||
if (e.PropertyName == Label.TextProperty.PropertyName || e.PropertyName == Label.FormattedTextProperty.PropertyName)
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.TextDecorationsProperty.PropertyName)
|
||||
UpdateTextDecorations();
|
||||
else if (e.PropertyName == Label.TextColorProperty.PropertyName)
|
||||
UpdateColor();
|
||||
else if (e.PropertyName == Label.HorizontalTextAlignmentProperty.PropertyName || e.PropertyName == Label.VerticalTextAlignmentProperty.PropertyName)
|
||||
|
@ -62,6 +65,29 @@ namespace Xamarin.Forms.Platform.WPF
|
|||
Control.UpdateDependencyColor(TextBlock.BackgroundProperty, Element.BackgroundColor);
|
||||
}
|
||||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
var textDecorations = Element.TextDecorations;
|
||||
|
||||
var newTextDecorations = new System.Windows.TextDecorationCollection(Control.TextDecorations);
|
||||
|
||||
if ((textDecorations & TextDecorations.Underline) == 0)
|
||||
newTextDecorations.TryRemove(System.Windows.TextDecorations.Underline, out newTextDecorations);
|
||||
else
|
||||
newTextDecorations.Add(System.Windows.TextDecorations.Underline);
|
||||
|
||||
if ((textDecorations & TextDecorations.Strikethrough) == 0)
|
||||
newTextDecorations.TryRemove(System.Windows.TextDecorations.Strikethrough, out newTextDecorations);
|
||||
else
|
||||
newTextDecorations.Add(System.Windows.TextDecorations.Strikethrough);
|
||||
|
||||
Control.TextDecorations = newTextDecorations;
|
||||
}
|
||||
|
||||
|
||||
void UpdateAlign()
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -76,20 +76,13 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
targetFont = ((IFontElement)owner).ToUIFont();
|
||||
else
|
||||
targetFont = span.ToUIFont();
|
||||
|
||||
var fgcolor = span.TextColor;
|
||||
if (fgcolor.IsDefault)
|
||||
fgcolor = defaultForegroundColor;
|
||||
if (fgcolor.IsDefault)
|
||||
fgcolor = Color.Black; // as defined by apple docs
|
||||
|
||||
return new NSAttributedString(text, targetFont, fgcolor.ToUIColor(), span.BackgroundColor.ToUIColor(), null, style);
|
||||
#else
|
||||
NSFont targetFont;
|
||||
if (span.IsDefault())
|
||||
targetFont = ((IFontElement)owner).ToNSFont();
|
||||
else
|
||||
targetFont = span.ToNSFont();
|
||||
#endif
|
||||
|
||||
var fgcolor = span.TextColor;
|
||||
if (fgcolor.IsDefault)
|
||||
|
@ -97,9 +90,32 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
if (fgcolor.IsDefault)
|
||||
fgcolor = Color.Black; // as defined by apple docs
|
||||
|
||||
return new NSAttributedString(text, targetFont, fgcolor.ToNSColor(), span.BackgroundColor.ToNSColor(),
|
||||
null, null, null, NSUnderlineStyle.None, NSUnderlineStyle.None, style);
|
||||
#if __MOBILE__
|
||||
UIColor spanFgColor;
|
||||
UIColor spanBgColor;
|
||||
spanFgColor = fgcolor.ToUIColor();
|
||||
spanBgColor = span.BackgroundColor.ToUIColor();
|
||||
#else
|
||||
NSColor spanFgColor;
|
||||
NSColor spanBgColor;
|
||||
spanFgColor = fgcolor.ToNSColor();
|
||||
spanBgColor = span.BackgroundColor.ToNSColor();
|
||||
#endif
|
||||
|
||||
bool hasUnderline = false;
|
||||
bool hasStrikethrough = false;
|
||||
if (span.IsSet(Span.TextDecorationsProperty))
|
||||
{
|
||||
var textDecorations = span.TextDecorations;
|
||||
hasUnderline = (textDecorations & TextDecorations.Underline) != 0;
|
||||
hasStrikethrough = (textDecorations & TextDecorations.Strikethrough) != 0;
|
||||
}
|
||||
|
||||
var attrString = new NSAttributedString(text, targetFont, spanFgColor, spanBgColor,
|
||||
underlineStyle: hasUnderline ? NSUnderlineStyle.Single : NSUnderlineStyle.None,
|
||||
strikethroughStyle: hasStrikethrough ? NSUnderlineStyle.Single : NSUnderlineStyle.None, paragraphStyle: style);
|
||||
|
||||
return attrString;
|
||||
}
|
||||
|
||||
internal static NSAttributedString ToAttributed(this FormattedString formattedString, Element owner,
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.ComponentModel;
|
||||
using RectangleF = CoreGraphics.CGRect;
|
||||
using SizeF = CoreGraphics.CGSize;
|
||||
using Foundation;
|
||||
|
||||
#if __MOBILE__
|
||||
using UIKit;
|
||||
|
@ -129,6 +130,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateLineBreakMode();
|
||||
UpdateAlignment();
|
||||
UpdateText();
|
||||
UpdateTextDecorations();
|
||||
UpdateTextColor();
|
||||
UpdateFont();
|
||||
}
|
||||
|
@ -150,6 +152,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateFont();
|
||||
else if (e.PropertyName == Label.TextProperty.PropertyName)
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.TextDecorationsProperty.PropertyName)
|
||||
UpdateTextDecorations();
|
||||
else if (e.PropertyName == Label.FormattedTextProperty.PropertyName)
|
||||
UpdateText();
|
||||
else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName)
|
||||
|
@ -160,6 +164,41 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateText();
|
||||
}
|
||||
|
||||
void UpdateTextDecorations()
|
||||
{
|
||||
if (!Element.IsSet(Label.TextDecorationsProperty))
|
||||
return;
|
||||
|
||||
var textDecorations = Element.TextDecorations;
|
||||
#if __MOBILE__
|
||||
var newAttributedText = new NSMutableAttributedString(Control.AttributedText);
|
||||
var strikeThroughStyleKey = UIStringAttributeKey.StrikethroughStyle;
|
||||
var underlineStyleKey = UIStringAttributeKey.UnderlineStyle;
|
||||
|
||||
#else
|
||||
var newAttributedText = new NSMutableAttributedString(Control.AttributedStringValue);
|
||||
var strikeThroughStyleKey = NSStringAttributeKey.StrikethroughStyle;
|
||||
var underlineStyleKey = NSStringAttributeKey.UnderlineStyle;
|
||||
#endif
|
||||
var range = new NSRange(0, newAttributedText.Length);
|
||||
|
||||
if ((textDecorations & TextDecorations.Strikethrough) == 0)
|
||||
newAttributedText.RemoveAttribute(strikeThroughStyleKey, range);
|
||||
else
|
||||
newAttributedText.AddAttribute(strikeThroughStyleKey, NSNumber.FromInt32((int)NSUnderlineStyle.Single), range);
|
||||
|
||||
if ((textDecorations & TextDecorations.Underline) == 0)
|
||||
newAttributedText.RemoveAttribute(underlineStyleKey, range);
|
||||
else
|
||||
newAttributedText.AddAttribute(underlineStyleKey, NSNumber.FromInt32((int)NSUnderlineStyle.Single), range);
|
||||
|
||||
#if __MOBILE__
|
||||
Control.AttributedText = newAttributedText;
|
||||
#else
|
||||
Control.AttributedStringValue = newAttributedText;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __MOBILE__
|
||||
protected override void SetAccessibilityLabel()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче