Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 40e5ec6

Browse files
committed
Fix #518 by re-using the insight window.
1 parent c621797 commit 40e5ec6

4 files changed

Lines changed: 181 additions & 52 deletions

File tree

src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeCompletionEditorAdapter.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,30 @@ public override IInsightWindow ShowInsightWindow(IEnumerable<IInsightItem> items
5555
{
5656
if (items == null)
5757
return null;
58-
var insightWindow = new SharpDevelopInsightWindow(this.TextEditor.TextArea);
59-
insightWindow.Items.AddRange(items);
60-
if (insightWindow.Items.Count > 0) {
61-
insightWindow.SelectedItem = insightWindow.Items[0];
58+
var insightWindow = textEditor.ActiveInsightWindow;
59+
bool isNewWindow = false;
60+
if (insightWindow == null) {
61+
insightWindow = new SharpDevelopInsightWindow(this.TextEditor.TextArea);
62+
isNewWindow = true;
63+
}
64+
var adapter = new SharpDevelopInsightWindowAdapter(insightWindow);
65+
adapter.Items.AddRange(items);
66+
if (adapter.Items.Count > 0) {
67+
adapter.SelectedItem = adapter.Items[0];
6268
} else {
6369
// don't open insight window when there are no items
6470
return null;
6571
}
66-
textEditor.ShowInsightWindow(insightWindow);
67-
return insightWindow;
72+
insightWindow.SetActiveAdapter(adapter, isNewWindow);
73+
if (isNewWindow)
74+
{
75+
textEditor.ShowInsightWindow(insightWindow);
76+
}
77+
return adapter;
6878
}
6979

7080
public override IInsightWindow ActiveInsightWindow {
71-
get { return textEditor.ActiveInsightWindow; }
81+
get { return textEditor.ActiveInsightWindow.activeAdapter; }
7282
}
7383

7484
public override ICompletionListWindow ActiveCompletionWindow {

src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/SharpDevelopInsightWindow.cs

Lines changed: 162 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using System.Collections.Specialized;
2323
using System.ComponentModel;
2424

25+
using System.Windows.Threading;
2526
using ICSharpCode.AvalonEdit.CodeCompletion;
2627
using ICSharpCode.AvalonEdit.Document;
2728
using ICSharpCode.AvalonEdit.Editing;
@@ -30,17 +31,94 @@
3031

3132
namespace ICSharpCode.AvalonEdit.AddIn
3233
{
34+
class SharpDevelopInsightWindow : OverloadInsightWindow
35+
{
36+
public SharpDevelopInsightWindow(TextArea textArea) : base(textArea)
37+
{
38+
this.Style = ICSharpCode.Core.Presentation.GlobalStyles.WindowStyle;
39+
AttachEvents();
40+
}
41+
42+
internal SharpDevelopInsightWindowAdapter activeAdapter;
43+
44+
public void SetActiveAdapter(SharpDevelopInsightWindowAdapter adapter, bool isNewWindow)
45+
{
46+
if (activeAdapter != null) {
47+
// tell the previous adapter that its window was closed,
48+
// but actually reuse the window for the new adapter
49+
activeAdapter.OnClosed();
50+
}
51+
activeAdapter = adapter;
52+
this.Provider = adapter.Provider;
53+
if (!isNewWindow) {
54+
// reset insight window to initial state
55+
CloseAutomatically = true;
56+
StartOffset = EndOffset = this.TextArea.Caret.Offset;
57+
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(SetPositionToStartOffset));
58+
}
59+
}
60+
61+
void SetPositionToStartOffset()
62+
{
63+
if (document != null && this.StartOffset != this.TextArea.Caret.Offset) {
64+
SetPosition(new TextViewPosition(document.GetLocation(this.StartOffset)));
65+
} else {
66+
SetPosition(this.TextArea.Caret.Position);
67+
}
68+
}
69+
70+
TextDocument document;
71+
Caret caret;
72+
73+
void AttachEvents()
74+
{
75+
document = this.TextArea.Document;
76+
caret = this.TextArea.Caret;
77+
if (document != null)
78+
document.Changed += document_Changed;
79+
if (caret != null)
80+
caret.PositionChanged += caret_PositionChanged;
81+
this.Closed += OnClosed;
82+
}
83+
84+
/// <inheritdoc/>
85+
protected override void DetachEvents()
86+
{
87+
if (document != null)
88+
document.Changed -= document_Changed;
89+
if (caret != null)
90+
caret.PositionChanged -= caret_PositionChanged;
91+
this.Closed -= OnClosed;
92+
base.DetachEvents();
93+
}
94+
95+
void OnClosed(object sender, EventArgs e)
96+
{
97+
activeAdapter.OnClosed();
98+
}
99+
100+
void caret_PositionChanged(object sender, EventArgs e)
101+
{
102+
activeAdapter.OnCaretPositionChanged(e);
103+
}
104+
105+
void document_Changed(object sender, DocumentChangeEventArgs e)
106+
{
107+
activeAdapter.OnDocumentChanged(e);
108+
}
109+
}
110+
33111
/// <summary>
34112
/// Adapter between AvalonEdit InsightWindow and SharpDevelop IInsightWindow interface.
35113
/// </summary>
36-
public class SharpDevelopInsightWindow : OverloadInsightWindow, IInsightWindow
114+
class SharpDevelopInsightWindowAdapter : IInsightWindow
37115
{
38116
sealed class SDItemProvider : IOverloadProvider
39117
{
40-
readonly SharpDevelopInsightWindow insightWindow;
118+
readonly SharpDevelopInsightWindowAdapter insightWindow;
41119
int selectedIndex;
42120

43-
public SDItemProvider(SharpDevelopInsightWindow insightWindow)
121+
public SDItemProvider(SharpDevelopInsightWindowAdapter insightWindow)
44122
{
45123
this.insightWindow = insightWindow;
46124
insightWindow.items.CollectionChanged += insightWindow_items_CollectionChanged;
@@ -103,16 +181,21 @@ internal void OnPropertyChanged(string propertyName)
103181
}
104182

105183
readonly ObservableCollection<IInsightItem> items = new ObservableCollection<IInsightItem>();
184+
SharpDevelopInsightWindow insightWindow;
185+
readonly SDItemProvider provider;
106186

107-
public SharpDevelopInsightWindow(TextArea textArea) : base(textArea)
187+
internal IOverloadProvider Provider {
188+
get { return provider; }
189+
}
190+
191+
internal SharpDevelopInsightWindowAdapter(SharpDevelopInsightWindow insightWindow)
108192
{
109-
this.Provider = new SDItemProvider(this);
110-
this.Provider.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
193+
this.insightWindow = insightWindow;
194+
provider = new SDItemProvider(this);
195+
provider.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
111196
if (e.PropertyName == "SelectedIndex")
112197
OnSelectedItemChanged(EventArgs.Empty);
113198
};
114-
this.Style = ICSharpCode.Core.Presentation.GlobalStyles.WindowStyle;
115-
AttachEvents();
116199
}
117200

118201
public IList<IInsightItem> Items {
@@ -121,55 +204,28 @@ public IList<IInsightItem> Items {
121204

122205
public IInsightItem SelectedItem {
123206
get {
124-
int index = this.Provider.SelectedIndex;
207+
int index = provider.SelectedIndex;
125208
if (index < 0 || index >= items.Count)
126209
return null;
127210
else
128211
return items[index];
129212
}
130213
set {
131-
this.Provider.SelectedIndex = items.IndexOf(value);
214+
provider.SelectedIndex = items.IndexOf(value);
132215
OnSelectedItemChanged(EventArgs.Empty);
133216
}
134217
}
135218

136-
TextDocument document;
137-
Caret caret;
138219
IInsightItem oldSelectedItem;
139220

140-
void AttachEvents()
141-
{
142-
document = this.TextArea.Document;
143-
caret = this.TextArea.Caret;
144-
if (document != null)
145-
document.Changed += document_Changed;
146-
if (caret != null)
147-
caret.PositionChanged += caret_PositionChanged;
148-
}
221+
public event EventHandler<TextChangeEventArgs> DocumentChanged;
149222

150-
void caret_PositionChanged(object sender, EventArgs e)
151-
{
152-
OnCaretPositionChanged(e);
153-
}
154-
155-
/// <inheritdoc/>
156-
protected override void DetachEvents()
157-
{
158-
if (document != null)
159-
document.Changed -= document_Changed;
160-
if (caret != null)
161-
caret.PositionChanged -= caret_PositionChanged;
162-
base.DetachEvents();
163-
}
164-
165-
void document_Changed(object sender, DocumentChangeEventArgs e)
223+
internal void OnDocumentChanged(DocumentChangeEventArgs e)
166224
{
167225
if (DocumentChanged != null)
168226
DocumentChanged(this, e);
169227
}
170228

171-
public event EventHandler<TextChangeEventArgs> DocumentChanged;
172-
173229
public event EventHandler SelectedItemChanged;
174230

175231
protected virtual void OnSelectedItemChanged(EventArgs e)
@@ -186,8 +242,6 @@ protected virtual void OnSelectedItemChanged(EventArgs e)
186242

187243
void SelectedItemPropertyChanged(object sender, PropertyChangedEventArgs e)
188244
{
189-
var provider = Provider as SDItemProvider;
190-
if (provider == null) return;
191245
switch (e.PropertyName) {
192246
case "Header":
193247
provider.OnPropertyChanged("CurrentHeader");
@@ -199,12 +253,77 @@ void SelectedItemPropertyChanged(object sender, PropertyChangedEventArgs e)
199253
}
200254

201255
public event EventHandler CaretPositionChanged;
202-
203-
protected virtual void OnCaretPositionChanged(EventArgs e)
256+
257+
internal void OnCaretPositionChanged(EventArgs e)
204258
{
205259
if (CaretPositionChanged != null) {
206260
CaretPositionChanged(this, e);
207261
}
208262
}
263+
264+
public event EventHandler Closed;
265+
266+
internal void OnClosed()
267+
{
268+
if (Closed != null)
269+
Closed(this, EventArgs.Empty);
270+
insightWindow = null;
271+
}
272+
273+
public void Close()
274+
{
275+
if (insightWindow != null)
276+
insightWindow.Close();
277+
}
278+
279+
public double Width {
280+
get {
281+
return insightWindow != null ? insightWindow.Width : 0;
282+
}
283+
set {
284+
if (insightWindow != null)
285+
insightWindow.Width = value;
286+
}
287+
}
288+
289+
public double Height {
290+
get {
291+
return insightWindow != null ? insightWindow.Height : 0;
292+
}
293+
set {
294+
if (insightWindow != null)
295+
insightWindow.Height = value;
296+
}
297+
}
298+
299+
public bool CloseAutomatically {
300+
get {
301+
return insightWindow != null && insightWindow.CloseAutomatically;
302+
}
303+
set {
304+
if (insightWindow != null)
305+
insightWindow.CloseAutomatically = value;
306+
}
307+
}
308+
309+
public int StartOffset {
310+
get {
311+
return insightWindow != null ? insightWindow.StartOffset : 0;
312+
}
313+
set {
314+
if (insightWindow != null)
315+
insightWindow.StartOffset = value;
316+
}
317+
}
318+
319+
public int EndOffset {
320+
get {
321+
return insightWindow != null ? insightWindow.EndOffset : 0;
322+
}
323+
set {
324+
if (insightWindow != null)
325+
insightWindow.EndOffset = value;
326+
}
327+
}
209328
}
210329
}

src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/SharpDevelopTextEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public SharpDevelopCompletionWindow ActiveCompletionWindow {
9797
get { return completionWindow; }
9898
}
9999

100-
public SharpDevelopInsightWindow ActiveInsightWindow {
100+
internal SharpDevelopInsightWindow ActiveInsightWindow {
101101
get { return insightWindow; }
102102
}
103103

src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/CodeCompletion/OverloadInsightWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public IOverloadProvider Provider {
5252
protected override void OnKeyDown(KeyEventArgs e)
5353
{
5454
base.OnKeyDown(e);
55-
if (!e.Handled && this.Provider.Count > 1) {
55+
if (!e.Handled && this.Provider != null && this.Provider.Count > 1) {
5656
switch (e.Key) {
5757
case Key.Up:
5858
e.Handled = true;

0 commit comments

Comments
 (0)