goto tick dialog

This commit is contained in:
Robin Appelman 2024-12-02 23:51:41 +01:00
commit 116b52c892
4 changed files with 81 additions and 10 deletions

13
package-lock.json generated
View file

@ -8,6 +8,7 @@
"@demostf/edit": "0.2.0", "@demostf/edit": "0.2.0",
"@demostf/tf-demos-viewer": "^0.1.2", "@demostf/tf-demos-viewer": "^0.1.2",
"@lutaok/solid-modal": "^0.1.1", "@lutaok/solid-modal": "^0.1.1",
"@solid-primitives/autofocus": "^0.0.111",
"@solid-primitives/keyboard": "^1.2.8", "@solid-primitives/keyboard": "^1.2.8",
"@solid-primitives/resize-observer": "^2.0.15", "@solid-primitives/resize-observer": "^2.0.15",
"@thisbeyond/solid-select": "^0.13.0", "@thisbeyond/solid-select": "^0.13.0",
@ -35,6 +36,18 @@
"solid-js": "^1.4.0" "solid-js": "^1.4.0"
} }
}, },
"node_modules/@solid-primitives/autofocus": {
"version": "0.0.111",
"resolved": "https://registry.npmjs.org/@solid-primitives/autofocus/-/autofocus-0.0.111.tgz",
"integrity": "sha512-WQUCcBzUmLdmHeyN0Z1lH75IN1IGIbvOMTcBEmuCY5DXeahRJm3riTGqVj+XOA4G+NHCMt7wPOJoYOAuwUov/Q==",
"license": "MIT",
"dependencies": {
"@solid-primitives/utils": "^6.2.3"
},
"peerDependencies": {
"solid-js": "^1.6.12"
}
},
"node_modules/@solid-primitives/event-listener": { "node_modules/@solid-primitives/event-listener": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.3.3.tgz", "resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.3.3.tgz",

View file

@ -3,6 +3,7 @@
"@demostf/edit": "0.2.0", "@demostf/edit": "0.2.0",
"@demostf/tf-demos-viewer": "^0.1.2", "@demostf/tf-demos-viewer": "^0.1.2",
"@lutaok/solid-modal": "^0.1.1", "@lutaok/solid-modal": "^0.1.1",
"@solid-primitives/autofocus": "^0.0.111",
"@solid-primitives/keyboard": "^1.2.8", "@solid-primitives/keyboard": "^1.2.8",
"@solid-primitives/resize-observer": "^2.0.15", "@solid-primitives/resize-observer": "^2.0.15",
"@thisbeyond/solid-select": "^0.13.0", "@thisbeyond/solid-select": "^0.13.0",

View file

@ -5,6 +5,9 @@ import {Timeline} from './Render/Timeline';
import {SpecHUD} from './Render/SpecHUD'; import {SpecHUD} from './Render/SpecHUD';
import {AnalyseMenu} from './AnalyseMenu' import {AnalyseMenu} from './AnalyseMenu'
import {useKeyDownEvent} from "@solid-primitives/keyboard"; import {useKeyDownEvent} from "@solid-primitives/keyboard";
import {autofocus} from "@solid-primitives/autofocus";
// prevents from being tree-shaken by TS
autofocus
import Modal from "@lutaok/solid-modal"; import Modal from "@lutaok/solid-modal";
import {AsyncParser} from "./Data/AsyncParser"; import {AsyncParser} from "./Data/AsyncParser";
@ -33,15 +36,17 @@ export const Analyser = (props: AnalyseProps) => {
const [sessionName, setSessionName] = createSignal<string>(""); const [sessionName, setSessionName] = createSignal<string>("");
const [clients, setClients] = createSignal<number>(0); const [clients, setClients] = createSignal<number>(0);
const [helpOpen, setHelpOpen] = createSignal<boolean>(false); const [helpOpen, setHelpOpen] = createSignal<boolean>(false);
const [gotoOpen, setGotoOpen] = createSignal<boolean>(false);
const [gotoInput, setGotoInput] = createSignal<number>(0);
const closeDialogs = () => { const closeDialogs = () => {
setHelpOpen(false); setHelpOpen(false);
setGotoOpen(false);
}; };
createEffect(() => { createEffect(() => {
const e = event(); const e = event();
untrack(() => { untrack(() => {
console.log(e);
if (e) { if (e) {
if (e.key === '.') { if (e.key === '.') {
seek(1); seek(1);
@ -63,6 +68,16 @@ export const Analyser = (props: AnalyseProps) => {
togglePlay(); togglePlay();
e.preventDefault(); e.preventDefault();
} }
if (e.key === '?') {
setHelpOpen(true);
setGotoOpen(false);
e.preventDefault();
}
if (!inShared && e.getModifierState("Control") && e.key === 'g') {
setHelpOpen(false);
setGotoOpen(true);
e.preventDefault();
}
if (e.key === 'Escape') { if (e.key === 'Escape') {
closeDialogs(); closeDialogs();
e.preventDefault(); e.preventDefault();
@ -71,6 +86,11 @@ export const Analyser = (props: AnalyseProps) => {
}); });
}); });
const gotoTickSubmitted = () => {
setTickNow(clampTick(gotoInput()));
closeDialogs();
}
let lastFrameTime = 0; let lastFrameTime = 0;
let playStartTick = 0; let playStartTick = 0;
let playStartTime = 0; let playStartTime = 0;
@ -87,7 +107,6 @@ export const Analyser = (props: AnalyseProps) => {
} }
} }
if (update.hasOwnProperty("clients")) { if (update.hasOwnProperty("clients")) {
console.log(update["clients"]);
setClients(update["clients"]); setClients(update["clients"]);
} }
} }
@ -116,10 +135,9 @@ export const Analyser = (props: AnalyseProps) => {
height: backgroundBoundaries.boundary_max.y - backgroundBoundaries.boundary_min.y, height: backgroundBoundaries.boundary_max.y - backgroundBoundaries.boundary_min.y,
}; };
const clampTick = (tick) => Math.max(0, Math.min(lastTick, tick))
const seek = (offset) => { const seek = (offset) => {
console.log(lastTick, tick(), tick() + offset); const target = clampTick(tick() + offset);
const target = Math.max(0, Math.min(lastTick, tick() + offset));
console.log(target);
setTickNow(target); setTickNow(target);
} }
@ -198,8 +216,6 @@ export const Analyser = (props: AnalyseProps) => {
const inShared = session && !session.isOwner(); const inShared = session && !session.isOwner();
const isShared = () => sessionName() !== ''; const isShared = () => sessionName() !== '';
console.log(intervalPerTick);
const timeTitle = () => `${tickToTime(tick(), intervalPerTick)} (tick ${tick()})`; const timeTitle = () => `${tickToTime(tick(), intervalPerTick)} (tick ${tick()})`;
return ( return (
@ -266,13 +282,34 @@ export const Analyser = (props: AnalyseProps) => {
<td><kbd></kbd></td> <td><kbd></kbd></td>
<td>0.5s backwards</td> <td>0.5s backwards</td>
</tr> </tr>
<tr>
<td><kbd>Ctrl</kbd> + <kbd>G</kbd></td>
<td>Goto tick</td>
</tr>
<tr> <tr>
<td><kbd>Spacebar</kbd></td> <td><kbd>Spacebar</kbd></td>
<td>Play/Pause</td> <td>Play/Pause</td>
</tr> </tr>
<tr>
<td><kbd>?</kbd></td>
<td>This help menu</td>
</tr>
<tr>
<td><kbd>Esc</kbd></td>
<td>Close dialogs</td>
</tr>
</tbody> </tbody>
</table> </table>
</Modal> </Modal>
<Modal class="goto" isOpen={gotoOpen()} onCloseRequest={() => setGotoOpen(false)}
closeOnOutsideClick={true} overlayClass="modal-overlay" contentClass="modal-content">
<h4>Goto Tick</h4>
<form use:formSubmit={gotoTickSubmitted} class="goto">
<input
onInput={(e) => setGotoInput(parseInt(e.target.value, 10))}
ref={autofocus} autofocus type="text" inputmode="numeric" min={0} max={lastTick - 1}/>
</form>
</Modal>
</div> </div>
); );
} }
@ -281,3 +318,12 @@ function tickToTime(tick: number, intervalPerTick: number): string {
let seconds = Math.floor(tick * intervalPerTick); let seconds = Math.floor(tick * intervalPerTick);
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`; return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`;
} }
const formSubmit = (ref, accessor) => {
const callback = accessor() || (() => {
});
ref.onsubmit = async (e) => {
e.preventDefault();
callback(ref);
};
};

View file

@ -91,7 +91,7 @@ kbd {
border-radius: 3px; border-radius: 3px;
border: 1px solid rgb(69, 75, 78); border: 1px solid rgb(69, 75, 78);
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 1px, rgba(24, 26, 27, 0.7) 0 2px inset; box-shadow: rgba(0, 0, 0, 0.2) 0 1px 1px, rgba(24, 26, 27, 0.7) 0 2px inset;
color: rgb(200, 195, 188);; color: rgb(200, 195, 188);
display: inline-block; display: inline-block;
font-size: 1.4em; font-size: 1.4em;
font-weight: 700; font-weight: 700;
@ -99,12 +99,11 @@ kbd {
padding: 2px 4px; padding: 2px 4px;
white-space: nowrap; white-space: nowrap;
min-width: 1.5em; min-width: 1.5em;
text-align: center;
} }
.shortcuts { .shortcuts {
td:first-child { td:first-child {
text-align: center; text-align: right;
} }
} }
@ -128,4 +127,16 @@ kbd {
overflow: auto; overflow: auto;
max-height: 90%; max-height: 90%;
max-width: 90%; max-width: 90%;
}
.modal-content input[type="text"] {
min-width: 300px;
background-color: rgb(34, 36, 38);
border-radius: 3px;
border: 1px solid rgb(69, 75, 78);
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 1px, rgba(24, 26, 27, 0.7) 0 2px inset;
outline: none;
color: rgb(200, 195, 188);
font-size: 130%;
padding: 1px 3px;
} }