diff --git a/.gitignore b/.gitignore index 57a1574c..ef5f1b7f 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,4 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +*.DotSettings diff --git a/Source/MonoGame.Extended/InputEvents/Input.cs b/Source/MonoGame.Extended/InputEvents/Input.cs deleted file mode 100644 index 00686a35..00000000 --- a/Source/MonoGame.Extended/InputEvents/Input.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Input; - -namespace MonoGame.Extended.InputEvents -{ - public abstract class Input - { - protected Game Game { get; set; } - - protected Input(Game game) - { - Game = game; - } - - /*####################################################################*/ - /* Input Events */ - /*####################################################################*/ - - public abstract void Update(GameTime gameTime); - - /*####################################################################*/ - /* Keyboard Events */ - /*####################################################################*/ - - public abstract event EventHandler CharacterTyped; - - public abstract event EventHandler KeyDown; - public abstract event EventHandler KeyUp; - - /*####################################################################*/ - /* Mouse Events */ - /*####################################################################*/ - - public abstract event EventHandler MouseMoved; - public abstract event EventHandler MouseDoubleClick; - - public abstract event EventHandler MouseDown; - public abstract event EventHandler MouseUp; - - public abstract event EventHandler MouseWheel; - - /*####################################################################*/ - /* Touch Events */ - /*####################################################################*/ - - public abstract event EventHandler TouchBegan; - public abstract event EventHandler TouchMoved; - public abstract event EventHandler TouchEnded; - public abstract event EventHandler TouchCancelled; - } -} diff --git a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/EventArgs/MonoGameMouseEventArgs.cs b/Source/MonoGame.Extended/InputEvents/MonoGame.Input/EventArgs/MonoGameMouseEventArgs.cs deleted file mode 100644 index 1927d528..00000000 --- a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/EventArgs/MonoGameMouseEventArgs.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - internal class MonoGameMouseEventArgs : MouseEventArgs - { - internal TimeSpan Time { get; set; } - - internal MouseState Previous { get; private set; } - internal MouseState Current { get; private set; } - - internal MonoGameMouseEventArgs(int x, int y, TimeSpan time, MouseState previous, MouseState current, - MouseButton button = MouseButton.None, int? value = null, int? delta = null) - : base(x, y, button, value, delta) - { - X = x; - Y = y; - Time = time; - Previous = previous; - Current = current; - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Keyboard/MonoGameMouseEvents.cs b/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Keyboard/MonoGameMouseEvents.cs deleted file mode 100644 index e59f0b77..00000000 --- a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Keyboard/MonoGameMouseEvents.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Linq; - -namespace Microsoft.Xna.Framework.Input -{ - internal class MonoGameKeyboardEvents - { - internal event EventHandler CharacterTyped; - internal event EventHandler KeyPressed; - internal event EventHandler KeyReleased; - - - private static int InitialDelay { get; set; } - private static int RepeatDelay { get; set; } - - private Keys _lastKey; - private TimeSpan _lastPress; - private bool _isInitial; - - private KeyboardState _previous; - - public MonoGameKeyboardEvents() - { - InitialDelay = 800; - RepeatDelay = 50; - } - - public void Update(GameTime gameTime) - { - var current = Keyboard.GetState(); - - if (!current.IsKeyDown(Keys.LeftAlt) - && !current.IsKeyDown(Keys.RightAlt)) - { - foreach (var key in Enum.GetValues(typeof (Keys)) - .Cast() - .Where(key => current.IsKeyDown(key) && _previous.IsKeyUp(key))) - { - var args = new KeyboardKeyEventArgs(key); - - OnKeyPressed(this, args); - - _lastKey = key; - _lastPress = gameTime.TotalGameTime; - _isInitial = true; - } - } - - foreach (var key in - Enum.GetValues(typeof(Keys)) - .Cast() - .Where(key => current.IsKeyUp(key) && _previous.IsKeyDown(key))) - { - OnKeyReleased(this, new KeyboardKeyEventArgs(key)); - } - - var elapsedTime = (gameTime.TotalGameTime - _lastPress).TotalMilliseconds; - - if (current.IsKeyDown(_lastKey) && - ((_isInitial && elapsedTime > InitialDelay) || - (!_isInitial && elapsedTime > RepeatDelay))) - { - OnCharacterPressed(this, new KeyboardKeyEventArgs(_lastKey)); - - _lastPress = gameTime.TotalGameTime; - _isInitial = false; - } - - _previous = current; - } - - private void OnKeyPressed(object sender, KeyboardKeyEventArgs args) - { - if (KeyPressed != null) - { - KeyPressed(sender, args); - } - - OnCharacterPressed(sender, args); - } - - private void OnCharacterPressed(object sender, KeyboardKeyEventArgs args) - { - if (CharacterTyped == null) { return; } - - var character = KeyboardUtil.ToChar(args.Key, args.Modifiers); - if (character.HasValue) - { - CharacterTyped(this, new KeyboardCharacterEventArgs(character.Value)); - } - } - - private void OnKeyReleased(object sender, KeyboardKeyEventArgs args) - { - if (KeyReleased != null) - { - KeyReleased(sender, args); - } - } - } -} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Mouse/MonoGameMouseEvents.cs b/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Mouse/MonoGameMouseEvents.cs deleted file mode 100644 index 48a6d6c3..00000000 --- a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Mouse/MonoGameMouseEvents.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - internal class MonoGameMouseEvents - { - internal event EventHandler ButtonReleased; - internal event EventHandler ButtonPressed; - internal event EventHandler ButtonDoubleClicked; - internal event EventHandler MouseMoved; - internal event EventHandler MouseWheelMoved; - - private MouseState _previous; - private MonoGameMouseEventArgs _lastClick; - - private readonly int _doubleClickMaxTimeDelta; - private readonly int _doubleClickMaxMovementDelta; - - internal MonoGameMouseEvents(int doubleClickMaxTimeDelta, int doubleClickMaxMovementDelta) - { - _doubleClickMaxTimeDelta = doubleClickMaxTimeDelta; - _doubleClickMaxMovementDelta = doubleClickMaxMovementDelta; - - _lastClick = new MonoGameMouseEventArgs( - -1, - -1, - new TimeSpan(), - Mouse.GetState(), - Mouse.GetState()); - } - - internal void Update(GameTime gameTime) - { - var current = Mouse.GetState(); - - // Check button press events. - if (current.LeftButton == ButtonState.Pressed - && _previous.LeftButton == ButtonState.Released) - { - OnButtonPressed(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Left)); - } - - if (current.MiddleButton == ButtonState.Pressed - && _previous.MiddleButton == ButtonState.Released) - { - OnButtonPressed(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Middle)); - } - - if (current.RightButton == ButtonState.Pressed - && _previous.RightButton == ButtonState.Released) - { - OnButtonPressed(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Right)); - } - - if (current.XButton1 == ButtonState.Pressed - && _previous.XButton1 == ButtonState.Released) - { - OnButtonPressed(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.XButton1)); - } - - if (current.XButton2 == ButtonState.Pressed - && _previous.XButton2 == ButtonState.Released) - { - OnButtonPressed(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.XButton2)); - } - - // Check button releases. - if (current.LeftButton == ButtonState.Released - && _previous.LeftButton == ButtonState.Pressed) - { - OnButtonReleased(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Left)); - } - - if (current.MiddleButton == ButtonState.Released - && _previous.MiddleButton == ButtonState.Pressed) - { - OnButtonReleased(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Middle)); - } - - if (current.RightButton == ButtonState.Released - && _previous.RightButton == ButtonState.Pressed) - { - OnButtonReleased(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.Right)); - } - - if (current.XButton1 == ButtonState.Released - && _previous.XButton1 == ButtonState.Pressed) - { - OnButtonReleased(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.XButton1)); - } - - if (current.XButton2 == ButtonState.Released - && _previous.XButton2 == ButtonState.Pressed) - { - OnButtonReleased(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.XButton2)); - } - - // Check for any sort of mouse movement. If a button is down, it's a drag, - // otherwise it's a move. - if (_previous.X != current.X || _previous.Y != current.Y) - { - OnMouseMoved(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current)); - } - - // Handle mouse wheel events. - if (_previous.ScrollWheelValue != current.ScrollWheelValue) - { - var value = current.ScrollWheelValue / 120; - var delta = (current.ScrollWheelValue - _previous.ScrollWheelValue) / 120; - OnMouseWheelMoved(this, new MonoGameMouseEventArgs( - current.X, - current.Y, - gameTime.TotalGameTime, - _previous, - current, - MouseButton.None, - value, - delta)); - } - - _previous = current; - } - - private void OnButtonReleased(object sender, MonoGameMouseEventArgs args) - { - if (ButtonReleased != null) - { - ButtonReleased(sender, args); - } - } - - private void OnButtonPressed(object sender, MonoGameMouseEventArgs args) - { - // If this click is within the right time and position of the last click, - // raise a double-click event as well. - if (ButtonDoubleClicked != null && - _lastClick.Button == args.Button && - (args.Time - _lastClick.Time).TotalMilliseconds < _doubleClickMaxTimeDelta && - DistanceBetween(args.Current, _lastClick.Current) < _doubleClickMaxMovementDelta) - { - ButtonDoubleClicked(sender, args); - //args.Time = new TimeSpan(0); - } - else if (ButtonPressed != null) - { - ButtonPressed(sender, args); - } - - _lastClick = args; - } - - private static int DistanceBetween(MouseState a, MouseState b) - { - return Math.Abs(a.X - b.X) + Math.Abs(a.Y - b.Y); - } - - private void OnMouseMoved(object sender, MouseEventArgs args) - { - if (MouseMoved != null) - { - MouseMoved(sender, args); - } - } - - private void OnMouseWheelMoved(object sender, MouseEventArgs args) - { - if (MouseWheelMoved != null) - { - MouseWheelMoved(sender, args); - } - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Touch/MonoGameTouchEvents.cs b/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Touch/MonoGameTouchEvents.cs deleted file mode 100644 index 5265f7fb..00000000 --- a/Source/MonoGame.Extended/InputEvents/MonoGame.Input/Touch/MonoGameTouchEvents.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using Microsoft.Xna.Framework.Input.Touch; - -namespace Microsoft.Xna.Framework.Input -{ - public class MonoGameTouchEvents - { - internal event EventHandler TouchBegan; - internal event EventHandler TouchMoved; - internal event EventHandler TouchEnded; - internal event EventHandler TouchCancelled; - - - public void Update(GameTime gameTime) - { - TouchCollection touchCollection = TouchPanel.GetState(); - foreach (TouchLocation tl in touchCollection) - { - switch (tl.State) - { - case TouchLocationState.Pressed: - OnTouchBegan(this, new TouchEventArgs(tl)); - break; - case TouchLocationState.Moved: - OnTouchMoved(this, new TouchEventArgs(tl)); - break; - case TouchLocationState.Released: - OnTouchEnded(this, new TouchEventArgs(tl)); - break; - case TouchLocationState.Invalid: - OnTouchCancelled(this, new TouchEventArgs(tl)); - break; - } - } - } - - private void OnTouchBegan(object sender, TouchEventArgs args) - { - if (TouchBegan != null) - { - TouchBegan(sender, args); - } - } - - private void OnTouchMoved(object sender, TouchEventArgs args) - { - if (TouchMoved != null) - { - TouchMoved(sender, args); - } - } - - private void OnTouchEnded(object sender, TouchEventArgs args) - { - if (TouchEnded != null) - { - TouchEnded(sender, args); - } - } - - private void OnTouchCancelled(object sender, TouchEventArgs args) - { - if (TouchCancelled != null) - { - TouchCancelled(sender, args); - } - } - } -} - diff --git a/Source/MonoGame.Extended/InputEvents/MonoGameInput.cs b/Source/MonoGame.Extended/InputEvents/MonoGameInput.cs deleted file mode 100644 index a94d59fb..00000000 --- a/Source/MonoGame.Extended/InputEvents/MonoGameInput.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Input; - -namespace MonoGame.Extended.InputEvents -{ - public sealed class MonoGameInput : Input - { - private readonly MonoGameMouseEvents _mouseEvents; - private readonly MonoGameKeyboardEvents _monoGameKeyboardEvents; - private readonly MonoGameTouchEvents _monoGameTouchEvents; - - public MonoGameInput(Game game, int? doubleClickMaxTimeDelta = null, - int? doubleClickMaxMovementDelta = null) : base(game) - { - if (doubleClickMaxTimeDelta == null) - { - doubleClickMaxTimeDelta = 500; //Windows default - } - - if (doubleClickMaxMovementDelta == null) - { - doubleClickMaxMovementDelta = 2; //Windows default - } - - _mouseEvents = new MonoGameMouseEvents( - doubleClickMaxTimeDelta.Value, - doubleClickMaxTimeDelta.Value); - - _monoGameKeyboardEvents = new MonoGameKeyboardEvents(); - - _monoGameTouchEvents = new MonoGameTouchEvents(); - } - - override public void Update(GameTime gameTime) - { - _mouseEvents.Update(gameTime); - _monoGameKeyboardEvents.Update(gameTime); - _monoGameTouchEvents.Update(gameTime); - } - - - /*####################################################################*/ - /* Keyboard Events */ - /*####################################################################*/ - - public override event EventHandler CharacterTyped - { - add { _monoGameKeyboardEvents.CharacterTyped += value; } - remove { _monoGameKeyboardEvents.CharacterTyped -= value; } - } - - public override event EventHandler KeyDown - { - add { _monoGameKeyboardEvents.KeyPressed += value; } - remove { _monoGameKeyboardEvents.KeyPressed -= value; } - } - - public override event EventHandler KeyUp - { - add { _monoGameKeyboardEvents.KeyReleased += value; } - remove { _monoGameKeyboardEvents.KeyReleased -= value; } - } - - - /*####################################################################*/ - /* Mouse Events */ - /*####################################################################*/ - - //Movement - public override event EventHandler MouseMoved - { - add { _mouseEvents.MouseMoved += value; } - remove { _mouseEvents.MouseMoved -= value; } - } - - //Buttons - public override event EventHandler MouseDoubleClick - { - add { _mouseEvents.ButtonDoubleClicked += value; } - remove { _mouseEvents.ButtonDoubleClicked -= value; } - } - - public override event EventHandler MouseDown - { - add { _mouseEvents.ButtonPressed += value; } - remove { _mouseEvents.ButtonPressed -= value; } - } - - public override event EventHandler MouseUp - { - add { _mouseEvents.ButtonReleased += value; } - remove { _mouseEvents.ButtonReleased -= value; } - } - - //Wheel - public override event EventHandler MouseWheel - { - add { _mouseEvents.MouseWheelMoved += value; } - remove { _mouseEvents.MouseWheelMoved -= value; } - } - - /*####################################################################*/ - /* Touch Events */ - /*####################################################################*/ - - public override event EventHandler TouchBegan - { - add { _monoGameTouchEvents.TouchBegan += value; } - remove { _monoGameTouchEvents.TouchBegan -= value; } - } - - public override event EventHandler TouchMoved - { - add { _monoGameTouchEvents.TouchMoved += value; } - remove { _monoGameTouchEvents.TouchMoved -= value; } - } - - public override event EventHandler TouchEnded - { - add { _monoGameTouchEvents.TouchEnded += value; } - remove { _monoGameTouchEvents.TouchEnded -= value; } - } - - public override event EventHandler TouchCancelled - { - add { _monoGameTouchEvents.TouchCancelled += value; } - remove { _monoGameTouchEvents.TouchCancelled -= value; } - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/README.md b/Source/MonoGame.Extended/InputEvents/README.md deleted file mode 100644 index f15834d1..00000000 --- a/Source/MonoGame.Extended/InputEvents/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# MonoGame-EventDriven-Input - -This project provides event driven input for desktop MonoGame projects. The input has been designed to mimic the behavior of the Windows Message Queue as closely as possible creating as familiar as possible behavior. - -## Getting Started - -Using the library is very simple. Simple create an instance of the MonoGameInput object, call Update in the Game.Update function, and then subscribe to the events. You can even create multiple MonoGameInput instances as an easy way or organize different input schemes (for example one for your menu and one for gameplay input). To disable a MonoGameInput instance simply stop updating it. - -```C# -Input _eventDrivenInput; -_eventDrivenInput = new MonoGameInput(this); - -_eventDrivenInput.Update(gameTime); - -_eventDrivenInput.KeyDown += (sender, keyDown) => -{ - //Subscribe to the events -}; -``` - -Below are the currently available events. - -```C# -public abstract event EventHandler CharacterTyped; -public abstract event EventHandler KeyDown; -public abstract event EventHandler KeyUp; - -public abstract event EventHandler MouseMoved; -public abstract event EventHandler MouseDoubleClick; -public abstract event EventHandler MouseDown; -public abstract event EventHandler MouseUp; -public abstract event EventHandler MouseWheel; - -public abstract event EventHandler TouchBegan; -public abstract event EventHandler TouchMoved; -public abstract event EventHandler TouchEnded; -public abstract event EventHandler TouchCancelled; -``` - -## Roadmap - - - Move the project into [MonoGame.Extended](https://github.com/craftworkgames/MonoGame.Extended). - - Add support for subscribing event classes to provide an abstraction over the event subscription. - - Test against FNA and XNA - diff --git a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardCharacterEventArgs.cs b/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardCharacterEventArgs.cs deleted file mode 100644 index 65e131e6..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardCharacterEventArgs.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - public class KeyboardCharacterEventArgs : EventArgs - { - public char Character { get; private set; } - - internal KeyboardCharacterEventArgs(char character) - { - Character = character; - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardKeyEventArgs.cs b/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardKeyEventArgs.cs deleted file mode 100644 index 89dfc559..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/KeyboardKeyEventArgs.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - public class KeyboardKeyEventArgs : EventArgs - { - public Keys Key { get; private set; } - public Modifiers Modifiers { get; private set; } - - protected internal KeyboardKeyEventArgs(Keys key) - { - Key = key; - - var current = Keyboard.GetState(); - Modifiers = Modifiers.None; - if (current.IsKeyDown(Keys.LeftControl) || current.IsKeyDown(Keys.RightControl)) - { - Modifiers |= Modifiers.Control; - } - if (current.IsKeyDown(Keys.LeftShift) || current.IsKeyDown(Keys.RightShift)) - { - Modifiers |= Modifiers.Shift; - } - if (current.IsKeyDown(Keys.LeftAlt) || current.IsKeyDown(Keys.RightAlt)) - { - Modifiers |= Modifiers.Alt; - } - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/MouseEventArgs.cs b/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/MouseEventArgs.cs deleted file mode 100644 index d0cb17b3..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/MouseEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - public abstract class MouseEventArgs : EventArgs - { - public int X { get; set; } - public int Y { get; set; } - - public MouseButton Button { get; protected set; } - - public int? Value { get; protected set; } - public int? Delta { get; protected set; } - - protected internal MouseEventArgs(int x, int y, MouseButton button, int? value, int? delta) - { - X = x; - Y = y; - Button = button; - Value = value; - Delta = delta; - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/TouchEventArgs.cs b/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/TouchEventArgs.cs deleted file mode 100644 index e40ce796..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/EventArgs/TouchEventArgs.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using Microsoft.Xna.Framework.Input.Touch; - -namespace Microsoft.Xna.Framework.Input -{ - public class TouchEventArgs : EventArgs - { - public TouchLocation TouchLocation { get; private set; } - - internal TouchEventArgs (TouchLocation touchLocation) - { - TouchLocation = touchLocation; - } - - public override bool Equals(System.Object obj) - { - if (obj == null) { return false; } - - // If parameter cannot be cast to Point return false. - TouchEventArgs t = obj as TouchEventArgs; - if ((System.Object)t == null) - { - return false; - } - - return TouchLocation.GetHashCode () == t.GetHashCode(); - } - - public override int GetHashCode() - { - return TouchLocation.Id; - } - } -} - diff --git a/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/KeyboardUtil.cs b/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/KeyboardUtil.cs deleted file mode 100644 index 611f0024..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/KeyboardUtil.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace Microsoft.Xna.Framework.Input -{ - internal static class KeyboardUtil - { - internal static char? ToChar(Keys key, Modifiers modifiers = Modifiers.None) - { - if (key == Keys.A) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'A' : 'a'; } - if (key == Keys.B) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'B' : 'b'; } - if (key == Keys.C) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'C' : 'c'; } - if (key == Keys.D) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'D' : 'd'; } - if (key == Keys.E) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'E' : 'e'; } - if (key == Keys.F) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'F' : 'f'; } - if (key == Keys.G) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'G' : 'g'; } - if (key == Keys.H) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'H' : 'h'; } - if (key == Keys.I) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'I' : 'i'; } - if (key == Keys.J) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'J' : 'j'; } - if (key == Keys.K) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'K' : 'k'; } - if (key == Keys.L) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'L' : 'l'; } - if (key == Keys.M) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'M' : 'm'; } - if (key == Keys.N) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'N' : 'n'; } - if (key == Keys.O) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'O' : 'o'; } - if (key == Keys.P) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'P' : 'p'; } - if (key == Keys.Q) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'Q' : 'q'; } - if (key == Keys.R) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'R' : 'r'; } - if (key == Keys.S) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'S' : 's'; } - if (key == Keys.T) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'T' : 't'; } - if (key == Keys.U) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'U' : 'u'; } - if (key == Keys.V) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'V' : 'v'; } - if (key == Keys.W) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'W' : 'w'; } - if (key == Keys.X) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'X' : 'x'; } - if (key == Keys.Y) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'Y' : 'y'; } - if (key == Keys.Z) { return ((modifiers & Modifiers.Shift) == Modifiers.Shift) ? 'Z' : 'z'; } - - if ((key == Keys.D0 && !ShiftDown(modifiers)) || key == Keys.NumPad0) { return '0'; } - if ((key == Keys.D1 && !ShiftDown(modifiers)) || key == Keys.NumPad1) { return '1'; } - if ((key == Keys.D2 && !ShiftDown(modifiers)) || key == Keys.NumPad2) { return '2'; } - if ((key == Keys.D3 && !ShiftDown(modifiers)) || key == Keys.NumPad3) { return '3'; } - if ((key == Keys.D4 && !ShiftDown(modifiers)) || key == Keys.NumPad4) { return '4'; } - if ((key == Keys.D5 && !ShiftDown(modifiers)) || key == Keys.NumPad5) { return '5'; } - if ((key == Keys.D6 && !ShiftDown(modifiers)) || key == Keys.NumPad6) { return '6'; } - if ((key == Keys.D7 && !ShiftDown(modifiers)) || key == Keys.NumPad7) { return '7'; } - if ((key == Keys.D8 && !ShiftDown(modifiers)) || key == Keys.NumPad8) { return '8'; } - if ((key == Keys.D9 && !ShiftDown(modifiers)) || key == Keys.NumPad9) { return '9'; } - - if (key == Keys.D0 && ShiftDown(modifiers)) { return ')'; } - if (key == Keys.D1 && ShiftDown(modifiers)) { return '!'; } - if (key == Keys.D2 && ShiftDown(modifiers)) { return '@'; } - if (key == Keys.D3 && ShiftDown(modifiers)) { return '#'; } - if (key == Keys.D4 && ShiftDown(modifiers)) { return '$'; } - if (key == Keys.D5 && ShiftDown(modifiers)) { return '%'; } - if (key == Keys.D6 && ShiftDown(modifiers)) { return '^'; } - if (key == Keys.D7 && ShiftDown(modifiers)) { return '&'; } - if (key == Keys.D8 && ShiftDown(modifiers)) { return '*'; } - if (key == Keys.D9 && ShiftDown(modifiers)) { return '('; } - - if (key == Keys.Space) { return ' '; } - if (key == Keys.Tab) { return '\t'; } - if (key == Keys.Enter) { return (char)13; } - if (key == Keys.Back) { return (char)8; } - - if (key == Keys.Add) { return '+'; } - if (key == Keys.Decimal) { return '.'; } - if (key == Keys.Divide) { return '/'; } - if (key == Keys.Multiply) { return '*'; } - if (key == Keys.OemBackslash) { return '\\'; } - if (key == Keys.OemComma && !ShiftDown(modifiers)) { return ','; } - if (key == Keys.OemComma && ShiftDown(modifiers)) { return '<'; } - if (key == Keys.OemOpenBrackets && !ShiftDown(modifiers)) { return '['; } - if (key == Keys.OemOpenBrackets && ShiftDown(modifiers)) { return '{'; } - if (key == Keys.OemCloseBrackets && !ShiftDown(modifiers)) { return ']'; } - if (key == Keys.OemCloseBrackets && ShiftDown(modifiers)) { return '}'; } - if (key == Keys.OemPeriod && !ShiftDown(modifiers)) { return '.'; } - if (key == Keys.OemPeriod && ShiftDown(modifiers)) { return '>'; } - if (key == Keys.OemPipe && !ShiftDown(modifiers)) { return '\\'; } - if (key == Keys.OemPipe && ShiftDown(modifiers)) { return '|'; } - if (key == Keys.OemPlus && !ShiftDown(modifiers)) { return '='; } - if (key == Keys.OemPlus && ShiftDown(modifiers)) { return '+'; } - if (key == Keys.OemMinus && !ShiftDown(modifiers)) { return '-'; } - if (key == Keys.OemMinus && ShiftDown(modifiers)) { return '_'; } - if (key == Keys.OemQuestion && !ShiftDown(modifiers)) { return '/'; } - if (key == Keys.OemQuestion && ShiftDown(modifiers)) { return '?'; } - if (key == Keys.OemQuotes && !ShiftDown(modifiers)) { return '\''; } - if (key == Keys.OemQuotes && ShiftDown(modifiers)) { return '"'; } - if (key == Keys.OemSemicolon && !ShiftDown(modifiers)) { return ';'; } - if (key == Keys.OemSemicolon && ShiftDown(modifiers)) { return ':'; } - if (key == Keys.OemTilde && !ShiftDown(modifiers)) { return '`'; } - if (key == Keys.OemTilde && ShiftDown(modifiers)) { return '~'; } - if (key == Keys.Subtract) { return '-'; } - - return null; - } - - private static bool ShiftDown(Modifiers modifiers) - { - return ((modifiers & Modifiers.Shift) == Modifiers.Shift); - } - } -} diff --git a/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/Modifiers.cs b/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/Modifiers.cs deleted file mode 100644 index 44d389cb..00000000 --- a/Source/MonoGame.Extended/InputEvents/Shared/Keyboard/Modifiers.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Microsoft.Xna.Framework.Input -{ - [Flags] - public enum Modifiers - { - Control = 1, - Shift = 2, - Alt = 4, - None = 0 - }; -} diff --git a/Source/MonoGame.Extended/InputListeners/EventListener.cs b/Source/MonoGame.Extended/InputListeners/EventListener.cs new file mode 100644 index 00000000..9c7288c2 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/EventListener.cs @@ -0,0 +1,19 @@ +using System; +using Microsoft.Xna.Framework; + +namespace MonoGame.Extended.InputListeners +{ + public abstract class EventListener + { + protected void RaiseEvent(EventHandler eventHandler, T args) + where T : EventArgs + { + var handler = eventHandler; + + if (handler != null) + handler(this, args); + } + + public abstract void Update(GameTime gameTime); + } +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputListeners/EventListenerManager.cs b/Source/MonoGame.Extended/InputListeners/EventListenerManager.cs new file mode 100644 index 00000000..00772891 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/EventListenerManager.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; + +namespace MonoGame.Extended.InputListeners +{ + public sealed class EventListenerManager + { + private readonly List _listeners; + + public List Listeners + { + get { return _listeners; } + } + + public EventListenerManager() + { + _listeners = new List(); + } + + public void Update(GameTime gameTime) + { + foreach (var eventListener in _listeners) + eventListener.Update(gameTime); + } + } +} diff --git a/Source/MonoGame.Extended/InputListeners/KeyboardEventArgs.cs b/Source/MonoGame.Extended/InputListeners/KeyboardEventArgs.cs new file mode 100644 index 00000000..3ba3ef96 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/KeyboardEventArgs.cs @@ -0,0 +1,122 @@ +using System; +using Microsoft.Xna.Framework.Input; + +namespace MonoGame.Extended.InputListeners +{ + public class KeyboardEventArgs : EventArgs + { + public KeyboardEventArgs(Keys key, KeyboardState keyboardState) + { + Key = key; + + Modifiers = KeyboardModifiers.None; + + if (keyboardState.IsKeyDown(Keys.LeftControl) || keyboardState.IsKeyDown(Keys.RightControl)) + Modifiers |= KeyboardModifiers.Control; + + if (keyboardState.IsKeyDown(Keys.LeftShift) || keyboardState.IsKeyDown(Keys.RightShift)) + Modifiers |= KeyboardModifiers.Shift; + + if (keyboardState.IsKeyDown(Keys.LeftAlt) || keyboardState.IsKeyDown(Keys.RightAlt)) + Modifiers |= KeyboardModifiers.Alt; + } + + public Keys Key { get; private set; } + public KeyboardModifiers Modifiers { get; private set; } + + public char? Character + { + get { return ToChar(Key, Modifiers); } + } + + internal static char? ToChar(Keys key, KeyboardModifiers modifiers = KeyboardModifiers.None) + { + var isShiftDown = ((modifiers & KeyboardModifiers.Shift) == KeyboardModifiers.Shift); + + if (key == Keys.A) { return isShiftDown ? 'A' : 'a'; } + if (key == Keys.B) { return isShiftDown ? 'B' : 'b'; } + if (key == Keys.C) { return isShiftDown ? 'C' : 'c'; } + if (key == Keys.D) { return isShiftDown ? 'D' : 'd'; } + if (key == Keys.E) { return isShiftDown ? 'E' : 'e'; } + if (key == Keys.F) { return isShiftDown ? 'F' : 'f'; } + if (key == Keys.G) { return isShiftDown ? 'G' : 'g'; } + if (key == Keys.H) { return isShiftDown ? 'H' : 'h'; } + if (key == Keys.I) { return isShiftDown ? 'I' : 'i'; } + if (key == Keys.J) { return isShiftDown ? 'J' : 'j'; } + if (key == Keys.K) { return isShiftDown ? 'K' : 'k'; } + if (key == Keys.L) { return isShiftDown ? 'L' : 'l'; } + if (key == Keys.M) { return isShiftDown ? 'M' : 'm'; } + if (key == Keys.N) { return isShiftDown ? 'N' : 'n'; } + if (key == Keys.O) { return isShiftDown ? 'O' : 'o'; } + if (key == Keys.P) { return isShiftDown ? 'P' : 'p'; } + if (key == Keys.Q) { return isShiftDown ? 'Q' : 'q'; } + if (key == Keys.R) { return isShiftDown ? 'R' : 'r'; } + if (key == Keys.S) { return isShiftDown ? 'S' : 's'; } + if (key == Keys.T) { return isShiftDown ? 'T' : 't'; } + if (key == Keys.U) { return isShiftDown ? 'U' : 'u'; } + if (key == Keys.V) { return isShiftDown ? 'V' : 'v'; } + if (key == Keys.W) { return isShiftDown ? 'W' : 'w'; } + if (key == Keys.X) { return isShiftDown ? 'X' : 'x'; } + if (key == Keys.Y) { return isShiftDown ? 'Y' : 'y'; } + if (key == Keys.Z) { return isShiftDown ? 'Z' : 'z'; } + + if ((key == Keys.D0 && !isShiftDown) || key == Keys.NumPad0) { return '0'; } + if ((key == Keys.D1 && !isShiftDown) || key == Keys.NumPad1) { return '1'; } + if ((key == Keys.D2 && !isShiftDown) || key == Keys.NumPad2) { return '2'; } + if ((key == Keys.D3 && !isShiftDown) || key == Keys.NumPad3) { return '3'; } + if ((key == Keys.D4 && !isShiftDown) || key == Keys.NumPad4) { return '4'; } + if ((key == Keys.D5 && !isShiftDown) || key == Keys.NumPad5) { return '5'; } + if ((key == Keys.D6 && !isShiftDown) || key == Keys.NumPad6) { return '6'; } + if ((key == Keys.D7 && !isShiftDown) || key == Keys.NumPad7) { return '7'; } + if ((key == Keys.D8 && !isShiftDown) || key == Keys.NumPad8) { return '8'; } + if ((key == Keys.D9 && !isShiftDown) || key == Keys.NumPad9) { return '9'; } + + if (key == Keys.D0 && isShiftDown) { return ')'; } + if (key == Keys.D1 && isShiftDown) { return '!'; } + if (key == Keys.D2 && isShiftDown) { return '@'; } + if (key == Keys.D3 && isShiftDown) { return '#'; } + if (key == Keys.D4 && isShiftDown) { return '$'; } + if (key == Keys.D5 && isShiftDown) { return '%'; } + if (key == Keys.D6 && isShiftDown) { return '^'; } + if (key == Keys.D7 && isShiftDown) { return '&'; } + if (key == Keys.D8 && isShiftDown) { return '*'; } + if (key == Keys.D9 && isShiftDown) { return '('; } + + if (key == Keys.Space) { return ' '; } + if (key == Keys.Tab) { return '\t'; } + if (key == Keys.Enter) { return (char)13; } + if (key == Keys.Back) { return (char)8; } + + if (key == Keys.Add) { return '+'; } + if (key == Keys.Decimal) { return '.'; } + if (key == Keys.Divide) { return '/'; } + if (key == Keys.Multiply) { return '*'; } + if (key == Keys.OemBackslash) { return '\\'; } + if (key == Keys.OemComma && !isShiftDown) { return ','; } + if (key == Keys.OemComma && isShiftDown) { return '<'; } + if (key == Keys.OemOpenBrackets && !isShiftDown) { return '['; } + if (key == Keys.OemOpenBrackets && isShiftDown) { return '{'; } + if (key == Keys.OemCloseBrackets && !isShiftDown) { return ']'; } + if (key == Keys.OemCloseBrackets && isShiftDown) { return '}'; } + if (key == Keys.OemPeriod && !isShiftDown) { return '.'; } + if (key == Keys.OemPeriod && isShiftDown) { return '>'; } + if (key == Keys.OemPipe && !isShiftDown) { return '\\'; } + if (key == Keys.OemPipe && isShiftDown) { return '|'; } + if (key == Keys.OemPlus && !isShiftDown) { return '='; } + if (key == Keys.OemPlus && isShiftDown) { return '+'; } + if (key == Keys.OemMinus && !isShiftDown) { return '-'; } + if (key == Keys.OemMinus && isShiftDown) { return '_'; } + if (key == Keys.OemQuestion && !isShiftDown) { return '/'; } + if (key == Keys.OemQuestion && isShiftDown) { return '?'; } + if (key == Keys.OemQuotes && !isShiftDown) { return '\''; } + if (key == Keys.OemQuotes && isShiftDown) { return '"'; } + if (key == Keys.OemSemicolon && !isShiftDown) { return ';'; } + if (key == Keys.OemSemicolon && isShiftDown) { return ':'; } + if (key == Keys.OemTilde && !isShiftDown) { return '`'; } + if (key == Keys.OemTilde && isShiftDown) { return '~'; } + if (key == Keys.Subtract) { return '-'; } + + return null; + } + } +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputListeners/KeyboardEventListener.cs b/Source/MonoGame.Extended/InputListeners/KeyboardEventListener.cs new file mode 100644 index 00000000..aa60cbf1 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/KeyboardEventListener.cs @@ -0,0 +1,89 @@ +using System; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace MonoGame.Extended.InputListeners +{ + public class KeyboardEventListener : EventListener + { + public KeyboardEventListener(int initialDelay = 800, int repeatDelay = 50) + { + InitialDelay = initialDelay; + RepeatDelay = repeatDelay; + } + + private Keys _previousKey; + private TimeSpan _lastPressTime; + private bool _isInitial; + private KeyboardState _previousState; + + public event EventHandler KeyTyped; + public event EventHandler KeyPressed; + public event EventHandler KeyReleased; + + public int InitialDelay { get; private set; } + public int RepeatDelay { get; private set; } + + public override void Update(GameTime gameTime) + { + var currentState = Keyboard.GetState(); + + RaisePressedEvents(gameTime, currentState); + RaiseReleasedEvents(currentState); + RaiseRepeatEvents(gameTime, currentState); + + _previousState = currentState; + } + + private void RaisePressedEvents(GameTime gameTime, KeyboardState currentState) + { + if (!currentState.IsKeyDown(Keys.LeftAlt) && !currentState.IsKeyDown(Keys.RightAlt)) + { + var pressedKeys = Enum.GetValues(typeof (Keys)) + .Cast() + .Where(key => currentState.IsKeyDown(key) && _previousState.IsKeyUp(key)); + + foreach (var key in pressedKeys) + { + var args = new KeyboardEventArgs(key, currentState); + + RaiseEvent(KeyPressed, args); + + if (args.Character.HasValue) + RaiseEvent(KeyTyped, args); + + _previousKey = key; + _lastPressTime = gameTime.TotalGameTime; + _isInitial = true; + } + } + } + + private void RaiseReleasedEvents(KeyboardState currentState) + { + var releasedKeys = Enum.GetValues(typeof (Keys)) + .Cast() + .Where(key => currentState.IsKeyUp(key) && _previousState.IsKeyDown(key)); + + foreach (var key in releasedKeys) + RaiseEvent(KeyReleased, new KeyboardEventArgs(key, currentState)); + } + + private void RaiseRepeatEvents(GameTime gameTime, KeyboardState currentState) + { + var elapsedTime = (gameTime.TotalGameTime - _lastPressTime).TotalMilliseconds; + + if (currentState.IsKeyDown(_previousKey) && ((_isInitial && elapsedTime > InitialDelay) || (!_isInitial && elapsedTime > RepeatDelay))) + { + var args = new KeyboardEventArgs(_previousKey, currentState); + + if (args.Character.HasValue) + RaiseEvent(KeyTyped, args); + + _lastPressTime = gameTime.TotalGameTime; + _isInitial = false; + } + } + } +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputListeners/KeyboardModifiers.cs b/Source/MonoGame.Extended/InputListeners/KeyboardModifiers.cs new file mode 100644 index 00000000..d99af078 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/KeyboardModifiers.cs @@ -0,0 +1,13 @@ +using System; + +namespace MonoGame.Extended.InputListeners +{ + [Flags] + public enum KeyboardModifiers + { + Control = 1, + Shift = 2, + Alt = 4, + None = 0 + }; +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputEvents/Shared/Mouse/MouseButton.cs b/Source/MonoGame.Extended/InputListeners/MouseButton.cs similarity index 75% rename from Source/MonoGame.Extended/InputEvents/Shared/Mouse/MouseButton.cs rename to Source/MonoGame.Extended/InputListeners/MouseButton.cs index 07ecd6d4..99b0672d 100644 --- a/Source/MonoGame.Extended/InputEvents/Shared/Mouse/MouseButton.cs +++ b/Source/MonoGame.Extended/InputListeners/MouseButton.cs @@ -1,4 +1,4 @@ -namespace Microsoft.Xna.Framework.Input +namespace MonoGame.Extended.InputListeners { public enum MouseButton { @@ -9,4 +9,4 @@ XButton1, XButton2 }; -} +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputListeners/MouseEventArgs.cs b/Source/MonoGame.Extended/InputListeners/MouseEventArgs.cs new file mode 100644 index 00000000..a82c46b0 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/MouseEventArgs.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.Xna.Framework.Input; + +namespace MonoGame.Extended.InputListeners +{ + public class MouseEventArgs : EventArgs + { + public MouseEventArgs(int x, int y, TimeSpan time, MouseState previous, MouseState current, + MouseButton button = MouseButton.None, int? value = null, int? delta = null) + { + X = x; + Y = y; + Button = button; + Value = value; + Delta = delta; + Time = time; + Previous = previous; + Current = current; + } + + public TimeSpan Time { get; set; } + public MouseState Previous { get; private set; } + public MouseState Current { get; private set; } + public int X { get; set; } + public int Y { get; set; } + public MouseButton Button { get; protected set; } + public int? Value { get; protected set; } + public int? Delta { get; protected set; } + } +} diff --git a/Source/MonoGame.Extended/InputListeners/MouseEventListener.cs b/Source/MonoGame.Extended/InputListeners/MouseEventListener.cs new file mode 100644 index 00000000..d01707bf --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/MouseEventListener.cs @@ -0,0 +1,144 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace MonoGame.Extended.InputListeners +{ + public class MouseEventListener : EventListener + { + public event EventHandler ButtonReleased; + public event EventHandler ButtonPressed; + public event EventHandler ButtonDoubleClicked; + public event EventHandler MouseMoved; + public event EventHandler MouseWheelMoved; + + private MouseState _previousState; + private MouseEventArgs _lastClick; + + private readonly int _doubleClickMaxTimeDelta; + private readonly int _doubleClickMaxMovementDelta; + + public MouseEventListener(int doubleClickMaxTimeDelta = 500, int doubleClickMaxMovementDelta = 2) // initial values are windows defaults + { + _doubleClickMaxTimeDelta = doubleClickMaxTimeDelta; + _doubleClickMaxMovementDelta = doubleClickMaxMovementDelta; + _lastClick = new MouseEventArgs(-1, -1, TimeSpan.Zero, Mouse.GetState(), Mouse.GetState()); + } + + public override void Update(GameTime gameTime) + { + var currentState = Mouse.GetState(); + + // Check button press events. + if (currentState.LeftButton == ButtonState.Pressed + && _previousState.LeftButton == ButtonState.Released) + { + OnButtonPressed(this, new MouseEventArgs(currentState.X,currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Left)); + } + + if (currentState.MiddleButton == ButtonState.Pressed + && _previousState.MiddleButton == ButtonState.Released) + { + OnButtonPressed(this, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Middle)); + } + + if (currentState.RightButton == ButtonState.Pressed + && _previousState.RightButton == ButtonState.Released) + { + OnButtonPressed(this, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Right)); + } + + if (currentState.XButton1 == ButtonState.Pressed + && _previousState.XButton1 == ButtonState.Released) + { + OnButtonPressed(this, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.XButton1)); + } + + if (currentState.XButton2 == ButtonState.Pressed + && _previousState.XButton2 == ButtonState.Released) + { + OnButtonPressed(this, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.XButton2)); + } + + // Check button releases. + if (currentState.LeftButton == ButtonState.Released && _previousState.LeftButton == ButtonState.Pressed) + { + RaiseEvent(ButtonReleased, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Left)); + } + + if (currentState.MiddleButton == ButtonState.Released && _previousState.MiddleButton == ButtonState.Pressed) + { + RaiseEvent(ButtonReleased, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Middle)); + } + + if (currentState.RightButton == ButtonState.Released && _previousState.RightButton == ButtonState.Pressed) + { + RaiseEvent(ButtonReleased, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.Right)); + } + + if (currentState.XButton1 == ButtonState.Released && _previousState.XButton1 == ButtonState.Pressed) + { + RaiseEvent(ButtonReleased, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.XButton1)); + } + + if (currentState.XButton2 == ButtonState.Released && _previousState.XButton2 == ButtonState.Pressed) + { + RaiseEvent(ButtonReleased, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.XButton2)); + } + + // Check for any sort of mouse movement. If a button is down, it's a drag, + // otherwise it's a move. + if (_previousState.X != currentState.X || _previousState.Y != currentState.Y) + { + RaiseEvent(MouseMoved, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState)); + } + + // Handle mouse wheel events. + if (_previousState.ScrollWheelValue != currentState.ScrollWheelValue) + { + var value = currentState.ScrollWheelValue / 120; + var delta = (currentState.ScrollWheelValue - _previousState.ScrollWheelValue) / 120; + + RaiseEvent(MouseWheelMoved, new MouseEventArgs(currentState.X, currentState.Y, gameTime.TotalGameTime, _previousState, + currentState, MouseButton.None, value, delta)); + } + + _previousState = currentState; + } + + private void OnButtonPressed(object sender, MouseEventArgs args) + { + // If this click is within the right time and position of the last click, + // raise a double-click event as well. + if (ButtonDoubleClicked != null && _lastClick.Button == args.Button && + (args.Time - _lastClick.Time).TotalMilliseconds < _doubleClickMaxTimeDelta && + DistanceBetween(args.Current, _lastClick.Current) < _doubleClickMaxMovementDelta) + { + ButtonDoubleClicked(sender, args); + //args.Time = new TimeSpan(0); + } + else if (ButtonPressed != null) + { + ButtonPressed(sender, args); + } + + _lastClick = args; + } + + private static int DistanceBetween(MouseState a, MouseState b) + { + return Math.Abs(a.X - b.X) + Math.Abs(a.Y - b.Y); + } + } +} diff --git a/Source/MonoGame.Extended/InputListeners/TouchEventArgs.cs b/Source/MonoGame.Extended/InputListeners/TouchEventArgs.cs new file mode 100644 index 00000000..758ef201 --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/TouchEventArgs.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework.Input.Touch; + +namespace MonoGame.Extended.InputListeners +{ + public class TouchEventArgs : System.EventArgs + { + public TouchLocation TouchLocation { get; private set; } + + internal TouchEventArgs(TouchLocation touchLocation) + { + TouchLocation = touchLocation; + } + + public override bool Equals(System.Object obj) + { + if (obj == null) { return false; } + + // If parameter cannot be cast to Point return false. + TouchEventArgs t = obj as TouchEventArgs; + if ((System.Object)t == null) + { + return false; + } + + return TouchLocation.GetHashCode() == t.GetHashCode(); + } + + public override int GetHashCode() + { + return TouchLocation.Id; + } + } +} \ No newline at end of file diff --git a/Source/MonoGame.Extended/InputListeners/TouchEventListener.cs b/Source/MonoGame.Extended/InputListeners/TouchEventListener.cs new file mode 100644 index 00000000..714184ca --- /dev/null +++ b/Source/MonoGame.Extended/InputListeners/TouchEventListener.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input.Touch; + +namespace MonoGame.Extended.InputListeners +{ + public class TouchEventListener : EventListener + { + internal event EventHandler TouchStarted; + internal event EventHandler TouchEnded; + internal event EventHandler TouchMoved; + internal event EventHandler TouchCancelled; + + public override void Update(GameTime gameTime) + { + var touchCollection = TouchPanel.GetState(); + + foreach (var touchLocation in touchCollection) + { + switch (touchLocation.State) + { + case TouchLocationState.Pressed: + RaiseEvent(TouchStarted, new TouchEventArgs(touchLocation)); + break; + case TouchLocationState.Moved: + RaiseEvent(TouchMoved, new TouchEventArgs(touchLocation)); + break; + case TouchLocationState.Released: + RaiseEvent(TouchEnded, new TouchEventArgs(touchLocation)); + break; + case TouchLocationState.Invalid: + RaiseEvent(TouchCancelled, new TouchEventArgs(touchLocation)); + break; + } + } + } + } +} + diff --git a/Source/MonoGame.Extended/MonoGame.Extended.csproj b/Source/MonoGame.Extended/MonoGame.Extended.csproj index c543b8e5..aec82011 100644 --- a/Source/MonoGame.Extended/MonoGame.Extended.csproj +++ b/Source/MonoGame.Extended/MonoGame.Extended.csproj @@ -47,19 +47,16 @@ - - - - - - - - - - - - - + + + + + + + + + + @@ -90,7 +87,6 @@ - diff --git a/Source/Sandbox/SandboxGame.cs b/Source/Sandbox/SandboxGame.cs index 69913101..e6b5a0c5 100644 --- a/Source/Sandbox/SandboxGame.cs +++ b/Source/Sandbox/SandboxGame.cs @@ -5,11 +5,11 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MonoGame.Extended; using MonoGame.Extended.BitmapFonts; +using MonoGame.Extended.InputListeners; using MonoGame.Extended.Maps.Tiled; using MonoGame.Extended.Sprites; using MonoGame.Extended.TextureAtlases; using MonoGame.Extended.ViewportAdapters; -using MonoGame.Extended.InputEvents; namespace Sandbox { @@ -30,7 +30,7 @@ namespace Sandbox private BitmapFont _bitmapFont; private TiledMap _tiledMap; - private Input _eventDrivenInput; + private EventListenerManager _inputManager; private Vector2 _cameraDirection = Vector2.Zero; private float _cameraRotation = 0f; @@ -88,16 +88,15 @@ namespace Sandbox { } - private int _previousScrollWheelValue; private TextureRegion2D _textureRegion; protected override void Update(GameTime gameTime) { - _eventDrivenInput.Update(gameTime); + _inputManager.Update(gameTime); var deltaTime = (float) gameTime.ElapsedGameTime.TotalMilliseconds * .001f; var keyboardState = Keyboard.GetState(); - var mouseState = Mouse.GetState(); + //var mouseState = Mouse.GetState(); //var gamePadState = GamePad.GetState(PlayerIndex.One); if (keyboardState.IsKeyDown(Keys.Escape)) @@ -106,6 +105,8 @@ namespace Sandbox _camera.Move(_cameraDirection * deltaTime); _camera.Rotation += _cameraRotation * deltaTime; + _sprite.Rotation += deltaTime; + base.Update(gameTime); } @@ -141,15 +142,19 @@ namespace Sandbox private void SetUpInput() { - _eventDrivenInput = new MonoGameInput(this); + _inputManager = new EventListenerManager(); var up = new Vector2(0, -250); var right = new Vector2(250, 0); - //camera movment - _eventDrivenInput.KeyDown += (sender, keyDown) => + //camera movement + var keyboardListener = new KeyboardEventListener(); + var mouseListener = new MouseEventListener(); + _inputManager.Listeners.Add(keyboardListener); + + keyboardListener.KeyPressed += (sender, args) => { - switch (keyDown.Key) + switch (args.Key) { case Keys.Escape: Exit(); @@ -176,10 +181,10 @@ namespace Sandbox break; } }; - - _eventDrivenInput.KeyUp += (sender, keyUp) => + + keyboardListener.KeyReleased += (sender, args) => { - switch (keyUp.Key) + switch (args.Key) { case Keys.Q: _cameraRotation -= 1; @@ -204,18 +209,18 @@ namespace Sandbox }; // zoom - _eventDrivenInput.MouseWheel += (sender, mouseEvent) => + mouseListener.MouseWheelMoved += (sender, args) => { - _camera.Zoom += mouseEvent.Delta.Value * 0.0001f; + _camera.Zoom += args.Delta.Value * 0.0001f; }; // look at - _eventDrivenInput.MouseUp += (sender, mouseUp) => + mouseListener.ButtonReleased += (sender, args) => { - if (mouseUp.Button == MouseButton.Left) + if (args.Button == MouseButton.Left) { - var p = _viewportAdapter.PointToScreen(mouseUp.X, mouseUp.Y); - Trace.WriteLine(string.Format("{0},{1} => {2},{3}", mouseUp.X, mouseUp.Y, p.X, p.Y)); + var p = _viewportAdapter.PointToScreen(args.X, args.Y); + Trace.WriteLine(string.Format("{0},{1} => {2},{3}", args.X, args.Y, p.X, p.Y)); } }; }