A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: continue reading card classic theme (#990)

## Summary

* **What is the goal of this PR?**
* **What changes are included?**

- Adapt card width to cover image aspect ratio in Classic theme
- Increase homeTopPadding from 20px to 40px to avoid overlap with
battery icon
- Card width now calculated from BMP dimensions instead of fixed 240px
- Maximum card width limited to 90% of screen width
- Falls back to original behavior (half screen width) when no cover
available

## Additional Context

* Solve conflicts in PR #683

Before:
<img width="1052" height="1014" alt="image"
src="https://github.com/user-attachments/assets/6c857913-d697-4e9e-9695-443c0a4c0804"
/>

PR:

![Screenshot_2026-02-19-14-22-36-68_99c04817c0de5652397fc8b56c3b3817](https://github.com/user-attachments/assets/81505728-d42e-41bd-bd77-44848e05b1eb)


---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES >**_

authored by

pablohc and committed by
GitHub
c9faf2a8 356fe9a3

+53 -28
+52 -27
src/components/themes/BaseTheme.cpp
··· 341 341 void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std::vector<RecentBook>& recentBooks, 342 342 const int selectorIndex, bool& coverRendered, bool& coverBufferStored, 343 343 bool& bufferRestored, std::function<bool()> storeCoverBuffer) const { 344 + const bool hasContinueReading = !recentBooks.empty(); 345 + const bool bookSelected = hasContinueReading && selectorIndex == 0; 346 + 344 347 // --- Top "book" card for the current title (selectorIndex == 0) --- 345 - const int bookWidth = rect.width / 2; 346 - const int bookHeight = rect.height; 347 - const int bookX = (rect.width - bookWidth) / 2; 348 + // When there's no cover image, use fixed size (half screen) 349 + // When there's cover image, adapt width to image aspect ratio, keep height fixed at 400px 350 + const int baseHeight = rect.height; // Fixed height (400px) 351 + 352 + int bookWidth, bookX; 353 + bool hasCoverImage = false; 354 + 355 + if (hasContinueReading && !recentBooks[0].coverBmpPath.empty()) { 356 + // Try to get actual image dimensions from BMP header 357 + const std::string coverBmpPath = 358 + UITheme::getCoverThumbPath(recentBooks[0].coverBmpPath, BaseMetrics::values.homeCoverHeight); 359 + 360 + FsFile file; 361 + if (Storage.openFileForRead("HOME", coverBmpPath, file)) { 362 + Bitmap bitmap(file); 363 + if (bitmap.parseHeaders() == BmpReaderError::Ok) { 364 + hasCoverImage = true; 365 + const int imgWidth = bitmap.getWidth(); 366 + const int imgHeight = bitmap.getHeight(); 367 + 368 + // Calculate width based on aspect ratio, maintaining baseHeight 369 + if (imgWidth > 0 && imgHeight > 0) { 370 + const float aspectRatio = static_cast<float>(imgWidth) / static_cast<float>(imgHeight); 371 + bookWidth = static_cast<int>(baseHeight * aspectRatio); 372 + 373 + // Ensure width doesn't exceed reasonable limits (max 90% of screen width) 374 + const int maxWidth = static_cast<int>(rect.width * 0.9f); 375 + if (bookWidth > maxWidth) { 376 + bookWidth = maxWidth; 377 + } 378 + } else { 379 + bookWidth = rect.width / 2; // Fallback 380 + } 381 + } 382 + file.close(); 383 + } 384 + } 385 + 386 + if (!hasCoverImage) { 387 + // No cover: use half screen size 388 + bookWidth = rect.width / 2; 389 + } 390 + 391 + bookX = rect.x + (rect.width - bookWidth) / 2; 348 392 const int bookY = rect.y; 349 - const bool hasContinueReading = !recentBooks.empty(); 350 - const bool bookSelected = hasContinueReading && selectorIndex == 0; 393 + const int bookHeight = baseHeight; 351 394 352 395 // Bookmark dimensions (used in multiple places) 353 396 const int bookmarkWidth = bookWidth / 8; ··· 370 413 Bitmap bitmap(file); 371 414 if (bitmap.parseHeaders() == BmpReaderError::Ok) { 372 415 LOG_DBG("THEME", "Rendering bmp"); 373 - // Calculate position to center image within the book card 374 - int coverX, coverY; 375 416 376 - if (bitmap.getWidth() > bookWidth || bitmap.getHeight() > bookHeight) { 377 - const float imgRatio = static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight()); 378 - const float boxRatio = static_cast<float>(bookWidth) / static_cast<float>(bookHeight); 379 - 380 - if (imgRatio > boxRatio) { 381 - coverX = bookX; 382 - coverY = bookY + (bookHeight - static_cast<int>(bookWidth / imgRatio)) / 2; 383 - } else { 384 - coverX = bookX + (bookWidth - static_cast<int>(bookHeight * imgRatio)) / 2; 385 - coverY = bookY; 386 - } 387 - } else { 388 - coverX = bookX + (bookWidth - bitmap.getWidth()) / 2; 389 - coverY = bookY + (bookHeight - bitmap.getHeight()) / 2; 390 - } 391 - 392 - // Draw the cover image centered within the book card 393 - renderer.drawBitmap(bitmap, coverX, coverY, bookWidth, bookHeight); 417 + // Draw the cover image (bookWidth and bookHeight already match image aspect ratio) 418 + renderer.drawBitmap(bitmap, bookX, bookY, bookWidth, bookHeight); 394 419 395 420 // Draw border around the card 396 421 renderer.drawRect(bookX, bookY, bookWidth, bookHeight); ··· 573 598 574 599 const int boxWidth = maxTextWidth + boxPadding * 2; 575 600 const int boxHeight = totalTextHeight + boxPadding * 2; 576 - const int boxX = (rect.width - boxWidth) / 2; 601 + const int boxX = rect.x + (rect.width - boxWidth) / 2; 577 602 const int boxY = titleYStart - boxPadding; 578 603 579 604 // Draw box (inverted when selected: black box instead of white) ··· 616 641 constexpr int continuePadding = 6; 617 642 const int continueBoxWidth = continueTextWidth + continuePadding * 2; 618 643 const int continueBoxHeight = renderer.getLineHeight(UI_10_FONT_ID) + continuePadding; 619 - const int continueBoxX = (rect.width - continueBoxWidth) / 2; 644 + const int continueBoxX = rect.x + (rect.width - continueBoxWidth) / 2; 620 645 const int continueBoxY = continueY - continuePadding / 2; 621 646 renderer.fillRect(continueBoxX, continueBoxY, continueBoxWidth, continueBoxHeight, bookSelected); 622 647 renderer.drawRect(continueBoxX, continueBoxY, continueBoxWidth, continueBoxHeight, !bookSelected);
+1 -1
src/components/themes/BaseTheme.h
··· 82 82 .tabBarHeight = 50, 83 83 .scrollBarWidth = 4, 84 84 .scrollBarRightOffset = 5, 85 - .homeTopPadding = 20, 85 + .homeTopPadding = 40, 86 86 .homeCoverHeight = 400, 87 87 .homeCoverTileHeight = 400, 88 88 .homeRecentBooksCount = 1,