diff --git a/Arma.Studio.Data/ArmA.Studio.Data.csproj b/Arma.Studio.Data/ArmA.Studio.Data.csproj
index 8c410cf..c48e1ec 100644
--- a/Arma.Studio.Data/ArmA.Studio.Data.csproj
+++ b/Arma.Studio.Data/ArmA.Studio.Data.csproj
@@ -177,6 +177,7 @@
+
diff --git a/Arma.Studio.Data/UI/RelayDataTemplateSelector.cs b/Arma.Studio.Data/UI/RelayDataTemplateSelector.cs
new file mode 100644
index 0000000..3e66e17
--- /dev/null
+++ b/Arma.Studio.Data/UI/RelayDataTemplateSelector.cs
@@ -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()
+ .Select((it) => it.Value)
+ .Where((it) => it is DataTemplate)
+ .Cast()
+ .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;
+ }
+ }
+}
diff --git a/Arma.Studio/ArmA.Studio.csproj b/Arma.Studio/ArmA.Studio.csproj
index 7c5cfcf..55d6541 100644
--- a/Arma.Studio/ArmA.Studio.csproj
+++ b/Arma.Studio/ArmA.Studio.csproj
@@ -247,6 +247,11 @@
+
+
+ PreserveNewest
+
+
git rev-parse HEAD > "$(ProjectDir)\git-version.txt"
diff --git a/Arma.Studio/Extensions.cs b/Arma.Studio/Extensions.cs
index e5843f1..757b8b1 100644
--- a/Arma.Studio/Extensions.cs
+++ b/Arma.Studio/Extensions.cs
@@ -64,11 +64,11 @@ public static int GetStartOffset(this TextEditor editor)
/// A valid instance.
/// The method to be used to test the characters. Should return True unless the char is not valid.
///
- public static int GetStartOffset(this TextEditor editor, Func isSeparatorCharacter = null)
+ public static int GetStartOffsetByCaret(this TextEditor editor, Func isSeparatorCharacter = null)
{
if (isSeparatorCharacter == null)
{
- isSeparatorCharacter = Char.IsLetter;
+ isSeparatorCharacter = (c) => !Char.IsLetter(c);
}
int off = editor.CaretOffset;
if (off <= 0 || off > editor.Document.TextLength)
@@ -91,6 +91,71 @@ public static int GetStartOffset(this TextEditor editor, Func isSepa
}
return 0;
}
+ ///
+ /// Tries to find the start of a word.
+ ///
+ /// A valid instance.
+ /// The method to be used to test the characters. Should return True unless the char is not valid.
+ ///
+ public static int GetStartOffset(this TextDocument document, int baseOffset, Func 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;
+ }
+ ///
+ /// Tries to find the start of a word.
+ ///
+ /// A valid instance.
+ /// The method to be used to test the characters. Should return True unless the char is not valid.
+ ///
+ public static int GetEndOffset(this TextDocument document, int baseOffset, Func 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;
+ }
}
}
diff --git a/Arma.Studio/UI/TextEditor.xaml b/Arma.Studio/UI/TextEditor.xaml
index bfb71ba..116b532 100644
--- a/Arma.Studio/UI/TextEditor.xaml
+++ b/Arma.Studio/UI/TextEditor.xaml
@@ -15,6 +15,23 @@
IsReadOnly="{Binding IsReadOnly}"
FontFamily="Consolas"
asd:AttachedDataContext.DataContext="{Binding}">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Arma.Studio/UI/TextEditorDataContext.cs b/Arma.Studio/UI/TextEditorDataContext.cs
index af2c637..aaa366b 100644
--- a/Arma.Studio/UI/TextEditorDataContext.cs
+++ b/Arma.Studio/UI/TextEditorDataContext.cs
@@ -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();
@@ -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)));
diff --git a/Arma.Studio/UI/UnderlineBackgroundRenderer.cs b/Arma.Studio/UI/UnderlineBackgroundRenderer.cs
index 03478f0..83f0f8c 100644
--- a/Arma.Studio/UI/UnderlineBackgroundRenderer.cs
+++ b/Arma.Studio/UI/UnderlineBackgroundRenderer.cs
@@ -60,7 +60,6 @@ private IEnumerable GetPoints(Rect rect, double offset, int count)
}
}
-
public void Draw(TextView textView, DrawingContext drawingContext)
{
textView.EnsureVisualLines();