Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/MarkdownTextBlock/src/HtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,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) =>
{
var uri = sender.NavigateUri;
Expand Down
26 changes: 26 additions & 0 deletions components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ public partial class MarkdownTextBlock
typeof(MarkdownTextBlock),
new PropertyMetadata(null));

/// <summary>
/// Identifies the <see cref="IsTextSelectionEnabled"/> dependency property.
/// </summary>
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);
Expand Down Expand Up @@ -203,4 +220,13 @@ public MarkdownDocument? MarkdownDocument
get => (MarkdownDocument)GetValue(MarkdownDocumentProperty);
private set => SetValue(MarkdownDocumentProperty, value);
}

/// <summary>
/// Gets or sets a value indicating whether text selection is enabled.
/// </summary>
public bool IsTextSelectionEnabled
{
get => (bool)GetValue(IsTextSelectionEnabledProperty);
set => SetValue(IsTextSelectionEnabledProperty, value);
}
}
67 changes: 61 additions & 6 deletions components/MarkdownTextBlock/src/MarkdownThemes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand All @@ -73,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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ protected override void Write(WinUIRenderer renderer, LinkInline link)
// Optionally restore later; not needed unless reused.
}
};
// 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) =>
{
var uri = sender.NavigateUri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 8 additions & 4 deletions components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 9 additions & 1 deletion components/MarkdownTextBlock/src/TextElements/MyHeading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public MyHyperlink(LinkInline linkInline, string? baseUrl)
_hyperlink = new Hyperlink()
{
NavigateUri = Extensions.GetUri(url, baseUrl),
Foreground = MarkdownConfig.Default.Themes.LinkForeground
};
}

Expand All @@ -52,6 +53,7 @@ public MyHyperlink(HtmlNode htmlNode, string? baseUrl)
_hyperlink = new Hyperlink()
{
NavigateUri = Extensions.GetUri(url, baseUrl),
Foreground = MarkdownConfig.Default.Themes.LinkForeground
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions components/MarkdownTextBlock/src/TextElements/MyImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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) { }
}
Expand Down
11 changes: 8 additions & 3 deletions components/MarkdownTextBlock/src/TextElements/MyParagraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,23 @@ 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)
{
string bullet = renderer.PeekListBullet();
Run bulletRun = new Run { Text = bullet + "\t" };

_paragraph.Inlines.Add(bulletRun);
_paragraph.TextIndent = -30;
_paragraph.TextIndent = -themes.ListGutterWidth;
}
}

Expand Down
18 changes: 12 additions & 6 deletions components/MarkdownTextBlock/src/TextElements/MyQuote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;

Expand Down
7 changes: 4 additions & 3 deletions components/MarkdownTextBlock/src/TextElements/MyTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion components/MarkdownTextBlock/src/TextElements/MyTableCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading