Opentk/Source/OpenTK/Input/KeyboardDevice.cs
Fraser Waters e855d2eb33 [Input] Legacy keyboard respects the KeyRepeat field.
If the legacy keyboard device receives a key down event with IsRepeat set it
will only raise it's own key down event if it's KeyRepeat field is set to true.

This is as documented, regression casused by refactoring. Fixes issue #201.

Also change the GameWindowState example to show setting of KeyRepeat to true
and false and how that changes the event counts for the legacy and new keyboard
devices.
2014-11-23 14:40:36 +01:00

232 lines
7.2 KiB
C#

#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
{
/// <summary>
/// Represents a keyboard device and provides methods to query its status.
/// </summary>
public sealed class KeyboardDevice : IInputDevice
{
//private IKeyboard keyboard;
private string description;
private int numKeys, numFKeys, numLeds;
private IntPtr devID;
private bool repeat;
private KeyboardState state;
#region --- Constructors ---
internal KeyboardDevice() { }
#endregion
#region --- IKeyboard members ---
/// <summary>
/// Gets a value indicating the status of the specified Key.
/// </summary>
/// <param name="key">The Key to check.</param>
/// <returns>True if the Key is pressed, false otherwise.</returns>
public bool this[Key key]
{
get { return state[key]; }
}
/// <summary>
/// Gets a value indicating the status of the specified Key.
/// </summary>
/// <param name="scancode">The scancode to check.</param>
/// <returns>True if the scancode is pressed, false otherwise.</returns>
[CLSCompliant(false)]
public bool this[uint scancode]
{
get { return scancode < (uint)Key.LastKey && state[(Key)scancode]; }
}
/// <summary>
/// Gets an integer representing the number of keys on this KeyboardDevice.
/// </summary>
public int NumberOfKeys
{
get { return numKeys; }
internal set { numKeys = value; }
}
/// <summary>
/// Gets an integer representing the number of function keys (F-keys) on this KeyboardDevice.
/// </summary>
public int NumberOfFunctionKeys
{
get { return numFKeys; }
internal set { numFKeys = value; }
}
/// <summary>
/// Gets a value indicating the number of led indicators on this KeyboardDevice.
/// </summary>
public int NumberOfLeds
{
get { return numLeds; }
internal set { numLeds = value; }
}
/// <summary>
/// Gets an IntPtr representing a device dependent ID.
/// </summary>
public IntPtr DeviceID
{
get { return devID; }
internal set { devID = value; }
}
#region public bool KeyRepeat
/// <summary>
/// Gets or sets a System.Boolean indicating key repeat status.
/// </summary>
/// <remarks>
/// If KeyRepeat is true, multiple KeyDown events will be generated while a key is being held.
/// Otherwise only one KeyDown event will be reported.
/// <para>
/// 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).
/// </para>
/// <para>
/// Set to true to handle text input (where keyboard repeat is desirable), but set to false
/// for game input.
/// </para>
/// </remarks>
public bool KeyRepeat
{
get { return repeat; }
set { repeat = value; }
}
#endregion
#region KeyDown
/// <summary>
/// Occurs when a key is pressed.
/// </summary>
public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
#endregion
#region KeyUp
/// <summary>
/// Occurs when a key is released.
/// </summary>
public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
#endregion
#endregion
#region --- IInputDevice Members ---
/// <summary>
/// Gets a <see cref="System.String"/> which describes this instance.
/// </summary>
public string Description
{
get { return description; }
internal set { description = value; }
}
/// <summary>
/// Gets the <see cref="InputDeviceType"/> for this instance.
/// </summary>
public InputDeviceType DeviceType
{
get { return InputDeviceType.Keyboard; }
}
#endregion
#region --- Public Methods ---
/// <summary>
/// Retrieves the combined <see cref="OpenTK.Input.KeyboardState"/> for all keyboard devices.
/// This method is equivalent to <see cref="OpenTK.Input.Keyboard.GetState()"/>.
/// </summary>
/// <returns>An <see cref="OpenTK.Input.KeyboardState"/> structure containing the combined state for all keyboard devices.</returns>
/// <seealso cref="OpenTK.Input.Keyboard.GetState()"/>
public KeyboardState GetState()
{
return Keyboard.GetState();
}
/// <summary>
/// Retrieves the <see cref="OpenTK.Input.KeyboardState"/> for the specified keyboard device.
/// This method is equivalent to <see cref="OpenTK.Input.Keyboard.GetState(int)"/>.
/// </summary>
/// <param name="index">The index of the keyboard device.</param>
/// <returns>An <see cref="OpenTK.Input.KeyboardState"/> structure containing the combined state for all keyboard devices.</returns>
/// <seealso cref="OpenTK.Input.Keyboard.GetState(int)"/>
public KeyboardState GetState(int index)
{
return Keyboard.GetState(index);
}
/// <summary>Returns the hash code for this KeyboardDevice.</summary>
/// <returns>A 32-bit signed integer hash code.</returns>
public override int GetHashCode()
{
//return base.GetHashCode();
return (int)(numKeys ^ numFKeys ^ numLeds ^ devID.GetHashCode() ^ description.GetHashCode());
}
/// <summary>
/// Returns a System.String representing this KeyboardDevice.
/// </summary>
/// <returns>A System.String representing this KeyboardDevice.</returns>
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 ---
internal void HandleKeyDown(object sender, KeyboardKeyEventArgs e)
{
state = e.Keyboard;
// KeyRepeat IsRepeat KeyDown
// False False True
// False True False
// True False True
// True True True
if (this.KeyRepeat || !e.IsRepeat)
{
KeyDown(this, e);
}
}
internal void HandleKeyUp(object sender, KeyboardKeyEventArgs e)
{
state = e.Keyboard;
KeyUp(this, e);
}
#endregion
}
}