Skip to content

Commit

Permalink
Disable the solve button when inapplicable
Browse files Browse the repository at this point in the history
The button should be disabled when the maze isn't fully generated.

Fixes #3
  • Loading branch information
imericxu committed Jul 10, 2024
1 parent 61e04f8 commit 58f6e18
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/app/components/OptionsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import { FormActionType } from "../page";

export interface OptionsFormProps {
onAction: (action: FormActionType, settings: MazeSettings) => void;
solvable: boolean;
className?: string;
}

export default function OptionsForm({
onAction,
solvable,
className,
}: OptionsFormProps): ReactElement {
const formRef = useRef<HTMLFormElement | null>(null);
Expand Down Expand Up @@ -177,8 +179,9 @@ export default function OptionsForm({
</Button>

<Button
isDisabled={!solvable}
onPress={() => handlePress("solve")}
className="glass-tube-container h-8 bg-blue-500/20 px-4 transition hover:bg-blue-500/30 pressed:bg-blue-500/40"
className="glass-tube-container h-8 bg-blue-500/20 px-4 transition hover:bg-blue-500/30 pressed:bg-blue-500/40 disabled:cursor-not-allowed disabled:bg-slate-700/20"
>
Solve
</Button>
Expand Down
17 changes: 11 additions & 6 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@ export default function Home(): ReactElement {
const [mazeController, setMazeController] = useState<MazeController | null>(
null,
);
const [solvable, setSolvable] = useState(false);

useEffect(() => {
if (canvasRef.current === null) return;
const ctx = canvasRef.current.getContext("2d");
if (ctx === null) return;
setMazeController((prev) => {
if (prev !== null) return prev;
return new MazeController(ctx, (size: Readonly<RectSize>) => {
if (containerRef.current === null) return;
containerRef.current.style.width = `${size.width}px`;
containerRef.current.style.height = `${size.height}px`;
});
return new MazeController(
ctx,
(size: Readonly<RectSize>) => {
if (containerRef.current === null) return;
containerRef.current.style.width = `${size.width}px`;
containerRef.current.style.height = `${size.height}px`;
},
setSolvable,
);
});
}, []);

Expand All @@ -55,7 +60,7 @@ export default function Home(): ReactElement {

return (
<main className="flex flex-col items-center gap-8 p-4">
<OptionsForm onAction={onAction} />
<OptionsForm onAction={onAction} solvable={solvable} />

{/* Zoom settings island */}
<RadioGroup
Expand Down
16 changes: 15 additions & 1 deletion src/lib/MazeController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ export class MazeController {

private maze: MazeCell[][] | null = null;

/**
* @param ctx - The canvas context to draw on.
* @param setContainerSize - Callback to set the container size when the maze
* is resized.
* @param setSolvable - Callback to set whether the maze is in a solvable
* state.
*/
constructor(
ctx: CanvasRenderingContext2D,
setContainerSize: (size: Readonly<RectSize>) => void,
private setSolvable: (solvable: boolean) => void,
) {
this.drawer = new MazeDrawer(
ctx,
Expand All @@ -78,6 +86,7 @@ export class MazeController {
public async generate(settings: MazeSettings): Promise<void> {
if (this.drawer.lastEvent === "solve") this.shouldSweep = true;
this.drawer.lastEvent = "generate";
this.setSolvable(false);

if (!deepEqual(this.dimensions, settings.dimensions)) {
this.dimensions = settings.dimensions;
Expand Down Expand Up @@ -119,7 +128,11 @@ export class MazeController {
}
if (settings.doAnimateGenerating) this.drawer.draw();
},
() => alg.finished,
() => {
if (!alg.finished) return false;
this.setSolvable(true);
return true;
},
settings.doAnimateGenerating ? 60 : null,
);

Expand Down Expand Up @@ -207,6 +220,7 @@ export class MazeController {
* Empties the canvas and stops all animations.
*/
public async clear(): Promise<void> {
this.setSolvable(false);
await this.stopMazeAnimation();
this.maze = null;
this.shouldSweep = false;
Expand Down

0 comments on commit 58f6e18

Please sign in to comment.