Compare commits

...

38 Commits

Author SHA1 Message Date
Irene Ying
bcaae08ca0
Merge b96e62520b into 78d6e5931c 2026-02-04 09:18:11 +11:00
Jake Kenneally
78d6e5931c
fix: Correct debugging_monitor.py script instructions (#676)
Some checks are pending
CI / build (push) Waiting to run
## Summary

**What is the goal of this PR?**
- Minor correction to the `debugging_monitor.py` script instructions

**What changes are included?**
- `pyserial` should be installed, NOT `serial`, which is a [different
lib](https://pypi.org/project/serial/)
- Added macOS serial port

## Additional Context

- Just a minor docs update. I can confirm the debugging script is
working great on macOS

---

### 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? _**< NO >**_
2026-02-04 00:33:20 +03:00
Luke Stein
dac11c3fdd
fix: Correct instruction text to match actual button text (#672)
## Summary

* Instruction text says "Press OK to scan again" but button label is
actually "Connect" (not OK)
* Corrects instruction text

---

### AI Usage

Did you use AI tools to help write this code? **No**
2026-02-04 00:32:52 +03:00
Irene Ying
b96e62520b
Merge branch 'master' into feature/currentScreenAsLockScreen 2026-02-02 17:52:15 -08:00
Irene Ying
f5390a821e move setting to bottom of file 2026-02-02 17:46:42 -08:00
Irene Ying
052b058643 fix moon icon positioning 2026-01-30 19:15:58 -08:00
Irene Ying
1b607f6de1 fix errors 2026-01-30 18:39:44 -08:00
Irene Ying
3de8472501
Merge branch 'master' into feature/currentScreenAsLockScreen 2026-01-29 22:15:45 -08:00
Irene Ying
a979a83732
Merge branch 'master' into feature/currentScreenAsLockScreen 2026-01-25 10:49:20 -08:00
Irene Ying
12c764d117 fix formatting 2026-01-25 10:43:24 -08:00
Irene Ying
44ddf110b2 Create new Show Sleep Screen setting 2026-01-25 10:40:31 -08:00
Irene Ying
1c3073f472 fix formatting issues 2026-01-25 10:38:08 -08:00
Irene Ying
5ca778fe6a Remove Entering Sleep message 2026-01-25 10:37:25 -08:00
Irene Ying
6791198522 Initial push 2026-01-25 10:35:24 -08:00
Dave Allie
a64a465f5b chore: Cut release 0.15.0 2026-01-25 10:34:49 -08:00
KasyanDiGris
c198100709 fix: OPDS browser OOM (#403)
## Summary

- Rewrite OpdsParser to stream parsing instead of full content
- Fix OOM due to big http xml response

Closes #385 

---

### 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? _**NO**_
2026-01-25 10:34:49 -08:00
Juan Biondi
ac291f2473 docs: Add detailed webserver documentation (#446)
## More detailed documentation

* **What is the goal of this PR?** 
Add more information about the exposed webserver.
* **What changes are included?**
Detailed documentation for the webserver endpoints
(`./docs/webserver-endpoints.md`)
Adding a table of content so it is easier to navigate directly to the
section you're interested on (Almost all `.md` files or at least all
those relevant)

## Additional Context

Not sure if this would get accepted but I thought it might be useful for
those trying to create separate apps that would sync files to the
device. It was at least to me trying to upload files using python as
stated
[here](https://github.com/crosspoint-reader/crosspoint-reader/discussions/434#discussioncomment-15545349)

---

### 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? _**PARTIALLY**_
2026-01-25 10:34:49 -08:00
Logan Garbarini
ab75dd08fb feat: invalidate cache on web uploads and opds downloads and add Clear Cache action (#393)
## Summary

When uploading or downloading an updated ebook from SD/WebUI/OPDS with
same the filename the `.crosspoint` cache is not cleared. This can lead
to issues with the Table of Contents and hangs when switching between
chapters.

I encountered this issue in two places:
- When I need to do further ePub cleaning using Calibre after I load an
ePub and find that some of its formatting should be cleaned up. When I
reprocess the same book and want to place it back in the same location I
need a way to invalidate the cache.
- When syncing RSS feed generated epubs. I generate news ePubs with
filenames like `news-outlet.epub` and so every day when I fetch new news
the crosspoint cache needs to be cleared to load that file.

This change offers the following features:
- On web uploads, if the file already exists, the cache for that file is
cleared
- On OPDS downloads, if the file already exists, the cache for that file
is cleared
- There's now an action for `Clear Cache` in the Settings page which can
clear the cache for all books


Addresses
https://github.com/crosspoint-reader/crosspoint-reader/issues/281

---

### 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? PARTIALLY

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:49 -08:00
Arthur Tazhitdinov
8cbd72bdae fix: hard reset via RTS pin after flashing firmware (#437)
## Summary

* Disables going to sleep after uploading new firmware
* Makes developer experience easier

---

### 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? _**< NO >**_

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-25 10:34:49 -08:00
Jonas Diemer
1e95a353bf fix: Skip negative screen coordinates only after we read the bitmap row. (#431)
Otherwise, we don't crop properly.

Fixes #430 

### AI Usage

Did you use AI tools to help write this code? _**< NO >**_
2026-01-25 10:34:49 -08:00
Jonas Diemer
72c96ef7ff Reclaim space if we don't show battery Percentage (#352)
## Summary

Give space to the chapter title if we don't show battery percentage.

---

### 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? _**NO**_

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:49 -08:00
Dave Allie
a8bfa42f17 feat: Include superscripts and subscripts in fonts (#463)
## Summary

* Include superscripts and subscripts in fonts

## Additional Context

* Original change came from
https://github.com/crosspoint-reader/crosspoint-reader/pull/248

---

### 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? No

---------

Co-authored-by: cor <cor@pruijs.dev>
2026-01-25 10:34:49 -08:00
Kenneth
d2b6506d23 My Library: Tab bar w/ Recent Books + File Browser (#250)
# Summary

This PR introduces a reusable Tab Bar component and combines the Recent
Books and File Browser into a unified tabbed page called "My Library"
accessible from the Home screen.

## Features
### New Tab Bar Component
A flexible, reusable tab bar component added to `ScreenComponents` that
can be used throughout the application.

### New Scroll Indicator Component
A page position indicator for lists that span multiple pages.
**Features:**
- Up/down arrow indicators
- Current page fraction display (e.g., "1/3")
- Only renders when content spans multiple pages

### My Library Activity
A new unified view combining Recent Books and File Browser into a single
tabbed page.

**Tabs:**
- **Recent** - Shows recently opened books
- **Files** - Browse SD card directory structure

**Navigation:**
- Up/Down or Left/Right: Navigate through list items
- Left/Right (when first item selected): Switch between tabs
- Confirm: Open selected book or enter directory
- Back: Go up directory (Files tab) or return home
- Long press Back: Jump to root directory (Files tab)

**UI Elements:**
- Tab bar with selection indicator
- Scroll/page indicator on right side
- Side button hints (up/down arrows)
- Dynamic bottom button labels ("BACK" in subdirectories, "HOME" at
root)

## Tab Bar Usage
The tab bar component is designed to be reusable across different
activities. Here's how to use it:

### Basic Example
```cpp
#include "ScreenComponents.h"
void MyActivity::render() const {
  renderer.clearScreen();
  
  // Define tabs with labels and selection state
  std::vector<TabInfo> tabs = {
    {"Tab One", currentTab == 0},   // Selected when currentTab is 0
    {"Tab Two", currentTab == 1},   // Selected when currentTab is 1
    {"Tab Three", currentTab == 2}  // Selected when currentTab is 2
  };
  
  // Draw tab bar at Y position 15, returns height of the tab bar
  int tabBarHeight = ScreenComponents::drawTabBar(renderer, 15, tabs);
  
  // Position your content below the tab bar
  int contentStartY = 15 + tabBarHeight + 10; // Add some padding
  
  // Draw content based on selected tab
  if (currentTab == 0) {
    renderTabOneContent(contentStartY);
  } else if (currentTab == 1) {
    renderTabTwoContent(contentStartY);
  } else {
    renderTabThreeContent(contentStartY);
  }
  
  renderer.displayBuffer();
}
```
Video Demo: https://share.cleanshot.com/P6NBncFS

<img width="250"
src="https://github.com/user-attachments/assets/07de4418-968e-4a88-9b42-ac5f53d8a832"
/>
<img width="250"
src="https://github.com/user-attachments/assets/e40201ed-dcc8-4568-b008-cd2bf13ebb2a"
/>
<img width="250"
src="https://github.com/user-attachments/assets/73db269f-e629-4696-b8ca-0b8443451a05"
/>

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:49 -08:00
Daniel Poulter
9de96e9812 feat: adding categories to settings screen (#331)
## Summary

* **What is the goal of this PR?** (e.g., Fixes a bug in the user
authentication module, Implements the new feature for
  file uploading.)

As we get more settings, I think it makes sense to do categories for
them. This just allows users to find the settings easier and navigate to
them.

* **What changes are included?**

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks, specific areas to
focus on).

Co-authored-by: dpoulter <daniel@yoco.com>
Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:49 -08:00
GenesiaW
31437e05fb fix: truncate chapter names that are too long (#422)
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)
- Implements a fix to truncate chapter names that exceeds display width
 
* **What changes are included?**
- Implements a fix to truncate chapter names that exceeds display width
## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).
- Prior to the fix, if the book contains multiple chapters with names
longer than the display width, there is a noticeable delay when
scrolling through the list of chapters.

Serial output of the issue:
```
[25673] [ACT] Entering activity: EpubReaderChapterSelection
[25693] [GFX] !! Outside range (485, 65) -> (65, -6)
[25693] [GFX] !! Outside range (486, 65) -> (65, -7)
[25693] [GFX] !! Outside range (487, 65) -> (65, -8)
[25693] [GFX] !! Outside range (488, 65) -> (65, -9)
[25693] [GFX] !! Outside range (485, 66) -> (66, -6)
[25693] [GFX] !! Outside range (486, 66) -> (66, -7)
[25694] [GFX] !! Outside range (487, 66) -> (66, -8)
[25694] [GFX] !! Outside range (484, 67) -> (67, -5)
[25694] [GFX] !! Outside range (485, 67) -> (67, -6)
[25694] [GFX] !! Outside range (486, 67) -> (67, -7)
[25694] [GFX] !! Outside range (483, 68) -> (68, -4)
[25694] [GFX] !! Outside range (484, 68) -> (68, -5)
[25694] [GFX] !! Outside range (485, 68) -> (68, -6)
``` 


---

### 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? _**NO**_

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:49 -08:00
Arthur Tazhitdinov
170e16033e feat: dict based Hyphenation (#305)
* Adds (optional) Hyphenation for English, French, German, Russian
languages

* Included hyphenation dictionaries add approximately 280kb to the flash
usage (German alone takes 200kb)
* Trie encoded dictionaries are adopted from hypher project
(https://github.com/typst/hypher)
* Soft hyphens (and other explicit hyphens) take precedence over
dict-based hyphenation. Overall, the hyphenation rules are quite
aggressive, as I believe it makes more sense on our smaller screen.

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:34:46 -08:00
Maeve Andrews
05e5db76f6 fix: render U+FFFD replacement character instead of ? (#366)
The current behavior of rendering `?` for an unknown Unicode character
can be hard to distinguish from a typo. Use the standard Unicode
"replacement character" instead, that's what it's designed for:

https://en.wikipedia.org/wiki/Specials_(Unicode_block)

I'm making this PR as a draft because I'm not sure I did everything that
was needed to change the character set covered by the fonts. Running
that script is in its own commit. If this is proper, I'll rebase/squash
into one commit and un-draft.

Co-authored-by: Maeve Andrews <maeve@git.mail.maeveandrews.com>
2026-01-25 10:32:18 -08:00
Luke Stein
bf38e2c3dc fix: Invert colors on home screen cover overlay when recent book is selected (#390)
## Summary

* Fixes #388 

## Additional Context

* Tested on my own device
  * See images at #388 for what home screen looked like before.
* With this PR the home screen shows the following (selected and
unselected recent book × cover image rendered or not)


![Picsew_20260115153419](https://github.com/user-attachments/assets/44193f9d-76b7-4c77-b890-72b0dbae01c4)


---

### 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**

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-01-25 10:32:18 -08:00
Justin Mitchell
511fa485be Adds KOReader Sync support (#232)
## Summary

- Adds KOReader progress sync integration, allowing CrossPoint to sync
reading positions with other
KOReader-compatible devices
- Stores credentials securely with XOR obfuscation
- Uses KOReader's partial MD5 document hashing for cross-device book
matching
  - Syncs position via percentage with estimated XPath for compatibility

# Features
- Settings: KOReader Username, Password, and Authenticate options
- Sync from chapters menu: "Sync Progress" option appears when
credentials are configured
- Bidirectional sync: Can apply remote progress or upload local progress

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
2026-01-25 10:32:18 -08:00
Nathan James
a5ade3fe81 feat: Change keyboard "caps" to "shift" & Wrap Keyboard (#377)
## Summary

* This PR solves issue
https://github.com/crosspoint-reader/crosspoint-reader/issues/357 in the
first commit
* I then added an additional commit which means when you reach the end
of the keyboard, if you go 'beyond', you wrap back to the other side.
* This replaces existing behaviour, so if you would rather this be
removed, let me know and I'll just do the `caps` -> `shift` change

## Additional Context

### Screenshots for the new shift display

I thought it might not fit and need column size changes, but ended up
fitting fine, see screenshots showing this below:

<img width="573" height="366" alt="image"
src="https://github.com/user-attachments/assets/b8f6a4ec-94f5-4f5e-b9a6-06cc5f250ddb"
/>

<img width="570" height="308" alt="image"
src="https://github.com/user-attachments/assets/7d775518-4784-4120-a20a-a9dc67af8565"
/>


### Gif showing the wrap-around of the text



![IMG_7648](https://github.com/user-attachments/assets/7eec9066-e1cc-49a1-8b6b-a61556038d31)

---

### AI Usage

Did you use AI tools to help write this code? **PARTIALLY** - used to
double check the text wrapping had no edge-cases. (It did also suggest
rewriting the function, but I decided that was too big of a change for a
working part of the codebase, for now!)
2026-01-25 10:32:18 -08:00
Eunchurn Park
73fbf2a812 fix: XTC 1-bit thumb BMP polarity inversion (#373)
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)
* **What changes are included?**

- Fix inverted colors in Continue Reading cover image for 1-bit XTC
files

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

- Fix `grayValue = pixelBit ? 0 : 255` → `grayValue = pixelBit ? 255 :
0` in `lib/Xtc/Xtc.cpp`
- The thumb BMP generation had inverted polarity compared to cover BMP
generation
- bit=0 should be black, bit=1 should be white (matching the BMP palette
order)
- Update misleading comment about XTC polarity

---

### 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? _**PARTIALLY**_
2026-01-25 10:32:18 -08:00
Irene Ying
91bcafebb9 Change sleep message to Moon icon 2026-01-25 10:22:11 -08:00
Irene Ying
cecf5a3fa7 Create new Show Sleep Screen setting 2026-01-25 00:25:10 -08:00
Irene Ying
7638680ee5 Move Last Screen option to end of list 2026-01-21 12:59:51 -08:00
Irene Ying
2a65d10925 remove placeholder 2026-01-18 10:26:02 -08:00
Irene Ying
0e6d7dd140 fix formatting issues 2026-01-17 14:23:18 -08:00
Irene Ying
0b3e8f1102 Remove Entering Sleep message 2026-01-17 14:05:46 -08:00
Irene Ying
68854812e9 Initial push 2026-01-17 13:30:59 -08:00
9 changed files with 67 additions and 13 deletions

View File

@ -102,13 +102,18 @@ After flashing the new features, its recommended to capture detailed logs fro
First, make sure all required Python packages are installed:
```python
python3 -m pip install serial colorama matplotlib
python3 -m pip install pyserial colorama matplotlib
```
after that run the script:
```sh
# For Linux
# This was tested on Debian and should work on most Linux systems.
python3 scripts/debugging_monitor.py
# For macOS
python3 scripts/debugging_monitor.py /dev/cu.usbmodem2101
```
This was tested on Debian and should work on most Linux systems. Minor adjustments may be required for Windows or macOS.
Minor adjustments may be required for Windows.
## Internals

View File

@ -22,7 +22,7 @@ void readAndValidate(FsFile& file, uint8_t& member, const uint8_t maxValue) {
namespace {
constexpr uint8_t SETTINGS_FILE_VERSION = 1;
// Increment this when adding new persisted settings fields
constexpr uint8_t SETTINGS_COUNT = 23;
constexpr uint8_t SETTINGS_COUNT = 24;
constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
} // namespace
@ -38,6 +38,7 @@ bool CrossPointSettings::saveToFile() const {
serialization::writePod(outputFile, SETTINGS_FILE_VERSION);
serialization::writePod(outputFile, SETTINGS_COUNT);
serialization::writePod(outputFile, sleepScreen);
serialization::writePod(outputFile, showSleepScreen);
serialization::writePod(outputFile, extraParagraphSpacing);
serialization::writePod(outputFile, shortPwrBtn);
serialization::writePod(outputFile, statusBar);
@ -148,6 +149,8 @@ bool CrossPointSettings::loadFromFile() {
if (++settingsRead >= fileSettingsCount) break;
readAndValidate(inputFile, sleepScreenCoverFilter, SLEEP_SCREEN_COVER_FILTER_COUNT);
if (++settingsRead >= fileSettingsCount) break;
serialization::readPod(inputFile, showSleepScreen);
if (++settingsRead >= fileSettingsCount) break;
// New fields added at end for backward compatibility
} while (false);

View File

@ -16,6 +16,7 @@ class CrossPointSettings {
CrossPointSettings& operator=(const CrossPointSettings&) = delete;
enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4, SLEEP_SCREEN_MODE_COUNT };
enum SHOW_SLEEP_SCREEN { ALWAYS = 0, EXCEPT_TIMEOUT = 1, NEVER = 2 };
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, SLEEP_SCREEN_COVER_MODE_COUNT };
enum SLEEP_SCREEN_COVER_FILTER {
NO_FILTER = 0,
@ -99,6 +100,8 @@ class CrossPointSettings {
// Sleep screen settings
uint8_t sleepScreen = DARK;
// Show sleep screen settings
uint8_t showSleepScreen = ALWAYS;
// Sleep screen cover mode settings
uint8_t sleepScreenCoverMode = FIT;
// Sleep screen cover filter

View File

@ -11,12 +11,20 @@
#include "ScreenComponents.h"
#include "fontIds.h"
#include "images/CrossLarge.h"
#include "images/MoonIcon.h"
#include "util/StringUtils.h"
void SleepActivity::onEnter() {
Activity::onEnter();
const bool SHOW_SLEEP_SCREEN =
SETTINGS.showSleepScreen == CrossPointSettings::SHOW_SLEEP_SCREEN::ALWAYS ||
(!fromTimeout && SETTINGS.showSleepScreen == CrossPointSettings::SHOW_SLEEP_SCREEN::EXCEPT_TIMEOUT);
ScreenComponents::drawPopup(renderer, "Entering Sleep...");
Activity::onEnter();
if (SHOW_SLEEP_SCREEN) {
ScreenComponents::drawPopup(renderer, "Entering Sleep...");
} else {
return renderLastScreenSleepScreen();
}
if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) {
return renderBlankSleepScreen();
@ -266,6 +274,13 @@ void SleepActivity::renderCoverSleepScreen() const {
renderDefaultSleepScreen();
}
void SleepActivity::renderLastScreenSleepScreen() const {
const auto pageHeight = renderer.getScreenHeight();
renderer.drawImage(MoonIcon, 0, pageHeight - 48, 48, 48);
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
}
void SleepActivity::renderBlankSleepScreen() const {
renderer.clearScreen();
renderer.displayBuffer(HalDisplay::HALF_REFRESH);

View File

@ -5,8 +5,8 @@ class Bitmap;
class SleepActivity final : public Activity {
public:
explicit SleepActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
: Activity("Sleep", renderer, mappedInput) {}
explicit SleepActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, bool fromTimeout)
: Activity("Sleep", renderer, mappedInput), fromTimeout(fromTimeout) {}
void onEnter() override;
private:
@ -14,5 +14,8 @@ class SleepActivity final : public Activity {
void renderCustomSleepScreen() const;
void renderCoverSleepScreen() const;
void renderBitmapSleepScreen(const Bitmap& bitmap) const;
void renderLastScreenSleepScreen() const;
void renderBlankSleepScreen() const;
bool fromTimeout = false;
};

View File

@ -520,7 +520,7 @@ void WifiSelectionActivity::renderNetworkList() const {
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
const auto top = (pageHeight - height) / 2;
renderer.drawCenteredText(UI_10_FONT_ID, top, "No networks found");
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press OK to scan again");
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press Connect to scan again");
} else {
// Calculate how many networks we can display
constexpr int startY = 60;

View File

@ -11,10 +11,11 @@
const char* SettingsActivity::categoryNames[categoryCount] = {"Display", "Reader", "Controls", "System"};
namespace {
constexpr int displaySettingsCount = 6;
constexpr int displaySettingsCount = 7;
const SettingInfo displaySettings[displaySettingsCount] = {
// Should match with SLEEP_SCREEN_MODE
SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}),
SettingInfo::Enum("Show Sleep Screen", &CrossPointSettings::showSleepScreen, {"Always", "Except Timeout", "Never"}),
SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}),
SettingInfo::Enum("Sleep Screen Cover Filter", &CrossPointSettings::sleepScreenCoverFilter,
{"None", "Contrast", "Inverted"}),

24
src/images/MoonIcon.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include <cstdint>
// Image dimensions: 48x48
#define MOONICON_WIDTH 48
#define MOONICON_HEIGHT 48
static const uint8_t MoonIcon[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF,
0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xF0, 0xFF, 0xFF,
0xFF, 0xC0, 0x1F, 0xF0, 0x3F, 0xFF, 0xFF, 0x00, 0x1F, 0xF8, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFC, 0x07, 0xFF,
0xFF, 0xF9, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xF9, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xF9, 0xFF, 0xFE, 0x01, 0xFF,
0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0xFF,
0xFF, 0xC7, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xC3, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC3, 0xFF, 0xF0, 0x00, 0x7F,
0xFF, 0xC1, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x7F, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF,
0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF,
0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF,
0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

View File

@ -191,9 +191,9 @@ void waitForPowerRelease() {
}
// Enter deep sleep mode
void enterDeepSleep() {
void enterDeepSleep(bool fromTimeout) {
exitActivity();
enterNewActivity(new SleepActivity(renderer, mappedInputManager));
enterNewActivity(new SleepActivity(renderer, mappedInputManager, fromTimeout));
display.deepSleep();
Serial.printf("[%lu] [ ] Power button press calibration value: %lu ms\n", millis(), t2 - t1);
@ -359,13 +359,13 @@ void loop() {
const unsigned long sleepTimeoutMs = SETTINGS.getSleepTimeoutMs();
if (millis() - lastActivityTime >= sleepTimeoutMs) {
Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), sleepTimeoutMs);
enterDeepSleep();
enterDeepSleep(true);
// This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start
return;
}
if (gpio.isPressed(HalGPIO::BTN_POWER) && gpio.getHeldTime() > SETTINGS.getPowerButtonDuration()) {
enterDeepSleep();
enterDeepSleep(false);
// This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start
return;
}