From ca703db1f46adbfc901c548d693f6a332c3cff3f Mon Sep 17 00:00:00 2001 From: Juan Osorio Date: Thu, 28 Nov 2024 13:39:58 -0800 Subject: [PATCH] MarkdownTextBlock: Fix nested styles, sub & super --- .../src/TextElements/ICascadeChild.cs | 14 +++++ .../src/TextElements/MyEmphasisInline.cs | 63 ++++++++++++++----- .../src/TextElements/MyHeading.cs | 2 + 3 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 components/MarkdownTextBlock/src/TextElements/ICascadeChild.cs diff --git a/components/MarkdownTextBlock/src/TextElements/ICascadeChild.cs b/components/MarkdownTextBlock/src/TextElements/ICascadeChild.cs new file mode 100644 index 000000000..c4aa022af --- /dev/null +++ b/components/MarkdownTextBlock/src/TextElements/ICascadeChild.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements; + +/// +/// Interface for elements that inherit properties from their parent. +/// +public interface ICascadeChild +{ + void InheritProperties(IAddChild parent); +} diff --git a/components/MarkdownTextBlock/src/TextElements/MyEmphasisInline.cs b/components/MarkdownTextBlock/src/TextElements/MyEmphasisInline.cs index eef14b962..382c8bb68 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyEmphasisInline.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyEmphasisInline.cs @@ -7,14 +7,14 @@ namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements; -internal class MyEmphasisInline : IAddChild +internal class MyEmphasisInline : IAddChild, ICascadeChild { private Span _span; private EmphasisInline _markdownObject; + private TextElement _textElementCur; - private bool _isBold; - private bool _isItalic; - private bool _isStrikeThrough; + private bool _isSuperscript; + private bool _isSubscript; public TextElement TextElement { @@ -24,6 +24,7 @@ public TextElement TextElement public MyEmphasisInline(EmphasisInline emphasisInline) { _span = new Span(); + _textElementCur = _span; _markdownObject = emphasisInline; } @@ -31,16 +32,17 @@ public void AddChild(IAddChild child) { try { + if (child is ICascadeChild cascadeChild) + cascadeChild.InheritProperties(this); + + var inlines = _textElementCur is Span span ? span.Inlines : ((Paragraph)_textElementCur).Inlines; if (child is MyInlineText inlineText) { - _span.Inlines.Add((Run)inlineText.TextElement); + inlines.Add((Run)inlineText.TextElement); } else if (child is MyEmphasisInline emphasisInline) { - if (emphasisInline._isBold) { SetBold(); } - if (emphasisInline._isItalic) { SetItalic(); } - if (emphasisInline._isStrikeThrough) { SetStrikeThrough(); } - _span.Inlines.Add(emphasisInline._span); + inlines.Add(emphasisInline._span); } } catch (Exception ex) @@ -56,14 +58,11 @@ public void SetBold() #elif WINUI2 _span.FontWeight = Windows.UI.Text.FontWeights.Bold; #endif - - _isBold = true; } public void SetItalic() { _span.FontStyle = FontStyle.Italic; - _isItalic = true; } public void SetStrikeThrough() @@ -73,17 +72,49 @@ public void SetStrikeThrough() #elif WINUI2 _span.TextDecorations = Windows.UI.Text.TextDecorations.Strikethrough; #endif - - _isStrikeThrough = true; } public void SetSubscript() { - _span.SetValue(Typography.VariantsProperty, FontVariants.Subscript); + _isSubscript = true; + ConstructContainer(); } public void SetSuperscript() { - _span.SetValue(Typography.VariantsProperty, FontVariants.Superscript); + _isSuperscript = true; + ConstructContainer(); + } + + public void InheritProperties(IAddChild parent) + { + if (!_isSuperscript && !_isSubscript) + return; + + _textElementCur.FontFamily = parent.TextElement.FontFamily; + _textElementCur.FontWeight = parent.TextElement.FontWeight; + _textElementCur.FontStyle = parent.TextElement.FontStyle; + _textElementCur.Foreground = parent.TextElement.Foreground; + } + + private void ConstructContainer() + { + var container = new InlineUIContainer(); + var richText = new RichTextBlock(); + var paragraph = new Paragraph + { + FontSize = _span.FontSize * 0.8, + }; + richText.Blocks.Add(paragraph); + container.Child = richText; + + double offset = _isSuperscript ? -0.4 : 0.16; + richText.RenderTransform = new TranslateTransform + { + Y = _span.FontSize * offset + }; + + _span.Inlines.Add(container); + _textElementCur = paragraph; } } diff --git a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs index 0c52a1be8..0f2d959f8 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs @@ -85,6 +85,8 @@ public void AddChild(IAddChild child) { if (child.TextElement is Inline inlineChild) { + if (child is ICascadeChild cascadeChild) + cascadeChild.InheritProperties(this); _paragraph.Inlines.Add(inlineChild); } }