UI fixes: Rework savedata manager a bit, default keyboard focus to Cancel in confirmation dialogs (#19771)

* Savedata manager screen: Use TabbedUIDialogScreenWithGameBackground

This fixes some minor UI issues on this screen.

* PromptScreen (used for "Are you sure?"): Default keyboard focus to Cancel

Fixes #19770
This commit is contained in:
Henrik Rydgård 2024-12-28 10:36:05 +01:00 committed by GitHub
parent cc040ab251
commit 88b4991753
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 80 additions and 68 deletions

View file

@ -309,6 +309,8 @@ public:
void PersistData(PersistStatus status, std::string anonId, PersistMap &storage) override;
LinearLayout *Container() { return tabContainer_; }
private:
void AddTabContents(std::string_view title, View *tabContents);
EventReturn OnTabClick(EventParams &e);

View file

@ -528,28 +528,26 @@ void PromptScreen::CreateViews() {
root_->Add(rightColumnItems);
Choice *yesButton = rightColumnItems->Add(new Choice(yesButtonText_));
yesButton->OnClick.Handle(this, &PromptScreen::OnYes);
root_->SetDefaultFocusView(yesButton);
yesButton->OnClick.Add([this](UI::EventParams &e) {
TriggerFinish(DR_OK);
return UI::EVENT_DONE;
});
if (!noButtonText_.empty()) {
rightColumnItems->Add(new Choice(noButtonText_))->OnClick.Handle(this, &PromptScreen::OnNo);
Choice *noButton = rightColumnItems->Add(new Choice(noButtonText_));
noButton->OnClick.Add([this](UI::EventParams &e) {
TriggerFinish(DR_CANCEL);
return UI::EVENT_DONE;
});
root_->SetDefaultFocusView(noButton);
} else {
// This is an information screen, not a question.
// Sneak in the version of PPSSPP in the corner, for debug-reporting user screenshots.
std::string version = System_GetProperty(SYSPROP_BUILD_VERSION);
root_->Add(new TextView(version, 0, true, new AnchorLayoutParams(10.0f, NONE, NONE, 10.0f)));
root_->SetDefaultFocusView(yesButton);
}
}
UI::EventReturn PromptScreen::OnYes(UI::EventParams &e) {
TriggerFinish(DR_OK);
return UI::EVENT_DONE;
}
UI::EventReturn PromptScreen::OnNo(UI::EventParams &e) {
TriggerFinish(DR_CANCEL);
return UI::EVENT_DONE;
}
void PromptScreen::TriggerFinish(DialogResult result) {
if (callback_) {
callback_(result == DR_OK || result == DR_YES);

View file

@ -97,9 +97,6 @@ public:
const char *tag() const override { return "Prompt"; }
private:
UI::EventReturn OnYes(UI::EventParams &e);
UI::EventReturn OnNo(UI::EventParams &e);
std::string message_;
std::string yesButtonText_;
std::string noButtonText_;

View file

@ -595,9 +595,6 @@ UI::EventReturn SavedataBrowser::SavedataButtonClick(UI::EventParams &e) {
return UI::EVENT_DONE;
}
SavedataScreen::SavedataScreen(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {
}
SavedataScreen::~SavedataScreen() {
if (g_gameInfoCache) {
g_gameInfoCache->PurgeType(IdentifiedFileType::PPSSPP_SAVESTATE);
@ -605,65 +602,73 @@ SavedataScreen::~SavedataScreen() {
}
}
void SavedataScreen::CreateViews() {
using namespace UI;
void SavedataScreen::CreateSavedataTab(UI::ViewGroup *savedata) {
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
using namespace UI;
Path savedata_dir = GetSysDirectory(DIRECTORY_SAVEDATA);
Path savestate_dir = GetSysDirectory(DIRECTORY_SAVESTATE);
gridStyle_ = false;
root_ = new AnchorLayout();
ChoiceStrip *sortStrip = new ChoiceStrip(ORIENT_HORIZONTAL, new LinearLayoutParams(0.0f, UI::Gravity::G_CENTER));
sortStrip->AddChoice(sa->T("Filename"));
sortStrip->AddChoice(sa->T("Size"));
sortStrip->AddChoice(sa->T("Date"));
sortStrip->SetSelection((int)sortOption_, false);
sortStrip->OnChoice.Add([this](UI::EventParams &e) {
sortOption_ = SavedataSortOption(e.a);
dataBrowser_->SetSortOption(sortOption_);
return UI::EVENT_DONE;
});
savedata->Add(sortStrip);
// Make space for buttons.
LinearLayout *main = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(FILL_PARENT, FILL_PARENT, 0, 0, 0, 84.0f));
TabHolder *tabs = new TabHolder(ORIENT_HORIZONTAL, 64, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
tabs->SetTag("Savedata");
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scroll->SetTag("SavedataBrowser");
dataBrowser_ = scroll->Add(new SavedataBrowser(savedata_dir, new LayoutParams(FILL_PARENT, FILL_PARENT)));
dataBrowser_ = savedata->Add(new SavedataBrowser(savedata_dir, new LayoutParams(FILL_PARENT, FILL_PARENT)));
dataBrowser_->SetSortOption(sortOption_);
if (!searchFilter_.empty())
dataBrowser_->SetSearchFilter(searchFilter_);
dataBrowser_->OnChoice.Handle(this, &SavedataScreen::OnSavedataButtonClick);
tabs->AddTab(sa->T("Save Data"), scroll);
}
ScrollView *scroll2 = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scroll2->SetTag("SavedataStatesBrowser");
stateBrowser_ = scroll2->Add(new SavedataBrowser(savestate_dir));
stateBrowser_->SetSortOption(sortOption_);
if (!searchFilter_.empty())
stateBrowser_->SetSearchFilter(searchFilter_);
stateBrowser_->OnChoice.Handle(this, &SavedataScreen::OnSavedataButtonClick);
tabs->AddTab(sa->T("Save States"), scroll2);
void SavedataScreen::CreateSavestateTab(UI::ViewGroup *savestate) {
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
using namespace UI;
Path savestate_dir = GetSysDirectory(DIRECTORY_SAVESTATE);
main->Add(tabs);
ChoiceStrip *sortStrip = new ChoiceStrip(ORIENT_HORIZONTAL, new AnchorLayoutParams(NONE, 0, 0, NONE));
ChoiceStrip *sortStrip = new ChoiceStrip(ORIENT_HORIZONTAL);
sortStrip->AddChoice(sa->T("Filename"));
sortStrip->AddChoice(sa->T("Size"));
sortStrip->AddChoice(sa->T("Date"));
sortStrip->SetSelection((int)sortOption_, false);
sortStrip->OnChoice.Handle<SavedataScreen>(this, &SavedataScreen::OnSortClick);
sortStrip->OnChoice.Add([this](UI::EventParams &e) {
sortOption_ = SavedataSortOption(e.a);
stateBrowser_->SetSortOption(sortOption_);
return UI::EVENT_DONE;
});
savestate->Add(sortStrip);
AddStandardBack(root_);
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
auto di = GetI18NCategory(I18NCat::DIALOG);
root_->Add(new Choice(di->T("Search"), "", false, new AnchorLayoutParams(WRAP_CONTENT, 64, NONE, NONE, 10, 10)))->OnClick.Handle<SavedataScreen>(this, &SavedataScreen::OnSearch);
}
root_->Add(main);
root_->Add(sortStrip);
stateBrowser_ = savestate->Add(new SavedataBrowser(savestate_dir));
stateBrowser_->SetSortOption(sortOption_);
if (!searchFilter_.empty())
stateBrowser_->SetSearchFilter(searchFilter_);
stateBrowser_->OnChoice.Handle(this, &SavedataScreen::OnSavedataButtonClick);
}
UI::EventReturn SavedataScreen::OnSortClick(UI::EventParams &e) {
sortOption_ = SavedataSortOption(e.a);
void SavedataScreen::CreateTabs() {
using namespace UI;
auto sa = GetI18NCategory(I18NCat::SAVEDATA);
dataBrowser_->SetSortOption(sortOption_);
stateBrowser_->SetSortOption(sortOption_);
LinearLayout *savedata = AddTab("SavedataBrowser", sa->T("Save Data"));
CreateSavedataTab(savedata);
return UI::EVENT_DONE;
LinearLayout *savestate = AddTab("SavedataStatesBrowser", sa->T("Save States"));
CreateSavestateTab(savestate);
}
void SavedataScreen::CreateExtraButtons(UI::LinearLayout *verticalLayout, int margins) {
using namespace UI;
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
auto di = GetI18NCategory(I18NCat::DIALOG);
verticalLayout->Add(new Choice(di->T("Search"), "", false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0, 0, margins, margins))))
->OnClick.Handle<SavedataScreen>(this, &SavedataScreen::OnSearch);
}
}
UI::EventReturn SavedataScreen::OnSearch(UI::EventParams &e) {

View file

@ -28,6 +28,7 @@
#include "UI/MiscScreens.h"
#include "UI/GameInfoCache.h"
#include "UI/TabbedDialogScreen.h"
enum class SavedataSortOption {
FILENAME,
@ -66,10 +67,10 @@ private:
bool searchPending_ = false;
};
class SavedataScreen : public UIDialogScreenWithGameBackground {
class SavedataScreen : public TabbedUIDialogScreenWithGameBackground {
public:
// gamePath can be empty, in that case this screen will show all savedata in the save directory.
SavedataScreen(const Path &gamePath);
SavedataScreen(const Path &gamePath) : TabbedUIDialogScreenWithGameBackground(gamePath) {}
~SavedataScreen();
void dialogFinished(const Screen *dialog, DialogResult result) override;
@ -78,15 +79,22 @@ public:
const char *tag() const override { return "Savedata"; }
protected:
UI::EventReturn OnSavedataButtonClick(UI::EventParams &e);
UI::EventReturn OnSortClick(UI::EventParams &e);
UI::EventReturn OnSearch(UI::EventParams &e);
void CreateViews() override;
void CreateTabs() override;
void CreateExtraButtons(UI::LinearLayout *verticalLayout, int margins) override;
bool gridStyle_;
bool ShowSearchControls() const override { return false; }
private:
UI::EventReturn OnSavedataButtonClick(UI::EventParams &e);
UI::EventReturn OnSearch(UI::EventParams &e);
void CreateSavedataTab(UI::ViewGroup *savedata);
void CreateSavestateTab(UI::ViewGroup *savestate);
bool gridStyle_ = false;
SavedataSortOption sortOption_ = SavedataSortOption::FILENAME;
SavedataBrowser *dataBrowser_;
SavedataBrowser *stateBrowser_;
SavedataBrowser *dataBrowser_ = nullptr;
SavedataBrowser *stateBrowser_ = nullptr;
std::string searchFilter_;
};

View file

@ -45,10 +45,12 @@ void TabbedUIDialogScreenWithGameBackground::CreateViews() {
LinearLayout *verticalLayout = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 200, new LinearLayoutParams(1.0f));
verticalLayout->Add(tabHolder_);
CreateExtraButtons(verticalLayout, 0);
verticalLayout->Add(new Choice(di->T("Back"), "", false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0))))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
root_->Add(verticalLayout);
} else {
tabHolder_ = new TabHolder(ORIENT_VERTICAL, 200, new AnchorLayoutParams(10, 0, 10, 0, false));
CreateExtraButtons(tabHolder_->Container(), 10);
tabHolder_->AddBack(this);
root_->Add(tabHolder_);
}

View file

@ -14,11 +14,11 @@ public:
UI::LinearLayout *AddTab(const char *tag, std::string_view title, bool isSearch = false);
void CreateViews() override;
protected:
// Load data and define your tabs here.
virtual void PreCreateViews() {}
virtual void CreateTabs() = 0;
virtual void CreateExtraButtons(UI::LinearLayout *verticalLayout, int margins) {}
virtual bool ShowSearchControls() const { return true; }
void RecreateViews() override;