OCR window: index-mapped scrollbar for the subtitle grid - #13756
Conversation
The OCR grid had the same jumping thumb as the main subtitle grid (#13579): Avalonia's VirtualizingStackPanel estimates the pixel extent from the average realized row height, which shifts on every scroll when rows differ in height - and here every row holds a subtitle bitmap, so they differ a lot. Wrap the grid in TableViewIndexScrollBar, the same control the main grid uses: it hides the native pixel-mapped vertical bar and docks a standalone one mapped to row indices, so the thumb tracks the first visible row instead of a moving estimate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ctrl+plus/minus re-measures every row, and the ScrollViewer keeps its pixel offset across that - so zooming moved the list to a different row: in a 500 line grid, zooming in five notches dropped the view from row 250 to row 172, and zooming out far enough pinned it to the end of the list. The index-mapped bar knows which row was at the viewport top, so add PreserveTopRow(): capture the row before the change and put it back once the new heights are measured. Repeated calls while one is pending keep the first row, so holding the zoom key down does not drift. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Follow-up: checked how the image zoom (Ctrl+plus/minus) interacts with the index bar. The bar itself is fine — a headless probe on 500 rows shows But the view jumped rows on zoom, because the ScrollViewer preserves its pixel offset across the re-measure (pre-existing, the native bar did the same): Since the bar now speaks row indices, this is cheap to fix: New test |
The OCR subtitle grid had the same jumping scrollbar thumb as the main subtitle grid (#13579): Avalonia's
VirtualizingStackPanelestimates the total pixel extent as realized rows + remaining × average realized height, so with variable-height rows the extent — and the native thumb — shifts on every wheel tick. The OCR grid is the worse case: every row holds a subtitle bitmap, so heights vary far more than the main grid's one-vs-two text lines.Change
MakeSubtitleViewnow wraps the grid inTableViewIndexScrollBar, the same control the main grid already uses. It hides the native pixel-mapped vertical bar and docks a standalone one mapped to row indices:Value= index of the first visible row (+ the fraction scrolled into it)Maximum= row count − fully visible rowsWheel, keyboard and the OCR loop's own
ScrollIntoViewstill move the pixel offset;ScrollChangedre-derives the thumb. Trough press-and-hold (#12894) and shift+click jump come along with the control.Verification
New test
OcrWindow_UsesIndexMappedScrollBarasserts, on a 500-item OCR window:Maximumis in row units (400–499), while the pixel extent is many times largerValue = 250places row 250 at the viewport top779 Ocr/TableView UI tests pass; build clean.
Not included
The main grid also gets
TableViewScrollAnchor.Attach(#13619) to hold the view steady when a row changes height. The OCR grid's rows do change height as text lands during OCR, but the OCR loop already scrolls to the current line itself, so an anchor could fight it — left for a separate look.🤖 Generated with Claude Code