Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b82e044ac3 | ||
|
|
026733a4fe | ||
|
|
57b075ec97 | ||
|
|
648c688642 | ||
|
|
06065dfd8b | ||
|
|
93226c9fbb |
10
README.md
10
README.md
@@ -33,11 +33,13 @@ This project is **not affiliated with Xteink**; it's built as a community projec
|
||||
- [x] Support nested folders
|
||||
- [ ] EPUB picker with cover art
|
||||
- [x] Custom sleep screen
|
||||
- [ ] Cover sleep screen
|
||||
- [x] Cover sleep screen
|
||||
- [x] Wifi book upload
|
||||
- [ ] Wifi OTA updates
|
||||
- [ ] Configurable font, layout, and display options
|
||||
- [ ] Screen rotation
|
||||
- [x] Wifi OTA updates
|
||||
- [x] Configurable font, layout, and display options
|
||||
- [ ] User provided fonts
|
||||
- [ ] Full UTF support
|
||||
- [x] Screen rotation
|
||||
|
||||
See [the user guide](./USER_GUIDE.md) for instructions on operating CrossPoint.
|
||||
|
||||
|
||||
@@ -64,10 +64,30 @@ The Settings screen allows you to configure the device's behavior. There are a f
|
||||
- "Light" - The same default sleep screen, on a white background
|
||||
- "Custom" - Custom images from the SD card, see [3.6 Sleep Screen](#36-sleep-screen) below for more information
|
||||
- "Cover" - The book cover image (Note: this is experimental and may not work as expected)
|
||||
- **Status Bar**: Configure the status bar displayed while reading, options are:
|
||||
- "None" - No status bar
|
||||
- "No Progress" - Show status bar without reading progress
|
||||
- "Full" - Show status bar with reading progress
|
||||
- **Extra Paragraph Spacing**: If enabled, vertical space will be added between paragraphs in the book, if disabled,
|
||||
paragraphs will not have vertical space between them, but will have first word indentation.
|
||||
- **Short Power Button Click**: Whether to trigger the power button on a short press or a long press.
|
||||
- **Front Button Layout**: Swap the order of the bottom edge buttons from Back/Confirm/Left/Right to Left/Right/Back/Confirm.
|
||||
- **Reading Orientation**: Set the screen orientation for reading, options are:
|
||||
- "Portrait" (default) - Standard portrait orientation
|
||||
- "Landscape CW" - Landscape, rotated clockwise
|
||||
- "Inverted" - Portrait, upside down
|
||||
- "Landscape CCW" - Landscape, rotated counter-clockwise
|
||||
- **Front Button Layout**: Configure the order of the bottom edge buttons, options are:
|
||||
- "Bck, Cnfrm, Lft, Rght" (default) - Back, Confirm, Left, Right
|
||||
- "Lft, Rght, Bck, Cnfrm" - Left, Right, Back, Confirm
|
||||
- "Lft, Bck, Cnfrm, Rght" - Left, Back, Confirm, Right
|
||||
- **Side Button Layout**: Swap the order of the volume buttons from Previous/Next to Next/Previous. This change is only in effect when reading.
|
||||
- **Reader Font Family**: Choose the font used for reading, options are:
|
||||
- "Bookerly" (default) - Amazon's reading font
|
||||
- "Noto Sans" - Google's sans-serif font
|
||||
- "Open Dyslexic" - Font designed for readers with dyslexia
|
||||
- **Reader Font Size**: Adjust the text size for reading, options are "Small", "Medium", "Large", or "X Large".
|
||||
- **Reader Line Spacing**: Adjust the spacing between lines, options are "Tight", "Normal", or "Wide".
|
||||
- **Check for updates**: Check for firmware updates over WiFi.
|
||||
|
||||
### 3.6 Sleep Screen
|
||||
|
||||
@@ -124,5 +144,3 @@ Please note that this firmware is currently in active development. The following
|
||||
are planned for future updates:
|
||||
|
||||
* **Images:** Embedded images in e-books will not render.
|
||||
* **Text Formatting:** There are currently no settings to adjust font type, size, line spacing, or margins.
|
||||
* **Rotation**: Different rotation options are not supported.
|
||||
|
||||
@@ -238,6 +238,17 @@ void GfxRenderer::displayBuffer(const EInkDisplay::RefreshMode refreshMode) cons
|
||||
einkDisplay.displayBuffer(refreshMode);
|
||||
}
|
||||
|
||||
std::string GfxRenderer::truncatedText(const int fontId, const char* text, const int maxWidth,
|
||||
const EpdFontStyle style) const {
|
||||
std::string item = text;
|
||||
int itemWidth = getTextWidth(fontId, item.c_str(), style);
|
||||
while (itemWidth > maxWidth && item.length() > 8) {
|
||||
item.replace(item.length() - 5, 5, "...");
|
||||
itemWidth = getTextWidth(fontId, item.c_str(), style);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
// Note: Internal driver treats screen in command orientation; this library exposes a logical orientation
|
||||
int GfxRenderer::getScreenWidth() const {
|
||||
switch (orientation) {
|
||||
|
||||
@@ -75,6 +75,8 @@ class GfxRenderer {
|
||||
int getSpaceWidth(int fontId) const;
|
||||
int getFontAscenderSize(int fontId) const;
|
||||
int getLineHeight(int fontId) const;
|
||||
std::string truncatedText(const int fontId, const char* text, const int maxWidth,
|
||||
const EpdFontStyle style = REGULAR) const;
|
||||
|
||||
// UI Components
|
||||
void drawButtonHints(int fontId, const char* btn1, const char* btn2, const char* btn3, const char* btn4) const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[platformio]
|
||||
crosspoint_version = 0.11.1
|
||||
crosspoint_version = 0.11.2
|
||||
default_envs = default
|
||||
|
||||
[base]
|
||||
@@ -26,6 +26,8 @@ build_flags =
|
||||
-DXML_GE=0
|
||||
-DXML_CONTEXT_BYTES=1024
|
||||
-std=c++2a
|
||||
# Enable UTF-8 long file names in SdFat
|
||||
-DUSE_UTF8_LONG_NAMES=1
|
||||
|
||||
; Board configuration
|
||||
board_build.flash_mode = dio
|
||||
|
||||
@@ -120,7 +120,9 @@ void EpubReaderChapterSelectionActivity::renderScreen() {
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const int pageItems = getPageItems();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Select Chapter", true, BOLD);
|
||||
|
||||
std::string title = renderer.truncatedText(UI_12_FONT_ID, epub->getTitle().c_str(), pageWidth - 40, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, title.c_str(), true, BOLD);
|
||||
|
||||
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
||||
renderer.fillRect(0, 60 + (selectorIndex % pageItems) * 30 - 2, pageWidth - 1, 30);
|
||||
|
||||
@@ -30,11 +30,19 @@ void FileSelectionActivity::taskTrampoline(void* param) {
|
||||
void FileSelectionActivity::loadFiles() {
|
||||
files.clear();
|
||||
selectorIndex = 0;
|
||||
|
||||
auto root = SdMan.open(basepath.c_str());
|
||||
if (!root || !root.isDirectory()) {
|
||||
if (root) root.close();
|
||||
return;
|
||||
}
|
||||
|
||||
root.rewindDirectory();
|
||||
|
||||
char name[128];
|
||||
for (auto file = root.openNextFile(); file; file = root.openNextFile()) {
|
||||
file.getName(name, sizeof(name));
|
||||
if (name[0] == '.') {
|
||||
if (name[0] == '.' || strcmp(name, "System Volume Information") == 0) {
|
||||
file.close();
|
||||
continue;
|
||||
}
|
||||
@@ -180,12 +188,7 @@ void FileSelectionActivity::render() const {
|
||||
const auto pageStartIndex = selectorIndex / PAGE_ITEMS * PAGE_ITEMS;
|
||||
renderer.fillRect(0, 60 + (selectorIndex % PAGE_ITEMS) * 30 - 2, pageWidth - 1, 30);
|
||||
for (int i = pageStartIndex; i < files.size() && i < pageStartIndex + PAGE_ITEMS; i++) {
|
||||
auto item = files[i];
|
||||
int itemWidth = renderer.getTextWidth(UI_10_FONT_ID, item.c_str());
|
||||
while (itemWidth > renderer.getScreenWidth() - 40 && item.length() > 8) {
|
||||
item.replace(item.length() - 5, 5, "...");
|
||||
itemWidth = renderer.getTextWidth(UI_10_FONT_ID, item.c_str());
|
||||
}
|
||||
auto item = renderer.truncatedText(UI_10_FONT_ID, files[i].c_str(), renderer.getScreenWidth() - 40);
|
||||
renderer.drawText(UI_10_FONT_ID, 20, 60 + (i % PAGE_ITEMS) * 30, item.c_str(), i != selectorIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,6 @@ void OtaUpdateActivity::render() {
|
||||
lastUpdaterPercentage = static_cast<int>(updaterProgress * 100);
|
||||
}
|
||||
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
|
||||
renderer.clearScreen();
|
||||
@@ -141,13 +140,8 @@ void OtaUpdateActivity::render() {
|
||||
renderer.drawText(UI_10_FONT_ID, 20, 250, "Current Version: " CROSSPOINT_VERSION);
|
||||
renderer.drawText(UI_10_FONT_ID, 20, 270, ("New Version: " + updater.getLatestVersion()).c_str());
|
||||
|
||||
renderer.drawRect(25, pageHeight - 40, 106, 40);
|
||||
renderer.drawText(UI_10_FONT_ID, 25 + (105 - renderer.getTextWidth(UI_10_FONT_ID, "Cancel")) / 2, pageHeight - 35,
|
||||
"Cancel");
|
||||
|
||||
renderer.drawRect(130, pageHeight - 40, 106, 40);
|
||||
renderer.drawText(UI_10_FONT_ID, 130 + (105 - renderer.getTextWidth(UI_10_FONT_ID, "Update")) / 2, pageHeight - 35,
|
||||
"Update");
|
||||
const auto labels = mappedInput.mapLabels("Cancel", "Update", "", "");
|
||||
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||
renderer.displayBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user