Basic Syntax highlighting, added CodeTextBox to MainWindow to test it.

This commit is contained in:
David
2016-10-13 21:08:34 -04:00
parent 071b63f01d
commit 1c44e00a1d
7 changed files with 137 additions and 17 deletions

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace Befunge.Editor.CharStyles
{
public class BefungeStyler : ITextStyler
{
private string _directionals = "<>^v?r";
public IEnumerable<Run> StyledString(string input)
{
var runs = new List<Run>();
foreach (var c in input)
{
if (_directionals.Contains(c))
runs.Add(new Run(c.ToString())
{
Foreground = new SolidColorBrush(Colors.CornflowerBlue),
FontWeight = FontWeights.Bold
});
else
{
runs.Add(new Run(c.ToString())
{
Foreground = new SolidColorBrush(Colors.Black),
FontWeight = FontWeights.Normal
});
}
}
return runs;
}
}
}

View File

@@ -1,14 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Documents; using System.Windows.Documents;
namespace Befunge.Editor.CharStyles namespace Befunge.Editor.CharStyles
{ {
public interface ICharStyler public interface ITextStyler
{ {
Run StyledString(string input); IEnumerable<Run> StyledString(string input);
} }
} }

View File

@@ -1,26 +1,89 @@
using System.ComponentModel; using System.ComponentModel;
using System.Data.SqlTypes;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using Befunge.Editor.CharStyles; using Befunge.Editor.CharStyles;
using Befunge.Editor.Utils;
namespace Befunge.Editor.Controls namespace Befunge.Editor.Controls
{ {
public class CodeTextBox : RichTextBox public class CodeTextBox : RichTextBox
{ {
public static readonly DependencyProperty TextProperty = DependencyProperty.Register( public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
nameof(Text), typeof(string), typeof(CodeTextBox), new PropertyMetadata(default(string), OnTextPropertyChanged)); nameof(Text), typeof(string), typeof(CodeTextBox),
new PropertyMetadata(default(string), OnTextPropertyChanged));
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new System.NotImplementedException();
}
public string Text public string Text
{ {
get { return (string) GetValue(TextProperty); } get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); } set
{
SetValue(TextProperty, value);
UpdateColors();
}
} }
public ICharStyler TextStyler { get; set; } private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctb = d as CodeTextBox;
var val = e.NewValue as string;
if (ctb == null) return;
var start = ctb.Document.ContentStart;
var end = ctb.Document.ContentEnd;
var range = new TextRange(start, end);
range.Text = val + "\r\n";
}
public ITextStyler TextStyler { get; set; }
private bool _changingColors;
public CodeTextBox()
{
var s = new Style {TargetType = typeof(Paragraph)};
s.Setters.Add(new Setter(Block.MarginProperty, new Thickness(0)));
Resources.Add(typeof(Paragraph), s);
FontFamily = new FontFamily("Consolas");
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
UpdateColors();
}
public void UpdateColors()
{
if (_changingColors) return;
_changingColors = true;
var start = Document.ContentStart;
var caret = CaretPosition;
var end = Document.ContentEnd;
var before = new TextRange(start, caret);
var after = new TextRange(caret, end);
var beforeText = before.Text.Replace("\r\n", "\n");
var afterText = after.Text.Replace("\r\n", "\n");
if (afterText.Length > 0)
afterText = afterText.Substring(0, afterText.Length - 1);
var allText = beforeText + afterText;
Text = allText;
Document.Blocks.Clear();
var p = new Paragraph();
Document.Blocks.Add(p);
p.AppendStylizedText(TextStyler, beforeText);
CaretPosition = p.ContentEnd;
p.AppendStylizedText(TextStyler, afterText);
_changingColors = false;
}
} }
} }

View File

@@ -63,8 +63,10 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="CharStyles\ICharStyler.cs" /> <Compile Include="CharStyles\BefungeStyler.cs" />
<Compile Include="CharStyles\ITextStyler.cs" />
<Compile Include="Controls\CodeTextBox.cs" /> <Compile Include="Controls\CodeTextBox.cs" />
<Compile Include="Utils\Extensions.cs" />
<Compile Include="MainWindow.xaml.cs"> <Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>

View File

@@ -7,6 +7,6 @@
mc:Ignorable="d" mc:Ignorable="d"
Title="Befunge Editor" Height="350" Width="525"> Title="Befunge Editor" Height="350" Width="525">
<Grid> <Grid>
<loc:CodeTextBox x:Name="EditRegion" Margin="10,10,10,10.5" Text="Hello, world!"/>
</Grid> </Grid>
</Window> </Window>

View File

@@ -1,12 +1,16 @@
using System.Windows; using System.Windows;
using Befunge.Editor.CharStyles;
namespace Befunge.Editor namespace Befunge.Editor
{ {
public partial class MainWindow public partial class MainWindow
{ {
public MainWindow () public MainWindow()
{ {
InitializeComponent (); InitializeComponent();
EditRegion.TextStyler = new BefungeStyler();
EditRegion.UpdateColors();
} }
} }
} }

View File

@@ -0,0 +1,14 @@
using System.Windows.Documents;
using Befunge.Editor.CharStyles;
namespace Befunge.Editor.Utils
{
internal static class Extensions
{
public static void AppendStylizedText(this Paragraph p, ITextStyler styler, char text)
=> AppendStylizedText(p, styler, text.ToString());
public static void AppendStylizedText(this Paragraph p, ITextStyler styler, string text)
=> p.Inlines.AddRange(styler?.StyledString(text) ?? new[] {new Run(text)});
}
}