Public Access
Add tray rules and identities editor
PR and Push Build/Test / build-and-test (push) Successful in 7m0s
PR and Push Build/Test / build-and-test (push) Successful in 7m0s
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
#if WINDOWS
|
||||
using Aprillz.MewUI;
|
||||
using Aprillz.MewUI.Controls;
|
||||
|
||||
namespace MeetingAssistant.Workflow;
|
||||
|
||||
internal static class WorkflowRulesEditorMarkdownRenderer
|
||||
{
|
||||
public static UIElement CreateContent(string content)
|
||||
{
|
||||
var panel = new StackPanel()
|
||||
.Vertical()
|
||||
.Spacing(7);
|
||||
foreach (var block in WorkflowRulesEditorMarkdown.Parse(content))
|
||||
{
|
||||
panel.Add(block switch
|
||||
{
|
||||
WorkflowRulesEditorMarkdownCodeBlock codeBlock => CreateCodeBlock(codeBlock),
|
||||
WorkflowRulesEditorMarkdownTable table => CreateTable(table),
|
||||
WorkflowRulesEditorMarkdownParagraph paragraph => CreateParagraph(paragraph),
|
||||
_ => new TextBlock()
|
||||
});
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static UIElement CreateParagraph(WorkflowRulesEditorMarkdownParagraph paragraph)
|
||||
{
|
||||
var lines = SplitInlineLines(paragraph.Inlines);
|
||||
if (lines.Count == 1)
|
||||
{
|
||||
return CreateParagraphLine(lines[0]);
|
||||
}
|
||||
|
||||
var panel = new StackPanel()
|
||||
.Vertical()
|
||||
.Spacing(3);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
panel.Add(CreateParagraphLine(line));
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static UIElement CreateParagraphLine(IReadOnlyList<WorkflowRulesEditorMarkdownInline> inlines)
|
||||
{
|
||||
var linePanel = new WrapPanel()
|
||||
.Spacing(1);
|
||||
foreach (var inline in inlines)
|
||||
{
|
||||
foreach (var element in CreateInlineElements(inline))
|
||||
{
|
||||
linePanel.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return linePanel;
|
||||
}
|
||||
|
||||
private static IEnumerable<UIElement> CreateInlineElements(WorkflowRulesEditorMarkdownInline inline)
|
||||
{
|
||||
if (inline.Style == WorkflowRulesEditorMarkdownInlineStyle.Code)
|
||||
{
|
||||
yield return CreateInlineCode(inline.Text);
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var token in SplitInlineText(inline.Text))
|
||||
{
|
||||
var text = new TextBlock()
|
||||
.Text(token)
|
||||
.TextWrapping(TextWrapping.Wrap)
|
||||
.Foreground(Color.FromRgb(230, 235, 243));
|
||||
if (inline.Style == WorkflowRulesEditorMarkdownInlineStyle.Bold)
|
||||
{
|
||||
text.FontWeight(FontWeight.Bold);
|
||||
}
|
||||
else if (inline.Style == WorkflowRulesEditorMarkdownInlineStyle.Italic)
|
||||
{
|
||||
text.FontFamily("Segoe UI Italic");
|
||||
}
|
||||
|
||||
yield return text;
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<IReadOnlyList<WorkflowRulesEditorMarkdownInline>> SplitInlineLines(
|
||||
IReadOnlyList<WorkflowRulesEditorMarkdownInline> inlines)
|
||||
{
|
||||
var lines = new List<IReadOnlyList<WorkflowRulesEditorMarkdownInline>>();
|
||||
var current = new List<WorkflowRulesEditorMarkdownInline>();
|
||||
foreach (var inline in inlines)
|
||||
{
|
||||
var parts = inline.Text.Split('\n');
|
||||
for (var index = 0; index < parts.Length; index++)
|
||||
{
|
||||
if (parts[index].Length > 0)
|
||||
{
|
||||
current.Add(inline with { Text = parts[index] });
|
||||
}
|
||||
|
||||
if (index < parts.Length - 1)
|
||||
{
|
||||
lines.Add(current);
|
||||
current = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lines.Add(current);
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static UIElement CreateInlineCode(string text)
|
||||
{
|
||||
return new Border()
|
||||
.Padding(4, 1, 4, 2)
|
||||
.Margin(1, 0, 1, 0)
|
||||
.CornerRadius(4)
|
||||
.BorderThickness(1)
|
||||
.BorderBrush(Color.FromRgb(86, 94, 108))
|
||||
.Background(Color.FromRgb(24, 28, 35))
|
||||
.Child(new TextBlock()
|
||||
.Text(text)
|
||||
.FontFamily("Consolas")
|
||||
.Foreground(Color.FromRgb(237, 241, 247)));
|
||||
}
|
||||
|
||||
private static UIElement CreateTable(WorkflowRulesEditorMarkdownTable table)
|
||||
{
|
||||
var rows = table.Rows
|
||||
.Select(row => new MarkdownTableRow(PadCells(row, table.Header.Count)))
|
||||
.ToArray();
|
||||
var gridView = new GridView()
|
||||
.HeaderHeight(30)
|
||||
.RowHeight(30)
|
||||
.CellPadding(new Thickness(8, 4, 8, 4))
|
||||
.ShowGridLines(true)
|
||||
.ZebraStriping(true);
|
||||
|
||||
for (var index = 0; index < table.Header.Count; index++)
|
||||
{
|
||||
var columnIndex = index;
|
||||
gridView.AddColumn<MarkdownTableRow>(
|
||||
table.Header[index],
|
||||
GetMarkdownTableColumnWidth(table, index),
|
||||
_ => new TextBlock()
|
||||
.TextWrapping(TextWrapping.NoWrap)
|
||||
.Foreground(Color.FromRgb(230, 235, 243)),
|
||||
(element, row, _, _) => ((TextBlock)element).Text(row.GetCell(columnIndex)),
|
||||
minWidth: 64,
|
||||
resizable: true);
|
||||
}
|
||||
|
||||
return gridView
|
||||
.ItemsSource(rows)
|
||||
.MinWidth(Math.Min(900, table.Header.Count * 120))
|
||||
.Height(Math.Min(420, 30 + Math.Max(1, rows.Length) * 30));
|
||||
}
|
||||
|
||||
private static UIElement CreateCodeBlock(WorkflowRulesEditorMarkdownCodeBlock codeBlock)
|
||||
{
|
||||
return new Border()
|
||||
.Padding(9)
|
||||
.CornerRadius(6)
|
||||
.BorderThickness(1)
|
||||
.BorderBrush(Color.FromRgb(86, 94, 108))
|
||||
.Background(Color.FromRgb(20, 24, 31))
|
||||
.Child(new TextBlock()
|
||||
.Text(codeBlock.Text)
|
||||
.TextWrapping(TextWrapping.Wrap)
|
||||
.FontFamily("Consolas")
|
||||
.Foreground(Color.FromRgb(237, 241, 247)));
|
||||
}
|
||||
|
||||
private static IEnumerable<string> SplitInlineText(string text)
|
||||
{
|
||||
var start = 0;
|
||||
while (start < text.Length)
|
||||
{
|
||||
var end = start;
|
||||
var isWhitespace = char.IsWhiteSpace(text[start]);
|
||||
while (end < text.Length && char.IsWhiteSpace(text[end]) == isWhitespace)
|
||||
{
|
||||
end++;
|
||||
}
|
||||
|
||||
var token = text[start..end];
|
||||
if (token.Length > 0)
|
||||
{
|
||||
yield return token;
|
||||
}
|
||||
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string> PadCells(IReadOnlyList<string> cells, int count)
|
||||
{
|
||||
if (cells.Count >= count)
|
||||
{
|
||||
return cells;
|
||||
}
|
||||
|
||||
return cells
|
||||
.Concat(Enumerable.Repeat("", count - cells.Count))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static double GetMarkdownTableColumnWidth(
|
||||
WorkflowRulesEditorMarkdownTable table,
|
||||
int index)
|
||||
{
|
||||
var maxLength = new[] { table.Header[index].Length }
|
||||
.Concat(table.Rows.Select(row => index < row.Count ? row[index].Length : 0))
|
||||
.DefaultIfEmpty(0)
|
||||
.Max();
|
||||
return Math.Clamp(maxLength * 8 + 28, 72, 260);
|
||||
}
|
||||
|
||||
private sealed record MarkdownTableRow(IReadOnlyList<string> Cells)
|
||||
{
|
||||
public string GetCell(int index)
|
||||
{
|
||||
return index >= 0 && index < Cells.Count
|
||||
? Cells[index]
|
||||
: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user