mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Nicer key rebinding
This commit is contained in:
parent
ce75b15716
commit
bf722ecdfa
|
@ -1,35 +1,97 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Mgba } from "./mgba";
|
import { Mgba } from "./mgba";
|
||||||
import { BindingsControl, DefaultBindingsSet } from "./bindings";
|
import { BindingsControl, DefaultBindingsSet, Bindings } from "./bindings";
|
||||||
|
import { styled } from "styled-components";
|
||||||
|
import { useOnKeyUp } from "./useOnKeyUp.hook";
|
||||||
|
|
||||||
|
const BindingsDialog = styled.dialog`
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const VolumeLabel = styled.label`
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CloseButton = styled.button`
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [volume, setVolume] = useState(1.0);
|
const [volume, setVolume] = useState(1.0);
|
||||||
const [bindings, setBindings] = useState(DefaultBindingsSet());
|
const [bindings, setBindings] = useState(DefaultBindingsSet());
|
||||||
const [paused, setPaused] = useState(false);
|
const [paused, setPaused] = useState(false);
|
||||||
|
|
||||||
|
const [showBindings, setShowBindings] = useState(false);
|
||||||
|
|
||||||
|
useOnKeyUp("Escape", () => {
|
||||||
|
setShowBindings(!showBindings);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{showBindings && (
|
||||||
|
<BindingsWindow
|
||||||
|
bindings={bindings}
|
||||||
|
setBindings={setBindings}
|
||||||
|
setPaused={setPaused}
|
||||||
|
volume={volume}
|
||||||
|
setVolume={setVolume}
|
||||||
|
hide={() => setShowBindings(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Mgba
|
<Mgba
|
||||||
gameUrl="/game.gba"
|
gameUrl="/game.gba"
|
||||||
volume={volume}
|
volume={volume}
|
||||||
controls={bindings.Actual}
|
controls={bindings.Actual}
|
||||||
paused={paused}
|
paused={paused}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BindingsWindow({
|
||||||
|
bindings,
|
||||||
|
setBindings,
|
||||||
|
setPaused,
|
||||||
|
volume,
|
||||||
|
setVolume,
|
||||||
|
hide,
|
||||||
|
}: {
|
||||||
|
bindings: Bindings;
|
||||||
|
setBindings: (b: Bindings) => void;
|
||||||
|
setPaused: (paused: boolean) => void;
|
||||||
|
volume: number;
|
||||||
|
setVolume: (v: number) => void;
|
||||||
|
hide: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<BindingsDialog open onClose={hide}>
|
||||||
|
<VolumeLabel>
|
||||||
|
Volume:
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
value={volume}
|
value={volume}
|
||||||
min="0"
|
min="0"
|
||||||
max="1"
|
max="1"
|
||||||
step="0.05"
|
step="0.05"
|
||||||
onChange={(e) => setVolume(Number(e.target.value))}
|
onChange={(e) => {
|
||||||
></input>
|
console.log("e.target.value", e.target.value);
|
||||||
|
console.log("volume", volume);
|
||||||
|
setVolume(Number(e.target.value));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</VolumeLabel>
|
||||||
<BindingsControl
|
<BindingsControl
|
||||||
bindings={bindings}
|
bindings={bindings}
|
||||||
setBindings={setBindings}
|
setBindings={setBindings}
|
||||||
setPaused={setPaused}
|
setPaused={setPaused}
|
||||||
/>
|
/>
|
||||||
</div>
|
<CloseButton onClick={hide}>Close</CloseButton>
|
||||||
|
</BindingsDialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ export type KeyBindings = {
|
||||||
[key in GbaKey]: string;
|
[key in GbaKey]: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Bindings {
|
export interface Bindings {
|
||||||
Displayed: KeyBindings;
|
Displayed: KeyBindings;
|
||||||
Actual: KeyBindings;
|
Actual: KeyBindings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import App from "./App";
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById("root") as HTMLElement
|
document.getElementById("root") as HTMLElement
|
||||||
);
|
);
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
|
|
|
@ -114,33 +114,5 @@ export const Mgba: FC<MgbaProps> = ({ gameUrl, volume, controls, paused }) => {
|
||||||
}
|
}
|
||||||
}, [gameLoaded, paused]);
|
}, [gameLoaded, paused]);
|
||||||
|
|
||||||
return (
|
return <MgbaCanvas ref={canvas} />;
|
||||||
<>
|
|
||||||
<MgbaCanvas ref={canvas} />
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
if (state !== MgbaState.Initialised) return;
|
|
||||||
mgbaModule.current.saveState(0);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save State
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
if (state !== MgbaState.Initialised) return;
|
|
||||||
mgbaModule.current.loadState(0);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Load State
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
if (state !== MgbaState.Initialised) return;
|
|
||||||
mgbaModule.current.quickReload();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Restart
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
18
website/src/useOnKeyUp.hook.ts
Normal file
18
website/src/useOnKeyUp.hook.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
export const useOnKeyUp = (targetKey: string, callback: () => void) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const downHandler = (evnt: KeyboardEvent) => {
|
||||||
|
console.log(evnt.key);
|
||||||
|
if (evnt.key === targetKey) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("keyup", downHandler);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("keyup", downHandler);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
};
|
Loading…
Reference in a new issue