Skip to content

feat: PageStrip, a virtualised strip of page thumbnails - #495

Merged
tannevaled merged 2 commits into
mainfrom
page-strip
Oct 22, 2026
Merged

tannevaled merged 2 commits into
mainfrom
page-strip

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Problem

The go-slides playground wants a column of slide thumbnails beside the preview (PowerPoint / Keynote slide panel); the go-tex playground and any PDF viewer want the same. Nothing in the toolkit was a page strip (PagedView is a viewer, GalleryView is not virtualised).

PageStrip

A generic, virtualised strip of page cards, vertical or horizontal, with page numbers, a current-page outline and a scrollbar.

  • Content: SetImage(i, rgba, w, h) bitmap, or the DrawPage callback, else a numbered placeholder.
  • Lazy like pdf.js's thumbnail sidebar: NeedImage(i) fires once per page when it comes within a page of the window; Invalidate(i) keeps the stale bitmap until the replacement arrives (an edited document re-renders only the changed pages); MaxResident bounds memory (farthest dropped, asked again on return).
  • Prefix-sum layout over optional per-page aspects, binary-searched window: Draw cost is independent of the page count (181 us at 10 pages, 155 us at 500, 142 us at 100000, 0-37 allocs).
  • Current() Observable (click, Arrow/Page/Home/End, or the host); the strip scrolls to keep it visible. Outline >= 3:1 vs the strip (tested in 4 themes).
  • Shared scrollbar machinery (scrollGeom, scrollDrag).

Bibliography opened: pdf.js pdf_thumbnail_view.js (THUMBNAIL_WIDTH = 126, per-view INITIAL/RUNNING/FINISHED rendering state), pdf_rendering_queue.js (visible views first), VS Code minimap.ts for the sibling minimap (#494).

Tests: virtualisation (500 pages: only the window and one neighbour requested, once), image/DrawPage/placeholder, invalidate/evict, selection by click and keys, follow-the-selection, scrollbar drag/page/wheel, horizontal, aspects, edge cases, a11y, benchmark. 100% coverage.

Stacked on #494 (v0.331.0), rebased on main.

🤖 Generated with Claude Code

tannevaled and others added 2 commits October 22, 2026 09:35
A vertical or horizontal strip of page cards with numbers, a current-page
outline and a scrollbar: the slide panel of PowerPoint / Keynote / Google
Slides, the thumbnail sidebar of pdf.js. Generic: a page is a bitmap handed in
with SetImage or painted by the DrawPage callback; NeedImage asks the host once
per page when it comes within a page of the window; Invalidate keeps the stale
bitmap on screen until the replacement arrives, so an edited document
re-renders only its changed pages; MaxResident bounds the bitmaps kept in
memory (the farthest are dropped and asked for again). Layout is a prefix-sum
over per-page aspects, the window a binary search: the cost of a Draw does not
depend on the page count (measured 181 us at 10 pages, 155 us at 500, 142 us at
100000).

Current() is an Observable (click, keys Arrow/Page/Home/End, or the host); the
strip scrolls to keep it visible. The selected outline keeps >= 3:1 against the
strip in light and dark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntent on the cards

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 85fb18e into main Oct 22, 2026
1 check passed
@tannevaled
tannevaled deleted the page-strip branch October 22, 2026 07:42
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.

1 participant