Skip to content

Commit cb5d81f

Browse files
authored
Merge branch 'main' into title_bar/RTL
2 parents 6614a11 + 8b6abbc commit cb5d81f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+536
-254
lines changed

ReadMe.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Otherwise, you can clone the repo, open the `components` directory, navigate wit
2828
- [DataTable](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/DataTable/samples/DataTable.md)
2929
- [Extensions.DependencyInjection](https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/Extensions.DependencyInjection)
3030
- [MarkdownTextBlock](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/MarkdownTextBlock/samples/MarkdownTextBlock.md)
31-
- [MarqueeText](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/MarqueeText/samples/MarqueeText.md)
31+
- [Marquee](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/Marquee/samples/Marquee.md)
3232
- [Notifications](https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/Notifications)
3333
- [Ribbon](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/Ribbon/samples/Ribbon.md)
3434
- [RivePlayer](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/RivePlayer/samples/RivePlayer.md)

components/MarkdownTextBlock/src/HtmlWriter.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,28 @@ public static void WriteHtml(WinUIRenderer renderer, HtmlNodeCollection nodes)
3636
var myHyperlinkButton = new MyHyperlinkButton(node, renderer.Config.BaseUrl);
3737
myHyperlinkButton.ClickEvent += (sender, e) =>
3838
{
39-
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(((HyperlinkButton)sender).NavigateUri);
39+
var button = (HyperlinkButton)sender;
40+
var uri = button.NavigateUri;
41+
var handled = renderer.MarkdownTextBlock.RaiseLinkClickedEvent(uri);
42+
if (handled)
43+
{
44+
button.NavigateUri = null;
45+
}
4046
};
4147
hyperLink = myHyperlinkButton;
4248
}
4349
else
4450
{
4551
var myHyperlink = new MyHyperlink(node, renderer.Config.BaseUrl);
52+
myHyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground;
4653
myHyperlink.ClickEvent += (sender, e) =>
4754
{
48-
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri);
55+
var uri = sender.NavigateUri;
56+
var handled = renderer.MarkdownTextBlock.RaiseLinkClickedEvent(uri);
57+
if (handled)
58+
{
59+
sender.NavigateUri = null;
60+
}
4961
};
5062
hyperLink = myHyperlink;
5163
}

components/MarkdownTextBlock/src/LinkClickedEventArgs.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ namespace CommunityToolkit.WinUI.Controls;
77
public class LinkClickedEventArgs : EventArgs
88
{
99
public Uri Uri { get; }
10+
/// <summary>
11+
/// Set to true in your handler to indicate the link click was handled and default navigation should be suppressed.
12+
/// </summary>
13+
public bool Handled { get; set; }
1014

1115
public LinkClickedEventArgs(Uri uri)
1216
{

components/MarkdownTextBlock/src/MarkdownTextBlock.Properties.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,23 @@ public partial class MarkdownTextBlock
108108
typeof(MarkdownTextBlock),
109109
new PropertyMetadata(null));
110110

111+
/// <summary>
112+
/// Identifies the <see cref="IsTextSelectionEnabled"/> dependency property.
113+
/// </summary>
114+
private static readonly DependencyProperty IsTextSelectionEnabledProperty = DependencyProperty.Register(
115+
nameof(IsTextSelectionEnabled),
116+
typeof(bool),
117+
typeof(MarkdownTextBlock),
118+
new PropertyMetadata(false, OnIsTextSelectionEnabledChanged));
119+
120+
private static void OnIsTextSelectionEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
121+
{
122+
if (d is MarkdownTextBlock mtb && mtb._document != null)
123+
{
124+
mtb._document.RichTextBlock.IsTextSelectionEnabled = (bool)e.NewValue;
125+
}
126+
}
127+
111128
public MarkdownConfig Config
112129
{
113130
get => (MarkdownConfig)GetValue(ConfigProperty);
@@ -203,4 +220,13 @@ public MarkdownDocument? MarkdownDocument
203220
get => (MarkdownDocument)GetValue(MarkdownDocumentProperty);
204221
private set => SetValue(MarkdownDocumentProperty, value);
205222
}
223+
224+
/// <summary>
225+
/// Gets or sets a value indicating whether text selection is enabled.
226+
/// </summary>
227+
public bool IsTextSelectionEnabled
228+
{
229+
get => (bool)GetValue(IsTextSelectionEnabledProperty);
230+
set => SetValue(IsTextSelectionEnabledProperty, value);
231+
}
206232
}

components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ public partial class MarkdownTextBlock : Control
2323

2424
public event EventHandler<LinkClickedEventArgs>? OnLinkClicked;
2525

26-
internal void RaiseLinkClickedEvent(Uri uri) => OnLinkClicked?.Invoke(this, new LinkClickedEventArgs(uri));
26+
internal bool RaiseLinkClickedEvent(Uri uri)
27+
{
28+
if (OnLinkClicked == null)
29+
{
30+
return false;
31+
}
32+
var args = new LinkClickedEventArgs(uri);
33+
OnLinkClicked?.Invoke(this, args);
34+
return args.Handled;
35+
}
2736

2837
private static void OnConfigChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
2938
{

components/MarkdownTextBlock/src/MarkdownThemes.cs

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ public sealed class MarkdownThemes : DependencyObject
3434

3535
public double H6FontSize { get; set; } = 12;
3636

37-
public Brush HeadingForeground { get; set; } = Extensions.GetAccentColorBrush();
37+
public Brush H1Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
38+
public Brush H2Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
39+
public Brush H3Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
40+
public Brush H4Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
41+
public Brush H5Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
42+
public Brush H6Foreground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
3843

39-
public FontWeight H1FontWeight { get; set; } = FontWeights.Bold;
44+
public FontWeight H1FontWeight { get; set; } = FontWeights.SemiBold;
4045

4146
public FontWeight H2FontWeight { get; set; } = FontWeights.Normal;
4247

@@ -48,10 +53,10 @@ public sealed class MarkdownThemes : DependencyObject
4853

4954
public FontWeight H6FontWeight { get; set; } = FontWeights.Normal;
5055

51-
public Thickness H1Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
52-
public Thickness H2Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
53-
public Thickness H3Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
54-
public Thickness H4Margin { get; set; } = new(left: 0, top: 14, right: 0, bottom: 0);
56+
public Thickness H1Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
57+
public Thickness H2Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
58+
public Thickness H3Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
59+
public Thickness H4Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
5560
public Thickness H5Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
5661
public Thickness H6Margin { get; set; } = new(left: 0, top: 8, right: 0, bottom: 0);
5762

@@ -73,4 +78,54 @@ public sealed class MarkdownThemes : DependencyObject
7378
public double InlineCodeFontSize { get; set; } = 10;
7479

7580
public FontWeight InlineCodeFontWeight { get; set; } = FontWeights.Normal;
81+
82+
// Legacy parity properties (new)
83+
// Code block styling
84+
public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
85+
public Brush CodeBlockBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
86+
public Thickness CodeBlockBorderThickness { get; set; } = new Thickness(1);
87+
public Thickness CodeBlockPadding { get; set; } = new Thickness(8);
88+
public Thickness CodeBlockMargin { get; set; } = new Thickness(0, 8, 0, 8);
89+
public FontFamily CodeBlockFontFamily { get; set; } = new FontFamily("Consolas");
90+
public Brush CodeBlockForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
91+
public CornerRadius CodeBlockCornerRadius { get; set; } = new CornerRadius(4);
92+
93+
// Horizontal rule
94+
public Brush HorizontalRuleBrush { get; set; } = new SolidColorBrush(Colors.Gray);
95+
public double HorizontalRuleThickness { get; set; } = 1.0;
96+
public Thickness HorizontalRuleMargin { get; set; } = new Thickness(0, 12, 0, 12);
97+
98+
// Link styling
99+
public Brush LinkForeground { get; set; } = (Brush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"] ?? new SolidColorBrush(Colors.DodgerBlue);
100+
101+
// Paragraph / list
102+
public Thickness ParagraphMargin { get; set; } = new Thickness(0, 8, 0, 8);
103+
public double ParagraphLineHeight { get; set; } = 0; // 0 = default
104+
public double ListBulletSpacing { get; set; } = 4; // spaces after bullet
105+
public double ListGutterWidth { get; set; } = 30; // indent delta per level
106+
public Thickness ListMargin { get; set; } = new Thickness(0, 4, 0, 4);
107+
108+
// Quote styling
109+
public Brush QuoteBackground { get; set; } = new SolidColorBrush(Colors.Transparent);
110+
public Brush QuoteBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
111+
public Thickness QuoteBorderThickness { get; set; } = new Thickness(4, 0, 0, 0);
112+
public Brush QuoteForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];
113+
public Thickness QuoteMargin { get; set; } = new Thickness(0, 4, 0, 4);
114+
public Thickness QuotePadding { get; set; } = new Thickness(4);
115+
public CornerRadius QuoteCornerRadius { get; set; } = new CornerRadius(4);
116+
117+
// Image styling
118+
public double ImageMaxWidth { get; set; } = 0; // 0 = no constraint
119+
public double ImageMaxHeight { get; set; } = 0;
120+
public Stretch ImageStretch { get; set; } = Stretch.Uniform;
121+
122+
// Table styling
123+
public Brush TableBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
124+
public double TableBorderThickness { get; set; } = 1;
125+
public Thickness TableCellPadding { get; set; } = new Thickness(4);
126+
public Thickness TableMargin { get; set; } = new Thickness(0, 10, 0, 10);
127+
128+
// YAML / not currently used - placeholders for parity
129+
public Brush YamlBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
130+
public Thickness YamlBorderThickness { get; set; } = new Thickness(1);
76131
}

components/MarkdownTextBlock/src/Renderers/ObjectRenderers/Inlines/LinkInlineRenderer.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,33 @@ protected override void Write(WinUIRenderer renderer, LinkInline link)
3333
var myHyperlinkButton = new MyHyperlinkButton(link, renderer.Config.BaseUrl);
3434
myHyperlinkButton.ClickEvent += (sender, e) =>
3535
{
36-
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(((HyperlinkButton)sender).NavigateUri);
36+
var button = (HyperlinkButton)sender;
37+
var uri = button.NavigateUri;
38+
var handled = renderer.MarkdownTextBlock.RaiseLinkClickedEvent(uri);
39+
if (handled)
40+
{
41+
// Suppress default navigation by clearing NavigateUri just for this invocation
42+
button.NavigateUri = null;
43+
// Optionally restore later; not needed unless reused.
44+
}
3745
};
46+
// Apply link foreground to nested RichTextBlock content
47+
// (Handled in MyHyperlinkButton initialization via MarkdownConfig.Default for now)
3848
renderer.Push(myHyperlinkButton);
3949
}
4050
else
4151
{
4252
var hyperlink = new MyHyperlink(link, renderer.Config.BaseUrl);
53+
hyperlink.TextElement.Foreground = renderer.Config.Themes.LinkForeground;
4354
hyperlink.ClickEvent += (sender, e) =>
4455
{
45-
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri);
56+
var uri = sender.NavigateUri;
57+
var handled = renderer.MarkdownTextBlock.RaiseLinkClickedEvent(uri);
58+
if (handled)
59+
{
60+
// Suppress navigation by clearing NavigateUri
61+
sender.NavigateUri = null;
62+
}
4663
};
4764

4865
renderer.Push(hyperlink);

components/MarkdownTextBlock/src/Renderers/ObjectRenderers/QuoteBlockRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protected override void Write(WinUIRenderer renderer, QuoteBlock obj)
1414
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
1515
if (obj == null) throw new ArgumentNullException(nameof(obj));
1616

17-
var quote = new MyQuote(obj);
17+
var quote = new MyQuote(obj, renderer.Config.Themes);
1818

1919
renderer.Push(quote);
2020
renderer.WriteChildren(obj);

components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ public MyCodeBlock(CodeBlock codeBlock, MarkdownConfig config)
2424
_paragraph = new Paragraph();
2525
var container = new InlineUIContainer();
2626
var border = new Border();
27-
border.Background = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
28-
border.Padding = _config.Themes.Padding;
29-
border.Margin = _config.Themes.InternalMargin;
30-
border.CornerRadius = _config.Themes.CornerRadius;
27+
border.Background = _config.Themes.CodeBlockBackground;
28+
border.BorderBrush = _config.Themes.CodeBlockBorderBrush;
29+
border.BorderThickness = _config.Themes.CodeBlockBorderThickness;
30+
border.Padding = _config.Themes.CodeBlockPadding;
31+
border.Margin = _config.Themes.CodeBlockMargin;
32+
border.CornerRadius = _config.Themes.CodeBlockCornerRadius;
3133
var richTextBlock = new RichTextBlock();
34+
richTextBlock.FontFamily = _config.Themes.CodeBlockFontFamily;
35+
richTextBlock.Foreground = _config.Themes.CodeBlockForeground;
3236

3337
#if false
3438
if (codeBlock is FencedCodeBlock fencedCodeBlock)

components/MarkdownTextBlock/src/TextElements/MyHeading.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,15 @@ private void SetHProperties(int level)
6060
5 => _config.Themes.H5FontSize,
6161
_ => _config.Themes.H6FontSize,
6262
};
63-
_paragraph.Foreground = _config.Themes.HeadingForeground;
63+
_paragraph.Foreground = level switch
64+
{
65+
1 => _config.Themes.H1Foreground,
66+
2 => _config.Themes.H2Foreground,
67+
3 => _config.Themes.H3Foreground,
68+
4 => _config.Themes.H4Foreground,
69+
5 => _config.Themes.H5Foreground,
70+
_ => _config.Themes.H6Foreground,
71+
};
6472
_paragraph.FontWeight = level switch
6573
{
6674
1 => _config.Themes.H1FontWeight,

0 commit comments

Comments
 (0)