feat(note): page background templates (rnote-style)
Some checks failed
CI / Windows build (push) Has been cancelled

A blank note can show a page-background template painted behind the
ink, picked from the toolbar and persisted per notebook.

- NoteBackground: blank / dots / ruled / grid / cornell, drawn in
  page space (scales with zoom), subtle grey. Cornell = left margin +
  bottom summary rule over a ruled body.
- Stored as the enum name in the notebook sidecar (back-compat:
  missing/unknown -> blank), saved/loaded via SidecarRepository so it
  restores on reopen.
- Picker added to the note tool palette.

PDF backgrounds skipped (PDFs have their own page content). analyze
clean, 386 tests green.
This commit is contained in:
2026-06-24 23:47:29 +08:00
parent 46589a4c87
commit c800295c12
6 changed files with 303 additions and 2 deletions

View File

@@ -231,6 +231,22 @@ void main() {
expect(reparsed.strokes[0]!.single.id, 's0');
});
test('background name round-trips through the sidecar', () {
final original = BadnoteSidecar(docType: 'notebook', background: 'cornell');
final reparsed = _roundTrip(original);
expect(reparsed.background, 'cornell');
// Omitted when null (no key bloat for blank/legacy sidecars).
expect(BadnoteSidecar().toJson().containsKey('background'), isFalse);
});
test('missing background decodes to null (back-compat → blank)', () {
final json =
jsonDecode(jsonEncode(BadnoteSidecar().toJson())) as Map<String, dynamic>;
expect(json.containsKey('background'), isFalse);
final reparsed = BadnoteSidecar.fromJson(json);
expect(reparsed.background, isNull);
});
test('missing scratchpad defaults to 4000x4000 empty pad', () {
final json = SidecarScratchLink(
link: const ScratchLink(