You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
7.5 KiB
202 lines
7.5 KiB
using System; |
|
using System.ComponentModel; |
|
using System.Text; |
|
using System.Windows.Input; |
|
|
|
namespace ICSharpCode.Core.Presentation |
|
{ |
|
/// <summary> |
|
/// Describes full key gesture or part of a key gesture |
|
/// |
|
/// This class is is designed to react to key events even it descibes only part of them |
|
/// For example if event argument holds modifiers Ctrl, Shift and key C then partial template |
|
/// with single modifier Ctrl and a key C will match this event |
|
/// </summary> |
|
[TypeConverter(typeof(PartialKeyGestureConverter))] |
|
public class PartialKeyGesture : KeyGesture |
|
{ |
|
private readonly Key _key; |
|
private readonly ModifierKeys _modifiers; |
|
|
|
/// <summary> |
|
/// Key associated with partial key gesture |
|
/// </summary> |
|
public new Key Key |
|
{ |
|
get |
|
{ |
|
return _key; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Modifier keys associated with partial key gesture |
|
/// </summary> |
|
public new ModifierKeys Modifiers |
|
{ |
|
get |
|
{ |
|
return _modifiers; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Create new instance of <see cref="PartialKeyGesture"/> from <see cref="KeyEventArgs"/> |
|
/// </summary> |
|
/// <param name="keyEventArgs">Arguments generated by key event</param> |
|
public PartialKeyGesture(KeyEventArgs keyEventArgs) |
|
: base(Key.None, ModifierKeys.None) |
|
{ |
|
var keyboardDevice = (KeyboardDevice)keyEventArgs.Device; |
|
|
|
_key = keyEventArgs.Key; |
|
_modifiers = keyboardDevice.Modifiers; |
|
} |
|
|
|
/// <summary> |
|
/// Create new instance of <see cref="PartialKeyGesture"/> from <see cref="KeyGesture"/> |
|
/// </summary> |
|
/// <param name="gesture">Key gesture</param> |
|
public PartialKeyGesture(KeyGesture gesture) |
|
: base(Key.None, ModifierKeys.None) |
|
{ |
|
_key = gesture.Key; |
|
_modifiers = gesture.Modifiers; |
|
} |
|
|
|
/// <summary> |
|
/// Create new instance of <see cref="PartialKeyGesture"/> having key and modifiers |
|
/// </summary> |
|
/// <param name="key">The key associated with partial key gesture</param> |
|
/// <param name="modifiers">Modifier keys associated with partial key gesture</param> |
|
public PartialKeyGesture(Key key, ModifierKeys modifiers) |
|
: base(Key.None, ModifierKeys.None) |
|
{ |
|
_key = key; |
|
_modifiers = modifiers; |
|
} |
|
|
|
/// <summary> |
|
/// Create new instance of<see cref="PartialKeyGesture"/> having only key and no modifiers |
|
/// </summary> |
|
/// <param name="key">The key associated with partial key gesture</param> |
|
public PartialKeyGesture(Key key) |
|
: base(Key.None, ModifierKeys.None) |
|
{ |
|
_key = key; |
|
_modifiers = ModifierKeys.None; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Create new instance of<see cref="PartialKeyGesture"/> having only key and no modifiers |
|
/// </summary> |
|
/// <param name="modifiers">Modifier keys associated with partial key gesture</param> |
|
public PartialKeyGesture(ModifierKeys modifiers) |
|
: base(Key.None, ModifierKeys.None) |
|
{ |
|
_key = Key.None; |
|
_modifiers = modifiers; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Determines whether key gesture strictly matches this key gesture template |
|
/// (That is key and modifier both match key event arguments) |
|
/// </summary> |
|
/// <param name="targetElement">The target</param> |
|
/// <param name="args">Input event arguments</param> |
|
/// <returns>True if the event data matches this <see cref="PartialKeyGesture"/>; otherwise, false. </returns> |
|
public bool StrictlyMatches(object targetElement, InputEventArgs args) |
|
{ |
|
var keyEventArgs = args as KeyEventArgs; |
|
if(keyEventArgs == null) |
|
{ |
|
return false; |
|
} |
|
|
|
var keyboard = (KeyboardDevice)keyEventArgs.Device; |
|
|
|
// If system key is pressed |
|
if (keyEventArgs.Key == Key.System) |
|
{ |
|
return keyboard.Modifiers == Modifiers && keyEventArgs.SystemKey == Key; |
|
} |
|
|
|
return keyboard.Modifiers == Modifiers && keyEventArgs.Key == Key; |
|
} |
|
|
|
/// <summary> |
|
/// Determines whether key event arguments matches this instance of <see cref="PartialKeyGesture"/> |
|
/// </summary> |
|
/// <param name="targetElement">The target</param> |
|
/// <param name="inputEventArgs">Input event arguments</param> |
|
/// <returns>True if event data matches parial event arguments otherwise false</returns> |
|
public override bool Matches(object targetElement, InputEventArgs inputEventArgs) |
|
{ |
|
var keyEventArgs = inputEventArgs as KeyEventArgs; |
|
if(keyEventArgs == null) |
|
{ |
|
return false; |
|
} |
|
|
|
var keyboard = (KeyboardDevice)keyEventArgs.Device; |
|
|
|
// When system key (Alt) is pressed real key is moved to SystemKey property |
|
var enteredKey = keyEventArgs.Key == Key.System ? keyEventArgs.SystemKey : keyEventArgs.Key; |
|
|
|
var keyMatches = Key == enteredKey; |
|
|
|
// Determine whether template contains only part of modifier keys contained in |
|
// gesture. For example if template contains Control modifier, but gesture contains |
|
// Control and Alt true will be returned |
|
var modifierMatches = keyboard.Modifiers - (keyboard.Modifiers ^ Modifiers) >= 0; |
|
|
|
// Template contains no modifiers compare only keys |
|
if (Modifiers == ModifierKeys.None) |
|
{ |
|
return keyMatches; |
|
} |
|
|
|
// If template has modifiers but key is one of modifier keys return true if |
|
// modifiers match. This is used because when user presses modifier key it is |
|
// presented in Key property and Modifiers property |
|
if (Array.IndexOf(new[] { Key.LeftAlt, Key.RightAlt, |
|
Key.LeftShift, Key.RightShift, |
|
Key.LeftCtrl, Key.RightCtrl, |
|
Key.LWin, Key.RWin, |
|
Key.System}, enteredKey) >= 0) |
|
{ |
|
return modifierMatches; |
|
} |
|
|
|
return modifierMatches && keyMatches; |
|
} |
|
|
|
/// <summary> |
|
/// Returns string that represents <see cref="PartialKeyGesture"/> |
|
/// </summary> |
|
/// <returns>String</returns> |
|
public override string ToString() |
|
{ |
|
var pressedButton = new StringBuilder(); |
|
|
|
if (Modifiers != ModifierKeys.None) |
|
{ |
|
pressedButton.AppendFormat("{0}+", new ModifierKeysConverter().ConvertToInvariantString(Modifiers)); |
|
} |
|
|
|
// Filter modifier keys from being displayed twice (example: Ctrl + LeftCtrl) |
|
if (Array.IndexOf(new[] { Key.LeftAlt, Key.RightAlt, |
|
Key.LeftShift, Key.RightShift, |
|
Key.LeftCtrl, Key.RightCtrl, |
|
Key.LWin, Key.RWin, |
|
Key.System}, Key) < 0) |
|
{ |
|
pressedButton.Append(new KeyConverter().ConvertToInvariantString(Key)); |
|
} |
|
|
|
return pressedButton.ToString(); |
|
} |
|
} |
|
}
|
|
|