Skip to content

Commit

Permalink
! Optimize display of <code> in C# XML Doc (#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
wmjordan committed Jun 16, 2024
1 parent f156ebf commit 81b4a32
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 30 deletions.
10 changes: 10 additions & 0 deletions Codist/Helpers/WpfHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
Expand Down Expand Up @@ -38,6 +39,7 @@ static partial class WpfHelper
internal static readonly Thickness MiddleVerticalMargin = new Thickness(0, 6, 0, 6);
internal static readonly Thickness MiddleTopMargin = new Thickness(0, 6, 0, 0);
internal static readonly Thickness MiddleBottomMargin = new Thickness(0, 0, 0, 6);
internal static readonly Thickness TinyBottomMargin = new Thickness(0, 0, 0, 1);
internal static readonly Thickness MenuItemMargin = new Thickness(6, 0, 6, 0);

#region TextBlock and Run
Expand Down Expand Up @@ -305,6 +307,14 @@ public static TElement LimitSize<TElement>(this TElement element)
}
return element;
}
public static TElement BindWidthAsAncestor<TElement>(this TElement element, Type ancestor)
where TElement : FrameworkElement {
return element.Bind(FrameworkElement.WidthProperty, new Binding {
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, ancestor, 1),
Path = new PropertyPath("ActualWidth")
});
}

public static TElement ClearSpacing<TElement>(this TElement element)
where TElement : Control {
element.Margin = element.Padding = element.BorderThickness = NoMargin;
Expand Down
9 changes: 9 additions & 0 deletions Codist/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Codist/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2785,4 +2785,7 @@ Ctrl: Match case</value>
<data name="CMD_ExtractLinesContainingSelection" xml:space="preserve">
<value>Extract Lines Containing Selection</value>
</data>
<data name="T_Code" xml:space="preserve">
<value>Code</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Codist/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2785,4 +2785,7 @@ Shift: Assign by default only</value>
Shift: Match whole word
Ctrl: Match case</value>
</data>
<data name="T_Code" xml:space="preserve">
<value>Code</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Codist/Properties/Resources.zh-Hans.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2771,4 +2771,7 @@ Ctrl: 匹配大小写</value>
<data name="CMD_ExtractLinesContainingSelection" xml:space="preserve">
<value>提取包含选中文字的行</value>
</data>
<data name="T_Code" xml:space="preserve">
<value>代码</value>
</data>
</root>
108 changes: 78 additions & 30 deletions Codist/Semantics/XmlDocRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace Codist
sealed class XmlDocRenderer
{
const int LIST_UNDEFINED = -1, LIST_BULLET = -2, LIST_NOT_NUMERIC = -3;
const int BLOCK_PARA = 0, BLOCK_ITEM = 1, BLOCK_OTHER = 2, BLOCK_TITLE = 3;

static readonly Regex __FixWhitespaces = new Regex(" {2,}", RegexOptions.Compiled | RegexOptions.CultureInvariant);
readonly Compilation _Compilation;
Expand Down Expand Up @@ -250,6 +249,15 @@ public void Render(XElement content, TextBlock text) {
}
Render(content, text.Inlines);
}
public void Render(XElement content, FlowDocument document) {
if (content == null || IsEmptyElement(content)) {
return;
}
if (document.Blocks.FirstBlock is Paragraph p == false) {
document.Blocks.Add(p = new Paragraph());
}
Render(content, p.Inlines);
}
public void Render(XContainer content, InlineCollection inlines) {
InternalRender(content, inlines, null);
}
Expand All @@ -264,7 +272,7 @@ void InternalRender(XContainer content, InlineCollection inlines, ListContext li
list = list == null
? new ListContext(e.Attribute("type")?.Value)
: new ListContext(e.Attribute("type")?.Value, list);
RenderBlockContent(inlines, list, e, BLOCK_OTHER);
RenderBlockContent(inlines, list, e, BlockType.List);
list = list.Parent;
break;
case "para":
Expand All @@ -282,36 +290,33 @@ void InternalRender(XContainer content, InlineCollection inlines, ListContext li
}
break;
case "listheader":
RenderBlockContent(inlines, list, e, BLOCK_OTHER);
RenderBlockContent(inlines, list, e, BlockType.List);
break;
case "h1":
RenderBlockContent(inlines, list, e, BLOCK_TITLE).FontSize = ThemeHelper.ToolTipFontSize + 5;
RenderBlockContent(inlines, list, e, BlockType.Title).FontSize = ThemeHelper.ToolTipFontSize + 5;
break;
case "h2":
RenderBlockContent(inlines, list, e, BLOCK_TITLE).FontSize = ThemeHelper.ToolTipFontSize + 3;
RenderBlockContent(inlines, list, e, BlockType.Title).FontSize = ThemeHelper.ToolTipFontSize + 3;
break;
case "h3":
RenderBlockContent(inlines, list, e, BLOCK_TITLE).FontSize = ThemeHelper.ToolTipFontSize + 2;
RenderBlockContent(inlines, list, e, BlockType.Title).FontSize = ThemeHelper.ToolTipFontSize + 2;
break;
case "h4":
RenderBlockContent(inlines, list, e, BLOCK_TITLE).FontSize = ThemeHelper.ToolTipFontSize + 1;
RenderBlockContent(inlines, list, e, BlockType.Title).FontSize = ThemeHelper.ToolTipFontSize + 1;
break;
case "h5":
RenderBlockContent(inlines, list, e, BLOCK_TITLE).FontSize = ThemeHelper.ToolTipFontSize + 0.5;
RenderBlockContent(inlines, list, e, BlockType.Title).FontSize = ThemeHelper.ToolTipFontSize + 0.5;
break;
case "h6":
RenderBlockContent(inlines, list, e, BLOCK_TITLE);
RenderBlockContent(inlines, list, e, BlockType.Title);
break;
case "code":
++_IsCode;
var span = RenderBlockContent(inlines, list, e, BLOCK_OTHER);
span.FontFamily = GetCodeFont();
span.Background = ThemeHelper.ToolWindowBackgroundBrush;
span.Foreground = ThemeHelper.ToolWindowTextBrush;
RenderBlockContent(inlines, list, e, BlockType.Code);
--_IsCode;
break;
case "item":
RenderBlockContent(inlines, list, e, BLOCK_ITEM);
RenderBlockContent(inlines, list, e, BlockType.ListItem);
break;
case "see":
case "seealso":
Expand All @@ -326,7 +331,11 @@ void InternalRender(XContainer content, InlineCollection inlines, ListContext li
case "c":
case "tt":
++_IsCode;
StyleInner(e, inlines, new Span() { FontFamily = GetCodeFont(), Background = ThemeHelper.ToolWindowBackgroundBrush, Foreground = ThemeHelper.ToolWindowTextBrush });
StyleInner(e, inlines, new Span() {
FontFamily = GetCodeFont(),
Background = ThemeHelper.ToolWindowBackgroundBrush,
Foreground = ThemeHelper.ToolWindowTextBrush
});
--_IsCode;
break;
case "b":
Expand Down Expand Up @@ -356,16 +365,7 @@ void InternalRender(XContainer content, InlineCollection inlines, ListContext li
case "hr":
inlines.AddRange(new Inline[] {
new LineBreak(),
new InlineUIContainer(new Border {
Height = 1,
Background = ThemeHelper.DocumentTextBrush,
Margin = WpfHelper.MiddleVerticalMargin,
Opacity = 0.5,
MinWidth = 100
}.Bind(FrameworkElement.WidthProperty, new Binding {
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ThemedTipText), 1),
Path = new PropertyPath("ActualWidth")
})),
CreateHorizontalRuler(),
new LineBreak() });
break;
//case "list":
Expand Down Expand Up @@ -414,6 +414,16 @@ void InternalRender(XContainer content, InlineCollection inlines, ListContext li
}
}

static InlineUIContainer CreateHorizontalRuler() {
return new InlineUIContainer(new Border {
Height = 1,
Background = ThemeHelper.DocumentTextBrush,
Margin = WpfHelper.MiddleVerticalMargin,
Opacity = 0.5,
MinWidth = 100
}.BindWidthAsAncestor(typeof(ThemedTipText)));
}

static bool IsUrl(string text) {
return text.StartsWith("http://", StringComparison.Ordinal) || text.StartsWith("https://", StringComparison.Ordinal);
}
Expand Down Expand Up @@ -516,11 +526,11 @@ XAttribute RenderTypeParamRef(InlineCollection inlines, XElement e) {
return r;
}

Span RenderBlockContent(InlineCollection inlines, ListContext list, XElement e, int blockType) {
Span RenderBlockContent(InlineCollection inlines, ListContext list, XElement e, BlockType blockType) {
if (inlines.LastInline != null && inlines.LastInline is LineBreak == false) {
inlines.AppendLineWithMargin();
}
if (blockType == BLOCK_ITEM) {
if (blockType == BlockType.ListItem) {
PopulateListNumber(inlines, list);
}
else {
Expand All @@ -530,18 +540,46 @@ Span RenderBlockContent(InlineCollection inlines, ListContext list, XElement e,
if (_IsCode > 0) {
span.FontFamily = GetCodeFont();
}
if (blockType == BLOCK_TITLE) {
if (blockType == BlockType.Title) {
span.FontWeight = FontWeights.Bold;
}
else if (blockType == BlockType.Code) {
inlines.Add(CreateCodeBlockStart());
}
inlines.Add(span);
InternalRender(e, span.Inlines, list);
if (blockType != BLOCK_ITEM && e.NextNode != null
if (blockType != BlockType.ListItem && e.NextNode != null
&& IsInlineElementName((e.NextNode as XElement)?.Name.LocalName) == false) {
inlines.Add(new LineBreak());
inlines.Add(blockType == BlockType.Code ? CreateCodeBlockEnd() : new LineBreak());
}
return span;
}

static InlineUIContainer CreateCodeBlockStart() {
return new InlineUIContainer(new Border {
Child = new TextBlock {
Text = R.T_Code,
Padding = WpfHelper.MiddleHorizontalMargin,
Margin = WpfHelper.MiddleHorizontalMargin,
Foreground = ThemeHelper.MenuTextBrush,
Background = ThemeHelper.MenuHoverBackgroundBrush,
TextAlignment = TextAlignment.Left,
HorizontalAlignment = HorizontalAlignment.Left,
},
BorderBrush = ThemeHelper.ToolWindowBackgroundBrush,
BorderThickness = WpfHelper.TinyBottomMargin,
Margin = WpfHelper.MiddleVerticalMargin,
}.BindWidthAsAncestor(typeof(ThemedTipText)));
}

static InlineUIContainer CreateCodeBlockEnd() {
return new InlineUIContainer(new Border {
Height = 1,
Background = ThemeHelper.MenuHoverBackgroundBrush,
Margin = WpfHelper.MiddleVerticalMargin,
}.BindWidthAsAncestor(typeof(ThemedTipText)));
}

static void PopulateListNumber(InlineCollection text, ListContext list) {
string indent = list.Indent > 0 ? new string(' ', list.Indent) : String.Empty;
if (list.ListType > 0) {
Expand Down Expand Up @@ -744,6 +782,16 @@ public ListContext(string type, ListContext parent) : this(type) {
Parent = parent;
}
}

enum BlockType
{
Normal,
ListItem,
List,
Title,
Code
}

enum ListType
{
Number = 1,
Expand Down

0 comments on commit 81b4a32

Please sign in to comment.