feat: implement keyboard and mouse input, pattern placement, and HiDPI scaling

Add configurable key bindings (TOML), modifier-aware dispatch, mouse-driven
pattern placement with preview and rotation, cell grid storage/rendering,
and fractional/integer HiDPI scaling. Archive the input-and-placement change
and sync its specs to main specs.

Tests: Hashtable, Config, Grid, Pattern (4/4 pass).
This commit is contained in:
2026-11-08 14:46:04 +01:00
parent 5e7abfb56b
commit 7874a5f7c6
31 changed files with 4081 additions and 96 deletions
@@ -0,0 +1,62 @@
# Spec Delta
## Purpose
Stores and renders the Game of Life cell grid with a fixed cell size and wall boundaries, independent of future simulation rules.
## ADDED Requirements
### Requirement: Grid stores alive and dead cells
The system SHALL maintain a grid of cells, each either alive or dead, addressable by column and row.
#### Scenario: Cell access
- **WHEN** a cell is set to alive
- **THEN** reading that cell returns alive
- **AND** cells never set remain dead
### Requirement: Boundary cells are treated as dead
The system SHALL treat any cell outside the grid bounds as dead and shall not store state outside the grid.
#### Scenario: Out of bounds read
- **WHEN** a cell position outside the grid is queried
- **THEN** the result is dead
### Requirement: Grid resizes while preserving overlapping cells
The system SHALL preserve cells that remain within bounds when the grid dimensions change, clearing only cells that fall outside the new bounds.
#### Scenario: Enlarge grid
- **WHEN** the grid grows in either dimension
- **THEN** previously alive cells within the old bounds remain alive
#### Scenario: Shrink grid
- **WHEN** the grid shrinks in either dimension
- **THEN** cells outside the new bounds are discarded
- **AND** remaining cells keep their state
### Requirement: Cell size is fixed in logical pixels
The system SHALL use a cell size of 8 logical pixels, so grid dimensions derive from the logical surface size.
#### Scenario: Dimension calculation
- **WHEN** the logical surface is 400 pixels wide
- **THEN** the grid has 50 columns
### Requirement: Alive cells are rendered
The system SHALL render alive cells distinctly from dead cells.
#### Scenario: Render alive cell
- **WHEN** a cell is alive
- **THEN** it is drawn with the alive cell color
### Requirement: Grid can be cleared
The system SHALL set all cells to dead when the clear action is triggered.
#### Scenario: Clear grid
- **WHEN** the user triggers the clear action
- **THEN** all cells become dead
### Requirement: Grid lines can be toggled
The system SHALL show or hide grid lines when the toggle_grid action is triggered.
#### Scenario: Toggle lines
- **WHEN** the user triggers the toggle_grid action
- **THEN** grid line visibility flips