// This code is distributed under MIT license.
// Copyright (c) 2010-2018 George Mamaladze
// See license.txt or https://mit-license.org/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Gma.System.MouseKeyHook.Implementation;
namespace Gma.System.MouseKeyHook
{
///
/// Used to represent a key combination as frequently used in application as shortcuts.
/// e.g. Alt+Shift+R. This combination is triggered when 'R' is pressed after 'Alt' and 'Shift' are already down.
///
public class Combination
{
private readonly Chord _chord;
private Combination(Keys triggerKey, IEnumerable chordKeys)
: this(triggerKey, new Chord(chordKeys))
{
}
private Combination(Keys triggerKey, Chord chord)
{
TriggerKey = triggerKey.Normalize();
_chord = chord;
}
///
/// Last key which triggers the combination.
///
public Keys TriggerKey { get; }
///
/// Keys which all must be alredy down when trigger key is pressed.
///
public IEnumerable Chord
{
get { return _chord; }
}
///
/// Number of chord (modifier) keys which must be already down when the trigger key is pressed.
///
public int ChordLength
{
get { return _chord.Count; }
}
///
/// A chainable builder method to simplify chord creation. Used along with ,
/// , , , .
///
///
public static Combination TriggeredBy(Keys key)
{
return new Combination(key, (IEnumerable) new Chord(Enumerable.Empty()));
}
///
/// A chainable builder method to simplify chord creation. Used along with ,
/// , , , .
///
///
public Combination With(Keys key)
{
return new Combination(TriggerKey, Chord.Concat(Enumerable.Repeat(key, 1)));
}
///
/// A chainable builder method to simplify chord creation. Used along with ,
/// , , , .
///
public Combination Control()
{
return With(Keys.Control);
}
///
/// A chainable builder method to simplify chord creation. Used along with ,
/// , , , .
///
public Combination Alt()
{
return With(Keys.Alt);
}
///
/// A chainable builder method to simplify chord creation. Used along with ,
/// , , , .
///
public Combination Shift()
{
return With(Keys.Shift);
}
///
public override string ToString()
{
return string.Join("+", Chord.Concat(Enumerable.Repeat(TriggerKey, 1)));
}
///
/// TriggeredBy a chord from any string like this 'Alt+Shift+R'.
/// Nothe that the trigger key must be the last one.
///
public static Combination FromString(string trigger)
{
var parts = trigger
.Split('+')
.Select(p => Enum.Parse(typeof(Keys), p))
.Cast();
var stack = new Stack(parts);
var triggerKey = stack.Pop();
return new Combination(triggerKey, stack);
}
///
protected bool Equals(Combination other)
{
return
TriggerKey == other.TriggerKey
&& Chord.Equals(other.Chord);
}
///
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Combination) obj);
}
///
public override int GetHashCode()
{
return Chord.GetHashCode() ^
(int) TriggerKey;
}
}
}