fix: prevent BookInfo content from overlapping header on scroll

Draw header after content with a white fill over the header zone,
so scrolled cover images and text slide behind the header instead
of rendering on top of it. Removed incorrect maxHeight clamping
that caused the cover to shrink rather than scroll.

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-09 03:42:47 -04:00
parent 4c62437689
commit 2aba348070
2 changed files with 24 additions and 5 deletions

View File

@@ -0,0 +1,19 @@
# BookInfo Header Overlap Fix
**Date**: 2026-03-09
**Task**: Fix BookInfo header not properly overlaying scrolled content (cover image and text fields bleeding into the header bar area).
## Problem
The BookInfo screen's header (clock, battery, "Book Info" title) was being drawn *before* content, so the book cover thumbnail and text fields could render on top of or overlap with the header when scrolling. Additionally, the initial attempt to clip the cover by reducing `maxHeight` in `drawBitmap1Bit` caused the cover to *shrink* rather than scroll behind the header, because `maxHeight` controls bitmap scaling, not clipping.
## Changes Made
### `src/activities/home/BookInfoActivity.cpp`
- **Moved header rendering after content**: `GUI.drawHeader()` is now called *after* all content (cover + fields) is drawn, not before. A `renderer.fillRect(0, 0, pageW, contentTop, false)` wipe of the header zone precedes the header draw, ensuring any content that scrolled into the header region is cleared before the header paints on top.
- **Removed incorrect cover clipping**: The cover bitmap is now drawn at its natural scrolled `y` position with full `coverDisplayWidth` and `coverDisplayHeight` (no clamping of `maxHeight`). The header fill+draw handles visual clipping. This gives the correct "scroll behind the header" behavior instead of the cover appearing to shrink.
## Follow-up
None -- visual behavior confirmed acceptable by user.

View File

@@ -255,19 +255,16 @@ void BookInfoActivity::render(RenderLock&&) {
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing; const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
const int contentBottom = pageH - metrics.buttonHintsHeight - metrics.verticalSpacing; const int contentBottom = pageH - metrics.buttonHintsHeight - metrics.verticalSpacing;
GUI.drawHeader(renderer, Rect(0, metrics.topPadding, pageW, metrics.headerHeight), tr(STR_BOOK_INFO));
int y = contentTop - scrollOffset; int y = contentTop - scrollOffset;
if (!coverBmpPath.empty() && coverDisplayHeight > 0) { if (!coverBmpPath.empty() && coverDisplayHeight > 0) {
if (y + coverDisplayHeight > contentTop && y < contentBottom) { if (y + coverDisplayHeight > 0 && y < contentBottom) {
FsFile file; FsFile file;
if (Storage.openFileForRead("BIF", coverBmpPath, file)) { if (Storage.openFileForRead("BIF", coverBmpPath, file)) {
Bitmap bitmap(file); Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) { if (bitmap.parseHeaders() == BmpReaderError::Ok) {
const int coverX = (pageW - coverDisplayWidth) / 2; const int coverX = (pageW - coverDisplayWidth) / 2;
renderer.drawBitmap1Bit(bitmap, coverX, y, coverDisplayWidth, renderer.drawBitmap1Bit(bitmap, coverX, y, coverDisplayWidth, coverDisplayHeight);
std::min(coverDisplayHeight, contentBottom - y));
} }
file.close(); file.close();
} }
@@ -296,6 +293,9 @@ void BookInfoActivity::render(RenderLock&&) {
y += SECTION_GAP; y += SECTION_GAP;
} }
renderer.fillRect(0, 0, pageW, contentTop, false);
GUI.drawHeader(renderer, Rect(0, metrics.topPadding, pageW, metrics.headerHeight), tr(STR_BOOK_INFO));
const bool canScrollDown = scrollOffset + pageH < contentHeight; const bool canScrollDown = scrollOffset + pageH < contentHeight;
const bool canScrollUp = scrollOffset > 0; const bool canScrollUp = scrollOffset > 0;
const char* downHint = canScrollDown ? tr(STR_DIR_DOWN) : ""; const char* downHint = canScrollDown ? tr(STR_DIR_DOWN) : "";