Add configurable default home screen action
Themes can now specify an initialAction in home screen config to set the default selected action when entering home normally. Falls back to this theme setting when no explicit action is requested, but explicit firmware navigation still takes precedence.
This commit is contained in:
@@ -217,6 +217,14 @@ Home `navigation` modes:
|
||||
- `splitAxis`: front left/right move through launcher actions; side up/down move through recent-book actions. Bottom button hints show Left/Right.
|
||||
- `carousel`: front left/right move through recent-book actions; side up/down move through launcher actions. Use this when left/right should stay inside a cover carousel and up/down should enter or leave the launcher menu.
|
||||
|
||||
Home `initialAction` can optionally choose the default selected action when entering home normally:
|
||||
|
||||
```json
|
||||
"initialAction": "reader:recent"
|
||||
```
|
||||
|
||||
Supported values match launcher `action` values. Explicit firmware navigation, such as returning to Settings from a settings submenu, still overrides this default.
|
||||
|
||||
### Layouts vs widgets
|
||||
|
||||
Layouts only create named rectangles. They do not choose whether a screen is a list, cover grid, carousel, or any other presentation.
|
||||
|
||||
@@ -145,7 +145,9 @@ void HomeActivity::onEnter() {
|
||||
metrics.homeRecentBooksCount);
|
||||
|
||||
const auto& actions = refreshHomeActions();
|
||||
const ThemeHomeScreenSpec* homeSpec = UITheme::getInstance().getHomeScreenSpec();
|
||||
selectorIndex = 0;
|
||||
bool hasWantedAction = initialMenuItem != HomeMenuItem::NONE;
|
||||
const auto wantedAction = [this]() {
|
||||
switch (initialMenuItem) {
|
||||
case HomeMenuItem::RECENTS:
|
||||
@@ -162,15 +164,23 @@ void HomeActivity::onEnter() {
|
||||
return ThemeHomeAction::FileBrowser;
|
||||
}
|
||||
}();
|
||||
if (initialMenuItem != HomeMenuItem::NONE) {
|
||||
ThemeHomeAction selectedEntryAction = wantedAction;
|
||||
if (!hasWantedAction && homeSpec != nullptr && homeSpec->hasInitialAction) {
|
||||
hasWantedAction = true;
|
||||
selectedEntryAction = homeSpec->initialAction;
|
||||
}
|
||||
if (hasWantedAction) {
|
||||
for (int i = 0; i < static_cast<int>(actions.size()); ++i) {
|
||||
if (actions[i].action == wantedAction) {
|
||||
if (actions[i].action == selectedEntryAction) {
|
||||
selectorIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
coverSelectorIndex = recentBooks.empty() ? 0 : std::min(selectorIndex, static_cast<int>(recentBooks.size()) - 1);
|
||||
coverSelectorIndex = !recentBooks.empty() && selectorIndex < static_cast<int>(actions.size()) &&
|
||||
actions[selectorIndex].action == ThemeHomeAction::RecentBook
|
||||
? actions[selectorIndex].value
|
||||
: 0;
|
||||
|
||||
// Trigger first update
|
||||
requestUpdate();
|
||||
|
||||
@@ -688,6 +688,11 @@ void parseHomeScreenSpec(JsonObjectConst obj, ThemeHomeScreenSpec& out) {
|
||||
|
||||
out.enabled = true;
|
||||
out.navigation = parseHomeNavigationMode(obj["navigation"].as<const char*>(), out.navigation);
|
||||
const char* initialAction = obj["initialAction"].as<const char*>();
|
||||
if (initialAction != nullptr) {
|
||||
out.hasInitialAction = true;
|
||||
out.initialAction = parseHomeAction(initialAction);
|
||||
}
|
||||
out.layout = ThemeLayoutNode{};
|
||||
out.layout.id = "root";
|
||||
out.layout.sizeType = ThemeLayoutSizeType::Flex;
|
||||
|
||||
@@ -120,6 +120,8 @@ struct ThemeHomeWidgetSpec {
|
||||
struct ThemeHomeScreenSpec {
|
||||
bool enabled = false;
|
||||
ThemeHomeNavigationMode navigation = ThemeHomeNavigationMode::Linear;
|
||||
bool hasInitialAction = false;
|
||||
ThemeHomeAction initialAction = ThemeHomeAction::FileBrowser;
|
||||
ThemeLayoutNode layout;
|
||||
std::vector<ThemeHomeWidgetSpec> widgets;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user