Skip to content

Commit

Permalink
Added Error-Highlighting by hover above
Browse files Browse the repository at this point in the history
  • Loading branch information
X39 committed Mar 17, 2020
1 parent baf2fb3 commit 1669563
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 7 deletions.
1 change: 1 addition & 0 deletions Arma.Studio.Data/ArmA.Studio.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
<Compile Include="UI\EditorInfo.cs" />
<Compile Include="UI\EditorInfoDrawingBrush.cs" />
<Compile Include="UI\EditorInfoIcon.cs" />
<Compile Include="UI\RelayDataTemplateSelector.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="TypeExtensions.tt">
Expand Down
43 changes: 43 additions & 0 deletions Arma.Studio.Data/UI/RelayDataTemplateSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace Arma.Studio.Data.UI
{
public class RelayDataTemplateSelector : DataTemplateSelector
{
private readonly Control RelayTo;
public RelayDataTemplateSelector(Control control)
{
this.RelayTo = control;
}

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var baseResult = base.SelectTemplate(item, container);
if (baseResult != null || item is null)
{
return baseResult;
}
var objType = item.GetType();
var matches = this.RelayTo.Resources
.Cast<DictionaryEntry>()
.Select((it) => it.Value)
.Where((it) => it is DataTemplate)
.Cast<DataTemplate>()
.Where((it) => it.DataType is Type t && t.IsAssignableFrom(objType)).ToArray();
if (!matches.Any())
{
return null;
}
// ToDo: Find the best match
var template = matches.First();
return (DataTemplate)template;
}
}
}
5 changes: 5 additions & 0 deletions Arma.Studio/ArmA.Studio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@
<ItemGroup>
<Resource Include="Resources\UserIdentificationDialog\UserIdentifier.png" />
</ItemGroup>
<ItemGroup>
<Content Include="ReadMe.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>git rev-parse HEAD &gt; "$(ProjectDir)\git-version.txt"
Expand Down
69 changes: 67 additions & 2 deletions Arma.Studio/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ public static int GetStartOffset(this TextEditor editor)
/// <param name="editor">A valid <see cref="TextEditor"/> instance.</param>
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
/// <returns></returns>
public static int GetStartOffset(this TextEditor editor, Func<char, bool> isSeparatorCharacter = null)
public static int GetStartOffsetByCaret(this TextEditor editor, Func<char, bool> isSeparatorCharacter = null)
{
if (isSeparatorCharacter == null)
{
isSeparatorCharacter = Char.IsLetter;
isSeparatorCharacter = (c) => !Char.IsLetter(c);
}
int off = editor.CaretOffset;
if (off <= 0 || off > editor.Document.TextLength)
Expand All @@ -91,6 +91,71 @@ public static int GetStartOffset(this TextEditor editor, Func<char, bool> isSepa
}
return 0;
}
/// <summary>
/// Tries to find the start of a word.
/// </summary>
/// <param name="document">A valid <see cref="TextDocument"/> instance.</param>
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
/// <returns></returns>
public static int GetStartOffset(this TextDocument document, int baseOffset, Func<char, bool> isSeparatorCharacter = null)
{
if (isSeparatorCharacter == null)
{
isSeparatorCharacter = (c) => !Char.IsLetter(c);
}
int off = baseOffset;
if (off <= 0 || off > document.TextLength)
{
return off;
}


int start;

// find start
for (start = off - 1; start >= 0; start--)
{
char c = document.GetCharAt(start);
if (isSeparatorCharacter(c))
{
start++;
return start;
}
}
return -1;
}
/// <summary>
/// Tries to find the start of a word.
/// </summary>
/// <param name="document">A valid <see cref="TextDocument"/> instance.</param>
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
/// <returns></returns>
public static int GetEndOffset(this TextDocument document, int baseOffset, Func<char, bool> isSeparatorCharacter = null)
{
if (isSeparatorCharacter == null)
{
isSeparatorCharacter = (c) => !Char.IsLetter(c);
}
int off = baseOffset;
if (off <= 0 || off > document.TextLength)
{
return off;
}


int start;

// find start
for (start = off; start < document.TextLength; start++)
{
char c = document.GetCharAt(start);
if (isSeparatorCharacter(c))
{
return start;
}
}
return -1;
}

}
}
19 changes: 18 additions & 1 deletion Arma.Studio/UI/TextEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@
IsReadOnly="{Binding IsReadOnly}"
FontFamily="Consolas"
asd:AttachedDataContext.DataContext="{Binding}">

<ae:TextEditor.Resources>
<DataTemplate DataType="{x:Type asd:LintInfo}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Severity, Converter={StaticResource EnumNameConverter}}" VerticalAlignment="Center" FontSize="10"/>
<TextBlock Grid.Column="2" Text="{Binding Line, StringFormat={}[L{0}}" VerticalAlignment="Center" FontSize="10"/>
<TextBlock Grid.Column="3" Text="{Binding Column, StringFormat={}C{0}]}" VerticalAlignment="Center" FontSize="10"/>
<TextBlock Grid.Column="5" Text="{Binding Description}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ae:TextEditor.Resources>
</ae:TextEditor>
</DataTemplate>
61 changes: 58 additions & 3 deletions Arma.Studio/UI/TextEditorDataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,65 @@ public void OnInitialized(FrameworkElement sender, EventArgs e)
this.FoldingManager = ICSharpCode.AvalonEdit.Folding.FoldingManager.Install(textEditor.TextArea);

textEditor.TextArea.TextEntering += this.TextArea_TextEntering;
textEditor.TextArea.TextEntered += this.TextArea_TextEntered; ;
textEditor.TextArea.TextEntered += this.TextArea_TextEntered;
textEditor.MouseHover += this.TextEditor_MouseHover;
textEditor.MouseHoverStopped += this.TextEditor_MouseHoverStopped;
}
}


public ToolTip ToolTip
{
get
{
if (this._ToolTip is null)
{
this._ToolTip = new ToolTip
{
PlacementTarget = this.TextEditorControl,
Placement = PlacementMode.MousePoint,
ContentTemplateSelector = new RelayDataTemplateSelector(this.TextEditorControl)
};
}
this._ToolTip.IsOpen = true;
return this._ToolTip;
}
}
private ToolTip _ToolTip;
private void TextEditor_MouseHover(object sender, MouseEventArgs e)
{
var relativePosition = e.GetPosition(this.TextEditorControl);
var textPosition = this.TextEditorControl.GetPositionFromPoint(relativePosition);
if (textPosition is null)
{
return;
}
var offset = this.TextDocument.GetOffset(textPosition.Value.Line, textPosition.Value.Column);
int start, end;
if (this.TextEditorInstance is ICodeCompletable codeCompletable)
{
start = this.TextDocument.GetStartOffset(offset, codeCompletable.IsSeparatorCharacter);
end = this.TextDocument.GetEndOffset(offset, codeCompletable.IsSeparatorCharacter);
}
else
{
start = this.TextDocument.GetStartOffset(offset);
end = this.TextDocument.GetEndOffset(offset);
}
var word = this.TextDocument.GetText(start, end - start);
start = this.TextDocument.GetLocation(start).Column - 1;
end = this.TextDocument.GetLocation(end).Column;
var lintInfo = this.GetLintInfos().Where((it) => it.Line == textPosition.Value.Line && start <= it.Column && it.Column <= end).FirstOrDefault();
if (lintInfo != null)
{
this.ToolTip.Content = lintInfo;
}
}
private void TextEditor_MouseHoverStopped(object sender, MouseEventArgs e)
{
this.ToolTip.IsOpen = false;
}

private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
this.ShowAutoCompletion();
Expand Down Expand Up @@ -571,11 +626,11 @@ private void ShowAutoCompletion()
this.CompletionWindow.Closed += delegate {
this.CompletionWindow = null;
};
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffset(codeCompletable.IsSeparatorCharacter);
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffsetByCaret(codeCompletable.IsSeparatorCharacter);
this.CompletionWindow.EndOffset = this.TextEditorControl.CaretOffset;
this.CompletionWindow.Show();
}
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffset(codeCompletable.IsSeparatorCharacter);
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffsetByCaret(codeCompletable.IsSeparatorCharacter);
var data = this.CompletionWindow.CompletionList.CompletionData;
data.Clear();
data.AddRange(codeCompletable.GetAutoCompleteInfos(this.TextDocument.Text, this.TextEditorControl.CaretOffset).Select((it) => new CompletionData(it)));
Expand Down
1 change: 0 additions & 1 deletion Arma.Studio/UI/UnderlineBackgroundRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ private IEnumerable<Point> GetPoints(Rect rect, double offset, int count)
}
}


public void Draw(TextView textView, DrawingContext drawingContext)
{
textView.EnsureVisualLines();
Expand Down

0 comments on commit 1669563

Please sign in to comment.