fix: Fixed issues on windows
feat: Implemented mouse and gamepad automatic switching fix: Made touch screen work better on the steam deck
This commit is contained in:
parent
e4df8fb9fb
commit
b4a89385d0
24 changed files with 334 additions and 137 deletions
|
|
@ -1,7 +1,13 @@
|
|||
import { getCurrentFocusKey, navigateByDirection, SpatialNavigation } from "@noriginmedia/norigin-spatial-navigation";
|
||||
import { dispatchFocusedEvent, GetFocusedElement } from "./spatialNavigation";
|
||||
import { getCurrentFocusKey, navigateByDirection } from "@noriginmedia/norigin-spatial-navigation";
|
||||
import { GetFocusedElement } from "./spatialNavigation";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
let loopStarted = false;
|
||||
let isTouching = false;
|
||||
type ActiveControlType = 'keyboard' | 'gamepad' | 'mouse' | 'touch' | undefined;
|
||||
let activeControls: ActiveControlType = undefined;
|
||||
let mouseUpdateTimeout: any | undefined = undefined;
|
||||
let touchStopTimeout: any | undefined = undefined;
|
||||
|
||||
const handleLoop = () =>
|
||||
{
|
||||
|
|
@ -11,8 +17,70 @@ const handleLoop = () =>
|
|||
loopStarted = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Mouse needs to be delayed so that touch events can cancel it.
|
||||
// This is to prevent both touch and mouse events triggering as they do on the steam deck.
|
||||
const handleMouseMove = (e: MouseEvent) =>
|
||||
{
|
||||
if (!mouseUpdateTimeout && !isTouching)
|
||||
{
|
||||
mouseUpdateTimeout = setTimeout(() =>
|
||||
{
|
||||
focusControl('mouse');
|
||||
mouseUpdateTimeout = undefined;
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
function clearMouseUpdate ()
|
||||
{
|
||||
if (mouseUpdateTimeout)
|
||||
clearTimeout(mouseUpdateTimeout);
|
||||
mouseUpdateTimeout = undefined;
|
||||
};
|
||||
|
||||
const handleKeyDown = () =>
|
||||
{
|
||||
focusControl('keyboard');
|
||||
};
|
||||
|
||||
const handleTouchStart = (e: TouchEvent) =>
|
||||
{
|
||||
isTouching = true;
|
||||
focusControl('touch');
|
||||
clearMouseUpdate();
|
||||
};
|
||||
|
||||
const handleTouchEnd = (e: TouchEvent) =>
|
||||
{
|
||||
setTimeout(() => isTouching = false, 10);
|
||||
};
|
||||
|
||||
window.addEventListener('touchstart', handleTouchStart);
|
||||
window.addEventListener('touchend', handleTouchEnd);
|
||||
window.addEventListener('touchcancel', handleTouchEnd);
|
||||
window.addEventListener("gamepadconnected", handleLoop);
|
||||
import.meta.hot.dispose(() => window.addEventListener('gamepaddisconnected', handleLoop));
|
||||
window.addEventListener('mousemove', handleMouseMove);
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
import.meta.hot.dispose(() => window.removeEventListener('gamepaddisconnected', handleLoop));
|
||||
import.meta.hot.dispose(() => window.removeEventListener('mousemove', handleMouseMove));
|
||||
import.meta.hot.dispose(() => window.removeEventListener('keydown', handleKeyDown));
|
||||
import.meta.hot.dispose(() => window.removeEventListener('touchstart', handleTouchStart));
|
||||
import.meta.hot.dispose(() => window.removeEventListener('touchend', handleTouchEnd));
|
||||
import.meta.hot.dispose(() => window.removeEventListener('touchcancel', handleTouchEnd));
|
||||
|
||||
export default function useActiveControl ()
|
||||
{
|
||||
const [c, setC] = useState<typeof activeControls>(activeControls);
|
||||
useEffect(() =>
|
||||
{
|
||||
const handler = (e: Event) => setC((e as CustomEvent).detail);
|
||||
window.addEventListener('activecontrolschange', handler);
|
||||
return () => window.removeEventListener('activecontrolschange', handler);
|
||||
});
|
||||
|
||||
return { isMouse: c === 'mouse', isPointer: c === 'mouse' || c === 'touch', control: c };
|
||||
}
|
||||
|
||||
const throttleMap = new Map<string, number>();
|
||||
const throttleAcceleration = new Map<string, number>();
|
||||
|
|
@ -32,6 +100,19 @@ function throttleNav (key: string, dir: string, event: Event)
|
|||
}
|
||||
}
|
||||
|
||||
function focusControl (control: typeof activeControls)
|
||||
{
|
||||
if (activeControls != control)
|
||||
{
|
||||
activeControls = control;
|
||||
window.dispatchEvent(new CustomEvent('activecontrolschange', { detail: control }));
|
||||
if (control !== 'mouse')
|
||||
{
|
||||
clearMouseUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*window.addEventListener('keydown', e =>
|
||||
{
|
||||
if (e.key === 'Escape')
|
||||
|
|
@ -74,6 +155,7 @@ function updateStatus ()
|
|||
if (!throttleMap.has(key))
|
||||
{
|
||||
window.dispatchEvent(new GamepadButtonEvent('gamepadbuttondown', { button: i, gamepad: gamepad }));
|
||||
focusControl('gamepad');
|
||||
throttleMap.set(key, 0);
|
||||
}
|
||||
} else
|
||||
|
|
@ -81,6 +163,7 @@ function updateStatus ()
|
|||
if (throttleMap.delete(key))
|
||||
{
|
||||
window.dispatchEvent(new GamepadButtonEvent('gamepadbuttonup', { button: i, gamepad: gamepad }));
|
||||
focusControl('gamepad');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue