Rework the reporting screen a bit

This commit is contained in:
Henrik Rydgård committed 2025-11-23 01:15:07 +01:00
1 parent 217e7c94a4
commit 6cc945e57a
9 files changed
+122 -107

No files matched your search

+87 -80
View File
@@ -37,11 +37,9 @@
#include "UI/PauseScreen.h"
#include "UI/ReportScreen.h"
using namespace UI;
class RatingChoice : public LinearLayout {
class RatingChoice : public UI::LinearLayout {
public:
RatingChoice(std::string_view captionKey, int *value, LayoutParams *layoutParams = 0);
RatingChoice(std::string_view captionKey, int *value, UI::LayoutParams *layoutParams = 0);
RatingChoice *SetEnabledPtrs(bool *enabled);
@@ -55,25 +53,25 @@ protected:
return 3;
}
void AddChoice(int i, std::string_view title);
StickyChoice *GetChoice(int i) {
return static_cast<StickyChoice *>(group_->GetViewByIndex(i));
UI::StickyChoice *GetChoice(int i) {
return static_cast<UI::StickyChoice *>(group_->GetViewByIndex(i));
}
LinearLayout *group_;
private:
void OnChoiceClick(EventParams &e);
void OnChoiceClick(UI::EventParams &e);
int *value_;
};
RatingChoice::RatingChoice(std::string_view captionKey, int *value, LayoutParams *layoutParams)
RatingChoice::RatingChoice(std::string_view captionKey, int *value, UI::LayoutParams *layoutParams)
: LinearLayout(ORIENT_VERTICAL, layoutParams), value_(value) {
SetSpacing(0.0f);
auto rp = GetI18NCategory(I18NCat::REPORTING);
group_ = new LinearLayout(ORIENT_HORIZONTAL);
Add(new TextView(rp->T(captionKey), FLAG_WRAP_TEXT, false))->SetShadow(true);
Add(new UI::TextView(rp->T(captionKey), FLAG_WRAP_TEXT, false))->SetShadow(true);
Add(group_);
group_->SetSpacing(0.0f);
@@ -84,7 +82,7 @@ void RatingChoice::Update() {
LinearLayout::Update();
for (int i = 0; i < TotalChoices(); i++) {
StickyChoice *chosen = GetChoice(i);
UI::StickyChoice *chosen = GetChoice(i);
bool down = chosen->IsDown();
if (down && *value_ != i) {
chosen->Release();
@@ -110,15 +108,15 @@ void RatingChoice::SetupChoices() {
}
void RatingChoice::AddChoice(int i, std::string_view title) {
auto c = group_->Add(new StickyChoice(title, ""));
auto c = group_->Add(new UI::StickyChoice(title, ""));
c->OnClick.Handle(this, &RatingChoice::OnChoiceClick);
}
void RatingChoice::OnChoiceClick(EventParams &e) {
void RatingChoice::OnChoiceClick(UI::EventParams &e) {
// Unstick the other choices that weren't clicked.
int total = TotalChoices();
for (int i = 0; i < total; i++) {
StickyChoice *v = GetChoice(i);
UI::StickyChoice *v = GetChoice(i);
if (v != e.v) {
v->Release();
} else {
@@ -126,7 +124,7 @@ void RatingChoice::OnChoiceClick(EventParams &e) {
}
}
EventParams e2{};
UI::EventParams e2{};
e2.v = e.v;
e2.a = *value_;
// Dispatch immediately (we're already on the UI thread as we're in an event handler).
@@ -135,7 +133,7 @@ void RatingChoice::OnChoiceClick(EventParams &e) {
class CompatRatingChoice : public RatingChoice {
public:
CompatRatingChoice(const char *captionKey, int *value, LayoutParams *layoutParams = 0);
CompatRatingChoice(const char *captionKey, int *value, UI::LayoutParams *layoutParams = 0);
protected:
void SetupChoices() override;
@@ -144,7 +142,7 @@ protected:
}
};
CompatRatingChoice::CompatRatingChoice(const char *captionKey, int *value, LayoutParams *layoutParams)
CompatRatingChoice::CompatRatingChoice(const char *captionKey, int *value, UI::LayoutParams *layoutParams)
: RatingChoice(captionKey, value, layoutParams) {
CompatRatingChoice::SetupChoices();
}
@@ -160,7 +158,7 @@ void CompatRatingChoice::SetupChoices() {
}
ReportScreen::ReportScreen(const Path &gamePath)
: UIDialogScreen(), gamePath_(gamePath) {
: UITwoPaneBaseDialogScreen(gamePath, TwoPaneFlags::SettingsToTheRight) {
enableReporting_ = Reporting::IsEnabled();
ratingEnabled_ = enableReporting_;
// Start computing a CRC immediately, we'll need it on submit.
@@ -196,20 +194,28 @@ ScreenRenderFlags ReportScreen::render(ScreenRenderMode mode) {
// We take the screenshot first, then we start rendering.
// We are the only screen visible so this avoid starting and then trying to resume a backbuffer render pass.
const ScreenRenderFlags flags = UIScreen::render(mode);
return flags;
return UITwoPaneBaseDialogScreen::render(mode);
}
// For the screenshotting functionality to work.
ScreenRenderRole ReportScreen::renderRole(bool isTop) const {
// if (tookScreenshot_) {
// return ScreenRenderRole::NONE;
// }
return ScreenRenderRole::MUST_BE_FIRST | ScreenRenderRole::CAN_BE_BACKGROUND;
}
void ReportScreen::update() {
if (screenshot_) {
if (includeScreenshot_) {
screenshot_->SetVisibility(V_VISIBLE);
screenshot_->SetVisibility(UI::V_VISIBLE);
} else {
screenshot_->SetVisibility(V_GONE);
screenshot_->SetVisibility(UI::V_GONE);
}
}
UIDialogScreen::update();
UpdateCRCInfo();
UpdateSubmit();
}
void ReportScreen::resized() {
@@ -217,7 +223,7 @@ void ReportScreen::resized() {
RecreateViews();
}
void ReportScreen::HandleChoice(EventParams &e) {
void ReportScreen::HandleChoice(UI::EventParams &e) {
if (overall_ == ReportingOverallScore::NONE) {
graphics_ = 0;
speed_ = 0;
@@ -244,7 +250,7 @@ void ReportScreen::HandleChoice(EventParams &e) {
UpdateOverallDescription();
}
void ReportScreen::HandleReportingChange(EventParams &e) {
void ReportScreen::HandleReportingChange(UI::EventParams &e) {
if (overall_ == ReportingOverallScore::NONE) {
ratingEnabled_ = false;
} else {
@@ -256,19 +262,35 @@ void ReportScreen::HandleReportingChange(EventParams &e) {
UpdateSubmit();
}
void ReportScreen::CreateViews() {
void ReportScreen::CreateSettingsViews(UI::ViewGroup *rightColumnItems) {
using namespace UI;
auto rp = GetI18NCategory(I18NCat::REPORTING);
auto di = GetI18NCategory(I18NCat::DIALOG);
Margins actionMenuMargins(0, 20, 15, 0);
Margins contentMargins(0, 20, 5, 5);
float leftColumnWidth = g_display.dp_xres - actionMenuMargins.horiz() - contentMargins.horiz() - 300.0f;
ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, FILL_PARENT, 0.4f, contentMargins));
LinearLayout *leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(WRAP_CONTENT, FILL_PARENT));
ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL);
rightColumnItems->Add(new Choice(rp->T("Open Browser"), ImageID("I_LINK_OUT")))->OnClick.Handle(this, &ReportScreen::HandleBrowser);
submit_ = new Choice(rp->T("Submit Feedback"), ImageID("I_CHECKMARK"));
rightColumnItems->Add(submit_)->OnClick.Handle(this, &ReportScreen::HandleSubmit);
submit_->SetEnabled(false); // Waiting for CRC
leftColumnItems->Add(new TextView(rp->T("FeedbackDesc", "How's the emulation? Let us and the community know!"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true);
UpdateSubmit();
}
void ReportScreen::CreateContentViews(UI::ViewGroup *parent) {
using namespace UI;
UI::ScrollView *scroll = new UI::ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f));
UI::LinearLayout *leftColumnItems = new UI::LinearLayout(ORIENT_VERTICAL, new UI::LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT));
scroll->Add(leftColumnItems);
parent->Add(scroll);
auto rp = GetI18NCategory(I18NCat::REPORTING);
auto di = GetI18NCategory(I18NCat::DIALOG);
bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
leftColumnItems->Add(new TextView(rp->T("FeedbackDesc", "How's the emulation? Let us and the community know!"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true);
if (!Reporting::IsEnabled()) {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
reportingNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDisabled", "Compatibility server reports must be enabled."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))));
@@ -309,36 +331,29 @@ void ReportScreen::CreateViews() {
overallDescription_ = leftColumnItems->Add(new TextView("", FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(10, 0))));
overallDescription_->SetShadow(true);
Orientation ratingsOrient = leftColumnWidth >= 750.0f ? ORIENT_HORIZONTAL : ORIENT_VERTICAL;
LinearLayout *ratingsHolder = new LinearLayoutList(ratingsOrient, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT));
LinearLayout *ratingsHolder = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT));
leftColumnItems->Add(ratingsHolder);
ratingsHolder->Add(new RatingChoice("Graphics", &graphics_))->SetEnabledPtrs(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
ratingsHolder->Add(new RatingChoice("Speed", &speed_))->SetEnabledPtrs(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
ratingsHolder->Add(new RatingChoice("Gameplay", &gameplay_))->SetEnabledPtrs(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
rightColumnItems->SetSpacing(0.0f);
rightColumnItems->Add(new Choice(rp->T("Open Browser")))->OnClick.Handle(this, &ReportScreen::HandleBrowser);
submit_ = new Choice(rp->T("Submit Feedback"));
rightColumnItems->Add(submit_)->OnClick.Handle(this, &ReportScreen::HandleSubmit);
submit_->SetEnabled(false); // Waiting for CRC
UpdateSubmit();
UpdateOverallDescription();
rightColumnItems->Add(new Spacer(25.0));
rightColumnItems->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
root_ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
root_->Add(leftColumn);
root_->Add(rightColumn);
leftColumn->Add(leftColumnItems);
rightColumn->Add(rightColumnItems);
UpdateCRCInfo();
UpdateOverallDescription();
}
void ReportScreen::UpdateSubmit() {
submit_->SetEnabled(enableReporting_ && overall_ != ReportingOverallScore::INVALID && graphics_ >= 0 && speed_ >= 0 && gameplay_ >= 0);
submit_->SetEnabled(Reporting::HasCRC(gamePath_) && enableReporting_ && overall_ != ReportingOverallScore::INVALID && graphics_ >= 0 && speed_ >= 0 && gameplay_ >= 0);
}
std::string_view ReportScreen::GetTitle() const {
if (titleCache_.empty()) {
titleCache_ = g_paramSFO.GetValueString("TITLE");
if (titleCache_.empty()) {
auto rp = GetI18NCategory(I18NCat::REPORTING);
titleCache_ = rp->T("Submit Feedback");
}
}
return titleCache_;
}
void ReportScreen::UpdateCRCInfo() {
@@ -348,14 +363,13 @@ void ReportScreen::UpdateCRCInfo() {
if (Reporting::HasCRC(gamePath_)) {
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_));
updated = ApplySafeSubstitutions(rp->T("FeedbackCRCValue", "Disc CRC: %1"), crc);
submit_->SetEnabled(true);
} else {
updated = rp->T("FeedbackCRCCalculating", "Disc CRC: Calculating...");
}
if (!updated.empty()) {
crcInfo_->SetText(updated);
crcInfo_->SetVisibility(V_VISIBLE);
crcInfo_->SetVisibility(UI::V_VISIBLE);
}
}
@@ -376,7 +390,7 @@ void ReportScreen::UpdateOverallDescription() {
overallDescription_->SetTextColor(c);
}
void ReportScreen::HandleSubmit(EventParams &e) {
void ReportScreen::HandleSubmit(UI::EventParams &e) {
const char *compat;
switch (overall_) {
case ReportingOverallScore::PERFECT: compat = "perfect"; break;
@@ -398,48 +412,39 @@ void ReportScreen::HandleSubmit(EventParams &e) {
screenManager()->push(new ReportFinishScreen(gamePath_, overall_));
}
void ReportScreen::HandleBrowser(EventParams &e) {
void ReportScreen::HandleBrowser(UI::EventParams &e) {
const std::string url = "https://" + Reporting::ServerHost() + "/";
System_LaunchUrl(LaunchUrlType::BROWSER_URL, url.c_str());
}
ReportFinishScreen::ReportFinishScreen(const Path &gamePath, ReportingOverallScore score)
: UIDialogScreen(), gamePath_(gamePath), score_(score) {
: UISimpleBaseDialogScreen(), gamePath_(gamePath), score_(score) {
}
void ReportFinishScreen::CreateViews() {
std::string_view ReportFinishScreen::GetTitle() const {
auto rp = GetI18NCategory(I18NCat::REPORTING);
return rp->T("Submit Feedback");
}
void ReportFinishScreen::CreateDialogViews(UI::ViewGroup *parent) {
auto rp = GetI18NCategory(I18NCat::REPORTING);
auto di = GetI18NCategory(I18NCat::DIALOG);
Margins actionMenuMargins(0, 20, 15, 0);
Margins contentMargins(0, 20, 5, 5);
ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, FILL_PARENT, 0.4f, contentMargins));
LinearLayout *leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(WRAP_CONTENT, FILL_PARENT));
ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL);
using namespace UI;
leftColumnItems->Add(new TextView(rp->T("FeedbackThanks", "Thanks for your feedback."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true);
parent->Add(new TextView(rp->T("FeedbackThanks", "Thanks for your feedback."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true);
if (score_ == ReportingOverallScore::PERFECT || score_ == ReportingOverallScore::PLAYABLE) {
resultNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDelayInfo", "Your data is being submitted in the background."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))));
resultNotice_ = parent->Add(new TextView(rp->T("FeedbackDelayInfo", "Your data is being submitted in the background."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))));
} else {
resultNotice_ = leftColumnItems->Add(new TextView(rp->T("SuggestionsWaiting", "Submitting and checking other user feedback.."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))));
resultNotice_ = parent->Add(new TextView(rp->T("SuggestionsWaiting", "Submitting and checking other user feedback.."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))));
}
resultNotice_->SetShadow(true);
resultItems_ = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(12, 5, 0, 5)));
leftColumnItems->Add(resultItems_);
parent->Add(resultItems_);
rightColumnItems->SetSpacing(0.0f);
rightColumnItems->Add(new Choice(rp->T("View Feedback")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback);
parent->Add(new Spacer(20.0f));
rightColumnItems->Add(new Spacer(25.0));
rightColumnItems->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
root_ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
root_->Add(leftColumn);
root_->Add(rightColumn);
leftColumn->Add(leftColumnItems);
rightColumn->Add(rightColumnItems);
parent->Add(new Choice(rp->T("View Feedback"), ImageID("I_LINK_OUT")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback);
}
void ReportFinishScreen::update() {
@@ -469,6 +474,8 @@ void ReportFinishScreen::update() {
}
void ReportFinishScreen::ShowSuggestions() {
using namespace UI;
auto rp = GetI18NCategory(I18NCat::REPORTING);
auto suggestions = Reporting::CompatibilitySuggestions();