fix: small QoL: return to the last selected menu location (#1629)
## Summary * **What is the goal of this PR?** Small UX improvement to the Home screen by preserving the last selected cursor position when returning to it. It supersedes #985 and #1103, which are both significantly outdated and hundreds of commits behind master. --- ### AI Usage Did you use AI tools to help write this code? _**< YES >**_
This commit is contained in:
@@ -10,7 +10,7 @@ void Activity::requestUpdate(bool immediate) { activityManager.requestUpdate(imm
|
|||||||
|
|
||||||
void Activity::requestUpdateAndWait() { activityManager.requestUpdateAndWait(); }
|
void Activity::requestUpdateAndWait() { activityManager.requestUpdateAndWait(); }
|
||||||
|
|
||||||
void Activity::onGoHome() { activityManager.goHome(); }
|
void Activity::onGoHome(HomeMenuItem item) { activityManager.goHome(item); }
|
||||||
|
|
||||||
void Activity::onSelectBook(const std::string& path) { activityManager.goToReader(path); }
|
void Activity::onSelectBook(const std::string& path) { activityManager.goToReader(path); }
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,6 @@ class Activity {
|
|||||||
|
|
||||||
// Convenience method to facilitate API transition to ActivityManager
|
// Convenience method to facilitate API transition to ActivityManager
|
||||||
// TODO: remove this in near future
|
// TODO: remove this in near future
|
||||||
void onGoHome();
|
void onGoHome(HomeMenuItem item = HomeMenuItem::NONE);
|
||||||
void onSelectBook(const std::string& path);
|
void onSelectBook(const std::string& path);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -207,10 +207,25 @@ void ActivityManager::goToFullScreenMessage(std::string message, EpdFontFamily::
|
|||||||
replaceActivity(std::make_unique<FullScreenMessageActivity>(renderer, mappedInput, std::move(message), style));
|
replaceActivity(std::make_unique<FullScreenMessageActivity>(renderer, mappedInput, std::move(message), style));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActivityManager::goHome(HomeMenuItem initialMenuItem) {
|
||||||
|
if (initialMenuItem == HomeMenuItem::NONE && currentActivity) {
|
||||||
|
const auto& activityName = currentActivity->name;
|
||||||
|
if (activityName == "FileBrowser") {
|
||||||
|
initialMenuItem = HomeMenuItem::FILE_BROWSER;
|
||||||
|
} else if (activityName == "RecentBooks") {
|
||||||
|
initialMenuItem = HomeMenuItem::RECENTS;
|
||||||
|
} else if (activityName == "OpdsBookBrowser") {
|
||||||
|
initialMenuItem = HomeMenuItem::OPDS_BROWSER;
|
||||||
|
} else if (activityName == "CrossPointWebServer") {
|
||||||
|
initialMenuItem = HomeMenuItem::FILE_TRANSFER;
|
||||||
|
} else if (activityName == "Settings") {
|
||||||
|
initialMenuItem = HomeMenuItem::SETTINGS_MENU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replaceActivity(std::make_unique<HomeActivity>(renderer, mappedInput, initialMenuItem));
|
||||||
|
}
|
||||||
void ActivityManager::goToCrashReport() { replaceActivity(std::make_unique<CrashActivity>(renderer, mappedInput)); }
|
void ActivityManager::goToCrashReport() { replaceActivity(std::make_unique<CrashActivity>(renderer, mappedInput)); }
|
||||||
|
|
||||||
void ActivityManager::goHome() { replaceActivity(std::make_unique<HomeActivity>(renderer, mappedInput)); }
|
|
||||||
|
|
||||||
void ActivityManager::pushActivity(std::unique_ptr<Activity>&& activity) {
|
void ActivityManager::pushActivity(std::unique_ptr<Activity>&& activity) {
|
||||||
if (pendingActivity) {
|
if (pendingActivity) {
|
||||||
// Should never happen in practice
|
// Should never happen in practice
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
class Activity; // forward declaration
|
class Activity; // forward declaration
|
||||||
class RenderLock; // forward declaration
|
class RenderLock; // forward declaration
|
||||||
|
|
||||||
|
enum class HomeMenuItem { NONE, FILE_BROWSER, RECENTS, OPDS_BROWSER, FILE_TRANSFER, SETTINGS_MENU };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityManager
|
* ActivityManager
|
||||||
*
|
*
|
||||||
@@ -88,7 +90,7 @@ class ActivityManager {
|
|||||||
void goToBoot();
|
void goToBoot();
|
||||||
void goToFullScreenMessage(std::string message, EpdFontFamily::Style style = EpdFontFamily::REGULAR);
|
void goToFullScreenMessage(std::string message, EpdFontFamily::Style style = EpdFontFamily::REGULAR);
|
||||||
void goToCrashReport();
|
void goToCrashReport();
|
||||||
void goHome();
|
void goHome(HomeMenuItem initialMenuItem = HomeMenuItem::NONE);
|
||||||
|
|
||||||
// This will move current activity to stack instead of deleting it
|
// This will move current activity to stack instead of deleting it
|
||||||
void pushActivity(std::unique_ptr<Activity>&& activity);
|
void pushActivity(std::unique_ptr<Activity>&& activity);
|
||||||
|
|||||||
@@ -113,11 +113,12 @@ void HomeActivity::onEnter() {
|
|||||||
|
|
||||||
hasOpdsServers = OPDS_STORE.hasServers();
|
hasOpdsServers = OPDS_STORE.hasServers();
|
||||||
|
|
||||||
selectorIndex = 0;
|
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
loadRecentBooks(metrics.homeRecentBooksCount);
|
loadRecentBooks(metrics.homeRecentBooksCount);
|
||||||
|
|
||||||
|
const auto base = static_cast<int>(recentBooks.size());
|
||||||
|
selectorIndex = initialMenuItem == HomeMenuItem::NONE ? 0 : base + menuItemToIndex(initialMenuItem, hasOpdsServers);
|
||||||
|
|
||||||
// Trigger first update
|
// Trigger first update
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
@@ -179,27 +180,29 @@ void HomeActivity::loop() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
|
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
|
||||||
// Calculate dynamic indices based on which options are available
|
|
||||||
int idx = 0;
|
|
||||||
int menuSelectedIndex = selectorIndex - static_cast<int>(recentBooks.size());
|
|
||||||
const int fileBrowserIdx = idx++;
|
|
||||||
const int recentsIdx = idx++;
|
|
||||||
const int opdsLibraryIdx = hasOpdsServers ? idx++ : -1;
|
|
||||||
const int fileTransferIdx = idx++;
|
|
||||||
const int settingsIdx = idx;
|
|
||||||
|
|
||||||
if (selectorIndex < recentBooks.size()) {
|
if (selectorIndex < recentBooks.size()) {
|
||||||
onSelectBook(recentBooks[selectorIndex].path);
|
onSelectBook(recentBooks[selectorIndex].path);
|
||||||
} else if (menuSelectedIndex == fileBrowserIdx) {
|
} else {
|
||||||
|
const int menuIndex = selectorIndex - static_cast<int>(recentBooks.size());
|
||||||
|
switch (indexToMenuItem(menuIndex, hasOpdsServers)) {
|
||||||
|
case HomeMenuItem::FILE_BROWSER:
|
||||||
onFileBrowserOpen();
|
onFileBrowserOpen();
|
||||||
} else if (menuSelectedIndex == recentsIdx) {
|
break;
|
||||||
|
case HomeMenuItem::RECENTS:
|
||||||
onRecentsOpen();
|
onRecentsOpen();
|
||||||
} else if (menuSelectedIndex == opdsLibraryIdx) {
|
break;
|
||||||
|
case HomeMenuItem::OPDS_BROWSER:
|
||||||
onOpdsBrowserOpen();
|
onOpdsBrowserOpen();
|
||||||
} else if (menuSelectedIndex == fileTransferIdx) {
|
break;
|
||||||
|
case HomeMenuItem::FILE_TRANSFER:
|
||||||
onFileTransferOpen();
|
onFileTransferOpen();
|
||||||
} else if (menuSelectedIndex == settingsIdx) {
|
break;
|
||||||
|
case HomeMenuItem::SETTINGS_MENU:
|
||||||
onSettingsOpen();
|
onSettingsOpen();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,33 @@ class HomeActivity final : public Activity {
|
|||||||
int coverRectW = 0;
|
int coverRectW = 0;
|
||||||
int coverRectH = 0;
|
int coverRectH = 0;
|
||||||
std::vector<RecentBook> recentBooks;
|
std::vector<RecentBook> recentBooks;
|
||||||
|
const HomeMenuItem initialMenuItem;
|
||||||
|
|
||||||
|
// Convert HomeMenuItem to menu index (used in onEnter)
|
||||||
|
static int menuItemToIndex(HomeMenuItem item, bool hasOpdsUrl) {
|
||||||
|
int i = 0;
|
||||||
|
if (item == HomeMenuItem::FILE_BROWSER) return i;
|
||||||
|
++i;
|
||||||
|
if (item == HomeMenuItem::RECENTS) return i;
|
||||||
|
++i;
|
||||||
|
if (item == HomeMenuItem::OPDS_BROWSER) return hasOpdsUrl ? i : 0;
|
||||||
|
if (hasOpdsUrl) ++i;
|
||||||
|
if (item == HomeMenuItem::FILE_TRANSFER) return i;
|
||||||
|
++i;
|
||||||
|
if (item == HomeMenuItem::SETTINGS_MENU) return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert menu index to HomeMenuItem (used in loop)
|
||||||
|
static HomeMenuItem indexToMenuItem(int idx, bool hasOpdsUrl) {
|
||||||
|
int i = 0;
|
||||||
|
if (idx == i++) return HomeMenuItem::FILE_BROWSER;
|
||||||
|
if (idx == i++) return HomeMenuItem::RECENTS;
|
||||||
|
if (hasOpdsUrl && idx == i++) return HomeMenuItem::OPDS_BROWSER;
|
||||||
|
if (idx == i++) return HomeMenuItem::FILE_TRANSFER;
|
||||||
|
if (idx == i) return HomeMenuItem::SETTINGS_MENU;
|
||||||
|
return HomeMenuItem::NONE;
|
||||||
|
}
|
||||||
void onSelectBook(const std::string& path);
|
void onSelectBook(const std::string& path);
|
||||||
void onFileBrowserOpen();
|
void onFileBrowserOpen();
|
||||||
void onRecentsOpen();
|
void onRecentsOpen();
|
||||||
@@ -43,8 +70,9 @@ class HomeActivity final : public Activity {
|
|||||||
void loadRecentCovers(int coverHeight);
|
void loadRecentCovers(int coverHeight);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HomeActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
|
explicit HomeActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
|
||||||
: Activity("Home", renderer, mappedInput) {}
|
HomeMenuItem initialMenuItemValue = HomeMenuItem::NONE)
|
||||||
|
: Activity("Home", renderer, mappedInput), initialMenuItem(initialMenuItemValue) {}
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void onExit() override;
|
void onExit() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ void OpdsServerListActivity::onExit() { Activity::onExit(); }
|
|||||||
void OpdsServerListActivity::loop() {
|
void OpdsServerListActivity::loop() {
|
||||||
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
|
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
|
||||||
if (pickerMode) {
|
if (pickerMode) {
|
||||||
activityManager.goHome();
|
activityManager.goHome(HomeMenuItem::OPDS_BROWSER);
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user