diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7e6bc65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +# .editorconfig +root = true +[*] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index a547bf3..a8bb46d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ dist-ssr .vscode/* !.vscode/extensions.json .idea +.fleet .DS_Store *.suo *.ntvs* diff --git a/src/App.tsx b/src/App.tsx index 62ddaa5..7e22793 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,7 @@ -import { useState } from 'react'; - import './styles/main.less'; import {Game} from './components/game'; const App = () => { - const [count, setCount] = useState(0) - return (
diff --git a/src/components/button/ButtonGroup.tsx b/src/components/button/ButtonGroup.tsx index fb1320f..3562dd8 100644 --- a/src/components/button/ButtonGroup.tsx +++ b/src/components/button/ButtonGroup.tsx @@ -7,6 +7,7 @@ interface ButtonGroupProps { export interface ButtonDefinition { text: string|JSX.Element; + title?: string; onClick: React.MouseEventHandler; cssProps: CSSProperties; buttonProps?: React.ButtonHTMLAttributes @@ -20,6 +21,7 @@ const ButtonGroup = ({buttons, buttonStyleProps}: ButtonGroupProps) => { - - -
- - - - ); -} - -export default ControlPanel; \ No newline at end of file diff --git a/src/components/game/Game.tsx b/src/components/game/Game.tsx index f5e115e..2c60141 100644 --- a/src/components/game/Game.tsx +++ b/src/components/game/Game.tsx @@ -2,7 +2,7 @@ import CellContainer from './CellContainer'; import {useCallback, useEffect, useRef, useState} from 'react'; import '../../styles/game.less'; -import ControlPanel from './ControlPanel'; +import {ControlPanel} from './controlPanel'; interface GameProps { @@ -33,7 +33,7 @@ const defaultGameOptions: GameOptions = { gameState: GameState.Stopped, width: 25, height: 25, - speed: 1000, + speed: 200, minSpeed: 10, randomizerDensity: 0.3, gameRules: { diff --git a/src/components/game/controlPanel/ControlElement.tsx b/src/components/game/controlPanel/ControlElement.tsx new file mode 100644 index 0000000..c7ed7b5 --- /dev/null +++ b/src/components/game/controlPanel/ControlElement.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; + +interface ControlElementProps { + title?: string; + children?: React.ReactNode; + alignment?: 'start'|'center'|'end'; +} + +const ControlElement = ({title, children, alignment = 'start'}: ControlElementProps) => { + return ( +
+
+ {title} +
+
+ {children} +
+
+ ); +} + +export default ControlElement; \ No newline at end of file diff --git a/src/components/game/controlPanel/ControlPanel.tsx b/src/components/game/controlPanel/ControlPanel.tsx new file mode 100644 index 0000000..3bd11cf --- /dev/null +++ b/src/components/game/controlPanel/ControlPanel.tsx @@ -0,0 +1,62 @@ +import {ButtonDefinition, ButtonGroup} from '../../button'; +import { + AiOutlineClear, + BsFillPlayFill, + BsFillStopFill, + CiSettings, + TbArrowsRandom +} from 'react-icons/all'; +import React, {useMemo} from 'react'; +import {GameOptions, GameState} from '../Game'; +import SpeedSelector from "./SpeedSelector"; +import ControlElement from "./ControlElement"; + +interface ControlPanelProps { + gameOptions: GameOptions; + handleStart: React.MouseEventHandler; + handleStop: React.MouseEventHandler; + handleRandomFill: React.MouseEventHandler; + handleClear: React.MouseEventHandler; + handleUpdateSpeed: (newVal: number) => void; +} + +const ControlPanel = ({ + gameOptions, + handleStart, + handleStop, + handleRandomFill, + handleClear, + handleUpdateSpeed +}: ControlPanelProps) => { + const controlButtons: ButtonDefinition[] = useMemo(() => [ + {text: , title: 'Start', onClick: handleStart, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Running}}, + {text: , title: 'Stop', onClick: handleStop, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Stopped}}, + {text: , title: 'Randomize Cells', onClick: handleRandomFill, cssProps: {}}, + {text: , title: 'Clear Cells', onClick: handleClear, cssProps: {}} + ], [handleStart, handleStop, handleRandomFill, handleClear, gameOptions]); + return ( +
+ + + + + + + + + + + +
+ ); +} + +export default ControlPanel; \ No newline at end of file diff --git a/src/components/game/controlPanel/SpeedSelector.tsx b/src/components/game/controlPanel/SpeedSelector.tsx new file mode 100644 index 0000000..937002b --- /dev/null +++ b/src/components/game/controlPanel/SpeedSelector.tsx @@ -0,0 +1,37 @@ +import React, { useCallback } from "react"; +import {IoAdd, IoRemove} from "react-icons/all"; + +interface SpeedSelectorProps { + handleUpdateSpeed: (newVal: number) => void; + speed: number; +} + +const SpeedSelector = ({handleUpdateSpeed, speed}: SpeedSelectorProps) => { + const handleSpeedChange = useCallback((event: React.ChangeEvent) => { + const value = event.target.value; + handleUpdateSpeed(Number(value)); + }, [handleUpdateSpeed]); + + const handleSpeedUp = useCallback((event: React.MouseEvent) => { + const newVal = speed + 100; + handleUpdateSpeed(newVal); + }, [handleUpdateSpeed, speed]); + + const handleSpeedDown = useCallback((event: React.MouseEvent) => { + const newVal = speed - 100; + handleUpdateSpeed(newVal); + }, [handleUpdateSpeed, speed]); + + return ( +
+ + + +
+ ); +} + +export default SpeedSelector; \ No newline at end of file diff --git a/src/components/game/controlPanel/index.ts b/src/components/game/controlPanel/index.ts new file mode 100644 index 0000000..99ea4a9 --- /dev/null +++ b/src/components/game/controlPanel/index.ts @@ -0,0 +1 @@ +export {default as ControlPanel} from './ControlPanel'; \ No newline at end of file diff --git a/src/styles/game.less b/src/styles/game.less index 523a203..864614a 100644 --- a/src/styles/game.less +++ b/src/styles/game.less @@ -12,6 +12,14 @@ display: flex; justify-content: space-between; margin-bottom: 1rem; + + .control-element { + display: flex; + flex-direction: column; + gap: 5px; + + justify-content: end; + } } .speed-selector { @@ -38,7 +46,6 @@ border: 1px solid @col-dark-light; width: 100%; height: 100%; - //pointer-events: none; user-select: none; diff --git a/src/styles/main.less b/src/styles/main.less index 25c2d8e..73723b7 100644 --- a/src/styles/main.less +++ b/src/styles/main.less @@ -11,8 +11,7 @@ body { .main { - height: 100vh; - width: 100%; + min-height: 100vh; display: flex; justify-content: center;