forked from MoonsideGames/MoonWorks
add system for text input
parent
ccefe570db
commit
984e30cc4c
40
src/Game.cs
40
src/Game.cs
|
@ -4,6 +4,7 @@ using MoonWorks.Audio;
|
|||
using MoonWorks.Graphics;
|
||||
using MoonWorks.Input;
|
||||
using MoonWorks.Window;
|
||||
using System.Text;
|
||||
|
||||
namespace MoonWorks
|
||||
{
|
||||
|
@ -107,6 +108,10 @@ namespace MoonWorks
|
|||
case SDL.SDL_EventType.SDL_QUIT:
|
||||
quit = true;
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_TEXTINPUT:
|
||||
HandleTextInput(_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,5 +119,40 @@ namespace MoonWorks
|
|||
protected abstract void Update(double dt);
|
||||
|
||||
protected abstract void Draw(double dt, double alpha);
|
||||
|
||||
private void HandleTextInput(SDL2.SDL.SDL_Event evt)
|
||||
{
|
||||
// Based on the SDL2# LPUtf8StrMarshaler
|
||||
unsafe
|
||||
{
|
||||
int bytes = MeasureStringLength(evt.text.text);
|
||||
if (bytes > 0)
|
||||
{
|
||||
/* UTF8 will never encode more characters
|
||||
* than bytes in a string, so bytes is a
|
||||
* suitable upper estimate of size needed
|
||||
*/
|
||||
char* charsBuffer = stackalloc char[bytes];
|
||||
int chars = Encoding.UTF8.GetChars(
|
||||
evt.text.text,
|
||||
bytes,
|
||||
charsBuffer,
|
||||
bytes
|
||||
);
|
||||
|
||||
for (int i = 0; i < chars; i += 1)
|
||||
{
|
||||
Inputs.OnTextInput(charsBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static int MeasureStringLength(byte* ptr)
|
||||
{
|
||||
int bytes;
|
||||
for (bytes = 0; *ptr != 0; ptr += 1, bytes += 1);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using SDL2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MoonWorks.Input
|
||||
|
@ -10,6 +11,8 @@ namespace MoonWorks.Input
|
|||
|
||||
List<Gamepad> gamepads = new List<Gamepad>();
|
||||
|
||||
public static event Action<char> TextInput;
|
||||
|
||||
internal Inputs()
|
||||
{
|
||||
Keyboard = new Keyboard();
|
||||
|
@ -45,5 +48,13 @@ namespace MoonWorks.Input
|
|||
{
|
||||
return gamepads[slot];
|
||||
}
|
||||
|
||||
internal static void OnTextInput(char c)
|
||||
{
|
||||
if (TextInput != null)
|
||||
{
|
||||
TextInput(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using SDL2;
|
||||
|
||||
|
@ -9,6 +10,28 @@ namespace MoonWorks.Input
|
|||
private ButtonState[] Keys { get; }
|
||||
private int numKeys;
|
||||
|
||||
private static readonly char[] TextInputCharacters = new char[]
|
||||
{
|
||||
(char) 2, // Home
|
||||
(char) 3, // End
|
||||
(char) 8, // Backspace
|
||||
(char) 9, // Tab
|
||||
(char) 13, // Enter
|
||||
(char) 127, // Delete
|
||||
(char) 22 // Ctrl+V (Paste)
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Keycode, int> TextInputBindings = new Dictionary<Keycode, int>()
|
||||
{
|
||||
{ Keycode.Home, 0 },
|
||||
{ Keycode.End, 1 },
|
||||
{ Keycode.Backspace, 2 },
|
||||
{ Keycode.Tab, 3 },
|
||||
{ Keycode.Return, 4 },
|
||||
{ Keycode.Delete, 5 }
|
||||
// Ctrl+V is special!
|
||||
};
|
||||
|
||||
internal Keyboard()
|
||||
{
|
||||
SDL.SDL_GetKeyboardState(out numKeys);
|
||||
|
@ -28,6 +51,18 @@ namespace MoonWorks.Input
|
|||
{
|
||||
var keyDown = Marshal.ReadByte(keyboardState, keycode);
|
||||
Keys[keycode].Update(Conversions.ByteToBool(keyDown));
|
||||
|
||||
if (Conversions.ByteToBool(keyDown))
|
||||
{
|
||||
if (TextInputBindings.TryGetValue((Keycode)keycode, out var textIndex))
|
||||
{
|
||||
Inputs.OnTextInput(TextInputCharacters[(textIndex)]);
|
||||
}
|
||||
else if (IsDown(Keycode.LeftControl) && (Keycode)keycode == Keycode.V)
|
||||
{
|
||||
Inputs.OnTextInput(TextInputCharacters[6]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue