From 13af9d5a9bd9473ce7ffecf864fa829bddff9982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 8 Jan 2026 23:18:26 +0100 Subject: [PATCH] Savestate UI: Add one more way to select the current state --- Common/UI/View.cpp | 2 +- Common/UI/View.h | 3 +-- UI/PauseScreen.cpp | 44 +++++++++++++++++++++++++++----------------- UI/PauseScreen.h | 2 -- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index e0e3891d0a..75fe18ba44 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -1070,7 +1070,7 @@ const FontStyle *SimpleTextView::ComputeStyle(const UIContext &dc) const { } } -const FontStyle *TextView::GetTextStyle(const UIContext &dc, TextSize size) { +const FontStyle *GetTextStyle(const UIContext &dc, TextSize size) { const FontStyle *style = &dc.GetTheme().uiFont; switch (size) { case TextSize::Tiny: diff --git a/Common/UI/View.h b/Common/UI/View.h index 4e02bc30ba..39108d6db4 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -1047,8 +1047,6 @@ public: bool CanBeFocused() const override { return focusable_; } private: - static const FontStyle *GetTextStyle(const UIContext &dc, TextSize size); - std::string text_; int textAlign_; uint32_t textColor_; @@ -1190,5 +1188,6 @@ bool IsTabRightKey(const KeyInput &key); // TODO: Doesn't really belong here. void DrawIconShine(UIContext &dc, const Bounds &bounds, float shine, bool animated); +const FontStyle *GetTextStyle(const UIContext &dc, TextSize size); } // namespace diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index d4ec91688b..96b6b87d83 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -211,6 +211,7 @@ public: UI::Event OnStateLoaded; UI::Event OnStateSaved; UI::Event OnScreenshotClicked; + UI::Event OnSelected; private: void OnSaveState(UI::EventParams &e); @@ -232,7 +233,13 @@ SaveSlotView::SaveSlotView(const Path &gameFilename, int slot, UI::LayoutParams std::string number = StringFromFormat("%d", slot + 1); Add(new Spacer(5)); - Add(new TextView(number, new LinearLayoutParams(40.0f, WRAP_CONTENT, 0.0f, Gravity::G_VCENTER)))->SetBig(true); + // TEMP HACK: use some other view, like a Choice, themed differently to enable keyboard access to selection. + ClickableTextView *numberView = Add(new ClickableTextView(number, new LinearLayoutParams(40.0f, WRAP_CONTENT, 0.0f, Gravity::G_VCENTER))); + numberView->SetBig(true); + numberView->OnClick.Add([this](UI::EventParams &e) { + e.v = this; + OnSelected.Trigger(e); + }); AsyncImageFileView *fv = Add(new AsyncImageFileView(screenshotFilename_, IS_DEFAULT, new UI::LayoutParams(82 * 2, 47 * 2))); @@ -369,23 +376,38 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems) SaveSlotView *slot = leftColumnItems->Add(new SaveSlotView(gamePath_, i, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Gravity::G_HCENTER, Margins(0,0,0,0)))); slot->OnStateLoaded.Handle(this, &GamePauseScreen::OnState); slot->OnStateSaved.Handle(this, &GamePauseScreen::OnState); - slot->OnScreenshotClicked.Handle(this, &GamePauseScreen::OnScreenshotClicked); + slot->OnScreenshotClicked.Add([this](UI::EventParams &e) { + SaveSlotView *v = static_cast(e.v); + int slot = v->GetSlot(); + g_Config.iCurrentStateSlot = v->GetSlot(); + if (SaveState::HasSaveInSlot(gamePath_, slot)) { + Path fn = v->GetScreenshotFilename(); + std::string title = v->GetScreenshotTitle(); + Screen *screen = new ScreenshotViewScreen(fn, title, v->GetSlot(), gamePath_); + screenManager()->push(screen); + } + }); + slot->OnSelected.Add([this](UI::EventParams &e) { + SaveSlotView *v = static_cast(e.v); + g_Config.iCurrentStateSlot = v->GetSlot(); + RecreateViews(); + }); } leftColumnItems->Add(new Spacer(0.0)); LinearLayout *buttonRow = leftColumnItems->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(Margins(10, 0, 0, 0)))); if (g_Config.bEnableStateUndo && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) { - UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"))); + UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"))); loadUndoButton->SetEnabled(SaveState::HasUndoLoad(gamePath_)); loadUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLoadUndo); - UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"))); + UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"))); saveUndoButton->SetEnabled(SaveState::HasUndoLastSave(gamePath_)); saveUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLastSaveUndo); } if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) { - UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"))); + UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"), ImageID("I_REWIND"))); rewindButton->SetEnabled(SaveState::CanRewind()); rewindButton->OnClick.Handle(this, &GamePauseScreen::OnRewind); } @@ -721,18 +743,6 @@ void GamePauseScreen::dialogFinished(const Screen *dialog, DialogResult dr) { } } -void GamePauseScreen::OnScreenshotClicked(UI::EventParams &e) { - SaveSlotView *v = static_cast(e.v); - int slot = v->GetSlot(); - g_Config.iCurrentStateSlot = v->GetSlot(); - if (SaveState::HasSaveInSlot(gamePath_, slot)) { - Path fn = v->GetScreenshotFilename(); - std::string title = v->GetScreenshotTitle(); - Screen *screen = new ScreenshotViewScreen(fn, title, v->GetSlot(), gamePath_); - screenManager()->push(screen); - } -} - int GetUnsavedProgressSeconds() { const double timeSinceSaveState = SaveState::SecondsSinceLastSavestate(); const double timeSinceGameSave = SecondsSinceLastGameSave(); diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index 27039c0596..fe2dc13ff4 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -53,8 +53,6 @@ private: void OnLoadUndo(UI::EventParams &e); void OnLastSaveUndo(UI::EventParams &e); - void OnScreenshotClicked(UI::EventParams &e); - void OnCreateConfig(UI::EventParams &e); void OnDeleteConfig(UI::EventParams &e);