Skip to content

Commit

Permalink
Merge pull request #143 from whistyun/nightly
Browse files Browse the repository at this point in the history
supports text selection and codeblock copy
  • Loading branch information
whistyun authored Mar 16, 2024
2 parents b7ed9d2 + 60ce07d commit 22701ab
Show file tree
Hide file tree
Showing 194 changed files with 6,627 additions and 1,662 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:

strategy:
matrix:
versions: [ 11.0.0, 11.0.3, 11.0.4 ]
versions: [ 11.0.10, 11.1.0-beta1 ]

steps:
- uses: actions/checkout@v2
Expand Down
37 changes: 37 additions & 0 deletions ColorDocument.Avalonia/ClassNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ColorDocument.Avalonia
{
public static class ClassNames
{
public const string Heading1Class = "Heading1";
public const string Heading2Class = "Heading2";
public const string Heading3Class = "Heading3";
public const string Heading4Class = "Heading4";
public const string Heading5Class = "Heading5";
public const string Heading6Class = "Heading6";

public const string CodeBlockClass = "CodeBlock";
public const string ContainerBlockClass = "ContainerBlock";
public const string NoContainerClass = "NoContainer";
public const string BlockquoteClass = "Blockquote";
public const string NoteClass = "Note";

public const string ParagraphClass = "Paragraph";

public const string TableClass = "Table";
public const string TableHeaderClass = "TableHeader";
public const string TableFirstRowClass = "FirstTableRow";
public const string TableRowOddClass = "OddTableRow";
public const string TableRowEvenClass = "EvenTableRow";
public const string TableLastRowClass = "LastTableRow";
public const string TableFooterClass = "TableFooter";

public const string ListClass = "List";
public const string ListMarkerClass = "ListMarker";
}
}
27 changes: 27 additions & 0 deletions ColorDocument.Avalonia/ColorDocument.Avalonia.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\Markdown.Avalonia.props" />

<PropertyGroup>
<TargetFrameworks>$(PackageTargetFrameworks)</TargetFrameworks>
<Version>$(PackageVersion)</Version>
<Authors>Bevan Arps(original); whistyun</Authors>
<PackageId>ColorDocument.Avalonia</PackageId>

<Version>$(PackageVersion)</Version>
<Authors>whistyun</Authors>
<Copyright>Copyright (c) 2024 whistyun</Copyright>
<PackageProjectUrl>https://github.com/whistyun/Markdown.Avalonia/tree/master/ColorDocument.Avalonia/</PackageProjectUrl>
<LangVersion>9</LangVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ColorTextBlock.Avalonia\ColorTextBlock.Avalonia.csproj" />
</ItemGroup>
</Project>
47 changes: 47 additions & 0 deletions ColorDocument.Avalonia/DocumentElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using System.Collections.Generic;
using System.Text;

namespace ColorDocument.Avalonia
{
public abstract class DocumentElement
{
private ISelectionRenderHelper? _helper;

public abstract Control Control { get; }
public abstract IEnumerable<DocumentElement> Children { get; }

public ISelectionRenderHelper? Helper
{
get => _helper;
set
{
_helper = value;
foreach (var child in Children)
child.Helper = value;
}
}

public Rect GetRect(Layoutable anchor) => Control.GetRectInDoc(anchor).GetValueOrDefault();
public abstract void Select(Point from, Point to);
public abstract void UnSelect();

public virtual string GetSelectedText()
{
var builder = new StringBuilder();
ConstructSelectedText(builder);
return builder.ToString();
}

public abstract void ConstructSelectedText(StringBuilder stringBuilder);

}

public interface ISelectionRenderHelper
{
void Register(Control control);
void Unregister(Control control);
}
}
88 changes: 88 additions & 0 deletions ColorDocument.Avalonia/DocumentElements/BlockquoteElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ColorDocument.Avalonia.DocumentElements
{
/// <summary>
/// The document element for expression of blockquote.
/// </summary>
// 引用を表現するためのドキュメント要素
public class BlockquoteElement : DocumentElement
{
private Lazy<Border> _block;
private EnumerableEx<DocumentElement> _children;
private SelectionList? _prevSelection;

public override Control Control => _block.Value;
public override IEnumerable<DocumentElement> Children => _children;

public BlockquoteElement(IEnumerable<DocumentElement> child)
{
_block = new Lazy<Border>(Create);
_children = child.ToEnumerable();
}

private Border Create()
{
var panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
panel.Classes.Add(ClassNames.BlockquoteClass);
foreach (var child in Children)
panel.Children.Add(child.Control);

var border = new Border();
border.Classes.Add(ClassNames.BlockquoteClass);
border.Child = panel;

return border;
}

public override void Select(Point from, Point to)
{
var selection = SelectionUtil.SelectVertical(Control, _children, from, to);

if (_prevSelection is not null)
{
foreach (var ps in _prevSelection)
{
if (!selection.Any(cs => ReferenceEquals(cs, ps)))
{
ps.UnSelect();
}
}
}

_prevSelection = selection;
}

public override void UnSelect()
{
foreach (var child in _children)
child.UnSelect();
}

public override void ConstructSelectedText(StringBuilder builder)
{
if (_prevSelection is null)
return;

var preLen = builder.Length;

foreach (var para in _prevSelection)
{
para.ConstructSelectedText(builder);

if (preLen == builder.Length)
continue;

if (builder[builder.Length - 1] != '\n')
builder.Append('\n');
}
}
}
}
78 changes: 78 additions & 0 deletions ColorDocument.Avalonia/DocumentElements/CTextBlockElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using ColorTextBlock.Avalonia;
using System;
using System.Collections.Generic;
using System.Text;

namespace ColorDocument.Avalonia.DocumentElements
{
public class CTextBlockElement : DocumentElement
{
private Lazy<CTextBlock> _text;

public string Text => _text.Value.Text;

public override Control Control => _text.Value;

public override IEnumerable<DocumentElement> Children => Array.Empty<DocumentElement>();

public CTextBlockElement(IEnumerable<CInline> inlines)
{
_text = new Lazy<CTextBlock>(() =>
{
var text = new CTextBlock();
foreach (var inline in inlines)
text.Content.Add(inline);
return text;
});
}
public CTextBlockElement(IEnumerable<CInline> inlines, string appendClass)
{
_text = new Lazy<CTextBlock>(() =>
{
var text = new CTextBlock();
foreach (var inline in inlines)
text.Content.Add(inline);

text.Classes.Add(appendClass);
return text;
});
}

public CTextBlockElement(IEnumerable<CInline> inlines, string appendClass, TextAlignment alignment)
{
_text = new Lazy<CTextBlock>(() =>
{
var text = new CTextBlock();
foreach (var inline in inlines)
text.Content.Add(inline);

text.TextAlignment = alignment;
text.Classes.Add(appendClass);
return text;
});
}


public override void Select(Point from, Point to)
{
var text = _text.Value;

var fromPoint = text.CalcuatePointerFrom(from.X, from.Y);
var toPoint = text.CalcuatePointerFrom(to.X, to.Y);
text.Select(fromPoint, toPoint);
}

public override void UnSelect()
{
_text.Value.ClearSelection();
}

public override void ConstructSelectedText(StringBuilder builder)
{
builder.Append(_text.Value.GetSelectedText());
}
}
}
82 changes: 82 additions & 0 deletions ColorDocument.Avalonia/DocumentElements/DocumentRootElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ColorDocument.Avalonia.DocumentElements
{
/// <summary>
/// The top document element.
/// </summary>
public class DocumentRootElement : DocumentElement
{
private Lazy<StackPanel> _block;
private EnumerableEx<DocumentElement> _children;
private SelectionList? _prevSelection;

public override Control Control => _block.Value;
public override IEnumerable<DocumentElement> Children => _children;

public DocumentRootElement(IEnumerable<DocumentElement> child)
{
_block = new Lazy<StackPanel>(Create);
_children = child.ToEnumerable();
}

private StackPanel Create()
{
var panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
foreach (var child in _children)
panel.Children.Add(child.Control);

return panel;
}

public override void Select(Point from, Point to)
{
var selection = SelectionUtil.SelectVertical(Control, _children, from, to);

if (_prevSelection is not null)
{
foreach (var ps in _prevSelection)
{
if (!selection.Any(cs => ReferenceEquals(cs, ps)))
{
ps.UnSelect();
}
}
}

_prevSelection = selection;
}

public override void UnSelect()
{
foreach (var child in _children)
child.UnSelect();
}

public override void ConstructSelectedText(StringBuilder builder)
{
if (_prevSelection is null)
return;

var preLen = builder.Length;

foreach (var para in _prevSelection)
{
para.ConstructSelectedText(builder);

if (preLen == builder.Length)
continue;

if (builder[builder.Length - 1] != '\n')
builder.Append('\n');
}
}
}
}
Loading

0 comments on commit 22701ab

Please sign in to comment.