diff --git a/Befunge/Editor/CharStyles/BefungeStyler.cs b/Befunge/Editor/CharStyles/BefungeStyler.cs new file mode 100644 index 0000000..2836b6e --- /dev/null +++ b/Befunge/Editor/CharStyles/BefungeStyler.cs @@ -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 StyledString(string input) + { + var runs = new List(); + + 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; + } + } +} \ No newline at end of file diff --git a/Befunge/Editor/CharStyles/ICharStyler.cs b/Befunge/Editor/CharStyles/ITextStyler.cs similarity index 66% rename from Befunge/Editor/CharStyles/ICharStyler.cs rename to Befunge/Editor/CharStyles/ITextStyler.cs index b127d6f..50aa729 100644 --- a/Befunge/Editor/CharStyles/ICharStyler.cs +++ b/Befunge/Editor/CharStyles/ITextStyler.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; namespace Befunge.Editor.CharStyles { - public interface ICharStyler + public interface ITextStyler { - Run StyledString(string input); + IEnumerable StyledString(string input); } -} +} \ No newline at end of file diff --git a/Befunge/Editor/Controls/CodeTextBox.cs b/Befunge/Editor/Controls/CodeTextBox.cs index 6ea6b01..4d015d0 100644 --- a/Befunge/Editor/Controls/CodeTextBox.cs +++ b/Befunge/Editor/Controls/CodeTextBox.cs @@ -1,26 +1,89 @@ using System.ComponentModel; +using System.Data.SqlTypes; using System.Windows; using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Media; using Befunge.Editor.CharStyles; +using Befunge.Editor.Utils; namespace Befunge.Editor.Controls { public class CodeTextBox : RichTextBox { public static readonly DependencyProperty TextProperty = DependencyProperty.Register( - nameof(Text), typeof(string), typeof(CodeTextBox), new PropertyMetadata(default(string), OnTextPropertyChanged)); - - private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - throw new System.NotImplementedException(); - } + nameof(Text), typeof(string), typeof(CodeTextBox), + new PropertyMetadata(default(string), OnTextPropertyChanged)); public string Text { 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; + } } } \ No newline at end of file diff --git a/Befunge/Editor/Editor.csproj b/Befunge/Editor/Editor.csproj index 2180e5a..0413167 100644 --- a/Befunge/Editor/Editor.csproj +++ b/Befunge/Editor/Editor.csproj @@ -63,8 +63,10 @@ App.xaml Code - + + + MainWindow.xaml Code diff --git a/Befunge/Editor/MainWindow.xaml b/Befunge/Editor/MainWindow.xaml index 858852b..6508d25 100644 --- a/Befunge/Editor/MainWindow.xaml +++ b/Befunge/Editor/MainWindow.xaml @@ -7,6 +7,6 @@ mc:Ignorable="d" Title="Befunge Editor" Height="350" Width="525"> - + diff --git a/Befunge/Editor/MainWindow.xaml.cs b/Befunge/Editor/MainWindow.xaml.cs index 2ff97f0..e75d2a2 100644 --- a/Befunge/Editor/MainWindow.xaml.cs +++ b/Befunge/Editor/MainWindow.xaml.cs @@ -1,12 +1,16 @@ using System.Windows; +using Befunge.Editor.CharStyles; namespace Befunge.Editor { public partial class MainWindow { - public MainWindow () + public MainWindow() { - InitializeComponent (); + InitializeComponent(); + + EditRegion.TextStyler = new BefungeStyler(); + EditRegion.UpdateColors(); } } -} +} \ No newline at end of file diff --git a/Befunge/Editor/Utils/Extensions.cs b/Befunge/Editor/Utils/Extensions.cs new file mode 100644 index 0000000..4c592b7 --- /dev/null +++ b/Befunge/Editor/Utils/Extensions.cs @@ -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)}); + } +} \ No newline at end of file