| 945 | } |
| 946 | |
| 947 | void SettingsScreen::update(const InputState& input) |
| 948 | { |
| 949 | if (mFlashTimer > 0) |
| 950 | mFlashTimer--; |
| 951 | |
| 952 | // A structural action last frame (or one from a dismissed overlay) marked |
| 953 | // the row list stale; rebuild before we touch any Row. |
| 954 | if (mNeedsRebuild) { |
| 955 | mNeedsRebuild = false; |
| 956 | rebuildRows(); |
| 957 | } |
| 958 | |
| 959 | const u64 kdown = input.kDown; |
| 960 | |
| 961 | // L/R jump categories from anywhere (shoulder shortcut). |
| 962 | if (kdown & HidNpadButton_L) { |
| 963 | switchCategory(-1); |
| 964 | return; |
| 965 | } |
| 966 | if (kdown & HidNpadButton_R) { |
| 967 | switchCategory(1); |
| 968 | return; |
| 969 | } |
| 970 | |
| 971 | // ---- Category rail focused: Up/Down pick a category, Right/A enters the |
| 972 | // rows, B leaves for the MainScreen we came from (deferred so we don't |
| 973 | // destroy ourselves mid-update; main() swaps after doUpdate). ---- |
| 974 | if (mCatFocused) { |
| 975 | if (kdown & HidNpadButton_B) { |
| 976 | g_pendingScreen = mReturnTo; |
| 977 | return; |
| 978 | } |
| 979 | if (kdown & HidNpadButton_Up) { |
| 980 | switchCategory(-1); |
| 981 | } |
| 982 | else if (kdown & HidNpadButton_Down) { |
| 983 | switchCategory(1); |
| 984 | } |
| 985 | const bool canEnter = hasFocusableRow() || (mCategory == Category::Logs && !mLogLines.empty()); |
| 986 | if ((kdown & (HidNpadButton_Right | HidNpadButton_A)) && canEnter) { |
| 987 | mCatFocused = false; // rebuildRows() already parked mCursor on the first focusable row |
| 988 | } |
| 989 | return; |
| 990 | } |
| 991 | |
| 992 | // ---- Logs pane focused: Up/Down scroll the log lines (d-pad auto-repeat), |
| 993 | // B/Left returns to the category rail. ---- |
| 994 | if (mCategory == Category::Logs) { |
| 995 | if ((kdown & HidNpadButton_B) || (kdown & HidNpadButton_Left)) { |
| 996 | mCatFocused = true; |
| 997 | return; |
| 998 | } |
| 999 | const int maxScroll = std::max(0, (int)mLogLines.size() - logLinesPerPage()); |
| 1000 | const u64 kheld = input.kHeld; |
| 1001 | auto up = [&]() { mLogScroll = std::max(0, mLogScroll - 1); }; |
| 1002 | auto down = [&]() { mLogScroll = std::min(maxScroll, mLogScroll + 1); }; |
| 1003 | if (kdown & HidNpadButton_AnyUp) { |
| 1004 | up(); |