Skip to content

Draw a background grid that shows the zoom level - #134

Merged
marcosqlbi merged 2 commits into
mainfrom
feature/background-grid
Sep 17, 2026
Merged

marcosqlbi merged 2 commits into
mainfrom
feature/background-grid

Conversation

@marcosqlbi

Copy link
Copy Markdown
Collaborator

Closes #129.

A board is a white plane, and at any zoom it looks the same. Nothing on screen
says whether you are drawing at half size or at four times, so a stroke that
matched the one beside it a minute ago turns out not to, and a container dropped
next to another is a guess. This is the cue the issue asks for: a faint grid
whose spacing stays fixed in board pixels, so zooming shows the lines spreading
and then stepping coarser, and the zoom level becomes something you can see.

It is off by default, and it is an application preference rather than something a
board carries — it says how one person likes to work, and a board opened
somewhere else should not arrive with their grid. Preferences → Board →
Background grid
offers Off, Lines, and Dots; View → Grid toggles between
Off and whichever of the two was last chosen, so the button never has to ask
which grid you meant. The two stay in step: choosing Dots in Preferences is what
the toggle brings back afterwards.

GridGeometry in Core.Viewport owns the arithmetic — the spacing for a zoom,
and the world positions of the lines crossing a visible rectangle — so the
surface only turns positions into screen coordinates, and the stepping is
testable without WPF. The spacing is 40 board pixels, multiplied by four while
the lines would fall closer than 12 screen pixels apart.

The grid never leaves the screen. BoardRasterizer and BoardPreviewRenderer
build their own surface and now say GridStyle = GridStyle.Off beside their
existing DrawFrames = false, rather than relying on the default, so the rule is
visible to the next person reading either file. Nothing about the board file, the
archive version, or the selection changes.

Settings go to version 19, once, as the plan says; every new field has a default,
so 18 → 19 needs no migration. No version bump and no changelog entry: that is
pull request 7.

Two readings the plan left open, taken here:

  • The Preferences editor is the plain combo, not drawn swatches. The three
    choices use the existing EnumChoice, because a drawn choice needs a new
    SettingEditorKind and its own sample renderer, and the brief was not to build
    one for this. The row's prose carries what the pictures would have said.
  • A dot reaches 1.5 pixels out from its intersection, rather than measuring 1.5
    across.
    At the grid's gray — #14000000, the same as the lines — a dot 1.5
    pixels wide covers so little of a pixel that antialiasing thins it to about
    three per cent of black, which is not there at all on a screen. At this radius
    a dot is as dark as a line pixel and still reads as subtler than the lines,
    which is what a dot grid is for. The gray is unchanged.

The dots are drawn as one geometry rather than as an ellipse each, because the
surface is redrawn on every frame of a pan and a dense grid runs to tens of
thousands of intersections.

Also worth knowing: the Grid button sits on the View row, which is not a sticky
tab, so pressing it closes the row exactly as Full screen and Canvas only do.
Turning the grid on and straight off again therefore takes two trips through the
tab. Changing that would change every View command, so it is left alone here.

The icon is Fluent UI System Icons' grid_24_regular, MIT, added to
Toolbar.xaml beside the others.

The smoke tests cover the spacing steps, the exact threshold and either side of
it, the line positions for a known rectangle, and the settings round trip and
normalization. In the WPF harness the surface is rendered at each style and
compared pixel for pixel, so a style that drew nothing would fail; a preview is
checked to be the same bytes twice and a fresh surface to start at Off, which is
where a preview's grid is decided. SQLBI_WHITEBOARD_GRID_PREVIEW=<path> writes
a sheet of the three pictures, in the manner of the Prompt harness, for anyone
who wants to see how faint faint is.

To try by hand

  • Open View → Grid. The button should check — accent icon and label, tinted
    background — and a faint grid should appear behind the board.
  • Zoom out slowly. The lines should spread and then snap to a coarser spacing
    rather than sliding closed, and the same going back in.
  • Pan at several zooms. The grid should stay crisp and one pixel wide, with no
    shimmer and no visible cost to the pan.
  • Switch to Dots in Preferences → Board. The View button should stay
    checked, and toggling it off and on again should bring dots back, not lines.
  • Turn the grid on, then Export a deck and a PDF, and Ctrl+C a selection:
    none of them should carry the grid. The same for the Explorer thumbnail and the
    VS Code preview of a saved board.
  • Alt+V then G should toggle it from the keyboard.
  • With the grid on, check it against a highlighter stroke and a picture: it is
    meant to sit under everything.

🤖 Generated with Claude Code

marcosqlbi and others added 2 commits September 17, 2026 00:16
GridStyle and the two settings that carry it, and GridGeometry, which
answers where the lines go so the renderer does no arithmetic of its own.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The surface draws it under everything and only on screen; the rasterizer
and the preview say so rather than relying on the default. The View row's
Grid button toggles between Off and the last style, and Preferences holds
the three choices under a new Board category.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@marcosqlbi
marcosqlbi merged commit 8130215 into main Sep 17, 2026
5 checks passed
@marcosqlbi
marcosqlbi deleted the feature/background-grid branch September 17, 2026 10:10
marcosqlbi added a commit that referenced this pull request Sep 17, 2026
The background grid (#134) and this branch both add settings, a Preferences
category, a command-row toggle, and a pass over BoardSurface.OnRender. Every
conflict was an addition from both sides, and both survive: settings version
19 is set once, the grid draws after the background and before the objects,
and Preferences now has a Selection category and a Board category.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
marcosqlbi added a commit that referenced this pull request Sep 17, 2026
)

Pull request 7 of the 1.6.0 plan in `docs/design-objects.md`: the
release cut. The five
features are on `main` — the grid (#134), selection by area (#135), text
labels (#136),
shapes and the Insert tab (#137), and connectors (#139) — and none of
them touched the
prose, so this is where a person is told what they got. **#138, the
native editable export,
must merge before this one**: the release notes and the guide both say
shapes and labels
leave as objects in a deck and a PDF, which is true once it lands.

`VersionPrefix` goes 1.5.2 → 1.6.0, so `CHANGELOG.md` gains the matching
section and the
**Release notes** check applies to this pull request.
`./scripts/release-notes.ps1 -Mode
Verify -Version 1.6.0` passes, and `dotnet build Whiteboard.sln -c
Release` is clean.

## What it affects

- **`CHANGELOG.md`** — one `## 1.6.0 - 17 September 2026` section with
three entries, which
is the shape of 1.5.0 (3), 1.5.1 (1) and 1.5.2 (2): the Insert tab with
shapes,
connectors and text, selection by area, and the grid. The toolbar
preference is one
sentence inside the first entry rather than a fourth entry, because it
is where somebody
meets it. The first entry also carries the one thing a person deciding
whether to upgrade
has to know: a board holding any of the new objects does not open in
1.5.x.
- **`README.md`** — three bullets in *Included in the application*,
seven rows in
*Controls*, the Preferences lists in the bullet and in the table, and
the containers
paragraph, which now says shapes and labels are containers and that a
shape is picked up
  by its outline.
- **`site/guide.html`** — a new *Shapes, connectors, and text* section
after *Text and
code*, a paragraph on area selection under *Containers*, one sentence on
the grid under
  *Navigation*, and the Insert tab named in the command-strip section.
- **`site/shortcuts.html`** — Insert, Lasso and Grid rows, the rubber
band and Ctrl-to-add,
and the Alt-mnemonic row extended with Alt+I, Edit L, View G, and Insert
T.
- **`site/index.html`** — two feature tiles, shapes/connectors/text and
select by area.
- **`docs/decisions.md`** — decision 31, why design objects are ordinary
board objects,
why a shape is taken by its outline, and why the grid is an application
preference. The
rest stays in `docs/design-objects.md`, whose status line is now shipped
in 1.6.0.
- **`TODO.md`** — the current version, which still said 1.3.0, and what
1.6.0 left out.

## Readings taken, since nobody could be asked

- **`site/compare.html` is untouched.** It has no row saying Whiteboard
lacks shapes, text,
a grid or multi-select; the nearest, *Ink and objects*, is a statement
about strokes
travelling with a container and is still true. The brief said to change
such cells and
  nothing else, so nothing else changed.
- **`site/faq.html` is untouched.** No answer on it became wrong.
- ***Architecture* in `README.md` is untouched.** The `Core` bullet
names no types — it
says "world geometry, camera math, retained board objects, commands, hit
testing" — so
there was no list for `ShapeGeometry`, `ConnectorGeometry` and
`RotatedRectangle` to join,
  and the brief said to leave it alone in that case.
- **Escape is an edited row, not a new one**, in both the README table
and the shortcut
  list: Escape already had one, and a second would contradict it.
- **`site/changelog.html` is untouched**, as it is generated from
`CHANGELOG.md` at
  deployment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Background Grid

1 participant