aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs')
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs229
1 files changed, 229 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
index c650ad425..b355ba818 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
@@ -47,7 +47,10 @@ namespace Tango.Scripting.Editors
private char[] word_separators = { ' ', '\t', '\n', '.', '(', ',', '-', '*', '/', '+', '$', '=', '<', '>' };
private string[] _blocking_type_words = { "class", "void" };
+ public event EventHandler<BreakPointSymbolPressedEventArgs> BreakPointSymbolPressed;
+
private DispatcherTimer _update_timer;
+ private BreakPointMargin breakPointMargin;
private Popup _popup;
private FoldingManager foldingManager;
private BraceFoldingStrategy foldingStrategy;
@@ -58,6 +61,11 @@ namespace Tango.Scripting.Editors
private List<ScriptType> _declaredTypes;
private bool _isLoadingTypes;
private TextMarkerService errorMarkerService;
+ private List<ScriptBreakPointSymbol> _breakPointSymbols;
+ private int _breakPointLineNumber;
+ private ScriptBreakPointSymbol _currentBreakPointSymbol;
+ private Point _currentBreakPointSymbolPosition;
+
private static JsonSerializerSettings _jsonSettings;
private static Dictionary<Type, KnownType> _knownTypesCache;
private static String KNOWN_TYPES_CACHE_FOLDER;
@@ -199,6 +207,39 @@ namespace Tango.Scripting.Editors
public static readonly DependencyProperty ErrorLineBrushProperty =
DependencyProperty.Register("ErrorLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Red) { Opacity = 0.5 }));
+ public Brush DebugLineBrush
+ {
+ get { return (Brush)GetValue(DebugLineBrushProperty); }
+ set { SetValue(DebugLineBrushProperty, value); }
+ }
+ public static readonly DependencyProperty DebugLineBrushProperty =
+ DependencyProperty.Register("DebugLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Gray) { Opacity = 0.5 }));
+
+ public Brush BreakPointLineBrush
+ {
+ get { return (Brush)GetValue(BreakPointLineBrushProperty); }
+ set { SetValue(BreakPointLineBrushProperty, value); }
+ }
+ public static readonly DependencyProperty BreakPointLineBrushProperty =
+ DependencyProperty.Register("BreakPointLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Yellow) { Opacity = 0.5 }));
+
+ public IScriptSource ScriptSource
+ {
+ get { return (IScriptSource)GetValue(ScriptSourceProperty); }
+ set { SetValue(ScriptSourceProperty, value); }
+ }
+ public static readonly DependencyProperty ScriptSourceProperty =
+ DependencyProperty.Register("ScriptSource", typeof(IScriptSource), typeof(ScriptEditor), new PropertyMetadata(null));
+
+ public bool DisableBreakPoints
+ {
+ get { return (bool)GetValue(DisableBreakPointsProperty); }
+ set { SetValue(DisableBreakPointsProperty, value); }
+ }
+ public static readonly DependencyProperty DisableBreakPointsProperty =
+ DependencyProperty.Register("DisableBreakPoints", typeof(bool), typeof(ScriptEditor), new PropertyMetadata(false));
+
+
#endregion
#region Constructors
@@ -337,6 +378,17 @@ namespace Tango.Scripting.Editors
TextArea.TextView.LineTransformers.Add(errorMarkerService);
Unloaded += ScriptEditor_Unloaded;
+
+ breakPointMargin = new BreakPointMargin(this);
+ _breakPointSymbols = new List<ScriptBreakPointSymbol>();
+ Loaded += ScriptEditor_Loaded;
+
+ MouseMove += ScriptEditor_MouseMove;
+ }
+
+ private void ScriptEditor_Loaded(object sender, RoutedEventArgs e)
+ {
+ TextArea.LeftMargins.Insert(0, breakPointMargin);
}
private void ScriptEditor_Unloaded(object sender, RoutedEventArgs e)
@@ -500,6 +552,8 @@ namespace Tango.Scripting.Editors
private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
+ if (IsReadOnly) return;
+
try
{
List<Object> items = new List<object>();
@@ -2505,6 +2559,47 @@ namespace Tango.Scripting.Editors
Document.EndUpdate();
}
+ public void HighlightDebugLine(int lineNumber)
+ {
+ Document.BeginUpdate();
+
+ var line = Document.GetLineByNumber(lineNumber);
+ OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, DebugLineBrush);
+ TextArea.TextView.LineTransformers.Add(errorLineColrizer);
+
+ Document.EndUpdate();
+ }
+
+ public void HighlightBreakPoint(int lineNumber, List<ScriptBreakPointSymbol> symbols)
+ {
+ _breakPointLineNumber = lineNumber;
+ _breakPointSymbols = symbols.ToList();
+ _currentBreakPointSymbol = null;
+
+ Document.BeginUpdate();
+
+ var line = Document.GetLineByNumber(lineNumber);
+ OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, BreakPointLineBrush);
+ TextArea.TextView.LineTransformers.Add(errorLineColrizer);
+
+ var breakPoint = breakPointMargin.BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber);
+ breakPoint.IsActive = true;
+ breakPointMargin.InvalidateVisual();
+
+ Document.EndUpdate();
+ }
+
+ public void ResetBreakPointLine()
+ {
+ _breakPointSymbols = new List<ScriptBreakPointSymbol>();
+ _currentBreakPointSymbol = null;
+ ResetColorizationByKeyword();
+ breakPointMargin.BreakPoints.ToList().ForEach(x => x.IsActive = false);
+ Mouse.OverrideCursor = null;
+ ClearErrors();
+ breakPointMargin.InvalidateVisual();
+ }
+
public Point? GetLineVisualPosition(int lineNumber)
{
double top = TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
@@ -2521,6 +2616,140 @@ namespace Tango.Scripting.Editors
return null;
}
+ public List<ScriptBreakPoint> GetBreakPoints()
+ {
+ List<ScriptBreakPoint> breakPoints = new List<ScriptBreakPoint>();
+
+ foreach (var b in breakPointMargin.BreakPoints)
+ {
+ ScriptBreakPoint breakPoint = new ScriptBreakPoint();
+ breakPoint.Script = ScriptSource;
+ breakPoint.LineNumber = b.LineNumber;
+
+ var line = Document.GetLineByNumber(b.LineNumber);
+ breakPoint.LineStartOffset = line.Offset;
+ breakPoint.LineEndOffset = line.EndOffset;
+
+ var symbols = _parser.GetContextSymbols(Document.Text, line.Offset);
+
+ foreach (var symbol in symbols.Where(x => (x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field || x.Kind == SymbolKind.Local || x.Kind == SymbolKind.Parameter) && !x.IsUnassigned))
+ {
+ if (symbol.Offset < line.Offset)
+ {
+ breakPoint.ContextSymbols.Add(new ScriptBreakPointSymbol()
+ {
+ Name = symbol.Name,
+ Offset = symbol.Offset,
+ Length = symbol.Length,
+ });
+ }
+ }
+
+ breakPoints.Add(breakPoint);
+ }
+
+ return breakPoints;
+ }
+
+ #endregion
+
+ #region BreakPoint Symbols Search
+
+ private void ScriptEditor_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (IsReadOnly && _breakPointSymbols.Count > 0)
+ {
+ try
+ {
+ var word_separators_plus = word_separators.ToList();
+ word_separators_plus.Add(')');
+ word_separators_plus.Add(';');
+
+ var textView = TextArea.TextView;
+ Point position = e.GetPosition(textView);
+ position.Y += textView.VerticalOffset;
+ VisualLine visualLine = textView.GetVisualLineFromVisualTop(position.Y);
+ int columnIndex = visualLine.GetVisualColumnFloor(position, false);
+ String line = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length);
+ if (columnIndex < line.Length)
+ {
+ int wordStartIndex = columnIndex;
+ int wordEndIndex = columnIndex;
+
+ while (wordStartIndex > 0)
+ {
+ if (word_separators_plus.Contains(line[wordStartIndex])) break;
+ wordStartIndex--;
+ }
+
+ while (wordEndIndex < line.Length)
+ {
+ if (word_separators_plus.Contains(line[wordEndIndex])) break;
+ wordEndIndex++;
+ }
+
+ if (wordStartIndex > 0)
+ {
+ wordStartIndex++;
+ }
+
+ String word = line.Substring(wordStartIndex, wordEndIndex - wordStartIndex);
+
+ var breakPointSymbol = _breakPointSymbols.FirstOrDefault(x => x.Name == word);
+
+ if (breakPointSymbol != null)
+ {
+ int wordStartOffset = visualLine.FirstDocumentLine.Offset + wordStartIndex;
+
+ ClearErrors();
+ ITextMarker marker = errorMarkerService.Create(wordStartOffset, word.Length);
+ marker.MarkerTypes = TextMarkerTypes.NormalUnderline;
+ marker.MarkerColor = Colors.Yellow;
+ Mouse.OverrideCursor = Cursors.Hand;
+
+ _currentBreakPointSymbol = breakPointSymbol;
+ _currentBreakPointSymbolPosition = visualLine.GetVisualPosition(wordEndIndex, VisualYPosition.LineTop);
+ }
+ else
+ {
+ _currentBreakPointSymbol = null;
+ Mouse.OverrideCursor = null;
+ ClearErrors();
+ }
+ }
+ else
+ {
+ _currentBreakPointSymbol = null;
+ Mouse.OverrideCursor = null;
+ ClearErrors();
+ }
+ }
+ catch (Exception ex)
+ {
+ _currentBreakPointSymbol = null;
+ Mouse.OverrideCursor = null;
+ ClearErrors();
+ Debug.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
+ {
+ base.OnPreviewMouseLeftButtonUp(e);
+
+ if (_currentBreakPointSymbol != null)
+ {
+ Mouse.OverrideCursor = null;
+ Debug.WriteLine($"Pressed on break point symbol: {_currentBreakPointSymbol.Name}");
+ BreakPointSymbolPressed?.Invoke(this, new BreakPointSymbolPressedEventArgs()
+ {
+ BreakPointSymbol = _currentBreakPointSymbol,
+ Position = _currentBreakPointSymbolPosition
+ });
+ }
+ }
+
#endregion
}
}