#region --- License ---
/* Copyright (c) 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
#region --- Using directives ---
using System;
using OpenTK.Input;
using System.Diagnostics;
#endregion
namespace OpenTK.Input
{
///
/// Represents a keyboard device and provides methods to query its status.
///
public sealed class KeyboardDevice : IInputDevice
{
//private IKeyboard keyboard;
private bool[] keys = new bool[Enum.GetValues(typeof(Key)).Length];
private bool[] scancodes = new bool[256];
private string description;
private int numKeys, numFKeys, numLeds;
private IntPtr devID;
private bool repeat;
private KeyboardKeyEventArgs args = new KeyboardKeyEventArgs();
#region --- Constructors ---
internal KeyboardDevice() { }
#endregion
#region --- IKeyboard members ---
///
/// Gets a value indicating the status of the specified Key.
///
/// The Key to check.
/// True if the Key is pressed, false otherwise.
public bool this[Key key]
{
get { return keys[(int)key]; }
}
///
/// Gets a value indicating the status of the specified Key.
///
/// The scancode to check.
/// True if the scancode is pressed, false otherwise.
public bool this[uint scancode]
{
get { return scancodes[scancode]; }
}
///
/// Gets an integer representing the number of keys on this KeyboardDevice.
///
public int NumberOfKeys
{
get { return numKeys; }
internal set { numKeys = value; }
}
///
/// Gets an integer representing the number of function keys (F-keys) on this KeyboardDevice.
///
public int NumberOfFunctionKeys
{
get { return numFKeys; }
internal set { numFKeys = value; }
}
///
/// Gets a value indicating the number of led indicators on this KeyboardDevice.
///
public int NumberOfLeds
{
get { return numLeds; }
internal set { numLeds = value; }
}
///
/// Gets an IntPtr representing a device dependent ID.
///
public IntPtr DeviceID
{
get { return devID; }
internal set { devID = value; }
}
#region public bool KeyRepeat
///
/// Gets or sets a System.Boolean indicating key repeat status.
///
///
/// If KeyRepeat is true, multiple KeyDown events will be generated while a key is being held.
/// Otherwise only one KeyDown event will be reported.
///
/// The rate of the generated KeyDown events is controlled by the Operating System. Usually,
/// one KeyDown event will be reported, followed by a small (250-1000ms) pause and several
/// more KeyDown events (6-30 events per second).
///
///
/// Set to true to handle text input (where keyboard repeat is desirable), but set to false
/// for game input.
///
///
public bool KeyRepeat
{
get { return repeat; }
set { repeat = value; }
}
#endregion
#region KeyDown
///
/// Occurs when a key is pressed.
///
public event EventHandler KeyDown;
#endregion
#region KeyUp
///
/// Occurs when a key is released.
///
public event EventHandler KeyUp;
#endregion
#endregion
#region --- IInputDevice Members ---
///
/// Gets a which describes this instance.
///
public string Description
{
get { return description; }
internal set { description = value; }
}
///
/// Gets the for this instance.
///
public InputDeviceType DeviceType
{
get { return InputDeviceType.Keyboard; }
}
#endregion
#region --- Public Methods ---
/// Returns the hash code for this KeyboardDevice.
/// A 32-bit signed integer hash code.
public override int GetHashCode()
{
//return base.GetHashCode();
return (int)(numKeys ^ numFKeys ^ numLeds ^ devID.GetHashCode() ^ description.GetHashCode());
}
///
/// Returns a System.String representing this KeyboardDevice.
///
/// A System.String representing this KeyboardDevice.
public override string ToString()
{
//return base.ToString();
return String.Format("ID: {0} ({1}). Keys: {2}, Function keys: {3}, Leds: {4}",
DeviceID, Description, NumberOfKeys, NumberOfFunctionKeys, NumberOfLeds);
}
#endregion
#region --- Internal Methods ---
#region internal void ClearKeys()
internal void ClearKeys()
{
for (int i = 0; i < keys.Length; i++)
keys[i] = false;
for (uint i = 0; i < scancodes.Length; i++)
scancodes[i] = false;
}
#endregion
internal void SetKey(Key key, uint scancode, bool state)
{
if (keys[(int)key] != state || KeyRepeat)
{
keys[(int)key] = scancodes[scancode] = state;
if (state && KeyDown != null)
{
args.Key = key;
args.ScanCode = scancode;
KeyDown(this, args);
}
else if (!state && KeyUp != null)
{
args.Key = key;
args.ScanCode = scancode;
KeyUp(this, args);
}
}
}
#endregion
}
}