Browse Source

Added keyboard event support.

improved_timing
Ian Burgmyer 7 years ago
parent
commit
815100b96e
  1. 20
      DotSDL/Events/EventConversion.cs
  2. 12
      DotSDL/Events/EventDispatcher.cs
  3. 16
      DotSDL/Events/EventHandler.cs
  4. 42
      DotSDL/Events/KeyboardEvent.cs
  5. 34
      DotSDL/Graphics/SdlWindow.cs
  6. 9
      DotSDL/Input/ButtonState.cs
  7. 2
      DotSDL/Input/Keyboard/Keycode.cs
  8. 13
      DotSDL/Sdl/Events.cs
  9. 11
      Samples/Sample.BasicPixels/Window.cs

20
DotSDL/Events/EventConversion.cs

@ -14,13 +14,27 @@ namespace DotSDL.Events {
/// <returns>A DotSDL <see cref="IEvent"/> that can be passed to applications.</returns>
internal static IEvent Convert(object sdlEvent) {
switch(sdlEvent) {
case SdlEvents.SdlWindowEvent e:
return ConvertWindowEvent(e);
case SdlEvents.SdlWindowEvent wnd:
return ConvertWindowEvent(wnd);
case SdlEvents.SdlKeyboardEvent kbd:
return ConvertKeyboardEvent(kbd);
}
return null;
}
private static KeyboardEvent ConvertKeyboardEvent(SdlEvents.SdlKeyboardEvent e) {
return new KeyboardEvent {
Timestamp = e.Timestamp,
Resource = Resources.GetResourceById(e.WindowId),
Keycode = e.Keysym.Sym,
Keymod = e.Keysym.Mod,
Repeat = e.Repeat != 0,
Scancode = e.Keysym.Scancode,
State = e.State
};
}
/// <summary>
///
/// </summary>
@ -29,8 +43,8 @@ namespace DotSDL.Events {
private static WindowEvent ConvertWindowEvent(SdlEvents.SdlWindowEvent e) {
return new WindowEvent {
Timestamp = e.Timestamp,
Event = e.EventId,
Resource = Resources.GetResourceById(e.WindowId),
Event = e.EventId,
X = e.Data1,
Y = e.Data2
};

12
DotSDL/Events/EventDispatcher.cs

@ -10,10 +10,16 @@ namespace DotSDL.Events {
/// </summary>
/// <param name="ev">The event to process.</param>
internal static void Dispatch(IEvent ev) {
SdlWindow window;
switch(ev) {
case WindowEvent e:
var window = (SdlWindow)e.Resource;
window.HandleEvent(e);
case KeyboardEvent kbd:
window = (SdlWindow)kbd.Resource;
window.HandleEvent(kbd);
break;
case WindowEvent wnd:
window = (SdlWindow)wnd.Resource;
window.HandleEvent(wnd);
break;
}
}

16
DotSDL/Events/EventHandler.cs

@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using SdlEvents = DotSDL.Sdl.Events;
@ -16,8 +17,8 @@ namespace DotSDL.Events {
/// <param name="sdlEvent">The event that should be converted.</param>
/// <returns>A structure of type T, containing the data in <paramref name="sdlEvent"/>.</returns>
private static unsafe T CastEvent<T>(SdlEvents.SdlEvent sdlEvent) {
var sdlEventIntPtr = new IntPtr(&sdlEvent);
return Marshal.PtrToStructure<T>(sdlEventIntPtr);
var sdlEventPtr = new IntPtr(&sdlEvent);
return Marshal.PtrToStructure<T>(sdlEventPtr);
}
/// <summary>
@ -28,9 +29,16 @@ namespace DotSDL.Events {
/// <returns>An <see cref="IEvent"/> that can be passed to an application.</returns>
private static IEvent ConvertEvent(SdlEvents.SdlEvent sdlEvent) {
switch(sdlEvent.Type) {
case SdlEvents.EventType.KeyDown:
case SdlEvents.EventType.KeyUp:
var kbd = CastEvent<SdlEvents.SdlKeyboardEvent>(sdlEvent);
return EventConversion.Convert(kbd);
case SdlEvents.EventType.WindowEvent:
var e = CastEvent<SdlEvents.SdlWindowEvent>(sdlEvent);
return EventConversion.Convert(e);
var wnd = CastEvent<SdlEvents.SdlWindowEvent>(sdlEvent);
return EventConversion.Convert(wnd);
default:
Debug.WriteLine(sdlEvent.Type);
break;
}
return null;
}

42
DotSDL/Events/KeyboardEvent.cs

@ -0,0 +1,42 @@
using DotSDL.Input;
using DotSDL.Input.Keyboard;
namespace DotSDL.Events {
/// <summary>
/// Represents a keyboard event. Keyboard events are thrown when an key is
/// pressed while an <see cref="Graphics.SdlWindow"/> has focus.
/// </summary>
public class KeyboardEvent : IEvent {
public uint Timestamp { get; set; }
public IResourceObject Resource { get; set; }
/// <summary>
/// A <see cref="Keycode"/> that represents the key being pressed or
/// released.
/// </summary>
public Keycode Keycode { get; set; }
/// <summary>
/// A <see cref="Keymod"/> that represents the key modifiers being held
/// down while the key is being pressed.
/// </summary>
public Keymod Keymod { get; set; }
/// <summary>
/// <c>true</c> if this event is the result of an auto-repeated
/// keystroke, otherwise <c>false</c>.
/// </summary>
public bool Repeat { get; set; }
/// <summary>
/// A <see cref="Scancode"/> that represents the key being pressed or
/// released.
/// </summary>
public Scancode Scancode { get; set; }
/// <summary>
/// Indicates the state of the key when the event is fired.
/// </summary>
public ButtonState State { get; set; }
}
}

34
DotSDL/Graphics/SdlWindow.cs

@ -1,6 +1,7 @@
using DotSDL.Sdl;
using DotSDL.Events;
using DotSDL.Sdl;
using System;
using DotSDL.Events;
using DotSDL.Input;
namespace DotSDL.Graphics {
/// <summary>
@ -50,6 +51,16 @@ namespace DotSDL.Graphics {
/// </summary>
public const int WindowPosUndefined = 0x1FFF0000;
/// <summary>
/// Fired when a key is pressed.
/// </summary>
public event EventHandler<KeyboardEvent> KeyPressed;
/// <summary>
/// Fired when a key is released.
/// </summary>
public event EventHandler<KeyboardEvent> KeyReleased;
/// <summary>
/// Calculates a value that allows the window to be placed on a specific display, with its exact position determined by the window manager.
/// </summary>
@ -168,9 +179,24 @@ namespace DotSDL.Graphics {
}
/// <summary>
/// Triggers this window to handle a specified event.
/// Triggers this window to handle a specified <see cref="KeyboardEvent"/>.
/// </summary>
/// <param name="ev">The <see cref="KeyboardEvent"/> to handle.</param>
internal void HandleEvent(KeyboardEvent ev) {
switch(ev.State) {
case ButtonState.Pressed:
KeyPressed?.Invoke(this, ev);
break;
case ButtonState.Released:
KeyReleased?.Invoke(this, ev);
break;
}
}
/// <summary>
/// Triggers this window to handle a specified <see cref="WindowEvent"/>.
/// </summary>
/// <param name="ev">The event to handle</param>
/// <param name="ev">The <see cref="WindowEvent"/> to handle.</param>
internal void HandleEvent(WindowEvent ev) {
switch(ev.Event) {
case WindowEventType.Close:

9
DotSDL/Input/ButtonState.cs

@ -0,0 +1,9 @@
namespace DotSDL.Input {
/// <summary>
/// Indicates the state of a keyboard, mouse, joystick, or controller button.
/// </summary>
public enum ButtonState : byte {
Released = 0,
Pressed = 1
}
}

2
DotSDL/Input/Keyboard/Keycode.cs

@ -12,7 +12,7 @@
public enum Keycode {
Unknown = 0,
Return = '\r',
Escape = 0x27,
Escape = 0x1B,
Backspace = '\b',
Tab = '\t',
Space = ' ',

13
DotSDL/Sdl/Events.cs

@ -1,25 +1,18 @@
using ControllerButton = DotSDL.Input.Controller.Button;
using DotSDL.Events;
using DotSDL.Input;
using DotSDL.Input.Controller;
using DotSDL.Input.Joystick;
using DotSDL.Input.Mouse;
using MouseButton = DotSDL.Input.Mouse.Button;
using System;
using System.Runtime.InteropServices;
using DotSDL.Events;
namespace DotSDL.Sdl {
/// <summary>
/// Contains the necessary constants and function imports from SDL_events.h.
/// </summary>
internal static class Events {
/// <summary>
/// Indicates the state of a keyboard, mouse, joystick, or controller button.
/// </summary>
internal enum ButtonState : byte {
Released = 0,
Pressed = 1
}
/// <summary>
/// Indicates the type of event.
/// </summary>
@ -356,7 +349,7 @@ namespace DotSDL.Sdl {
internal EventType Type;
internal uint Timestamp;
internal uint WindowId;
internal byte State;
internal ButtonState State;
internal byte Repeat;
internal byte Padding2;
internal byte Padding3;

11
Samples/Sample.BasicPixels/Window.cs

@ -1,9 +1,13 @@
using DotSDL.Graphics;
using System;
using System.Diagnostics;
using DotSDL.Input.Keyboard;
namespace DotSDL.Sample.BasicPixels {
internal class Window : SdlWindow {
public Window(int width, int height) : base("Basic Pixels", new Point { X = WindowPosUndefined, Y = WindowPosUndefined }, width, height) { }
public Window(int width, int height) : base("Basic Pixels", new Point { X = WindowPosUndefined, Y = WindowPosUndefined }, width, height) {
KeyPressed += Window_KeyPressed;
}
private void DrawBackground(ref Color[] pixels) {
byte d = 0;
@ -111,5 +115,10 @@ namespace DotSDL.Sample.BasicPixels {
return color;
}
private void Window_KeyPressed(object sender, Events.KeyboardEvent e) {
if(e.Keycode == Keycode.Escape)
Stop();
}
}
}

Loading…
Cancel
Save