Skip to content

Commit

Permalink
Keyboard and mouse input binding fixes (#8)
Browse files Browse the repository at this point in the history
Keyboard and mouse input binding fixes
  • Loading branch information
viktor-ferenczi authored Sep 27, 2021
1 parent b236bed commit 23b039c
Showing 1 changed file with 111 additions and 80 deletions.
191 changes: 111 additions & 80 deletions EnhancedUI/Gui/ChromiumGuiControl.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CefSharp;
using Sandbox.Graphics;
using Sandbox.Graphics.GUI;
Expand All @@ -15,6 +16,7 @@ public class ChromiumGuiControl : MyGuiControlBase
{
private Chromium? chromium;
public static BatchDataPlayer? Player;
private static MyKeyThrottler keyThrottler = new();

private uint videoId;

Expand All @@ -30,8 +32,8 @@ public class ChromiumGuiControl : MyGuiControlBase
private readonly string name;

private bool capsLock;
private MyKeys lastKey;
private int delay;
private Vector2I lastValidMousePosition = -Vector2I.One;
private List<MyKeys> lastPressedKeys = new();

public ChromiumGuiControl(WebContent content, string name)
{
Expand Down Expand Up @@ -156,139 +158,151 @@ public override MyGuiControlBase HandleInput()
return null!;
}

if (chromium == null)
{
throw new Exception("This should not happen");
}

var ret = base.HandleInput();
if (ret != null)
return ret;

var input = MyInput.Static;

// Do not handle the ESC key, so the player can exit the menu anytime
if (input.IsNewKeyPressed(MyKeys.Escape))
return null!;

// Reload the page with Ctrl-R, also clears cookies with Ctrl-Shift-R
if (input.IsAnyCtrlKeyPressed() && input.IsNewKeyPressed(MyKeys.R))
{
ReloadPage();
if (MyInput.Static.IsAnyShiftKeyPressed())
{
ClearCookies();
}

return base.HandleInput();
return this;
}

if (chromium == null)
{
throw new Exception("This should not happen");
}
var handled = false;

var browser = chromium.Browser;
var browserHost = browser.GetBrowser().GetHost();

if (input.IsKeyPress(MyKeys.CapsLock))
if (input.IsNewKeyPressed(MyKeys.CapsLock))
{
capsLock = !capsLock;
handled = true;
}

var modifiers = GetModifiers();

var pressedKeys = new List<MyKeys>();
input.GetPressedKeys(pressedKeys);

if (pressedKeys.Count == 0)
{
lastKey = MyKeys.None;
}
if (pressedKeys.Count > 0)
handled = true;

foreach (var key in pressedKeys)
{
if (key == MyKeys.Escape)
if (keyThrottler.GetKeyStatus(key) == ThrottledKeyStatus.PRESSED_AND_READY)
{
continue;
}

if (key == lastKey)
{
if (delay > 0)
var windowsKeyCode = ToWindowsKeyCode(key);
browserHost.SendKeyEvent(new KeyEvent
{
delay--;
continue;
}

delay = 5;
WindowsKeyCode = windowsKeyCode,
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyDown,
Modifiers = modifiers
});
}
else
{
lastKey = key;
delay = 20;
}

var keyChar = (char)key;
}

browserHost.SendKeyEvent(new KeyEvent
{
WindowsKeyCode = keyChar, // Space
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyDown,
Modifiers = modifiers
});
foreach (var ch in input.TextInput)
{
if (char.IsControl(ch) && ch != '\r' && ch != '\t')
continue;

browserHost.SendKeyEvent(new KeyEvent
{
WindowsKeyCode = keyChar, // Space
WindowsKeyCode = ch,
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.Char,
Modifiers = modifiers
});
}

browserHost.SendKeyEvent(new KeyEvent
foreach (var lastPressedKey in lastPressedKeys)
{
if (keyThrottler.GetKeyStatus(lastPressedKey) == ThrottledKeyStatus.UNPRESSED)
{
WindowsKeyCode = keyChar, // Space
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyUp,
Modifiers = modifiers
});
browserHost.SendKeyEvent(new KeyEvent
{
WindowsKeyCode = ToWindowsKeyCode(lastPressedKey),
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyUp,
Modifiers = modifiers
});
}
}

var mousePosition = input.GetMousePosition();
var hasValidMousePosition = mousePosition.X >= 0 && mousePosition.Y >= 0;
lastPressedKeys = pressedKeys;

if (!hasValidMousePosition)
if (IsMouseOver)
{
return base.HandleInput();
}
var mousePosition = input.GetMousePosition();

// Correct for left-top corner (position)
var vr = GetVideoScreenRectangle();
mousePosition.X -= vr.Left;
mousePosition.Y -= vr.Top;
// Correct for left-top corner (position)
var vr = GetVideoScreenRectangle();
mousePosition.X -= vr.Left;
mousePosition.Y -= vr.Top;

var intMousePosition = new Vector2I(mousePosition + new Vector2(0.5f, 0.5f));
var intMousePosition = new Vector2I(mousePosition + new Vector2(0.5f, 0.5f));
lastValidMousePosition = intMousePosition;

var wheelDelta = MyInput.Static.DeltaMouseScrollWheelValue();
var wheelDelta = MyInput.Static.DeltaMouseScrollWheelValue();
if (wheelDelta != 0)
{
browser.SendMouseWheelEvent(intMousePosition.X, intMousePosition.Y, 0, wheelDelta, modifiers);
}
else
{
browserHost.SendMouseMoveEvent(intMousePosition.X, intMousePosition.Y, false, modifiers);
}

if (wheelDelta != 0)
{
browser.SendMouseWheelEvent(intMousePosition.X, intMousePosition.Y, 0, wheelDelta, modifiers);
}
else
{
browserHost.SendMouseMoveEvent(intMousePosition.X, intMousePosition.Y, false, modifiers);
}
if (input.IsNewLeftMousePressed())
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Left, false, 1, modifiers);
}

if (input.IsLeftMousePressed())
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Left, false, 1, modifiers);
}
if (input.IsNewMiddleMousePressed())
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Middle, false, 1, modifiers);
}

if (input.IsMiddleMousePressed())
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Middle, false, 1, modifiers);
if (input.IsNewRightMousePressed())
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Right, false, 1, modifiers);
}
}

if (input.IsRightMousePressed())
else
{
browserHost.SendMouseClickEvent(intMousePosition.X, intMousePosition.Y, MouseButtonType.Right, false, 1, modifiers);
if (lastValidMousePosition.X >= 0)
{
browserHost.SendMouseMoveEvent(lastValidMousePosition.X, lastValidMousePosition.Y, true, modifiers);
}
lastValidMousePosition = -Vector2I.One;
}

// TODO: Double-click, drag&drop, context menu
return handled ? this : null!;
}

return base.HandleInput();
private static int ToWindowsKeyCode(MyKeys key)
{
return (int)key;
}

private CefEventFlags GetModifiers()
Expand All @@ -302,5 +316,22 @@ private CefEventFlags GetModifiers()
(input.IsMiddleMousePressed() ? CefEventFlags.MiddleMouseButton : 0) |
(input.IsRightMousePressed() ? CefEventFlags.RightMouseButton : 0);
}
}

public void FocusEnded()
{
OnFocusChanged(false);
}

public override void OnFocusChanged(bool focus)
{
chromium?.Browser.GetBrowser().GetHost().SetFocus(focus);

base.OnFocusChanged(focus);
}

private void DebugDraw()
{
MyGuiManager.DrawBorders(GetPositionAbsoluteTopLeft(), Size, Color.White, 1);
}
}
}

0 comments on commit 23b039c

Please sign in to comment.