feat: Take screenshots (#759)

## Summary

* **What is the goal of this PR?** Implements a take-screenshot feature
* **What changes are included?**

- Quick press Power button and Down button at the same time to take a
screenshot
- Screenshots are saved in `screenshots` folder

## Additional Context

- Currently it does not use the device orientation.

---

Example screenshots:


![screenshot-6771.bmp](https://github.com/user-attachments/files/25157071/screenshot-6771.bmp)

[screenshot-6771.bmp](https://github.com/user-attachments/files/25157071/screenshot-6771.bmp)


![screenshot-14158.bmp](https://github.com/user-attachments/files/25157073/screenshot-14158.bmp)

[screenshot-14158.bmp](https://github.com/user-attachments/files/25157073/screenshot-14158.bmp)


### AI Usage

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

---------

Co-authored-by: Eliz Kilic <elizk@google.com>
Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Arthur Tazhitdinov <lisnake@gmail.com>
This commit is contained in:
Eliz
2026-02-22 04:22:32 +00:00
committed by GitHub
parent 5f5561b684
commit c1fad16e10
19 changed files with 264 additions and 10 deletions

View File

@@ -17,6 +17,7 @@
#include "RecentBooksStore.h"
#include "components/UITheme.h"
#include "fontIds.h"
#include "util/ScreenshotUtil.h"
namespace {
// pagesPerRefresh now comes from SETTINGS.getRefreshFrequency()
@@ -431,6 +432,15 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction
pendingGoHome = true;
break;
}
case EpubReaderMenuActivity::MenuAction::SCREENSHOT: {
{
RenderLock lock(*this);
pendingScreenshot = true;
}
exitActivity();
requestUpdate();
break;
}
case EpubReaderMenuActivity::MenuAction::SYNC: {
if (KOREADER_STORE.hasCredentials()) {
const int currentPage = section ? section->currentPage : 0;
@@ -616,6 +626,11 @@ void EpubReaderActivity::render(Activity::RenderLock&& lock) {
renderer.clearFontCache();
}
saveProgress(currentSpineIndex, section->currentPage, section->pageCount);
if (pendingScreenshot) {
pendingScreenshot = false;
ScreenshotUtil::takeScreenshot(renderer);
}
}
void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) {

View File

@@ -20,7 +20,8 @@ class EpubReaderActivity final : public ActivityWithSubactivity {
float pendingSpineProgress = 0.0f;
bool pendingSubactivityExit = false; // Defer subactivity exit to avoid use-after-free
bool pendingGoHome = false; // Defer go home to avoid race condition with display task
bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit
bool pendingScreenshot = false;
bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit
const std::function<void()> onGoBack;
const std::function<void()> onGoHome;

View File

@@ -12,7 +12,7 @@
class EpubReaderMenuActivity final : public ActivityWithSubactivity {
public:
// Menu actions available from the reader menu.
enum class MenuAction { SELECT_CHAPTER, GO_TO_PERCENT, ROTATE_SCREEN, GO_HOME, SYNC, DELETE_CACHE };
enum class MenuAction { SELECT_CHAPTER, GO_TO_PERCENT, ROTATE_SCREEN, SCREENSHOT, GO_HOME, SYNC, DELETE_CACHE };
explicit EpubReaderMenuActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::string& title,
const int currentPage, const int totalPages, const int bookProgressPercent,
@@ -39,13 +39,11 @@ class EpubReaderMenuActivity final : public ActivityWithSubactivity {
};
// Fixed menu layout (order matters for up/down navigation).
const std::vector<MenuItem> menuItems = {{MenuAction::SELECT_CHAPTER, StrId::STR_SELECT_CHAPTER},
{MenuAction::ROTATE_SCREEN, StrId::STR_ORIENTATION},
{MenuAction::GO_TO_PERCENT, StrId::STR_GO_TO_PERCENT},
{MenuAction::GO_HOME, StrId::STR_GO_HOME_BUTTON},
{MenuAction::SYNC, StrId::STR_SYNC_PROGRESS},
{MenuAction::DELETE_CACHE, StrId::STR_DELETE_CACHE}};
const std::vector<MenuItem> menuItems = {
{MenuAction::SELECT_CHAPTER, StrId::STR_SELECT_CHAPTER}, {MenuAction::ROTATE_SCREEN, StrId::STR_ORIENTATION},
{MenuAction::GO_TO_PERCENT, StrId::STR_GO_TO_PERCENT}, {MenuAction::SCREENSHOT, StrId::STR_SCREENSHOT_BUTTON},
{MenuAction::GO_HOME, StrId::STR_GO_HOME_BUTTON}, {MenuAction::SYNC, StrId::STR_SYNC_PROGRESS},
{MenuAction::DELETE_CACHE, StrId::STR_DELETE_CACHE}};
int selectedIndex = 0;
ButtonNavigator buttonNavigator;