Add handling for buttons
This commit is contained in:
parent
4d3113dc99
commit
591ed62ccd
@ -9,6 +9,7 @@ export interface ButtonDefinition {
|
||||
text: string|JSX.Element;
|
||||
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||
cssProps: CSSProperties;
|
||||
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>
|
||||
}
|
||||
|
||||
const ButtonGroup = ({buttons, buttonStyleProps}: ButtonGroupProps) => {
|
||||
@ -23,6 +24,7 @@ const ButtonGroup = ({buttons, buttonStyleProps}: ButtonGroupProps) => {
|
||||
...buttonStyleProps,
|
||||
...btn.cssProps
|
||||
}}
|
||||
{...(btn.buttonProps ?? {})}
|
||||
>
|
||||
<>{btn.text}</>
|
||||
</button>
|
||||
|
||||
@ -1,26 +1,54 @@
|
||||
import {ButtonDefinition, ButtonGroup} from '../button';
|
||||
import {AiOutlineClear, BsFillPlayFill, BsFillStopFill, CiSettings, TbArrowsRandom} from 'react-icons/all';
|
||||
import React, {useMemo} from 'react';
|
||||
import {
|
||||
AiOutlineClear,
|
||||
BsFillPlayFill,
|
||||
BsFillStopFill,
|
||||
CiSettings,
|
||||
IoAdd,
|
||||
IoRemove,
|
||||
TbArrowsRandom
|
||||
} from 'react-icons/all';
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {GameOptions, GameState} from './Game';
|
||||
|
||||
interface ControlPanelProps {
|
||||
gameOptions: GameOptions;
|
||||
handleStart: React.MouseEventHandler<HTMLButtonElement>;
|
||||
handleStop: React.MouseEventHandler<HTMLButtonElement>;
|
||||
handleRandomFill: React.MouseEventHandler<HTMLButtonElement>;
|
||||
handleClear: React.MouseEventHandler<HTMLButtonElement>;
|
||||
handleUpdateSpeed: (newVal: number) => void;
|
||||
}
|
||||
|
||||
const ControlPanel = ({
|
||||
gameOptions,
|
||||
handleStart,
|
||||
handleStop,
|
||||
handleRandomFill,
|
||||
handleClear
|
||||
handleClear,
|
||||
handleUpdateSpeed
|
||||
}: ControlPanelProps) => {
|
||||
const controlButtons: ButtonDefinition[] = useMemo(() => [
|
||||
{text: <BsFillPlayFill />, onClick: handleStart, cssProps: {}},
|
||||
{text: <BsFillStopFill />, onClick: handleStop, cssProps: {}},
|
||||
{text: <BsFillPlayFill />, onClick: handleStart, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Running}},
|
||||
{text: <BsFillStopFill />, onClick: handleStop, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Stopped}},
|
||||
{text: <TbArrowsRandom />, onClick: handleRandomFill, cssProps: {}},
|
||||
{text: <AiOutlineClear />, onClick: handleClear, cssProps: {}}
|
||||
], [handleStart, handleStop, handleRandomFill, handleClear]);
|
||||
], [handleStart, handleStop, handleRandomFill, handleClear, gameOptions]);
|
||||
|
||||
const handleSpeedChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value;
|
||||
handleUpdateSpeed(Number(value));
|
||||
}, [handleUpdateSpeed]);
|
||||
|
||||
const handleSpeedUp = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
const newVal = gameOptions.speed + 100;
|
||||
handleUpdateSpeed(newVal);
|
||||
}, [handleUpdateSpeed, gameOptions]);
|
||||
|
||||
const handleSpeedDown = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
const newVal = gameOptions.speed - 100;
|
||||
handleUpdateSpeed(newVal);
|
||||
}, [handleUpdateSpeed, gameOptions]);
|
||||
|
||||
return (
|
||||
<div className='control-panel'>
|
||||
@ -30,6 +58,16 @@ const ControlPanel = ({
|
||||
width: '50px'
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className='speed-selector'>
|
||||
<button onClick={handleSpeedUp}><IoAdd /></button>
|
||||
<input
|
||||
value={gameOptions.speed}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
<button onClick={handleSpeedDown}><IoRemove /></button>
|
||||
</div>
|
||||
|
||||
<button><CiSettings/></button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -8,30 +8,66 @@ interface GameProps {
|
||||
|
||||
}
|
||||
|
||||
interface GameOptions {
|
||||
export enum GameState {
|
||||
Stopped,
|
||||
Running
|
||||
}
|
||||
|
||||
export interface GameOptions {
|
||||
gameState: GameState;
|
||||
width: number;
|
||||
height: number;
|
||||
speed: number;
|
||||
minSpeed: number;
|
||||
}
|
||||
|
||||
const defaultGameOptions: GameOptions = {
|
||||
gameState: GameState.Stopped,
|
||||
width: 25,
|
||||
height: 25
|
||||
height: 25,
|
||||
speed: 1000,
|
||||
minSpeed: 100
|
||||
}
|
||||
|
||||
const Game = ({}: GameProps) => {
|
||||
const [gameOptions, setGameOptions] = useState<GameOptions>(defaultGameOptions);
|
||||
const [cells, setCells] = useState<boolean[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleStart = useCallback(() => {
|
||||
setGameOptions(prev => {
|
||||
prev.gameState = GameState.Running;
|
||||
return {...prev};
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleStop = useCallback(() => {
|
||||
setGameOptions(prev => {
|
||||
prev.gameState = GameState.Stopped;
|
||||
return {...prev};
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleRandomFill = useCallback(() => {
|
||||
const newCells: boolean[] = [];
|
||||
const totalCells = gameOptions.width * gameOptions.height;
|
||||
|
||||
for(let i = 0; i < totalCells; i++) {
|
||||
newCells.push(false);
|
||||
newCells.push(Math.random() < 0.5);
|
||||
}
|
||||
|
||||
setCells(newCells);
|
||||
}, [gameOptions]);
|
||||
}, []);
|
||||
|
||||
const handleClear = useCallback(() => {
|
||||
const newCells: boolean[] = [];
|
||||
const totalCells = gameOptions.width * gameOptions.height;
|
||||
|
||||
for(let i = 0; i < totalCells; i++) {
|
||||
newCells.push(false);
|
||||
}
|
||||
|
||||
setCells(newCells);
|
||||
}, []);
|
||||
|
||||
const handleCellUpdate = useCallback((newVal: boolean, position: number) => {
|
||||
setCells(prev => {
|
||||
@ -40,13 +76,30 @@ const Game = ({}: GameProps) => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleUpdateSpeed = useCallback((newVal: number) => {
|
||||
if(newVal < gameOptions.minSpeed) {
|
||||
newVal = gameOptions.minSpeed;
|
||||
}
|
||||
|
||||
setGameOptions(prev => {
|
||||
prev.speed = newVal;
|
||||
return {...prev};
|
||||
})
|
||||
}, [gameOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
handleClear();
|
||||
}, [handleClear]);
|
||||
|
||||
return (
|
||||
<div className='game-container'>
|
||||
<ControlPanel
|
||||
handleStart={() => {}}
|
||||
handleStop={() => {}}
|
||||
handleRandomFill={() => {}}
|
||||
handleClear={() => {}}
|
||||
gameOptions={gameOptions}
|
||||
handleStart={handleStart}
|
||||
handleStop={handleStop}
|
||||
handleRandomFill={handleRandomFill}
|
||||
handleClear={handleClear}
|
||||
handleUpdateSpeed={handleUpdateSpeed}
|
||||
/>
|
||||
<CellContainer
|
||||
cells={cells}
|
||||
|
||||
@ -10,6 +10,18 @@
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.speed-selector {
|
||||
display: flex;
|
||||
|
||||
input {
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cell-container {
|
||||
flex-grow: 1;
|
||||
display: grid;
|
||||
|
||||
@ -26,6 +26,7 @@ button {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
|
||||
align-content: center;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user