Skip to content

Commit 1669563

Browse files
committed
Added Error-Highlighting by hover above
1 parent baf2fb3 commit 1669563

File tree

7 files changed

+192
-7
lines changed

7 files changed

+192
-7
lines changed

Arma.Studio.Data/ArmA.Studio.Data.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
<Compile Include="UI\EditorInfo.cs" />
178178
<Compile Include="UI\EditorInfoDrawingBrush.cs" />
179179
<Compile Include="UI\EditorInfoIcon.cs" />
180+
<Compile Include="UI\RelayDataTemplateSelector.cs" />
180181
</ItemGroup>
181182
<ItemGroup>
182183
<Content Include="TypeExtensions.tt">
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
using System.Windows.Controls;
9+
10+
namespace Arma.Studio.Data.UI
11+
{
12+
public class RelayDataTemplateSelector : DataTemplateSelector
13+
{
14+
private readonly Control RelayTo;
15+
public RelayDataTemplateSelector(Control control)
16+
{
17+
this.RelayTo = control;
18+
}
19+
20+
public override DataTemplate SelectTemplate(object item, DependencyObject container)
21+
{
22+
var baseResult = base.SelectTemplate(item, container);
23+
if (baseResult != null || item is null)
24+
{
25+
return baseResult;
26+
}
27+
var objType = item.GetType();
28+
var matches = this.RelayTo.Resources
29+
.Cast<DictionaryEntry>()
30+
.Select((it) => it.Value)
31+
.Where((it) => it is DataTemplate)
32+
.Cast<DataTemplate>()
33+
.Where((it) => it.DataType is Type t && t.IsAssignableFrom(objType)).ToArray();
34+
if (!matches.Any())
35+
{
36+
return null;
37+
}
38+
// ToDo: Find the best match
39+
var template = matches.First();
40+
return (DataTemplate)template;
41+
}
42+
}
43+
}

Arma.Studio/ArmA.Studio.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@
247247
<ItemGroup>
248248
<Resource Include="Resources\UserIdentificationDialog\UserIdentifier.png" />
249249
</ItemGroup>
250+
<ItemGroup>
251+
<Content Include="ReadMe.txt">
252+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
253+
</Content>
254+
</ItemGroup>
250255
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
251256
<PropertyGroup>
252257
<PreBuildEvent>git rev-parse HEAD &gt; "$(ProjectDir)\git-version.txt"

Arma.Studio/Extensions.cs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ public static int GetStartOffset(this TextEditor editor)
6464
/// <param name="editor">A valid <see cref="TextEditor"/> instance.</param>
6565
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
6666
/// <returns></returns>
67-
public static int GetStartOffset(this TextEditor editor, Func<char, bool> isSeparatorCharacter = null)
67+
public static int GetStartOffsetByCaret(this TextEditor editor, Func<char, bool> isSeparatorCharacter = null)
6868
{
6969
if (isSeparatorCharacter == null)
7070
{
71-
isSeparatorCharacter = Char.IsLetter;
71+
isSeparatorCharacter = (c) => !Char.IsLetter(c);
7272
}
7373
int off = editor.CaretOffset;
7474
if (off <= 0 || off > editor.Document.TextLength)
@@ -91,6 +91,71 @@ public static int GetStartOffset(this TextEditor editor, Func<char, bool> isSepa
9191
}
9292
return 0;
9393
}
94+
/// <summary>
95+
/// Tries to find the start of a word.
96+
/// </summary>
97+
/// <param name="document">A valid <see cref="TextDocument"/> instance.</param>
98+
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
99+
/// <returns></returns>
100+
public static int GetStartOffset(this TextDocument document, int baseOffset, Func<char, bool> isSeparatorCharacter = null)
101+
{
102+
if (isSeparatorCharacter == null)
103+
{
104+
isSeparatorCharacter = (c) => !Char.IsLetter(c);
105+
}
106+
int off = baseOffset;
107+
if (off <= 0 || off > document.TextLength)
108+
{
109+
return off;
110+
}
111+
112+
113+
int start;
114+
115+
// find start
116+
for (start = off - 1; start >= 0; start--)
117+
{
118+
char c = document.GetCharAt(start);
119+
if (isSeparatorCharacter(c))
120+
{
121+
start++;
122+
return start;
123+
}
124+
}
125+
return -1;
126+
}
127+
/// <summary>
128+
/// Tries to find the start of a word.
129+
/// </summary>
130+
/// <param name="document">A valid <see cref="TextDocument"/> instance.</param>
131+
/// <param name="isSeparatorCharacter">The method to be used to test the characters. Should return True unless the char is not valid.</param>
132+
/// <returns></returns>
133+
public static int GetEndOffset(this TextDocument document, int baseOffset, Func<char, bool> isSeparatorCharacter = null)
134+
{
135+
if (isSeparatorCharacter == null)
136+
{
137+
isSeparatorCharacter = (c) => !Char.IsLetter(c);
138+
}
139+
int off = baseOffset;
140+
if (off <= 0 || off > document.TextLength)
141+
{
142+
return off;
143+
}
144+
145+
146+
int start;
147+
148+
// find start
149+
for (start = off; start < document.TextLength; start++)
150+
{
151+
char c = document.GetCharAt(start);
152+
if (isSeparatorCharacter(c))
153+
{
154+
return start;
155+
}
156+
}
157+
return -1;
158+
}
94159

95160
}
96161
}

Arma.Studio/UI/TextEditor.xaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@
1515
IsReadOnly="{Binding IsReadOnly}"
1616
FontFamily="Consolas"
1717
asd:AttachedDataContext.DataContext="{Binding}">
18-
18+
<ae:TextEditor.Resources>
19+
<DataTemplate DataType="{x:Type asd:LintInfo}">
20+
<Grid>
21+
<Grid.ColumnDefinitions>
22+
<ColumnDefinition Width="Auto"/>
23+
<ColumnDefinition Width="4"/>
24+
<ColumnDefinition Width="Auto"/>
25+
<ColumnDefinition Width="Auto"/>
26+
<ColumnDefinition Width="4"/>
27+
<ColumnDefinition Width="*"/>
28+
</Grid.ColumnDefinitions>
29+
<TextBlock Grid.Column="0" Text="{Binding Severity, Converter={StaticResource EnumNameConverter}}" VerticalAlignment="Center" FontSize="10"/>
30+
<TextBlock Grid.Column="2" Text="{Binding Line, StringFormat={}[L{0}}" VerticalAlignment="Center" FontSize="10"/>
31+
<TextBlock Grid.Column="3" Text="{Binding Column, StringFormat={}C{0}]}" VerticalAlignment="Center" FontSize="10"/>
32+
<TextBlock Grid.Column="5" Text="{Binding Description}" VerticalAlignment="Center"/>
33+
</Grid>
34+
</DataTemplate>
35+
</ae:TextEditor.Resources>
1936
</ae:TextEditor>
2037
</DataTemplate>

Arma.Studio/UI/TextEditorDataContext.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,65 @@ public void OnInitialized(FrameworkElement sender, EventArgs e)
439439
this.FoldingManager = ICSharpCode.AvalonEdit.Folding.FoldingManager.Install(textEditor.TextArea);
440440

441441
textEditor.TextArea.TextEntering += this.TextArea_TextEntering;
442-
textEditor.TextArea.TextEntered += this.TextArea_TextEntered; ;
442+
textEditor.TextArea.TextEntered += this.TextArea_TextEntered;
443+
textEditor.MouseHover += this.TextEditor_MouseHover;
444+
textEditor.MouseHoverStopped += this.TextEditor_MouseHoverStopped;
443445
}
444446
}
445447

448+
449+
public ToolTip ToolTip
450+
{
451+
get
452+
{
453+
if (this._ToolTip is null)
454+
{
455+
this._ToolTip = new ToolTip
456+
{
457+
PlacementTarget = this.TextEditorControl,
458+
Placement = PlacementMode.MousePoint,
459+
ContentTemplateSelector = new RelayDataTemplateSelector(this.TextEditorControl)
460+
};
461+
}
462+
this._ToolTip.IsOpen = true;
463+
return this._ToolTip;
464+
}
465+
}
466+
private ToolTip _ToolTip;
467+
private void TextEditor_MouseHover(object sender, MouseEventArgs e)
468+
{
469+
var relativePosition = e.GetPosition(this.TextEditorControl);
470+
var textPosition = this.TextEditorControl.GetPositionFromPoint(relativePosition);
471+
if (textPosition is null)
472+
{
473+
return;
474+
}
475+
var offset = this.TextDocument.GetOffset(textPosition.Value.Line, textPosition.Value.Column);
476+
int start, end;
477+
if (this.TextEditorInstance is ICodeCompletable codeCompletable)
478+
{
479+
start = this.TextDocument.GetStartOffset(offset, codeCompletable.IsSeparatorCharacter);
480+
end = this.TextDocument.GetEndOffset(offset, codeCompletable.IsSeparatorCharacter);
481+
}
482+
else
483+
{
484+
start = this.TextDocument.GetStartOffset(offset);
485+
end = this.TextDocument.GetEndOffset(offset);
486+
}
487+
var word = this.TextDocument.GetText(start, end - start);
488+
start = this.TextDocument.GetLocation(start).Column - 1;
489+
end = this.TextDocument.GetLocation(end).Column;
490+
var lintInfo = this.GetLintInfos().Where((it) => it.Line == textPosition.Value.Line && start <= it.Column && it.Column <= end).FirstOrDefault();
491+
if (lintInfo != null)
492+
{
493+
this.ToolTip.Content = lintInfo;
494+
}
495+
}
496+
private void TextEditor_MouseHoverStopped(object sender, MouseEventArgs e)
497+
{
498+
this.ToolTip.IsOpen = false;
499+
}
500+
446501
private void TextArea_TextEntered(object sender, TextCompositionEventArgs e)
447502
{
448503
this.ShowAutoCompletion();
@@ -571,11 +626,11 @@ private void ShowAutoCompletion()
571626
this.CompletionWindow.Closed += delegate {
572627
this.CompletionWindow = null;
573628
};
574-
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffset(codeCompletable.IsSeparatorCharacter);
629+
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffsetByCaret(codeCompletable.IsSeparatorCharacter);
575630
this.CompletionWindow.EndOffset = this.TextEditorControl.CaretOffset;
576631
this.CompletionWindow.Show();
577632
}
578-
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffset(codeCompletable.IsSeparatorCharacter);
633+
this.CompletionWindow.StartOffset = this.TextEditorControl.GetStartOffsetByCaret(codeCompletable.IsSeparatorCharacter);
579634
var data = this.CompletionWindow.CompletionList.CompletionData;
580635
data.Clear();
581636
data.AddRange(codeCompletable.GetAutoCompleteInfos(this.TextDocument.Text, this.TextEditorControl.CaretOffset).Select((it) => new CompletionData(it)));

Arma.Studio/UI/UnderlineBackgroundRenderer.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ private IEnumerable<Point> GetPoints(Rect rect, double offset, int count)
6060
}
6161
}
6262

63-
6463
public void Draw(TextView textView, DrawingContext drawingContext)
6564
{
6665
textView.EnsureVisualLines();

0 commit comments

Comments
 (0)