Browse Source
Added support for "stacked" input handlers. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5065 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
21 changed files with 412 additions and 194 deletions
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.AvalonEdit.Editing; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Snippets |
||||
{ |
||||
sealed class SnippetInputHandler : ITextAreaInputHandler |
||||
{ |
||||
readonly InsertionContext context; |
||||
|
||||
public SnippetInputHandler(InsertionContext context) |
||||
{ |
||||
this.context = context; |
||||
} |
||||
|
||||
public TextArea TextArea { |
||||
get { return context.TextArea; } |
||||
} |
||||
|
||||
public void Attach() |
||||
{ |
||||
TextArea.PreviewKeyDown += TextArea_PreviewKeyDown; |
||||
|
||||
SelectElement(FindNextEditableElement(-1, false)); |
||||
} |
||||
|
||||
void SelectElement(IActiveElement element) |
||||
{ |
||||
if (element != null) { |
||||
TextArea.Selection = new SimpleSelection(element.Segment); |
||||
TextArea.Caret.Offset = element.Segment.EndOffset; |
||||
} |
||||
} |
||||
|
||||
public void Detach() |
||||
{ |
||||
TextArea.PreviewKeyDown -= TextArea_PreviewKeyDown; |
||||
context.Deactivate(EventArgs.Empty); |
||||
} |
||||
|
||||
void TextArea_PreviewKeyDown(object sender, KeyEventArgs e) |
||||
{ |
||||
if (e.Key == Key.Escape || e.Key == Key.Return) { |
||||
context.Deactivate(e); |
||||
e.Handled = true; |
||||
} else if (e.Key == Key.Tab) { |
||||
bool backwards = e.KeyboardDevice.Modifiers == ModifierKeys.Shift; |
||||
SelectElement(FindNextEditableElement(TextArea.Caret.Offset, backwards)); |
||||
e.Handled = true; |
||||
} |
||||
} |
||||
|
||||
IActiveElement FindNextEditableElement(int offset, bool backwards) |
||||
{ |
||||
IEnumerable<IActiveElement> elements = context.ActiveElements.Where(e => e.IsEditable && e.Segment != null); |
||||
if (backwards) { |
||||
elements = elements.Reverse(); |
||||
foreach (IActiveElement element in elements) { |
||||
if (offset > element.Segment.EndOffset) |
||||
return element; |
||||
} |
||||
} else { |
||||
foreach (IActiveElement element in elements) { |
||||
if (offset < element.Segment.Offset) |
||||
return element; |
||||
} |
||||
} |
||||
return elements.FirstOrDefault(); |
||||
} |
||||
} |
||||
} |
@ -1,72 +0,0 @@
@@ -1,72 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.AvalonEdit.Utils |
||||
{ |
||||
interface IFreezable |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe.
|
||||
/// </summary>
|
||||
bool IsFrozen { get; } |
||||
|
||||
/// <summary>
|
||||
/// Freezes this instance.
|
||||
/// </summary>
|
||||
void Freeze(); |
||||
} |
||||
|
||||
[Serializable] |
||||
sealed class FreezableNullSafeCollection<T> : NullSafeCollection<T>, IFreezable where T : class, IFreezable |
||||
{ |
||||
bool isFrozen; |
||||
|
||||
public bool IsFrozen { get { return isFrozen; } } |
||||
|
||||
public void Freeze() |
||||
{ |
||||
if (!isFrozen) { |
||||
foreach (T item in this) { |
||||
item.Freeze(); |
||||
} |
||||
isFrozen = true; |
||||
} |
||||
} |
||||
|
||||
void CheckBeforeMutation() |
||||
{ |
||||
if (isFrozen) |
||||
throw new InvalidOperationException("Cannot mutate frozen " + GetType().Name); |
||||
} |
||||
|
||||
protected override void ClearItems() |
||||
{ |
||||
this.CheckBeforeMutation(); |
||||
base.ClearItems(); |
||||
} |
||||
|
||||
protected override void InsertItem(int index, T item) |
||||
{ |
||||
this.CheckBeforeMutation(); |
||||
base.InsertItem(index, item); |
||||
} |
||||
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
this.CheckBeforeMutation(); |
||||
base.RemoveItem(index); |
||||
} |
||||
|
||||
protected override void SetItem(int index, T item) |
||||
{ |
||||
this.CheckBeforeMutation(); |
||||
base.SetItem(index, item); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue