From 850912131c74eb0bf72a58026b7561576b3b6eaa Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 18 Sep 2025 16:35:24 +0200 Subject: [PATCH 1/3] Adding per heading foreground --- .../MarkdownTextBlockExampleSample.xaml.cs | 8 +++++++- .../MarkdownTextBlock/src/MarkdownThemes.cs | 17 +++++++++++------ .../src/TextElements/MyHeading.cs | 10 +++++++++- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs index 0e5019958..be6763435 100644 --- a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs +++ b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.WinUI.Controls; +using Microsoft.UI; using System.Diagnostics; namespace MarkdownTextBlockExperiment.Samples; @@ -600,7 +601,12 @@ public string Text public MarkdownTextBlockExampleSample() { this.InitializeComponent(); - _config = new MarkdownConfig(); + + var themes = new MarkdownThemes + { + + }; + _config = new MarkdownConfig { Themes = themes }; _text = _markdown; MarkdownTextBlock.OnLinkClicked += MarkdownTextBlock_OnLinkClicked; } diff --git a/components/MarkdownTextBlock/src/MarkdownThemes.cs b/components/MarkdownTextBlock/src/MarkdownThemes.cs index d29ec9bf5..2afcd04b5 100644 --- a/components/MarkdownTextBlock/src/MarkdownThemes.cs +++ b/components/MarkdownTextBlock/src/MarkdownThemes.cs @@ -34,9 +34,14 @@ public sealed class MarkdownThemes : DependencyObject public double H6FontSize { get; set; } = 12; - public Brush HeadingForeground { get; set; } = Extensions.GetAccentColorBrush(); + public Brush H1Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Brush H2Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Brush H3Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Brush H4Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Brush H5Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Brush H6Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; - public FontWeight H1FontWeight { get; set; } = FontWeights.Bold; + public FontWeight H1FontWeight { get; set; } = FontWeights.SemiBold; public FontWeight H2FontWeight { get; set; } = FontWeights.Normal; @@ -48,10 +53,10 @@ public sealed class MarkdownThemes : DependencyObject public FontWeight H6FontWeight { get; set; } = FontWeights.Normal; - public Thickness H1Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0); - public Thickness H2Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0); - public Thickness H3Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0); - public Thickness H4Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0); + public Thickness H1Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0); + public Thickness H2Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0); + public Thickness H3Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0); + public Thickness H4Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0); public Thickness H5Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0); public Thickness H6Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0); diff --git a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs index 43ceae327..ab8a85392 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyHeading.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyHeading.cs @@ -60,7 +60,15 @@ private void SetHProperties(int level) 5 => _config.Themes.H5FontSize, _ => _config.Themes.H6FontSize, }; - _paragraph.Foreground = _config.Themes.HeadingForeground; + _paragraph.Foreground = level switch + { + 1 => _config.Themes.H1Foreground, + 2 => _config.Themes.H2Foreground, + 3 => _config.Themes.H3Foreground, + 4 => _config.Themes.H4Foreground, + 5 => _config.Themes.H5Foreground, + _ => _config.Themes.H6Foreground, + }; _paragraph.FontWeight = level switch { 1 => _config.Themes.H1FontWeight, From de5a3a946f81d3a1d55d9fa336a87a79a1425958 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 18 Sep 2025 19:57:49 +0200 Subject: [PATCH 2/3] Adding more styling properties --- .../MarkdownTextBlockExampleSample.xaml.cs | 99 ++++++++++++++++++- .../MarkdownTextBlock/src/HtmlWriter.cs | 1 + .../src/MarkdownTextBlock.Properties.cs | 26 +++++ .../MarkdownTextBlock/src/MarkdownThemes.cs | 50 ++++++++++ .../Inlines/LinkInlineRenderer.cs | 3 + .../ObjectRenderers/QuoteBlockRenderer.cs | 2 +- .../src/TextElements/MyCodeBlock.cs | 12 ++- .../src/TextElements/MyHyperlink.cs | 2 + .../src/TextElements/MyHyperlinkButton.cs | 3 +- .../src/TextElements/MyImage.cs | 12 +++ .../src/TextElements/MyParagraph.cs | 11 ++- .../src/TextElements/MyQuote.cs | 18 ++-- .../src/TextElements/MyTable.cs | 7 +- .../src/TextElements/MyTableCell.cs | 3 +- .../src/TextElements/MyTableUIElement.cs | 5 +- .../src/TextElements/MyThematicBreak.cs | 5 +- 16 files changed, 234 insertions(+), 25 deletions(-) diff --git a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs index be6763435..76d74bcf0 100644 --- a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs +++ b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs @@ -4,7 +4,9 @@ using CommunityToolkit.WinUI.Controls; using Microsoft.UI; +using Microsoft.UI.Text; using System.Diagnostics; +using Windows.UI; namespace MarkdownTextBlockExperiment.Samples; @@ -604,7 +606,102 @@ public MarkdownTextBlockExampleSample() var themes = new MarkdownThemes { - + // Headings + H1FontSize = 28, + H2FontSize = 24, + H3FontSize = 20, + H4FontSize = 18, + H5FontSize = 16, + H6FontSize = 14, + + H1FontWeight = FontWeights.Bold, + H2FontWeight = FontWeights.SemiBold, + H3FontWeight = FontWeights.Medium, + H4FontWeight = FontWeights.Normal, + H5FontWeight = FontWeights.Normal, + H6FontWeight = FontWeights.Normal, + + H1Foreground = new SolidColorBrush(Colors.Crimson), + H2Foreground = new SolidColorBrush(Colors.DarkOrange), + H3Foreground = new SolidColorBrush(Colors.Goldenrod), + H4Foreground = new SolidColorBrush(Colors.ForestGreen), + H5Foreground = new SolidColorBrush(Colors.SteelBlue), + H6Foreground = new SolidColorBrush(Colors.MediumPurple), + + H1Margin = new Thickness(0, 20, 0, 4), + H2Margin = new Thickness(0, 18, 0, 4), + H3Margin = new Thickness(0, 16, 0, 4), + H4Margin = new Thickness(0, 14, 0, 4), + H5Margin = new Thickness(0, 12, 0, 2), + H6Margin = new Thickness(0, 10, 0, 2), + + // General container + Padding = new Thickness(12), + InternalMargin = new Thickness(6), + CornerRadius = new CornerRadius(6), + + // Paragraph / lists + ParagraphMargin = new Thickness(0, 10, 0, 10), + ParagraphLineHeight = 22, + ListGutterWidth = 28, + ListBulletSpacing = 6, + ListMargin = new Thickness(0, 6, 0, 6), + + // Horizontal rule + HorizontalRuleBrush = new SolidColorBrush(Colors.Gray), + HorizontalRuleThickness = 2, + HorizontalRuleMargin = new Thickness(0, 18, 0, 18), + + // Links + LinkForeground = new SolidColorBrush(Colors.DodgerBlue), + + // Inline code + InlineCodeBackground = new SolidColorBrush(Color.FromArgb(255, 40, 44, 52)), + InlineCodeForeground = new SolidColorBrush(Colors.White), + InlineCodeBorderBrush = new SolidColorBrush(Color.FromArgb(255, 70, 75, 85)), + InlineCodeBorderThickness = new Thickness(1), + InlineCodeCornerRadius = new CornerRadius(3), + InlineCodePadding = new Thickness(4, 0, 4, 0), + InlineCodeFontSize = 13, + InlineCodeFontWeight = FontWeights.SemiBold, + + // Code blocks + CodeBlockBackground = new SolidColorBrush(Color.FromArgb(255, 30, 34, 40)), + CodeBlockForeground = new SolidColorBrush(Colors.Gainsboro), + CodeBlockBorderBrush = new SolidColorBrush(Color.FromArgb(255, 60, 65, 75)), + CodeBlockBorderThickness = new Thickness(1), + CodeBlockPadding = new Thickness(12), + CodeBlockMargin = new Thickness(0, 14, 0, 16), + CodeBlockFontFamily = new FontFamily("Consolas"), + CodeBlockCornerRadius = new CornerRadius(8), + + // Quotes + QuoteBackground = new SolidColorBrush(Color.FromArgb(30, 255, 200, 0)), + QuoteBorderBrush = new SolidColorBrush(Colors.Orange), + QuoteBorderThickness = new Thickness(5, 0, 0, 0), + QuoteForeground = new SolidColorBrush(Colors.DarkSlateGray), + QuoteMargin = new Thickness(0, 10, 0, 10), + QuotePadding = new Thickness(10), + QuoteCornerRadius = new CornerRadius(6), + + // Images + ImageMaxWidth = 420, + ImageMaxHeight = 260, + ImageStretch = Stretch.UniformToFill, + + // Tables + TableBorderBrush = new SolidColorBrush(Colors.DimGray), + TableBorderThickness = 1, + TableCellPadding = new Thickness(8, 4, 8, 4), + TableMargin = new Thickness(0, 18, 0, 18), + TableHeadingBackground = new SolidColorBrush(Color.FromArgb(255, 50, 70, 95)), + + // Other / border defaults + BorderBrush = new SolidColorBrush(Colors.DarkGray), + + // (YAML placeholders if ever used) + YamlBorderBrush = new SolidColorBrush(Colors.DarkGoldenrod), + YamlBorderThickness = new Thickness(1) }; _config = new MarkdownConfig { Themes = themes }; _text = _markdown; diff --git a/components/MarkdownTextBlock/src/HtmlWriter.cs b/components/MarkdownTextBlock/src/HtmlWriter.cs index a581583bb..dc993353e 100644 --- a/components/MarkdownTextBlock/src/HtmlWriter.cs +++ b/components/MarkdownTextBlock/src/HtmlWriter.cs @@ -43,6 +43,7 @@ public static void WriteHtml(WinUIRenderer renderer, HtmlNodeCollection nodes) else { var myHyperlink = new MyHyperlink(node, renderer.Config.BaseUrl); + myHyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground; myHyperlink.ClickEvent += (sender, e) => { renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri); diff --git a/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs b/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs index 8dae4cad1..06ad510cc 100644 --- a/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs +++ b/components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs @@ -108,6 +108,23 @@ public partial class MarkdownTextBlock typeof(MarkdownTextBlock), new PropertyMetadata(null)); + /// + /// Identifies the dependency property. + /// + private static readonly DependencyProperty IsTextSelectionEnabledProperty = DependencyProperty.Register( + nameof(IsTextSelectionEnabled), + typeof(bool), + typeof(MarkdownTextBlock), + new PropertyMetadata(false, OnIsTextSelectionEnabledChanged)); + + private static void OnIsTextSelectionEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is MarkdownTextBlock mtb && mtb._document != null) + { + mtb._document.RichTextBlock.IsTextSelectionEnabled = (bool)e.NewValue; + } + } + public MarkdownConfig Config { get => (MarkdownConfig)GetValue(ConfigProperty); @@ -203,4 +220,13 @@ public MarkdownDocument? MarkdownDocument get => (MarkdownDocument)GetValue(MarkdownDocumentProperty); private set => SetValue(MarkdownDocumentProperty, value); } + + /// + /// Gets or sets a value indicating whether text selection is enabled. + /// + public bool IsTextSelectionEnabled + { + get => (bool)GetValue(IsTextSelectionEnabledProperty); + set => SetValue(IsTextSelectionEnabledProperty, value); + } } diff --git a/components/MarkdownTextBlock/src/MarkdownThemes.cs b/components/MarkdownTextBlock/src/MarkdownThemes.cs index 2afcd04b5..ad0317cfd 100644 --- a/components/MarkdownTextBlock/src/MarkdownThemes.cs +++ b/components/MarkdownTextBlock/src/MarkdownThemes.cs @@ -78,4 +78,54 @@ public sealed class MarkdownThemes : DependencyObject public double InlineCodeFontSize { get; set; } = 10; public FontWeight InlineCodeFontWeight { get; set; } = FontWeights.Normal; + + // Legacy parity properties (new) + // Code block styling + public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"]; + public Brush CodeBlockBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray); + public Thickness CodeBlockBorderThickness { get; set; } = new Thickness(1); + public Thickness CodeBlockPadding { get; set; } = new Thickness(8); + public Thickness CodeBlockMargin { get; set; } = new Thickness(0, 8, 0, 8); + public FontFamily CodeBlockFontFamily { get; set; } = new FontFamily("Consolas"); + public Brush CodeBlockForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public CornerRadius CodeBlockCornerRadius { get; set; } = new CornerRadius(4); + + // Horizontal rule + public Brush HorizontalRuleBrush { get; set; } = new SolidColorBrush(Colors.Gray); + public double HorizontalRuleThickness { get; set; } = 1.0; + public Thickness HorizontalRuleMargin { get; set; } = new Thickness(0, 12, 0, 12); + + // Link styling + public Brush LinkForeground { get; set; } = (Brush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"] ?? new SolidColorBrush(Colors.DodgerBlue); + + // Paragraph / list + public Thickness ParagraphMargin { get; set; } = new Thickness(0, 8, 0, 8); + public double ParagraphLineHeight { get; set; } = 0; // 0 = default + public double ListBulletSpacing { get; set; } = 4; // spaces after bullet + public double ListGutterWidth { get; set; } = 30; // indent delta per level + public Thickness ListMargin { get; set; } = new Thickness(0, 4, 0, 4); + + // Quote styling + public Brush QuoteBackground { get; set; } = new SolidColorBrush(Colors.Transparent); + public Brush QuoteBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray); + public Thickness QuoteBorderThickness { get; set; } = new Thickness(4, 0, 0, 0); + public Brush QuoteForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; + public Thickness QuoteMargin { get; set; } = new Thickness(0, 4, 0, 4); + public Thickness QuotePadding { get; set; } = new Thickness(4); + public CornerRadius QuoteCornerRadius { get; set; } = new CornerRadius(4); + + // Image styling + public double ImageMaxWidth { get; set; } = 0; // 0 = no constraint + public double ImageMaxHeight { get; set; } = 0; + public Stretch ImageStretch { get; set; } = Stretch.Uniform; + + // Table styling + public Brush TableBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray); + public double TableBorderThickness { get; set; } = 1; + public Thickness TableCellPadding { get; set; } = new Thickness(4); + public Thickness TableMargin { get; set; } = new Thickness(0, 10, 0, 10); + + // YAML / not currently used - placeholders for parity + public Brush YamlBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray); + public Thickness YamlBorderThickness { get; set; } = new Thickness(1); } diff --git a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs index a14091eca..0a6acf9e5 100644 --- a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs +++ b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs @@ -35,11 +35,14 @@ protected override void Write(WinUIRenderer renderer, LinkInline link) { renderer.MarkdownTextBlock.RaiseLinkClickedEvent(((HyperlinkButton)sender).NavigateUri); }; + // Apply link foreground to nested RichTextBlock content + // (Handled in MyHyperlinkButton initialization via MarkdownConfig.Default for now) renderer.Push(myHyperlinkButton); } else { var hyperlink = new MyHyperlink(link, renderer.Config.BaseUrl); + hyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground; hyperlink.ClickEvent += (sender, e) => { renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri); diff --git a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs index 139db86d9..bdc1b3210 100644 --- a/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs +++ b/components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs @@ -14,7 +14,7 @@ protected override void Write(WinUIRenderer renderer, QuoteBlock obj) if (renderer == null) throw new ArgumentNullException(nameof(renderer)); if (obj == null) throw new ArgumentNullException(nameof(obj)); - var quote = new MyQuote(obj); + var quote = new MyQuote(obj, renderer.Config.Themes); renderer.Push(quote); renderer.WriteChildren(obj); diff --git a/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs b/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs index c60109e0d..f7502b9e3 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs @@ -24,11 +24,15 @@ public MyCodeBlock(CodeBlock codeBlock, MarkdownConfig config) _paragraph = new Paragraph(); var container = new InlineUIContainer(); var border = new Border(); - border.Background = (Brush)Application.Current.Resources["ExpanderHeaderBackground"]; - border.Padding = _config.Themes.Padding; - border.Margin = _config.Themes.InternalMargin; - border.CornerRadius = _config.Themes.CornerRadius; + border.Background = _config.Themes.CodeBlockBackground; + border.BorderBrush = _config.Themes.CodeBlockBorderBrush; + border.BorderThickness = _config.Themes.CodeBlockBorderThickness; + border.Padding = _config.Themes.CodeBlockPadding; + border.Margin = _config.Themes.CodeBlockMargin; + border.CornerRadius = _config.Themes.CodeBlockCornerRadius; var richTextBlock = new RichTextBlock(); + richTextBlock.FontFamily = _config.Themes.CodeBlockFontFamily; + richTextBlock.Foreground = _config.Themes.CodeBlockForeground; #if false if (codeBlock is FencedCodeBlock fencedCodeBlock) diff --git a/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs b/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs index bb4feea3d..fdbb9ad6d 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs @@ -41,6 +41,7 @@ public MyHyperlink(LinkInline linkInline, string? baseUrl) _hyperlink = new Hyperlink() { NavigateUri = Extensions.GetUri(url, baseUrl), + Foreground = MarkdownConfig.Default.Themes.LinkForeground }; } @@ -52,6 +53,7 @@ public MyHyperlink(HtmlNode htmlNode, string? baseUrl) _hyperlink = new Hyperlink() { NavigateUri = Extensions.GetUri(url, baseUrl), + Foreground = MarkdownConfig.Default.Themes.LinkForeground }; } diff --git a/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs b/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs index 927083ac4..594d6fd66 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs @@ -65,7 +65,8 @@ private MyHyperlinkButton(string? url, string? baseUrl, HtmlNode? htmlNode, Link _flowDoc = new MyFlowDocument(_linkInline!); } _inlineUIContainer.Child = _hyperLinkButton; - _hyperLinkButton.Content = _flowDoc.RichTextBlock; + _flowDoc.RichTextBlock.Foreground = MarkdownConfig.Default.Themes.LinkForeground; + _hyperLinkButton.Content = _flowDoc.RichTextBlock; } public void AddChild(IAddChild child) diff --git a/components/MarkdownTextBlock/src/TextElements/MyImage.cs b/components/MarkdownTextBlock/src/TextElements/MyImage.cs index 4a2e35df8..64b94fd84 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyImage.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyImage.cs @@ -150,6 +150,18 @@ private async void LoadImage(object sender, RoutedEventArgs e) { _image.Height = _precedentHeight; } + + // Apply theme constraints if provided + var themes = MarkdownConfig.Default.Themes; + if (themes.ImageMaxWidth > 0) + { + _image.MaxWidth = themes.ImageMaxWidth; + } + if (themes.ImageMaxHeight > 0) + { + _image.MaxHeight = themes.ImageMaxHeight; + } + _image.Stretch = themes.ImageStretch; } catch (Exception) { } } diff --git a/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs b/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs index 25ef22618..65ffbf5a0 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyParagraph.cs @@ -26,10 +26,15 @@ public MyParagraph(ParagraphBlock paragraphBlock, WinUIRenderer renderer) // Lists are plain Paragraph_s, one per item. // This is so that you can select across list items. - Thickness margin = new Thickness(0, 8, 0, 8); // renderer.Config.Themes.BlockMargin; + var themes = renderer.Config.Themes; + Thickness margin = themes.ParagraphMargin; int bulletCount = renderer.GetListBulletCount(); - margin.Left += 30 * bulletCount; + margin.Left += themes.ListGutterWidth * bulletCount; _paragraph.Margin = margin; + if (themes.ParagraphLineHeight > 0) + { + _paragraph.LineHeight = themes.ParagraphLineHeight; + } if (bulletCount != 0) { @@ -37,7 +42,7 @@ public MyParagraph(ParagraphBlock paragraphBlock, WinUIRenderer renderer) Run bulletRun = new Run { Text = bullet + "\t" }; _paragraph.Inlines.Add(bulletRun); - _paragraph.TextIndent = -30; + _paragraph.TextIndent = -themes.ListGutterWidth; } } diff --git a/components/MarkdownTextBlock/src/TextElements/MyQuote.cs b/components/MarkdownTextBlock/src/TextElements/MyQuote.cs index 077a22eb7..6633c5bdb 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyQuote.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyQuote.cs @@ -11,15 +11,17 @@ internal class MyQuote : IAddChild private Paragraph _paragraph; private MyFlowDocument _flowDocument; private QuoteBlock _quoteBlock; + private MarkdownThemes _themes; public TextElement TextElement { get => _paragraph; } - public MyQuote(QuoteBlock quoteBlock) + public MyQuote(QuoteBlock quoteBlock, MarkdownThemes themes) { _quoteBlock = quoteBlock; + _themes = themes; _paragraph = new Paragraph(); _flowDocument = new MyFlowDocument(quoteBlock); @@ -30,20 +32,24 @@ public MyQuote(QuoteBlock quoteBlock) grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); var bar = new Grid(); - bar.Width = 4; - bar.Background = new SolidColorBrush(Colors.Gray); + var borderThickness = _themes.QuoteBorderThickness.Left > 0 ? _themes.QuoteBorderThickness.Left : 4; + bar.Width = borderThickness; + bar.Background = _themes.QuoteBorderBrush ?? new SolidColorBrush(Colors.Gray); bar.SetValue(Grid.ColumnProperty, 0); bar.VerticalAlignment = VerticalAlignment.Stretch; bar.Margin = new Thickness(0, 0, 4, 0); grid.Children.Add(bar); - var rightGrid = new Grid(); - rightGrid.Padding = new Thickness(4); + var rightGrid = new Grid(); + rightGrid.Padding = _themes.QuotePadding; + rightGrid.Background = _themes.QuoteBackground; + rightGrid.CornerRadius = _themes.QuoteCornerRadius; rightGrid.Children.Add(_flowDocument.RichTextBlock); + _flowDocument.RichTextBlock.Foreground = _themes.QuoteForeground; rightGrid.SetValue(Grid.ColumnProperty, 1); grid.Children.Add(rightGrid); - grid.Margin = new Thickness(0, 2, 0, 2); + grid.Margin = _themes.QuoteMargin; inlineUIContainer.Child = grid; diff --git a/components/MarkdownTextBlock/src/TextElements/MyTable.cs b/components/MarkdownTextBlock/src/TextElements/MyTable.cs index 423b9fbc8..2cd341cb5 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyTable.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyTable.cs @@ -29,10 +29,11 @@ public MyTable(Table table, MarkdownThemes themes) ( column, table.Count, - borderThickness: 1, - themes.BorderBrush, + borderThickness: themes.TableBorderThickness, + themes.TableBorderBrush ?? themes.BorderBrush, themes.TableHeadingBackground, - themes.CornerRadius + themes.CornerRadius, + themes.TableMargin ); var inlineUIContainer = new InlineUIContainer(); diff --git a/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs b/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs index a9ec2634a..1374b7afd 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyTableCell.cs @@ -66,7 +66,8 @@ public MyTableCell(TableCell tableCell, TextAlignment textAlignment, bool isHead _ => HorizontalAlignment.Left, }; - _container.Padding = new Thickness(4); + // Use themed table cell padding if available + _container.Padding = MarkdownConfig.Default.Themes.TableCellPadding; if (_isHeader) { _flowDocument.RichTextBlock.FontWeight = FontWeights.Bold; diff --git a/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs b/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs index 585cf304a..687a9398c 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyTableUIElement.cs @@ -18,13 +18,12 @@ internal partial class MyTableUIElement : Panel private double[]? _columnWidths; private double[]? _rowHeights; - public MyTableUIElement(int columnCount, int rowCount, double borderThickness, Brush borderBrush, Brush headingBrush, CornerRadius cornerRadius) + public MyTableUIElement(int columnCount, int rowCount, double borderThickness, Brush borderBrush, Brush headingBrush, CornerRadius cornerRadius, Thickness tableMargin) { _columnCount = columnCount; _rowCount = rowCount; _borderThickness = borderThickness; - - Margin = new Thickness(left: 0, top: 10, right: 0, bottom: 10); + Margin = tableMargin; Children.Add(new Border { diff --git a/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs b/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs index 152b16fb1..771ef37c2 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyThematicBreak.cs @@ -26,9 +26,10 @@ public MyThematicBreak(ThematicBreakBlock thematicBreakBlock, MarkdownThemes the Line line = new Line { Stretch = Stretch.Fill, - Stroke = themes.BorderBrush, + Stroke = themes.HorizontalRuleBrush ?? themes.BorderBrush, X2 = 1, - Margin = new Thickness(0, 12, 0, 12) + StrokeThickness = themes.HorizontalRuleThickness, + Margin = themes.HorizontalRuleMargin }; inlineUIContainer.Child = line; _paragraph.Inlines.Add(inlineUIContainer); From 7054b146d52a8416f0bb35e59e83eeb0bbbee7cb Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 18 Sep 2025 20:00:33 +0200 Subject: [PATCH 3/3] Update MarkdownTextBlockExampleSample.xaml.cs --- .../MarkdownTextBlockExampleSample.xaml.cs | 105 +----------------- 1 file changed, 1 insertion(+), 104 deletions(-) diff --git a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs index 76d74bcf0..0e5019958 100644 --- a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs +++ b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs @@ -3,10 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.WinUI.Controls; -using Microsoft.UI; -using Microsoft.UI.Text; using System.Diagnostics; -using Windows.UI; namespace MarkdownTextBlockExperiment.Samples; @@ -603,107 +600,7 @@ public string Text public MarkdownTextBlockExampleSample() { this.InitializeComponent(); - - var themes = new MarkdownThemes - { - // Headings - H1FontSize = 28, - H2FontSize = 24, - H3FontSize = 20, - H4FontSize = 18, - H5FontSize = 16, - H6FontSize = 14, - - H1FontWeight = FontWeights.Bold, - H2FontWeight = FontWeights.SemiBold, - H3FontWeight = FontWeights.Medium, - H4FontWeight = FontWeights.Normal, - H5FontWeight = FontWeights.Normal, - H6FontWeight = FontWeights.Normal, - - H1Foreground = new SolidColorBrush(Colors.Crimson), - H2Foreground = new SolidColorBrush(Colors.DarkOrange), - H3Foreground = new SolidColorBrush(Colors.Goldenrod), - H4Foreground = new SolidColorBrush(Colors.ForestGreen), - H5Foreground = new SolidColorBrush(Colors.SteelBlue), - H6Foreground = new SolidColorBrush(Colors.MediumPurple), - - H1Margin = new Thickness(0, 20, 0, 4), - H2Margin = new Thickness(0, 18, 0, 4), - H3Margin = new Thickness(0, 16, 0, 4), - H4Margin = new Thickness(0, 14, 0, 4), - H5Margin = new Thickness(0, 12, 0, 2), - H6Margin = new Thickness(0, 10, 0, 2), - - // General container - Padding = new Thickness(12), - InternalMargin = new Thickness(6), - CornerRadius = new CornerRadius(6), - - // Paragraph / lists - ParagraphMargin = new Thickness(0, 10, 0, 10), - ParagraphLineHeight = 22, - ListGutterWidth = 28, - ListBulletSpacing = 6, - ListMargin = new Thickness(0, 6, 0, 6), - - // Horizontal rule - HorizontalRuleBrush = new SolidColorBrush(Colors.Gray), - HorizontalRuleThickness = 2, - HorizontalRuleMargin = new Thickness(0, 18, 0, 18), - - // Links - LinkForeground = new SolidColorBrush(Colors.DodgerBlue), - - // Inline code - InlineCodeBackground = new SolidColorBrush(Color.FromArgb(255, 40, 44, 52)), - InlineCodeForeground = new SolidColorBrush(Colors.White), - InlineCodeBorderBrush = new SolidColorBrush(Color.FromArgb(255, 70, 75, 85)), - InlineCodeBorderThickness = new Thickness(1), - InlineCodeCornerRadius = new CornerRadius(3), - InlineCodePadding = new Thickness(4, 0, 4, 0), - InlineCodeFontSize = 13, - InlineCodeFontWeight = FontWeights.SemiBold, - - // Code blocks - CodeBlockBackground = new SolidColorBrush(Color.FromArgb(255, 30, 34, 40)), - CodeBlockForeground = new SolidColorBrush(Colors.Gainsboro), - CodeBlockBorderBrush = new SolidColorBrush(Color.FromArgb(255, 60, 65, 75)), - CodeBlockBorderThickness = new Thickness(1), - CodeBlockPadding = new Thickness(12), - CodeBlockMargin = new Thickness(0, 14, 0, 16), - CodeBlockFontFamily = new FontFamily("Consolas"), - CodeBlockCornerRadius = new CornerRadius(8), - - // Quotes - QuoteBackground = new SolidColorBrush(Color.FromArgb(30, 255, 200, 0)), - QuoteBorderBrush = new SolidColorBrush(Colors.Orange), - QuoteBorderThickness = new Thickness(5, 0, 0, 0), - QuoteForeground = new SolidColorBrush(Colors.DarkSlateGray), - QuoteMargin = new Thickness(0, 10, 0, 10), - QuotePadding = new Thickness(10), - QuoteCornerRadius = new CornerRadius(6), - - // Images - ImageMaxWidth = 420, - ImageMaxHeight = 260, - ImageStretch = Stretch.UniformToFill, - - // Tables - TableBorderBrush = new SolidColorBrush(Colors.DimGray), - TableBorderThickness = 1, - TableCellPadding = new Thickness(8, 4, 8, 4), - TableMargin = new Thickness(0, 18, 0, 18), - TableHeadingBackground = new SolidColorBrush(Color.FromArgb(255, 50, 70, 95)), - - // Other / border defaults - BorderBrush = new SolidColorBrush(Colors.DarkGray), - - // (YAML placeholders if ever used) - YamlBorderBrush = new SolidColorBrush(Colors.DarkGoldenrod), - YamlBorderThickness = new Thickness(1) - }; - _config = new MarkdownConfig { Themes = themes }; + _config = new MarkdownConfig(); _text = _markdown; MarkdownTextBlock.OnLinkClicked += MarkdownTextBlock_OnLinkClicked; }