Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions src/AnimationControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,12 @@ import SkipPreviousIcon from '@mui/icons-material/SkipPrevious';
import SkipNextIcon from '@mui/icons-material/SkipNext';
import MenuIcon from '@mui/icons-material/Menu';
import { useEffect } from 'react';
import { KeyMap } from './Params';

const STEP_SIZE_INCREMENT = 0.2;
const STEP_SIZE_MAX = 10;
const STEP_SIZE_MIN = 0.2;

const STEP_BACKWARD_KEY = 'ArrowLeft';
const PLAY_PAUSE_KEY = ' ';
const STEP_FORWARD_KEY = 'ArrowRight';
const RESTART_KEY = 'r';
const LOOP_KEY = 'l';
const FIT_VIEW_KEY = 'f';
const SHOW_AGENT_ID_KEY = 'a';
const STEP_SIZE_UP_KEY = 'ArrowUp';
const STEP_SIZE_DOWN_KEY = 'ArrowDown';
const TRACE_PATHS_KEY = 'p';
const SCREENSHOT_KEY = 's';
const SHOW_CELL_ID_KEY = 'c';
const SHOW_GOALS_KEY = 'g';
const SHOW_GOAL_VECTORS_KEY = 'v';

interface AnimationControlProps {
playAnimation: boolean;
onPlayChange: (play: boolean) => void;
Expand Down Expand Up @@ -90,50 +76,50 @@ function AnimationControl({
}

switch (event.key) {
case STEP_BACKWARD_KEY:
case KeyMap.STEP_BACKWARD_KEY:
onSkipBackward();
break;
case PLAY_PAUSE_KEY:
case KeyMap.PLAY_PAUSE_KEY:
onPlayChange(!playAnimation);
break;
case STEP_FORWARD_KEY:
case KeyMap.STEP_FORWARD_KEY:
onSkipForward();
break;
case RESTART_KEY:
case KeyMap.RESTART_KEY:
onRestart();
break;
case LOOP_KEY:
case KeyMap.LOOP_KEY:
onLoopAnimationChange(!loopAnimation);
break;
case FIT_VIEW_KEY:
case KeyMap.FIT_VIEW_KEY:
onFitView();
break;
case SHOW_AGENT_ID_KEY:
case KeyMap.SHOW_AGENT_ID_KEY:
onShowAgentIdChange(!showAgentId);
break;
case STEP_SIZE_UP_KEY:
case KeyMap.STEP_SIZE_UP_KEY:
if (stepSize + STEP_SIZE_INCREMENT <= STEP_SIZE_MAX) {
roundAndSetStepSize(stepSize + STEP_SIZE_INCREMENT);
}
break;
case STEP_SIZE_DOWN_KEY:
case KeyMap.STEP_SIZE_DOWN_KEY:
if (stepSize - STEP_SIZE_INCREMENT >= STEP_SIZE_MIN) {
roundAndSetStepSize(stepSize - STEP_SIZE_INCREMENT);
}
break;
case TRACE_PATHS_KEY:
case KeyMap.TRACE_PATHS_KEY:
onTracePathsChange(!tracePaths);
break;
case SCREENSHOT_KEY:
case KeyMap.SCREENSHOT_KEY:
takeScreenshot();
break;
case SHOW_CELL_ID_KEY:
case KeyMap.SHOW_CELL_ID_KEY:
setShowCellId(!showCellId);
break;
case SHOW_GOALS_KEY:
case KeyMap.SHOW_GOALS_KEY:
setShowGoals(!showGoals);
break;
case SHOW_GOAL_VECTORS_KEY:
case KeyMap.SHOW_GOAL_VECTORS_KEY:
setShowGoalVectors(!showGoalVectors);
break;
}
Expand Down Expand Up @@ -180,9 +166,20 @@ function AnimationControl({
py: 1.5,
}}>
<Stack direction="row" alignItems="center" justifyContent="space-between">
<Box sx={{ width: 48 }} />
<Box>
Drag to pan, scroll to zoom.
</Box>

<Stack direction="row" spacing={2} alignItems="center">
<Stack
direction="row"
spacing={2}
alignItems="center"
sx={{
position: 'absolute',
left: '50%',
transform: 'translateX(-50%)',
}}
>
<Tooltip title="Previous step (🡐)">
<IconButton
onClick={onSkipBackward}
Expand Down
69 changes: 41 additions & 28 deletions src/ControlsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import RepeatIcon from '@mui/icons-material/Repeat';
import RepeatOnIcon from '@mui/icons-material/RepeatOn';
import FilterCenterFocusOutlinedIcon from '@mui/icons-material/FilterCenterFocusOutlined';
import ScreenshotMonitorOutlinedIcon from '@mui/icons-material/ScreenshotMonitorOutlined';
import Tooltip from '@mui/material/Tooltip';
import { KeyMap } from './Params';

interface ControlsSectionProps {
onRestart: () => void;
Expand All @@ -26,24 +28,31 @@ function ControlsSection({
<Stack spacing={1}>
<Box sx={{ fontSize: '0.75rem', fontWeight: 600, textTransform: 'uppercase', color: 'text.secondary', letterSpacing: 1 }}>Controls</Box>
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0.5 }}>
<Button
onClick={onRestart}
size="small"
variant="outlined"
startIcon={<StartIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Restart
</Button>
<Button
onClick={() => onLoopAnimationChange(!loopAnimation)}
size="small"
variant="outlined"
startIcon={loopAnimation ? <RepeatOnIcon /> : <RepeatIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Loop
</Button>
<Tooltip title={KeyMap.RESTART_KEY} arrow placement='top'>
<Button
onClick={onRestart}
size="small"
variant="outlined"
startIcon={<StartIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Restart
</Button>
</Tooltip>

<Tooltip title={KeyMap.LOOP_KEY} arrow placement='top'>
<Button
onClick={() => onLoopAnimationChange(!loopAnimation)}
size="small"
variant="outlined"
startIcon={loopAnimation ? <RepeatOnIcon /> : <RepeatIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Loop
</Button>
</Tooltip>

<Tooltip title={KeyMap.FIT_VIEW_KEY} arrow placement='bottom'>
<Button
onClick={onFitView}
size="small"
Expand All @@ -53,16 +62,20 @@ function ControlsSection({
>
Fit View
</Button>
<Button
disabled={!canScreenshot}
onClick={takeScreenshot}
size="small"
variant="outlined"
startIcon={<ScreenshotMonitorOutlinedIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Screenshot
</Button>
</Tooltip>

<Tooltip title={KeyMap.SCREENSHOT_KEY} arrow placement='bottom'>
<Button
disabled={!canScreenshot}
onClick={takeScreenshot}
size="small"
variant="outlined"
startIcon={<ScreenshotMonitorOutlinedIcon />}
sx={{ justifyContent: 'flex-start', textTransform: 'none' }}
>
Screenshot
</Button>
</Tooltip>
</Box>
</Stack>
);
Expand Down
82 changes: 47 additions & 35 deletions src/DisplaySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import LooksOneOutlinedIcon from '@mui/icons-material/LooksOneOutlined';
import DirectionsOutlinedIcon from '@mui/icons-material/DirectionsOutlined';
import OutlinedFlagIcon from '@mui/icons-material/OutlinedFlag';
import PolylineOutlinedIcon from '@mui/icons-material/PolylineOutlined';
import { KeyMap } from './Params';
import Tooltip from '@mui/material/Tooltip';

interface DisplaySectionProps {
showAgentId: boolean;
Expand Down Expand Up @@ -34,45 +36,55 @@ function DisplaySection({
<Stack spacing={1}>
<Box sx={{ fontSize: '0.75rem', fontWeight: 600, textTransform: 'uppercase', color: 'text.secondary', letterSpacing: 1 }}>Display</Box>
<Stack spacing={0.5}>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer' }} onClick={() => onShowAgentIdChange(!showAgentId)}>
<Checkbox size="small" checked={showAgentId} onChange={(e) => onShowAgentIdChange(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<SmartToyOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Agent IDs
</Box>
</Stack>
<Tooltip title={KeyMap.SHOW_AGENT_ID_KEY} placement='right' arrow>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer', width: 'fit-content' }} onClick={() => onShowAgentIdChange(!showAgentId)}>
<Checkbox size="small" checked={showAgentId} onChange={(e) => onShowAgentIdChange(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<SmartToyOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Agent IDs
</Box>
</Stack>
</Tooltip>

<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer' }} onClick={() => setShowCellId(!showCellId)}>
<Checkbox size="small" checked={showCellId} onChange={(e) => setShowCellId(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<LooksOneOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Cell IDs
</Box>
</Stack>
<Tooltip title={KeyMap.SHOW_CELL_ID_KEY} placement='right' arrow>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer', width: 'fit-content' }} onClick={() => setShowCellId(!showCellId)}>
<Checkbox size="small" checked={showCellId} onChange={(e) => setShowCellId(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<LooksOneOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Cell IDs
</Box>
</Stack>
</Tooltip>

<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer' }} onClick={() => onTracePathsChange(!tracePaths)}>
<Checkbox size="small" checked={tracePaths} onChange={(e) => onTracePathsChange(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<DirectionsOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Paths
</Box>
</Stack>
<Tooltip title={KeyMap.TRACE_PATHS_KEY} placement='right' arrow>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer', width: 'fit-content' }} onClick={() => onTracePathsChange(!tracePaths)}>
<Checkbox size="small" checked={tracePaths} onChange={(e) => onTracePathsChange(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<DirectionsOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Paths
</Box>
</Stack>
</Tooltip>

<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer' }} onClick={() => setShowGoals(!showGoals)}>
<Checkbox size="small" checked={showGoals} onChange={(e) => setShowGoals(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<OutlinedFlagIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Goals
</Box>
</Stack>
<Tooltip title={KeyMap.SHOW_GOALS_KEY} placement='right' arrow>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer', width: 'fit-content' }} onClick={() => setShowGoals(!showGoals)}>
<Checkbox size="small" checked={showGoals} onChange={(e) => setShowGoals(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<OutlinedFlagIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Goals
</Box>
</Stack>
</Tooltip>

<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer' }} onClick={() => setShowGoalVectors(!showGoalVectors)}>
<Checkbox size="small" checked={showGoalVectors} onChange={(e) => setShowGoalVectors(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<PolylineOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Vectors
</Box>
</Stack>
<Tooltip title={KeyMap.SHOW_GOAL_VECTORS_KEY} placement='right' arrow>
<Stack direction="row" alignItems="center" sx={{ cursor: 'pointer', width: 'fit-content' }} onClick={() => setShowGoalVectors(!showGoalVectors)}>
<Checkbox size="small" checked={showGoalVectors} onChange={(e) => setShowGoalVectors(e.target.checked)} sx={{ py: 0.5 }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontSize: '0.875rem' }}>
<PolylineOutlinedIcon fontSize="small" sx={{ color: 'text.secondary' }} />
Vectors
</Box>
</Stack>
</Tooltip>
</Stack>
</Stack>
);
Expand Down
17 changes: 17 additions & 0 deletions src/Params.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,20 @@ export const AGENT_COLORS: number[] = [
0x009688,
0x3F51B5
];

export enum KeyMap {
STEP_BACKWARD_KEY = 'ArrowLeft',
PLAY_PAUSE_KEY = ' ',
STEP_FORWARD_KEY = 'ArrowRight',
RESTART_KEY = 'r',
LOOP_KEY = 'l',
FIT_VIEW_KEY = 'f',
SHOW_AGENT_ID_KEY = 'a',
STEP_SIZE_UP_KEY = 'ArrowUp',
STEP_SIZE_DOWN_KEY = 'ArrowDown',
TRACE_PATHS_KEY = 'p',
SCREENSHOT_KEY = 's',
SHOW_CELL_ID_KEY = 'c',
SHOW_GOALS_KEY = 'g',
SHOW_GOAL_VECTORS_KEY = 'v',
}
15 changes: 2 additions & 13 deletions src/PixiApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ const PixiApp = forwardRef(({
app.stage.addChild(viewport);
hudRef.current = app.stage.addChild(new PIXI.Container());
const textStyle = new PIXI.TextStyle({
fontSize: 24,
fontSize: 24 * FONT_SUPER_RESOLUTION_SCALE,
fill: TEXT_COLOR,
fontFamily: "Arial",
fontWeight: "bold",
Expand All @@ -387,16 +387,7 @@ const PixiApp = forwardRef(({
y: height / 100,
anchor: new PIXI.Point(0, 0),
style: textStyle,
})
);

hudRef.current.addChild(
new PIXI.Text({
x: width - width / 100,
y: height / 100,
anchor: new PIXI.Point(1, 0),
text: "Click and drag to pan. Scroll to zoom.",
style: textStyle,
scale: {x: 1 / FONT_SUPER_RESOLUTION_SCALE, y: 1 / FONT_SUPER_RESOLUTION_SCALE}
})
);
}
Expand Down Expand Up @@ -450,8 +441,6 @@ const PixiApp = forwardRef(({
if (hudRef.current) {
hudRef.current.children[0].x = width / 100;
hudRef.current.children[0].y = height / 100;
hudRef.current.children[1].x = width - width / 100;
hudRef.current.children[1].y = height / 100;
}
fit();
}
Expand Down