Skip to content

Grid Browser with file thumbnails#108

Closed
CaptainFrito wants to merge 4 commits intocrosspoint-reader:masterfrom
CaptainFrito:feature/gridView
Closed

Grid Browser with file thumbnails#108
CaptainFrito wants to merge 4 commits intocrosspoint-reader:masterfrom
CaptainFrito:feature/gridView

Conversation

@CaptainFrito
Copy link
Contributor

IMG_7326 Medium
IMG_7327 Medium

  • UI design by Discord user gan_shu
  • Drop in replacement for the existing FileSelectionActivity, with the same features and key bindings
  • Currently only renders files with extension .thumb.bmp - meant as a proof of concept to decide if we want to pursue this further considering the limitations

@CaptainFrito CaptainFrito force-pushed the feature/gridView branch 2 times, most recently from 8830e45 to 228d615 Compare December 27, 2025 02:10
@CaptainFrito
Copy link
Contributor Author

PR updated and ready for review/merge

IMG_7398 Large

  • Works just like FileSelectionActivity, with the same features and key bindings. "UI Theme" setting to switch between the two
  • Lazily extracts cover art from epubs while browsing, converts them to dithered 1-bit BMP of size 90x120px
  • New GfxRenderer methods for drawing greyscale rects (using dithering), rounded corners, centered multiline text box

Copy link
Member

@daveallie daveallie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall some comments on the code, but probably more critically is that when entering a directory, I don't seem to get any of the laziness you were mentioning in the PR body, the whole device seems to lock up as the thumbnails are rendered. This won't be mergable if we can't fix this / do thumbnail generation at another point, waiting for 9 books to generate thumbnails is a bit slow

renderer.drawRoundedRect(GRID_OFFSET_LEFT + tileIndex % 3 * TILE_W, GRID_OFFSET_TOP + tileIndex / 3 * TILE_H, TILE_W, TILE_H, 2, 5, black);
}

void GridBrowserActivity::update(bool render) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This parameter is unused

Comment on lines +305 to +308
if (previousSelectorIndex >= 0) {
drawSelectionRectangle(previousSelectorIndex, false);
}
drawSelectionRectangle(selectorIndex, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double tapping a button to go from selection n to n+2 can mean that by the time this runs previousSelectorIndex can be n+1 and selectorIndex can be n+2. This results in an issue where the item at n still has a selector indicator around it and it's not cleared until you go back over it. To fix this, you can wrap any code in loop which adjusts variables used by the rendering loop e.g. selectorIndex and previousSelectorIndex in the renderingMutex.

For this same reason, navigating too quickly into a folder after pressing left and right result in the screen not updating correctly.

Comment on lines +277 to +288
if (!file.thumbPath.empty()) {
Serial.printf("Rendering file thumb: %s\n", file.thumbPath.c_str());
File bmpFile = SD.open(file.thumbPath.c_str());
if (bmpFile) {
Bitmap bitmap(bmpFile);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
constexpr int thumbOffsetX = (TILE_W - THUMB_W) / 2;
constexpr int thumbOffsetY = (TILE_H - TILE_TEXT_H - THUMB_H) / 2;
renderer.drawBitmap(bitmap, tileX + thumbOffsetX, tileY + thumbOffsetY, THUMB_W, THUMB_H);
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have a fallback icon for books where the cover can't be generated

Comment on lines +327 to +332
if (bitsPerPixel == 8) {
return (width + 3) / 4 * 4; // 8 bits per pixel, padded
} else if (bitsPerPixel == 2) {
return (width * 2 + 31) / 32 * 4; // 2 bits per pixel, round up
}
return (width + 31) / 32 * 4; // 1 bit per pixel, round up
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can this be simplified to return (width * bitsPerPixel + 31) / 32 * 4;?

@icannotttt
Copy link

icannotttt commented Jan 2, 2026

I have a suggest. If it's difficult to render 3*3 images, how about a 2*2 one? We could use it to display the 4 most recently read books, which should work much better? Maybe we don't need to render all book.

@stiivgiaco
Copy link

will this be the only option on how to display the library or will it be based on user preference; ex list or grid?

@daveallie
Copy link
Member

will this be the only option on how to display the library or will it be based on user preference; ex list or grid?

The current implementation adds a setting to toggle between the existing setup (list) and this one (grid).

@CaptainFrito
Copy link
Contributor Author

Closing this PR now, see #528 for a more up to date implementation of UI themes. The thumbnail grid can be revisited later on.

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.

4 participants