Skip to content

Commit

Permalink
Some mouse button implementation
Browse files Browse the repository at this point in the history
Needs further testing
  • Loading branch information
luttje committed May 20, 2022
1 parent 17cea9c commit 029fb0c
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 59 deletions.
2 changes: 1 addition & 1 deletion KeyToJoy/BindingForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions KeyToJoy/BindingForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Linearstar.Windows.RawInput.Native;
using System.Drawing;

namespace KeyToJoy
{
Expand Down Expand Up @@ -110,6 +112,23 @@ protected override void WndProc(ref Message m)

SetConfirmBindButtonText(BindingSetting.Binding.ToString());
}
else if (data is RawInputMouseData mouse
&& mouse.Mouse.Buttons != RawMouseButtonFlags.None
&& txtKeyBind.ClientRectangle.Contains(txtKeyBind.PointToClient(MousePosition)))
{
try
{
BindingSetting.Binding = new MouseBinding(mouse.Mouse.Buttons);

txtKeyBind.Text = $"{BindingSetting.Binding}";

SetConfirmBindButtonText(BindingSetting.Binding.ToString());
}
catch (ArgumentOutOfRangeException ex)
{
MessageBox.Show($"Unknown mouse button pressed ({ex.Message}). Can't bind this (yet).", "Unknown mouse button!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

base.WndProc(ref m);
Expand Down
19 changes: 15 additions & 4 deletions KeyToJoy/Input/BindingPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace KeyToJoy.Input
[JsonObject(MemberSerialization.OptIn)]
internal class BindingPreset
{
const int NO_VERSION = 0;

const string SAVE_DIR = "Key2Joy Presets";
public static BindingList<BindingPreset> All { get; } = new BindingList<BindingPreset>();

Expand All @@ -21,6 +23,9 @@ internal class BindingPreset
[JsonProperty]
public string Name { get; set; }

[JsonProperty]
public int Version { get; set; } = NO_VERSION; // Version is set on save

public string Display => $"{Name} ({Path.GetFileName(filePath)})";

private string filePath;
Expand All @@ -35,11 +40,11 @@ internal BindingPreset(string name, List<BindingOption> bindings = null)

if (filePath == null)
{
int version = 1;
int alt = 1;
do
{
filePath = Path.Combine(directory, $"profile-{version}.key2joy.json");
version++;
filePath = Path.Combine(directory, $"profile-{alt}.key2joy.json");
alt++;
} while (File.Exists(filePath));
}

Expand All @@ -66,7 +71,12 @@ internal void AddOption(BindingOption bindingOption)
CacheLookup(bindingOption);
}

private void CacheLookup(BindingOption bindingOption)
internal void PruneCacheKey(string oldBindingKey)
{
lookup.Remove(oldBindingKey);
}

internal void CacheLookup(BindingOption bindingOption)
{
lookup.Add(bindingOption.Binding.GetUniqueBindingKey(), bindingOption);
}
Expand All @@ -91,6 +101,7 @@ internal void Save()
using (var sw = new StreamWriter(filePath))
using (var writer = new JsonTextWriter(sw))
{
this.Version = 2;
serializer.Serialize(writer, this);
}
}
Expand Down
13 changes: 13 additions & 0 deletions KeyToJoy/Input/LowLevel/GlobalMouseHookEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,18 @@ public GlobalMouseHookEventArgs(
MouseData = mouseData;
MouseState = mouseState;
}

public bool AreButtonsDown()
{
switch (MouseState)
{
case MouseState.LeftButtonDown:
case MouseState.RightButtonDown:
case MouseState.MiddleButtonDown:
return true;
}

return false;
}
}
}
21 changes: 12 additions & 9 deletions KeyToJoy/Input/LowLevel/MouseState.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KeyToJoy.Input.LowLevel
namespace KeyToJoy.Input.LowLevel
{
// Source: https://stackoverflow.com/a/34384189
// Extra Info:
// - http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx
// - https://www.autoitscript.com/forum/topic/81761-callback-low-level-mouse-hook/
public enum MouseState
{
Move = 0x0200,

LeftButtonDown = 0x0201,
LeftButtonUp = 0x0202,
RightButtonDown = 0x0204,
RightButtonUp = 0x0205,
Wheel = 0x020A,
WheelH = 0x020E,

MiddleButtonDown = 0x0207,
MiddleButtonUp = 0x0208,
MiddleButtonDoubleClick = 0x0209,

Wheel = 0x020A, // Wheel Up/Down
WheelHorizontal = 0x020E, // Wheel Left/Right
}
}
13 changes: 11 additions & 2 deletions KeyToJoy/Input/MouseAxisBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ namespace KeyToJoy.Input
{
internal class MouseAxisBinding : Binding
{
const string PREFIX = "Mouse ";
const string PREFIX = "Mouse Move ";
private AxisDirection axisBinding;

[JsonConstructor]
internal MouseAxisBinding(string name)
{
this.axisBinding = (AxisDirection)Enum.Parse(typeof(AxisDirection), name.Replace(PREFIX, ""));
try
{
this.axisBinding = (AxisDirection)Enum.Parse(typeof(AxisDirection), name.Replace(PREFIX, ""));
}
catch(ArgumentException ex)
{
// Handle profile file versions before 2
var oldPrefix = "Mouse ";
this.axisBinding = (AxisDirection)Enum.Parse(typeof(AxisDirection), name.Replace(oldPrefix, ""));
}
}

internal MouseAxisBinding(AxisDirection axisBinding)
Expand Down
105 changes: 105 additions & 0 deletions KeyToJoy/Input/MouseBinding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.Windows.Forms;
using KeyToJoy.Input.LowLevel;
using Linearstar.Windows.RawInput.Native;
using Newtonsoft.Json;

namespace KeyToJoy.Input
{
internal class MouseBinding : Binding, IEquatable<MouseBinding>
{
private const string MOUSE_SERIALIZE_PREFIX = "Mouse_";

private MouseButtons mouseButtons;

[JsonConstructor]
internal MouseBinding(string name)
{
name = name.Substring(MOUSE_SERIALIZE_PREFIX.Length);
this.mouseButtons = (MouseButtons)Enum.Parse(typeof(MouseButtons), name);
}

// TODO: Clean up (currently very prone to human error when adding buttons)
// Note: Also add the other constructor: MouseBinding(MouseState mouseState)
internal MouseBinding(RawMouseButtonFlags mouseButton)
{
// TODO: Support up and down states seperately
switch (mouseButton)
{
case RawMouseButtonFlags.LeftButtonUp:
case RawMouseButtonFlags.LeftButtonDown:
this.mouseButtons = MouseButtons.Left;
break;
case RawMouseButtonFlags.RightButtonUp:
case RawMouseButtonFlags.RightButtonDown:
this.mouseButtons = MouseButtons.Right;
break;
case RawMouseButtonFlags.MiddleButtonUp:
case RawMouseButtonFlags.MiddleButtonDown:
this.mouseButtons = MouseButtons.Middle;
break;
// TODO: Support these (requires knowing low level input numbers for MouseState)
//case RawMouseButtonFlags.Button4Up:
//case RawMouseButtonFlags.Button4Down:
// this.mouseButtons = MouseButtons.XButton1;
// break;
//case RawMouseButtonFlags.Button5Up:
//case RawMouseButtonFlags.Button5Down:
// this.mouseButtons = MouseButtons.XButton2;
// break;
default: throw new ArgumentOutOfRangeException(mouseButton.ToString());
}
}

// TODO: Clean up (currently very prone to human error when adding buttons)
// Note: Also add the other constructor: MouseBinding(RawMouseButtonFlags mouseButton)
public MouseBinding(MouseState mouseState)
{
// TODO: Support up and down states seperately
switch (mouseState)
{
case MouseState.LeftButtonUp:
case MouseState.LeftButtonDown:
this.mouseButtons = MouseButtons.Left;
break;
case MouseState.RightButtonUp:
case MouseState.RightButtonDown:
this.mouseButtons = MouseButtons.Right;
break;
case MouseState.MiddleButtonUp:
case MouseState.MiddleButtonDown:
this.mouseButtons = MouseButtons.Middle;
break;
default: throw new ArgumentOutOfRangeException(mouseState.ToString());
}
}

internal override string GetUniqueBindingKey()
{
return MOUSE_SERIALIZE_PREFIX + mouseButtons.ToString();
}

public override bool Equals(object obj)
{
if(!(obj is MouseBinding other))
return false;

return Equals(other);
}

public bool Equals(MouseBinding other)
{
return mouseButtons == other.mouseButtons;
}

public override string ToString()
{
return "(mouse) " + mouseButtons.ToString();
}

public override object Clone()
{
return MemberwiseClone();
}
}
}
1 change: 1 addition & 0 deletions KeyToJoy/KeyToJoy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
<DependentUpon>InitForm.cs</DependentUpon>
</Compile>
<Compile Include="Input\GlobalInputHook.cs" />
<Compile Include="Input\MouseBinding.cs" />
<Compile Include="Input\KeyboardBinding.cs" />
<Compile Include="Input\LowLevel\GlobalKeyboardHookEventArgs.cs" />
<Compile Include="Input\LowLevel\GlobalMouseHookEventArgs.cs" />
Expand Down
Loading

0 comments on commit 029fb0c

Please sign in to comment.