Skip to content
Closed
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
8 changes: 0 additions & 8 deletions ColorCode.Core/CodeColorizerBase.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using ColorCode.Compilation;
using ColorCode.Parsing;
using ColorCode.Styling;
using System.Collections.Generic;

namespace ColorCode
{
Expand All @@ -20,13 +19,6 @@ public CodeColorizerBase(StyleDictionary Styles, ILanguageParser languageParser)
this.Styles = Styles ?? StyleDictionary.DefaultLight;
}

/// <summary>
/// Writes the parsed source code to the ouput using the specified style sheet.
/// </summary>
/// <param name="parsedSourceCode">The parsed source code to format and write to the output.</param>
/// <param name="scopes">The captured scopes for the parsed source code.</param>
protected abstract void Write(string parsedSourceCode, IList<Scope> scopes);

/// <summary>
/// The language parser that the <see cref="CodeColorizerBase"/> instance will use for its lifetime.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion ColorCode.HTML/HtmlClassFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public string GetCSSString()
return str.ToString();
}

protected override void Write(string parsedSourceCode, IList<Scope> scopes)
protected void Write(string parsedSourceCode, IList<Scope> scopes)
{
var styleInsertions = new List<TextInsertion>();

Expand Down
2 changes: 1 addition & 1 deletion ColorCode.HTML/HtmlFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public string GetHtmlString(string sourceCode, ILanguage language)
return buffer.ToString();
}

protected override void Write(string parsedSourceCode, IList<Scope> scopes)
protected void Write(string parsedSourceCode, IList<Scope> scopes)
{
var styleInsertions = new List<TextInsertion>();

Expand Down
11 changes: 9 additions & 2 deletions ColorCode.UWP/Common/ExtensionMethods.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using System;
using Windows.UI;
using Windows.UI.Xaml.Media;

namespace ColorCode.UWP.Common
{
public static class ExtensionMethods
{
public static SolidColorBrush GetSolidColorBrush(this string hex)
{
var color = GetColor(hex);
SolidColorBrush myBrush = new SolidColorBrush(color);
return myBrush;
}

public static Color GetColor(this string hex)
{
hex = hex.Replace("#", string.Empty);

Expand All @@ -23,8 +31,7 @@ public static SolidColorBrush GetSolidColorBrush(this string hex)
byte g = (byte)(Convert.ToUInt32(hex.Substring(index, 2), 16));
index += 2;
byte b = (byte)(Convert.ToUInt32(hex.Substring(index, 2), 16));
SolidColorBrush myBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(a, r, g, b));
return myBrush;
return Color.FromArgb(a, r, g, b);
}
}
}
74 changes: 74 additions & 0 deletions ColorCode.UWP/Common/VisualHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace ColorCode.Common
{
public static class VisualHelpers
{
/// <summary>
/// Commandbars causing crashes at the mo
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parent"></param>
/// <param name="deepscan"></param>
/// <param name="includeCommandBars"></param>
/// <returns></returns>
public static T FirstChildofType<T>(DependencyObject parent, bool deepscan = false, bool includeCommandBars = false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like just a combo of the LogicalTree Helpers and the VisualTree Helpers already in the toolkit, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't see any in the toolkit? Point me?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
if (parent == null) return (T)(object)null;
if (deepscan)
{
if (parent is ContentPresenter presenter)
{
var _Child = presenter.Content as DependencyObject;
if (_Child is T)
{
return (T)(object)_Child;
}
if (!(_Child is CommandBar) || includeCommandBars)
{
var next = (FirstChildofType<T>(_Child, deepscan));
if (next is T)
{
return ((T)(object)next);
}
}
}
else if (parent is ContentControl control)
{
var _Child = control.Content as DependencyObject;
if (_Child is T)
{
return (T)(object)_Child;
}
if (!(_Child is CommandBar) || includeCommandBars)
{
var next = (FirstChildofType<T>(_Child, deepscan));
if (next is T)
{
return ((T)(object)next);
}
}
}
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var _Child = VisualTreeHelper.GetChild(parent, i);
if (_Child is T)
{
return ((T)(object)_Child);
}
if (!(_Child is CommandBar) || includeCommandBars)
{
var next = (FirstChildofType<T>(_Child, deepscan));
if (next is T)
{
return ((T)(object)next);
}
}
}
return (T)(object)null;
}
}
}
196 changes: 196 additions & 0 deletions ColorCode.UWP/RichEditBoxFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
using System.Collections.Generic;
using ColorCode.Parsing;
using Windows.UI.Xaml.Controls;
using ColorCode.Styling;
using Windows.UI.Text;
using ColorCode.UWP.Common;
using ColorCode.Common;
using Windows.UI.Xaml;
using System.Text.RegularExpressions;

namespace ColorCode
{
/// <summary>
/// Creates a <see cref="RichTextBlockFormatter"/>, for rendering Syntax Highlighted code to a RichTextBlock.
/// </summary>
public class RichEditBoxFormatter : CodeColorizerBase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this could this be an extension with an attached property instead of a helper class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be both, I would like to keep the formatter class style, as that is what the other Formatters are.

I haven't played with extensions before, but I'll look into it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would I set a Markup Extension for a specific control only, is there some documentation on creating UI Extensions for more info than I can garner from the ones in the Toolkit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You just change the type in the Get/SetValue from DependencyProperty to the specific control to limit it (like they did in TextBoxRegEx). Is that what you're asking?

{
/// <summary>
/// Creates a <see cref="RichTextBlockFormatter"/>, for rendering Syntax Highlighted code to a RichTextBlock.
/// </summary>
/// <param name="Theme">The Theme to use, determines whether to use Default Light or Default Dark.</param>
public RichEditBoxFormatter(ElementTheme Theme, ILanguageParser languageParser = null) : this(Theme == ElementTheme.Dark ? StyleDictionary.DefaultDark : StyleDictionary.DefaultLight, languageParser)
{
}

/// <summary>
/// Creates a <see cref="RichTextBlockFormatter"/>, for rendering Syntax Highlighted code to a RichTextBlock.
/// </summary>
/// <param name="Style">The Custom styles to Apply to the formatted Code.</param>
/// <param name="languageParser">The language parser that the <see cref="RichTextBlockFormatter"/> instance will use for its lifetime.</param>
public RichEditBoxFormatter(StyleDictionary Style = null, ILanguageParser languageParser = null) : base(Style, languageParser)
{
}

private RichEditBox RichEdit { get; set; }

public ILanguage Language
{
get => _Language;
set
{
_Language = value;
UpdateText();
}
}

private ILanguage _Language;

/// <summary>
/// Adds Syntax Highlighted Source Code to the provided RichTextBlock.
/// </summary>
/// <param name="sourceCode">The source code to colorize.</param>
/// <param name="language">The language to use to colorize the source code.</param>
/// <param name="RichEdit">The Control to add the Text to.</param>
public void AttachRichEditBox(RichEditBox RichEdit, ILanguage Language)
{
this.RichEdit = RichEdit;
RichEdit.TextChanging += RichEdit_TextChanging;
this.Language = Language;
}

private void RichEdit_TextChanging(RichEditBox sender, RichEditBoxTextChangingEventArgs args)
{
if (args.IsContentChanging)
{
UpdateText();
}
}

public void UpdateText()
{
if (RichEdit != null)
{
// Attempt to get Scrollviewer offsets, to preserve location.
var scroll = VisualHelpers.FirstChildofType<ScrollViewer>(RichEdit);
var vertOffset = scroll?.VerticalOffset;
var horOffset = scroll?.HorizontalOffset;

var selection = RichEdit.Document.Selection;
var selectionStart = selection.StartPosition;
var selectionEnd = selection.EndPosition;

RichEdit.Document.GetText(TextGetOptions.UseCrlf, out string raw);
RichEdit.Document.Undo();

RichEdit.Document.BeginUndoGroup();
RichEdit.Document.SetText(TextSetOptions.None, raw);

var newSelection = RichEdit.Document.Selection;
newSelection.StartPosition = selectionStart;
newSelection.EndPosition = selectionEnd;

Index = 0;
source = raw;

languageParser.Parse(raw, Language, (range, captures) => Style(range, captures));
RichEdit.Document.ApplyDisplayUpdates();
RichEdit.Document.EndUndoGroup();

if (scroll != null)
{
scroll.ChangeView(horOffset, vertOffset, null, true);
}
}
}

private static int Index = 0;
private static string source = string.Empty;

protected void Style(string range, IList<Scope> scopes)
{
var scopeRange = source.Substring(Index);

var start = Index;

try
{
var previous = source.Remove(Index);
var crlfCorrection = CountOccurences(previous, "\r\n");
start -= crlfCorrection;
}
catch
{
}

var subIndex = scopeRange.IndexOf(range);
if (subIndex != -1)
{
start += subIndex;
}

foreach (var scope in scopes)
{
StyleFromScope(start, scope);
}

Index += range.Length;
}

private int CountOccurences(string str, string match)
{
return Regex.Matches(str, match).Count;
}

private void StyleFromScope(int Start, Scope Scope)
{
Start += Scope.Index;
var Range = RichEdit.Document.GetRange(Start, Start + Scope.Length);

string foreground = null;
string background = null;
bool italic = false;
bool bold = false;

if (Styles.Contains(Scope.Name))
{
Styling.Style style = Styles[Scope.Name];

foreground = style.Foreground;
background = style.Background;
italic = style.Italic;
bold = style.Bold;
}

if (!string.IsNullOrWhiteSpace(foreground))
{
Range.CharacterFormat.ForegroundColor = foreground.GetColor();
}

if (!string.IsNullOrWhiteSpace(background))
{
Range.CharacterFormat.BackgroundColor = background.GetColor();
}

if (italic)
Range.CharacterFormat.Italic = FormatEffect.On;

if (bold)
Range.CharacterFormat.Bold = FormatEffect.On;

foreach (var subScope in Scope.Children)
{
StyleFromScope(Start, subScope);
}
}

private void Reset(ITextRange Range)
{
var defaults = RichEdit.Document.GetDefaultCharacterFormat();
Range.CharacterFormat.Italic = FormatEffect.Off;
Range.CharacterFormat.Bold = FormatEffect.Off;
Range.CharacterFormat.BackgroundColor = defaults.BackgroundColor;
Range.CharacterFormat.ForegroundColor = defaults.ForegroundColor;
}
}
}
4 changes: 2 additions & 2 deletions ColorCode.UWP/RichTextBlockFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ public void FormatRichTextBlock(string sourceCode, ILanguage Language, RichTextB
public void FormatInlines(string sourceCode, ILanguage Language, InlineCollection InlineCollection)
{
this.InlineCollection = InlineCollection;
languageParser.Parse(sourceCode, Language, (parsedSourceCode, captures) => Write(parsedSourceCode, captures));
languageParser.Parse(sourceCode, Language, (parsedSourceCode, captures) => Insert(parsedSourceCode, captures));
}

private InlineCollection InlineCollection { get; set; }

protected override void Write(string parsedSourceCode, IList<Scope> scopes)
protected void Insert(string parsedSourceCode, IList<Scope> scopes)
{
var styleInsertions = new List<TextInsertion>();

Expand Down
14 changes: 14 additions & 0 deletions Tests/ColorCode.UWPTests/ColorCode.UWPTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RichEditSample.xaml.cs">
<DependentUpon>RichEditSample.xaml</DependentUpon>
</Compile>
<Compile Include="RichTextSample.xaml.cs">
<DependentUpon>RichTextSample.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
Expand All @@ -123,6 +129,14 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="RichEditSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="RichTextSample.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
Expand Down
Loading