You may find that you need granular control over blocking the users mouse or keyboard.
In this guide we’ll walk through implementing interacting with an in-game window via a particular
key or mouse button, for example, the middle mouse click. You’ll want to follow this pattern if:
- You want a window that is not interactive by default
- You want the user to be able to opt-in to interacting with the window
Simple Approach
The easiest way to accomplish this is with the below code snippet.
class ScoreboardWindow {
private browserWindow: RenderWindow | null = null;
private overrides: InputOverrides;
private boundMouseDown = this.onMouseDown.bind(this);
public constructor() {
this.browserWindow = overlay.windows.createWindow({
// ...
});
// Setup our input scope, this makes input blocking multi-window compatibile.
this.overrides = overlay.input.scope("ScoreboardWindow");
}
private onScoreboardWindowShow() {
// Block the game from receiving middle mouse clicks
this.overrides.setKeyInputBlock(0x04, true);
// Make sure the cursor does not appear over the window
this.overrides.setGlobalCursorOverride(false);
// Listen to mouse down events while the window is open
overlay.windows.on("mouseDown", this.boundMouseDown);
}
private onScoreboardWindowHide() {
overlay.windows.off("mouseDown", this.boundMouseDown);
this.resetOverrides();
}
private onMouseDown(event: MouseButtonEvent) {
if (!this.browserWindow?.isVisible()) {
return;
}
// If they click mouse1 and its not on the window
// aka if they click outside the window
// we should hide the window
if (event.key === 0x01 && !event.window) {
this.browserWindow?.hide();
return;
}
// If they didn't click middle mouse button
if (event.key !== 0x04) {
return;
}
// Show the cursor
this.overrides.setGlobalCursorOverride(true);
// Block mouse input to the game
this.overrides.setGlobalMouseBlock(true);
// Allow interacting with the browser window
this.browserWindow?.setCursorOverride(true);
}
// Its important to make sure to reset all blocks when appropraite
private resetOverrides() {
this.overrides.setKeyInputBlock(0x04, false);
this.overrides.setGlobalCursorOverride(false);
this.overrides.setGlobalMouseBlock(false);
this.browserWindow?.setCursorOverride(false);
}
}
Scope
The problem that the scope
method solves is the following:
Imagine you have two windows that have opt-in interactivity. If you use the advanced API mentioned
below to try and handle the blocking yourself:
- The user opens Window A
- The user clicks middle mouse to interact with Window A
- The user opens Window B, with Window A still open
- The user closes Window A
- Window A removes cursor blocking that it previously set
- Problem: Now the user cant properly interact with Window B
scope
solves this by globally registering each scope, and not removing a given block until all
scopes have removed it. This can of course be implemented on your own if you desire different
functionality.
API Overview (Advanced)
Below is the raw API to manage input blocking, though we recommend using our scope
helper in most
cases. Internally, scope
wraps these methods to provide the above behavior.
Global Mouse Block
The following allows you to block the game from receiving mouse input:
setGlobalMouseBlock(block: boolean): void;
getGlobalMouseBlock(): boolean;
Global Cursor Override
Force the cursor to be shown or hidden:
setGlobalCursorOverride(show: boolean): void;
getGlobalCursorOverride(): boolean;
Keyboard Block
Block the game from receiving keyboard input:
setGlobalKeyboardBlock(block: boolean): void;
getGlobalKeyboardBlock(): boolean;
Block the game from receiving input from a specific key:
setKeyInputBlock(key: VirtualKey, block: boolean): void;
getKeyInputBlock(key: VirtualKey): boolean;