feat: Lyra screens#732
Conversation
4b6845d to
2c4621f
Compare
|
Looking good. I notice that on the Wifi selection screen, the width of the black bar for the selected network varies between encrypted and unencrypted networks. Also, the |
Ah yes this is not great. The mockups don't actually have the black highlight for this screen, it looks better without it. I just didn't want to add another parameter to the drawList method which already has enough as it is, but it looks like we're gonna have to! |
2f6c876 to
aa90516
Compare
aa90516 to
5370e6f
Compare
cc42ec7 to
5003cee
Compare
|
The home screen is updated with the 1-cover, 1-column layout that won the popular vote! I moved the 3-cover layout to a separate theme file, Lyra3CoversTheme, to keep that as an additional theme option, but since it's not a very popular choice we can remove it if you'd like. Edit: The extra theme with 3 covers is now called "Lyra Extended". Again we can keep it or not. |
92a27a0 to
51151e1
Compare
a2ffaa7 to
ffec742
Compare
|
I really like what you are doing, kudos. |
Thanks! Good catch, I didn’t realize we could change the orientation in the menus now. Time to work on this. |
Wait no we still can’t rotate the menus, other than the in reader menu. What did you mean by the WifiSelectionActivity is a non working one? |
ffec742 to
7545475
Compare
7545475 to
17ebbc6
Compare
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new UI theme option LYRA_3_COVERS with full theme implementation and wiring; extends BaseTheme/LyraTheme drawing APIs and UI metrics; refactors many activities to use metric-driven GUI helpers; updates translations and I18n keys; small API/field type adjustments (int → size_t) and renderer geometry fixes. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Comment |
Open the ReaderMenu (orientation aware) choose KoSync (another faulty layout), that will cause the wifi selector to appear |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/UITheme.cpp (1)
28-46:⚠️ Potential issue | 🟡 MinorPotential memory leak in
setTheme.When
setThemeis called multiple times (e.g., viareload()), the previouscurrentThemepointer is overwritten without being deleted, causing a memory leak. Consider deleting the old theme before allocating a new one.🛠️ Proposed fix
void UITheme::setTheme(CrossPointSettings::UI_THEME type) { + delete currentTheme; + currentTheme = nullptr; + switch (type) { case CrossPointSettings::UI_THEME::CLASSIC:src/components/themes/lyra/LyraTheme.cpp (1)
384-390:⚠️ Potential issue | 🔴 CriticalCritical: Dangling pointer causes undefined behavior.
buttonLabel(i)returns astd::stringby value. Calling.c_str()on this temporary and storing the result inlabelcreates a dangling pointer because the temporary string is destroyed at the semicolon. Whenlabelis used indrawTextat line 390, it reads freed memory.This is inconsistent with the safe pattern used elsewhere in this file (e.g., lines 196-198 in
drawList), where the string is stored in a variable first.🐛 Proposed fix
- const char* label = buttonLabel(i).c_str(); const int textX = tileRect.x + 16; const int lineHeight = renderer.getLineHeight(UI_12_FONT_ID); const int textY = tileRect.y + (LyraMetrics::values.menuRowHeight - lineHeight) / 2; // Invert text when the tile is selected, to contrast with the filled background - renderer.drawText(UI_12_FONT_ID, textX, textY, label, true); + renderer.drawText(UI_12_FONT_ID, textX, textY, buttonLabel(i).c_str(), true);Or store the string in a variable to keep it alive:
- const char* label = buttonLabel(i).c_str(); + const std::string label = buttonLabel(i); const int textX = tileRect.x + 16; const int lineHeight = renderer.getLineHeight(UI_12_FONT_ID); const int textY = tileRect.y + (LyraMetrics::values.menuRowHeight - lineHeight) / 2; // Invert text when the tile is selected, to contrast with the filled background - renderer.drawText(UI_12_FONT_ID, textX, textY, label, true); + renderer.drawText(UI_12_FONT_ID, textX, textY, label.c_str(), true);
🤖 Fix all issues with AI agents
In `@src/activities/network/CrossPointWebServerActivity.cpp`:
- Around line 446-448: The SSID is concatenated directly into the Wi‑Fi QR
payload (wifiConfig) without escaping reserved ZXing characters; update
CrossPointWebServerActivity.cpp to sanitize connectedSSID before building
wifiConfig by replacing/escaping any occurrences of backslash, semicolon, comma,
or colon (e.g. convert '\' to '\\', ';' to '\;', ',' to '\,', ':' to '\:');
implement a small helper (e.g. escapeWifiSSID or sanitizeSSID) and use that
escaped string when constructing wifiConfig and passing to drawQRCode to ensure
the QR payload remains valid for arbitrary SSIDs.
In `@src/components/themes/BaseTheme.cpp`:
- Line 20: The hardcoded constant subtitleY (constexpr int subtitleY = 738)
assumes a fixed screen size; remove or stop using this global constant and
compute subtitleY dynamically inside drawHeader (or wherever header rendering
occurs) using the current header rectangle and font metrics — e.g., calculate
subtitleY = rect.y + rect.height - renderer.getLineHeight(SMALL_FONT_ID) - 5 (or
similar) so the subtitle is always positioned relative to rect and the
renderer’s line height; update any references to subtitleY to use this computed
local value and delete the hardcoded constexpr to avoid conflicting layout on
different screen sizes.
🧹 Nitpick comments (16)
src/components/UITheme.h (1)
9-10: Unused forward declaration.
MappedInputManageris forward-declared but not referenced anywhere in this header. If it's not needed, consider removing it.🧹 Proposed removal
-class MappedInputManager; - class UITheme {src/CrossPointSettings.h (1)
120-120: Consider adding a count sentinel for consistency.Other enums in this file include a
_COUNTsentinel value (e.g.,SLEEP_SCREEN_MODE_COUNT,ORIENTATION_COUNT). AddingUI_THEME_COUNTwould maintain consistency and simplify bounds checking.♻️ Proposed change
- enum UI_THEME { CLASSIC = 0, LYRA = 1, LYRA_3_COVERS = 2 }; + enum UI_THEME { CLASSIC = 0, LYRA = 1, LYRA_3_COVERS = 2, UI_THEME_COUNT };src/activities/settings/ClearCacheActivity.cpp (1)
78-82: Minor: "Clearing cache..." no longer bold.The removal of the bold styling and the
trueparameter for text wrapping from the "Clearing cache..." message appears intentional but is a subtle UX change. Confirm this is the desired behavior, as other status messages in this file (e.g., "Cache Cleared" at line 85) retain bold styling.src/components/UITheme.cpp (2)
7-7: Unused include.
MappedInputManager.happears to be included but not used in this file. Consider removing it if not needed.
12-14: Remove unused constantSKIP_PAGE_MS.The constant is defined but never used anywhere in the codebase. Remove it to reduce code clutter.
src/activities/network/WifiSelectionActivity.cpp (1)
593-595: Magic number in help text positioning.The
-15offset in the Y coordinate calculation (pageHeight - metrics.buttonHintsHeight - metrics.contentSidePadding - 15) appears to be a hardcoded adjustment. Consider extracting this as a named constant or using a metric value for consistency with the theme system.src/activities/settings/OtaUpdateActivity.cpp (1)
166-174: Missing button hints for terminal states.The
NO_UPDATE,FAILED, andFINISHEDstates render status text but don't display button hints to inform the user how to navigate back. Theloop()method handlesBackbutton presses forNO_UPDATEandFAILED, but users won't see visual guidance.Consider adding button hints similar to
WAITING_CONFIRMATION:} else if (state == NO_UPDATE) { renderer.drawCenteredText(UI_10_FONT_ID, top, "No update available", true, EpdFontFamily::BOLD); + const auto labels = mappedInput.mapLabels("« Back", "", "", ""); + GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } else if (state == FAILED) { renderer.drawCenteredText(UI_10_FONT_ID, top, "Update failed", true, EpdFontFamily::BOLD); + const auto labels = mappedInput.mapLabels("« Back", "", "", ""); + GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } else if (state == FINISHED) {src/components/themes/lyra/Lyra3CoversTheme.cpp (1)
16-20: Remove unusedcoverWidthvariable.The
coverWidthvariable is declared in the anonymous namespace but never used in this file. This appears to be leftover from copying the structure fromLyraTheme.cpp.namespace { constexpr int hPaddingInSelection = 8; constexpr int cornerRadius = 6; -int coverWidth = 0; } // namespacesrc/components/themes/lyra/Lyra3CoversTheme.h (1)
1-3: Remove extraneous blank lines at file start.Minor style issue: the file starts with two blank lines before
#pragma once.- - `#pragma` oncesrc/components/themes/BaseTheme.cpp (2)
67-67: Remove or gate debug logging in production code.The
Serial.printfindrawProgressBarwill output to serial on every progress update. Consider removing this debug statement or guarding it with a debug flag:- Serial.printf("Drawing progress bar: current=%u, total=%u, percent=%d\n", current, total, percent);
262-281: Remove unused local constants indrawSubHeader.The constants
underlineHeightandunderlineGapare declared but never used in the function body:void BaseTheme::drawSubHeader(const GfxRenderer& renderer, Rect rect, const char* label, const char* rightLabel) const { - constexpr int underlineHeight = 2; // Height of selection underline - constexpr int underlineGap = 4; // Gap between text and underline constexpr int maxListValueWidth = 200;src/components/themes/lyra/LyraTheme.cpp (2)
23-23: Mutable namespace-scope variable can cause persistent state issues.
coverWidthis modified at runtime (lines 300, 322) and never reset. Once a bitmap sets this width, subsequent calls will use that width even for different books or after the cover fails to load. Consider making this a class member variable or passing it as an output parameter to avoid shared mutable state.
307-307: Consider usingconstreference to avoid copy.
RecentBook book = recentBooks[0];creates a full copy of the struct. Since the book is only read, using a const reference would be more efficient.♻️ Suggested change
- RecentBook book = recentBooks[0]; + const RecentBook& book = recentBooks[0];src/activities/settings/KOReaderAuthActivity.cpp (1)
126-148: Center the multi-line status block within the available content.
topis computed from a single-line height across the full page, but SUCCESS/FAILED render two lines. This makes the block sit low and can crowd header/button hints on smaller or landscape screens. Consider computing a block height and centering that (and, if available, within the content area below the header).Proposed adjustment
- const auto height = renderer.getLineHeight(UI_10_FONT_ID); - const auto top = (pageHeight - height) / 2; + const auto height = renderer.getLineHeight(UI_10_FONT_ID); + const auto lineCount = (state == SUCCESS || state == FAILED) ? 2 : 1; + const auto blockHeight = lineCount * height + (lineCount - 1) * 10; + const auto top = (pageHeight - blockHeight) / 2;src/activities/network/CrossPointWebServerActivity.cpp (2)
26-27: Align QR code height with the rendered size.The QR code is rendered as 33 modules × 6 px (= 198), but
QR_CODE_HEIGHTis set to 200. This small mismatch can accumulate into layout drift. Consider deriving height from width to keep the geometry consistent.🛠️ Suggested tweak
-constexpr int QR_CODE_HEIGHT = 200; +constexpr int QR_CODE_HEIGHT = QR_CODE_WIDTH;
386-399: Avoid double‑drawing the header/subheader in SERVER_RUNNING.
render()draws the header/subheader and thenrenderServerRunning()draws them again, duplicating work each render. Let one path own the header/subheader to keep responsibilities clear and reduce buffer work.♻️ Suggested refactor
- GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, - isApMode ? "Hotspot Mode" : "Network Transfer", nullptr); - - if (state == WebServerActivityState::SERVER_RUNNING) { - GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight}, - connectedSSID.c_str()); - renderServerRunning(); - } else { + if (state == WebServerActivityState::SERVER_RUNNING) { + renderServerRunning(); + } else { + GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, + isApMode ? "Hotspot Mode" : "Network Transfer", nullptr); const auto height = renderer.getLineHeight(UI_10_FONT_ID); const auto top = (pageHeight - height) / 2; renderer.drawCenteredText(UI_10_FONT_ID, top, "Starting Hotspot..."); }
I have added it directly to crosspoint, it can be found here: #911 |
Misconfigured coderabbit to block PRs
/!\ This PR depends on #732 being merged first Also requires the open-x4-epaper/community-sdk#18 PR ## Summary Lyra theme icons on the home menu, in the file browser and on empty book covers     ## Additional Context - Added a function to the open-x4-sdk renderer to draw transparent images - Added a scripts/convert_icon.py script to convert svg/png icons into a C array that can be directly imported into the project. Usage: ```bash python ./scripts/convert_icon.py 'path/to/icon.png' cover 32 32 ``` This will create a components/icons/cover.h file with a C array called CoverIcon, of size 32x32px. Lyra uses icons from https://lucide.dev/icons with a stroke width of 2px, that can be downloaded with any desired size on the site. > The file browser is noticeably slower with the addition of icons, and using an image buffer like on the home page doesn't help very much. Any suggestions to optimize this are welcome. --- ### 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**_ The icon conversion python script was generated by Copilot as I am not a python dev. --------- Co-authored-by: Dave Allie <[email protected]>
|
I just tried it and the navigation has improved incredibly, it feels super smooth!!! Thank you @CaptainFrito |
## Summary Implements Lyra theme for some more Crosspoint screens:       ## Additional Context - A bit of refactoring for list scrolling logic --- ### 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 <[email protected]>
/!\ This PR depends on crosspoint-reader#732 being merged first Also requires the open-x4-epaper/community-sdk#18 PR ## Summary Lyra theme icons on the home menu, in the file browser and on empty book covers     ## Additional Context - Added a function to the open-x4-sdk renderer to draw transparent images - Added a scripts/convert_icon.py script to convert svg/png icons into a C array that can be directly imported into the project. Usage: ```bash python ./scripts/convert_icon.py 'path/to/icon.png' cover 32 32 ``` This will create a components/icons/cover.h file with a C array called CoverIcon, of size 32x32px. Lyra uses icons from https://lucide.dev/icons with a stroke width of 2px, that can be downloaded with any desired size on the site. > The file browser is noticeably slower with the addition of icons, and using an image buffer like on the home page doesn't help very much. Any suggestions to optimize this are welcome. --- ### 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**_ The icon conversion python script was generated by Copilot as I am not a python dev. --------- Co-authored-by: Dave Allie <[email protected]>
## Summary Implements Lyra theme for some more Crosspoint screens:       ## Additional Context - A bit of refactoring for list scrolling logic --- ### 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 <[email protected]>
/!\ This PR depends on crosspoint-reader#732 being merged first Also requires the open-x4-epaper/community-sdk#18 PR ## Summary Lyra theme icons on the home menu, in the file browser and on empty book covers     ## Additional Context - Added a function to the open-x4-sdk renderer to draw transparent images - Added a scripts/convert_icon.py script to convert svg/png icons into a C array that can be directly imported into the project. Usage: ```bash python ./scripts/convert_icon.py 'path/to/icon.png' cover 32 32 ``` This will create a components/icons/cover.h file with a C array called CoverIcon, of size 32x32px. Lyra uses icons from https://lucide.dev/icons with a stroke width of 2px, that can be downloaded with any desired size on the site. > The file browser is noticeably slower with the addition of icons, and using an image buffer like on the home page doesn't help very much. Any suggestions to optimize this are welcome. --- ### 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**_ The icon conversion python script was generated by Copilot as I am not a python dev. --------- Co-authored-by: Dave Allie <[email protected]>
## Summary Implements Lyra theme for some more Crosspoint screens:       ## Additional Context - A bit of refactoring for list scrolling logic --- ### 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 <[email protected]>
/!\ This PR depends on crosspoint-reader#732 being merged first Also requires the open-x4-epaper/community-sdk#18 PR ## Summary Lyra theme icons on the home menu, in the file browser and on empty book covers     ## Additional Context - Added a function to the open-x4-sdk renderer to draw transparent images - Added a scripts/convert_icon.py script to convert svg/png icons into a C array that can be directly imported into the project. Usage: ```bash python ./scripts/convert_icon.py 'path/to/icon.png' cover 32 32 ``` This will create a components/icons/cover.h file with a C array called CoverIcon, of size 32x32px. Lyra uses icons from https://lucide.dev/icons with a stroke width of 2px, that can be downloaded with any desired size on the site. > The file browser is noticeably slower with the addition of icons, and using an image buffer like on the home page doesn't help very much. Any suggestions to optimize this are welcome. --- ### 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**_ The icon conversion python script was generated by Copilot as I am not a python dev. --------- Co-authored-by: Dave Allie <[email protected]>




Summary
Implements Lyra theme for some more Crosspoint screens:
Additional Context
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